[dev.cc] cmd/internal/obj: reconvert from liblink

cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.

- Brings in new, more regular Prog, Addr definitions

- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).

- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
  They need to be updated for the changes.

- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.

All architectures build successfully again.

Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Russ Cox 2015-02-05 03:57:44 -05:00
parent 8db173b85e
commit 1fc330d8fe
54 changed files with 6531 additions and 6787 deletions

View File

@ -1,3 +1,5 @@
// +build ignore
// Copyright 2015 The Go Authors. All rights reserved. // Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,3 +1,5 @@
// +build ignore
// Copyright 2015 The Go Authors. All rights reserved. // Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,3 +1,5 @@
// +build ignore
// Copyright 2014 The Go Authors. All rights reserved. // Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,3 +1,5 @@
// +build ignore
// Copyright 2015 The Go Authors. All rights reserved. // Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,3 +1,5 @@
// +build ignore
// Copyright 2015 The Go Authors. All rights reserved. // Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,3 +1,5 @@
// +build ignore
// Copyright 2014 The Go Authors. All rights reserved. // Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1678,7 +1678,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool,
// verifyAsm specifies whether to check the assemblers written in Go // verifyAsm specifies whether to check the assemblers written in Go
// against the assemblers written in C. If set, asm will run both (say) 6a and new6a // against the assemblers written in C. If set, asm will run both (say) 6a and new6a
// and fail if the two produce different output files. // and fail if the two produce different output files.
const verifyAsm = false const verifyAsm = true
func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files. // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
@ -1691,8 +1691,8 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
if verifyAsm { if verifyAsm {
newArgs := make([]interface{}, len(args)) newArgs := make([]interface{}, len(args))
copy(newArgs, args) copy(newArgs, args)
newArgs[0] = tool("new" + archChar + "a") newArgs[1] = tool("new" + archChar + "a")
newArgs[2] = ofile + ".new" // x.6 becomes x.6.new newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil { if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
return err return err
} }
@ -1705,7 +1705,7 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
return err return err
} }
if !bytes.Equal(data1, data2) { if !bytes.Equal(data1, data2) {
return fmt.Errorf("%sa and n%sa produced different output files:\n%s\n%s", archChar, archChar, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " ")) return fmt.Errorf("%sa and new%sa produced different output files:\n%s\n%s", archChar, archChar, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " "))
} }
} }
return nil return nil

View File

@ -30,17 +30,7 @@
package arm package arm
// list[5689].c import "cmd/internal/obj"
// obj.c
// objfile.c
// pass.c
// pcln.c
// sym.c
// TODO(ality): remove this workaround. // TODO(ality): remove this workaround.
// It's here because Pconv in liblink/list?.c references %L. // It's here because Pconv in liblink/list?.c references %L.
@ -57,18 +47,54 @@ const (
) )
const ( const (
REGRET = 0 REG_R0 = 32 + iota
REGEXT = 10 REG_R1
REG_R2
REG_R3
REG_R4
REG_R5
REG_R6
REG_R7
REG_R8
REG_R9
REG_R10
REG_R11
REG_R12
REG_R13
REG_R14
REG_R15
REG_F0
REG_F1
REG_F2
REG_F3
REG_F4
REG_F5
REG_F6
REG_F7
REG_F8
REG_F9
REG_F10
REG_F11
REG_F12
REG_F13
REG_F14
REG_F15
REG_FPSR
REG_FPCR
REG_CPSR
REG_SPSR
REGRET = REG_R0
REGEXT = REG_R10
REGG = REGEXT - 0 REGG = REGEXT - 0
REGM = REGEXT - 1 REGM = REGEXT - 1
REGTMP = 11 REGTMP = REG_R11
REGSP = 13 REGSP = REG_R13
REGLINK = 14 REGLINK = REG_R14
REGPC = 15 REGPC = REG_R15
NFREG = 16 NFREG = 16
FREGRET = 0 FREGRET = REG_F0
FREGEXT = 7 FREGEXT = REG_F7
FREGTMP = 15 FREGTMP = REG_F15
) )
/* compiler allocates register variables F0 up */ /* compiler allocates register variables F0 up */
@ -110,13 +136,13 @@ const (
C_SP C_SP
C_HREG C_HREG
C_ADDR C_ADDR
C_TEXTSIZE
C_GOK C_GOK
C_NCLASS C_NCLASS
) )
const ( const (
AXXX = iota AAND = obj.A_ARCHSPECIFIC + iota
AAND
AEOR AEOR
ASUB ASUB
ARSB ARSB
@ -131,8 +157,6 @@ const (
AORR AORR
ABIC ABIC
AMVN AMVN
AB
ABL
ABEQ ABEQ
ABNE ABNE
ABCS ABCS
@ -190,23 +214,12 @@ const (
AMOVM AMOVM
ASWPBU ASWPBU
ASWPW ASWPW
ANOP
ARFE ARFE
ASWI ASWI
AMULA AMULA
ADATA
AGLOBL
AGOK
AHISTORY
ANAME
ARET
ATEXT
AWORD AWORD
ADYNT_
AINIT_
ABCASE ABCASE
ACASE ACASE
AEND
AMULL AMULL
AMULAL AMULAL
AMULLU AMULLU
@ -214,31 +227,22 @@ const (
ABX ABX
ABXRET ABXRET
ADWORD ADWORD
ASIGNAME
ALDREX ALDREX
ASTREX ASTREX
ALDREXD ALDREXD
ASTREXD ASTREXD
APLD APLD
AUNDEF
ACLZ ACLZ
AMULWT AMULWT
AMULWB AMULWB
AMULAWT AMULAWT
AMULAWB AMULAWB
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ADATABUNDLE ADATABUNDLE
ADATABUNDLEEND ADATABUNDLEEND
AMRC AMRC
ALAST ALAST
AB = obj.AJMP
ABL = obj.ACALL
) )
/* scond byte */ /* scond byte */
@ -249,56 +253,29 @@ const (
C_WBIT = 1 << 6 C_WBIT = 1 << 6
C_FBIT = 1 << 7 C_FBIT = 1 << 7
C_UBIT = 1 << 7 C_UBIT = 1 << 7
C_SCOND_EQ = 0 C_SCOND_XOR = 14
C_SCOND_NE = 1 C_SCOND_EQ = 0 ^ C_SCOND_XOR
C_SCOND_HS = 2 C_SCOND_NE = 1 ^ C_SCOND_XOR
C_SCOND_LO = 3 C_SCOND_HS = 2 ^ C_SCOND_XOR
C_SCOND_MI = 4 C_SCOND_LO = 3 ^ C_SCOND_XOR
C_SCOND_PL = 5 C_SCOND_MI = 4 ^ C_SCOND_XOR
C_SCOND_VS = 6 C_SCOND_PL = 5 ^ C_SCOND_XOR
C_SCOND_VC = 7 C_SCOND_VS = 6 ^ C_SCOND_XOR
C_SCOND_HI = 8 C_SCOND_VC = 7 ^ C_SCOND_XOR
C_SCOND_LS = 9 C_SCOND_HI = 8 ^ C_SCOND_XOR
C_SCOND_GE = 10 C_SCOND_LS = 9 ^ C_SCOND_XOR
C_SCOND_LT = 11 C_SCOND_GE = 10 ^ C_SCOND_XOR
C_SCOND_GT = 12 C_SCOND_LT = 11 ^ C_SCOND_XOR
C_SCOND_LE = 13 C_SCOND_GT = 12 ^ C_SCOND_XOR
C_SCOND_NONE = 14 C_SCOND_LE = 13 ^ C_SCOND_XOR
C_SCOND_NV = 15 C_SCOND_NONE = 14 ^ C_SCOND_XOR
C_SCOND_NV = 15 ^ C_SCOND_XOR
SHIFT_LL = 0 << 5 SHIFT_LL = 0 << 5
SHIFT_LR = 1 << 5 SHIFT_LR = 1 << 5
SHIFT_AR = 2 << 5 SHIFT_AR = 2 << 5
SHIFT_RR = 3 << 5 SHIFT_RR = 3 << 5
) )
const (
D_GOK = 0
D_NONE = 1
D_BRANCH = D_NONE + 1
D_OREG = D_NONE + 2
D_CONST = D_NONE + 7
D_FCONST = D_NONE + 8
D_SCONST = D_NONE + 9
D_PSR = D_NONE + 10
D_REG = D_NONE + 12
D_FREG = D_NONE + 13
D_FILE = D_NONE + 16
D_OCONST = D_NONE + 17
D_FILE1 = D_NONE + 18
D_SHIFT = D_NONE + 19
D_FPCR = D_NONE + 20
D_REGREG = D_NONE + 21
D_ADDR = D_NONE + 22
D_SBIG = D_NONE + 23
D_CONST2 = D_NONE + 24
D_REGREG2 = D_NONE + 25
D_EXTERN = D_NONE + 3
D_STATIC = D_NONE + 4
D_AUTO = D_NONE + 5
D_PARAM = D_NONE + 6
D_LAST = D_NONE + 26
)
/* /*
* this is the ranlib header * this is the ranlib header
*/ */

View File

@ -1,8 +1,26 @@
package arm package arm
var Anames = []string{ var Anames = []string{
"XXX", "XXX ",
"AND", "CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"AND ",
"EOR", "EOR",
"SUB", "SUB",
"RSB", "RSB",
@ -17,8 +35,6 @@ var Anames = []string{
"ORR", "ORR",
"BIC", "BIC",
"MVN", "MVN",
"B",
"BL",
"BEQ", "BEQ",
"BNE", "BNE",
"BCS", "BCS",
@ -76,23 +92,12 @@ var Anames = []string{
"MOVM", "MOVM",
"SWPBU", "SWPBU",
"SWPW", "SWPW",
"NOP",
"RFE", "RFE",
"SWI", "SWI",
"MULA", "MULA",
"DATA",
"GLOBL",
"GOK",
"HISTORY",
"NAME",
"RET",
"TEXT",
"WORD", "WORD",
"DYNT_",
"INIT_",
"BCASE", "BCASE",
"CASE", "CASE",
"END",
"MULL", "MULL",
"MULAL", "MULAL",
"MULLU", "MULLU",
@ -100,27 +105,16 @@ var Anames = []string{
"BX", "BX",
"BXRET", "BXRET",
"DWORD", "DWORD",
"SIGNAME",
"LDREX", "LDREX",
"STREX", "STREX",
"LDREXD", "LDREXD",
"STREXD", "STREXD",
"PLD", "PLD",
"UNDEF",
"CLZ", "CLZ",
"MULWT", "MULWT",
"MULWB", "MULWB",
"MULAWT", "MULAWT",
"MULAWB", "MULAWB",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"DATABUNDLE", "DATABUNDLE",
"DATABUNDLEEND", "DATABUNDLEEND",
"MRC", "MRC",
@ -164,6 +158,7 @@ var cnames5 = []string{
"SP", "SP",
"HREG", "HREG",
"ADDR", "ADDR",
"TEXTSIZE",
"GOK", "GOK",
"NCLASS", "NCLASS",
"SCOND = (1<<4)-1", "SCOND = (1<<4)-1",
@ -172,25 +167,21 @@ var cnames5 = []string{
"WBIT = 1<<6", "WBIT = 1<<6",
"FBIT = 1<<7", "FBIT = 1<<7",
"UBIT = 1<<7", "UBIT = 1<<7",
"SCOND_EQ = 0", "SCOND_XOR = 14",
"SCOND_NE = 1", "SCOND_EQ = 0 ^ C_SCOND_XOR",
"SCOND_HS = 2", "SCOND_NE = 1 ^ C_SCOND_XOR",
"SCOND_LO = 3", "SCOND_HS = 2 ^ C_SCOND_XOR",
"SCOND_MI = 4", "SCOND_LO = 3 ^ C_SCOND_XOR",
"SCOND_PL = 5", "SCOND_MI = 4 ^ C_SCOND_XOR",
"SCOND_VS = 6", "SCOND_PL = 5 ^ C_SCOND_XOR",
"SCOND_VC = 7", "SCOND_VS = 6 ^ C_SCOND_XOR",
"SCOND_HI = 8", "SCOND_VC = 7 ^ C_SCOND_XOR",
"SCOND_LS = 9", "SCOND_HI = 8 ^ C_SCOND_XOR",
"SCOND_GE = 10", "SCOND_LS = 9 ^ C_SCOND_XOR",
"SCOND_LT = 11", "SCOND_GE = 10 ^ C_SCOND_XOR",
"SCOND_GT = 12", "SCOND_LT = 11 ^ C_SCOND_XOR",
"SCOND_LE = 13", "SCOND_GT = 12 ^ C_SCOND_XOR",
"SCOND_NONE = 14", "SCOND_LE = 13 ^ C_SCOND_XOR",
"SCOND_NV = 15", "SCOND_NONE = 14 ^ C_SCOND_XOR",
} "SCOND_NV = 15 ^ C_SCOND_XOR",
var dnames5 = []string{
D_GOK: "GOK",
D_NONE: "NONE",
} }

File diff suppressed because it is too large Load Diff

View File

@ -70,7 +70,7 @@ func Pconv(p *obj.Prog) string {
a = int(p.As) a = int(p.As)
s = int(p.Scond) s = int(p.Scond)
sc = extra[s&C_SCOND] sc = extra[(s&C_SCOND)^C_SCOND_XOR]
if s&C_SBIT != 0 { if s&C_SBIT != 0 {
sc += ".S" sc += ".S"
} }
@ -84,25 +84,21 @@ func Pconv(p *obj.Prog) string {
sc += ".U" sc += ".U"
} }
if a == AMOVM { if a == AMOVM {
if p.From.Type == D_CONST { if p.From.Type == obj.TYPE_CONST {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), Dconv(p, 0, &p.To))
} else if p.To.Type == D_CONST { } else if p.To.Type == obj.TYPE_CONST {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), RAconv(&p.To)) str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), RAconv(&p.To))
} else { } else {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
} }
} else if a == ADATA { } else if a == obj.ADATA {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
} else if p.As == ATEXT { } else if p.As == obj.ATEXT {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
} else if p.Reg == NREG { } else if p.Reg == 0 {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
} else if p.From.Type != D_FREG {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,R%d,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
} else { } else {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Rconv(int(p.Reg)), Dconv(p, 0, &p.To))
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,F%d,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
} }
fp += str fp += str
@ -114,7 +110,7 @@ func Aconv(a int) string {
var fp string var fp string
s = "???" s = "???"
if a >= AXXX && a < ALAST { if a >= obj.AXXX && a < ALAST {
s = Anames[a] s = Anames[a]
} }
fp += s fp += s
@ -132,63 +128,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
default: default:
str = fmt.Sprintf("GOK-type(%d)", a.Type) str = fmt.Sprintf("GOK-type(%d)", a.Type)
case D_NONE: case obj.TYPE_NONE:
str = "" str = ""
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil { if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg) str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
} }
case D_CONST: case obj.TYPE_CONST,
if a.Reg != NREG { obj.TYPE_ADDR:
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg) if a.Reg != 0 {
str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else { } else {
str = fmt.Sprintf("$%v", Mconv(a)) str = fmt.Sprintf("$%v", Mconv(a))
} }
case D_CONST2: case obj.TYPE_TEXTSIZE:
str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2) if a.U.Argsize == obj.ArgsSizeUnknown {
str = fmt.Sprintf("$%d", a.Offset)
} else {
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
}
case D_SHIFT: case obj.TYPE_SHIFT:
v = int(a.Offset) v = int(a.Offset)
op = string("<<>>->@>"[((v>>5)&3)<<1:]) op = string("<<>>->@>"[((v>>5)&3)<<1:])
if v&(1<<4) != 0 { if v&(1<<4) != 0 {
str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15) str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15)
} else { } else {
str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31) str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31)
} }
if a.Reg != NREG { if a.Reg != 0 {
str += fmt.Sprintf("(R%d)", a.Reg) str += fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
} }
case D_OREG: case obj.TYPE_MEM:
if a.Reg != NREG { if a.Reg != 0 {
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg) str = fmt.Sprintf("%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else { } else {
str = fmt.Sprintf("%v", Mconv(a)) str = fmt.Sprintf("%v", Mconv(a))
} }
case D_REG: case obj.TYPE_REG:
str = fmt.Sprintf("R%d", a.Reg) str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
if a.Name != D_NONE || a.Sym != nil { if a.Name != obj.TYPE_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg) str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
} }
case D_FREG: case obj.TYPE_BRANCH:
str = fmt.Sprintf("F%d", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
}
case D_PSR:
str = fmt.Sprintf("PSR")
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(PSR)(REG)", Mconv(a))
}
case D_BRANCH:
if a.Sym != nil { if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name) str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} else if p != nil && p.Pcond != nil { } else if p != nil && p.Pcond != nil {
@ -196,14 +182,13 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
} else if a.U.Branch != nil { } else if a.U.Branch != nil {
str = fmt.Sprintf("%d", a.U.Branch.Pc) str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else { } else {
str = fmt.Sprintf("%d(PC)", a.Offset) /*-pc*/ str = fmt.Sprintf("%d(PC)", a.Offset) /*-pc*/
} }
case D_FCONST: case obj.TYPE_FCONST:
str = fmt.Sprintf("$%.17g", a.U.Dval) str = fmt.Sprintf("$%.17g", a.U.Dval)
case D_SCONST: case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval) str = fmt.Sprintf("$\"%q\"", a.U.Sval)
break break
} }
@ -221,9 +206,8 @@ func RAconv(a *obj.Addr) string {
str = fmt.Sprintf("GOK-reglist") str = fmt.Sprintf("GOK-reglist")
switch a.Type { switch a.Type {
case D_CONST, case obj.TYPE_CONST:
D_CONST2: if a.Reg != 0 {
if a.Reg != NREG {
break break
} }
if a.Sym != nil { if a.Sym != nil {
@ -233,10 +217,9 @@ func RAconv(a *obj.Addr) string {
str = "" str = ""
for i = 0; i < NREG; i++ { for i = 0; i < NREG; i++ {
if v&(1<<uint(i)) != 0 { if v&(1<<uint(i)) != 0 {
if str[0] == 0 { if str == "" {
str += "[R" str += "[R"
} else { } else {
str += ",R" str += ",R"
} }
str += fmt.Sprintf("%d", i) str += fmt.Sprintf("%d", i)
@ -253,10 +236,38 @@ func RAconv(a *obj.Addr) string {
func Rconv(r int) string { func Rconv(r int) string {
var fp string var fp string
var str string if r == 0 {
fp += "NONE"
return fp
}
if REG_R0 <= r && r <= REG_R15 {
fp += fmt.Sprintf("R%d", r-REG_R0)
return fp
}
if REG_F0 <= r && r <= REG_F15 {
fp += fmt.Sprintf("F%d", r-REG_F0)
return fp
}
str = fmt.Sprintf("R%d", r) switch r {
fp += str case REG_FPSR:
fp += "FPSR"
return fp
case REG_FPCR:
fp += "FPCR"
return fp
case REG_CPSR:
fp += "CPSR"
return fp
case REG_SPSR:
fp += "SPSR"
return fp
}
fp += fmt.Sprintf("badreg(%d)", r)
return fp return fp
} }
@ -288,19 +299,19 @@ func Mconv(a *obj.Addr) string {
default: default:
str = fmt.Sprintf("GOK-name(%d)", a.Name) str = fmt.Sprintf("GOK-name(%d)", a.Name)
case D_NONE: case obj.NAME_NONE:
str = fmt.Sprintf("%d", a.Offset) str = fmt.Sprintf("%d", a.Offset)
case D_EXTERN: case obj.NAME_EXTERN:
str = fmt.Sprintf("%s+%d(SB)", s.Name, int(a.Offset)) str = fmt.Sprintf("%s+%d(SB)", s.Name, int(a.Offset))
case D_STATIC: case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, int(a.Offset)) str = fmt.Sprintf("%s<>+%d(SB)", s.Name, int(a.Offset))
case D_AUTO: case obj.NAME_AUTO:
str = fmt.Sprintf("%s-%d(SP)", s.Name, int(-a.Offset)) str = fmt.Sprintf("%s-%d(SP)", s.Name, int(-a.Offset))
case D_PARAM: case obj.NAME_PARAM:
str = fmt.Sprintf("%s+%d(FP)", s.Name, int(a.Offset)) str = fmt.Sprintf("%s+%d(FP)", s.Name, int(a.Offset))
break break
} }

View File

@ -38,46 +38,6 @@ import (
"math" "math"
) )
var zprg5 = obj.Prog{
As: AGOK,
Scond: C_SCOND_NONE,
Reg: NREG,
From: obj.Addr{
Name: D_NONE,
Type: D_NONE,
Reg: NREG,
},
To: obj.Addr{
Name: D_NONE,
Type: D_NONE,
Reg: NREG,
},
}
func symtype(a *obj.Addr) int {
return int(a.Name)
}
func isdata(p *obj.Prog) bool {
return p.As == ADATA || p.As == AGLOBL
}
func iscall(p *obj.Prog) bool {
return p.As == ABL
}
func datasize(p *obj.Prog) int {
return int(p.Reg)
}
func textflag(p *obj.Prog) int {
return int(p.Reg)
}
func settextflag(p *obj.Prog, f int) {
p.Reg = uint8(f)
}
func progedit(ctxt *obj.Link, p *obj.Prog) { func progedit(ctxt *obj.Link, p *obj.Prog) {
var literal string var literal string
var s *obj.LSym var s *obj.LSym
@ -86,53 +46,48 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p.From.Class = 0 p.From.Class = 0
p.To.Class = 0 p.To.Class = 0
// Rewrite B/BL to symbol as D_BRANCH. // Rewrite B/BL to symbol as TYPE_BRANCH.
switch p.As { switch p.As {
case AB, case AB,
ABL, ABL,
ADUFFZERO, obj.ADUFFZERO,
ADUFFCOPY: obj.ADUFFCOPY:
if p.To.Type == D_OREG && (p.To.Name == D_EXTERN || p.To.Name == D_STATIC) && p.To.Sym != nil { if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil {
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
} }
break break
} }
// Replace TLS register fetches on older ARM procesors. // Replace TLS register fetches on older ARM procesors.
switch p.As { switch p.As {
// Treat MRC 15, 0, <reg>, C13, C0, 3 specially. // Treat MRC 15, 0, <reg>, C13, C0, 3 specially.
case AMRC: case AMRC:
if p.To.Offset&0xffff0fff == 0xee1d0f70 { if p.To.Offset&0xffff0fff == 0xee1d0f70 {
// Because the instruction might be rewriten to a BL which returns in R0 // Because the instruction might be rewriten to a BL which returns in R0
// the register must be zero. // the register must be zero.
if p.To.Offset&0xf000 != 0 { if p.To.Offset&0xf000 != 0 {
ctxt.Diag("%v: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p.Line()) ctxt.Diag("%v: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p.Line())
} }
if ctxt.Goarm < 7 { if ctxt.Goarm < 7 {
// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension. // Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
if tlsfallback == nil { if tlsfallback == nil {
tlsfallback = obj.Linklookup(ctxt, "runtime.read_tls_fallback", 0) tlsfallback = obj.Linklookup(ctxt, "runtime.read_tls_fallback", 0)
} }
// MOVW LR, R11 // MOVW LR, R11
p.As = AMOVW p.As = AMOVW
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK p.From.Reg = REGLINK
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP p.To.Reg = REGTMP
// BL runtime.read_tls_fallback(SB) // BL runtime.read_tls_fallback(SB)
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ABL p.As = ABL
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p.To.Sym = tlsfallback p.To.Sym = tlsfallback
p.To.Offset = 0 p.To.Offset = 0
@ -140,9 +95,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP p.From.Reg = REGTMP
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGLINK p.To.Reg = REGLINK
break break
} }
@ -156,9 +111,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// Rewrite float constants to values stored in memory. // Rewrite float constants to values stored in memory.
switch p.As { switch p.As {
case AMOVF: case AMOVF:
if p.From.Type == D_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) { if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
var i32 uint32 var i32 uint32
var f32 float32 var f32 float32
f32 = float32(p.From.U.Dval) f32 = float32(p.From.U.Dval)
@ -171,14 +125,14 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
s.Reachable = 0 s.Reachable = 0
} }
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Sym = s p.From.Sym = s
p.From.Name = D_EXTERN p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0 p.From.Offset = 0
} }
case AMOVD: case AMOVD:
if p.From.Type == D_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) { if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
var i64 uint64 var i64 uint64
i64 = math.Float64bits(p.From.U.Dval) i64 = math.Float64bits(p.From.U.Dval)
literal = fmt.Sprintf("$f64.%016x", i64) literal = fmt.Sprintf("$f64.%016x", i64)
@ -189,9 +143,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
s.Reachable = 0 s.Reachable = 0
} }
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Sym = s p.From.Sym = s
p.From.Name = D_EXTERN p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0 p.From.Offset = 0
} }
@ -205,24 +159,18 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// offset. Rewrite $runtime.tlsg(SB) to runtime.tlsg(SB) to // offset. Rewrite $runtime.tlsg(SB) to runtime.tlsg(SB) to
// compensate. // compensate.
if ctxt.Tlsg == nil { if ctxt.Tlsg == nil {
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0) ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
} }
if p.From.Type == D_CONST && p.From.Name == D_EXTERN && p.From.Sym == ctxt.Tlsg { if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && p.From.Sym == ctxt.Tlsg {
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
} }
if p.To.Type == D_CONST && p.To.Name == D_EXTERN && p.To.Sym == ctxt.Tlsg { if p.To.Type == obj.TYPE_ADDR && p.To.Name == obj.NAME_EXTERN && p.To.Sym == ctxt.Tlsg {
p.To.Type = D_OREG p.To.Type = obj.TYPE_MEM
} }
} }
} }
func prg() *obj.Prog {
p := zprg
return &p
}
// Prog.mark // Prog.mark
const ( const (
FOLL = 1 << 0 FOLL = 1 << 0
@ -249,7 +197,7 @@ func nocache5(p *obj.Prog) {
p.To.Class = 0 p.To.Class = 0
} }
func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
var p *obj.Prog var p *obj.Prog
var pl *obj.Prog var pl *obj.Prog
var p1 *obj.Prog var p1 *obj.Prog
@ -284,38 +232,38 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
autoffset = 0 autoffset = 0
} }
cursym.Locals = autoffset cursym.Locals = autoffset
cursym.Args = p.To.Offset2 cursym.Args = p.To.U.Argsize
if ctxt.Debugzerostack != 0 { if ctxt.Debugzerostack != 0 {
if autoffset != 0 && !(p.Reg&obj.NOSPLIT != 0) { if autoffset != 0 && !(p.From3.Offset&obj.NOSPLIT != 0) {
// MOVW $4(R13), R1 // MOVW $4(R13), R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_CONST p.From.Type = obj.TYPE_ADDR
p.From.Reg = 13 p.From.Reg = REG_R13
p.From.Offset = 4 p.From.Offset = 4
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 1 p.To.Reg = REG_R1
// MOVW $n(R13), R2 // MOVW $n(R13), R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_CONST p.From.Type = obj.TYPE_ADDR
p.From.Reg = 13 p.From.Reg = REG_R13
p.From.Offset = 4 + int64(autoffset) p.From.Offset = 4 + int64(autoffset)
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 2 p.To.Reg = REG_R2
// MOVW $0, R3 // MOVW $0, R3
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 0 p.From.Offset = 0
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 3 p.To.Reg = REG_R3
// L: // L:
// MOVW.nil R3, 0(R1) +4 // MOVW.nil R3, 0(R1) +4
@ -325,22 +273,22 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p = pl p = pl
p.As = AMOVW p.As = AMOVW
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 3 p.From.Reg = REG_R3
p.To.Type = D_OREG p.To.Type = obj.TYPE_MEM
p.To.Reg = 1 p.To.Reg = REG_R1
p.To.Offset = 4 p.To.Offset = 4
p.Scond |= C_PBIT p.Scond |= C_PBIT
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMP p.As = ACMP
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 1 p.From.Reg = REG_R1
p.Reg = 2 p.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ABNE p.As = ABNE
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = pl p.Pcond = pl
} }
} }
@ -352,17 +300,16 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
* expand BECOME pseudo * expand BECOME pseudo
*/ */
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
switch p.As { switch p.As {
case ACASE: case ACASE:
if ctxt.Flag_shared != 0 { if ctxt.Flag_shared != 0 {
linkcase(p) linkcase(p)
} }
case ATEXT: case obj.ATEXT:
p.Mark |= LEAF p.Mark |= LEAF
case ARET: case obj.ARET:
break break
case ADIV, case ADIV,
@ -376,7 +323,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
cursym.Text.Mark &^= LEAF cursym.Text.Mark &^= LEAF
continue continue
case ANOP: case obj.ANOP:
q1 = p.Link q1 = p.Link
q.Link = q1 /* q is non-nop */ q.Link = q1 /* q is non-nop */
if q1 != nil { if q1 != nil {
@ -386,8 +333,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
case ABL, case ABL,
ABX, ABX,
ADUFFZERO, obj.ADUFFZERO,
ADUFFCOPY: obj.ADUFFCOPY:
cursym.Text.Mark &^= LEAF cursym.Text.Mark &^= LEAF
fallthrough fallthrough
@ -411,7 +358,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
ABLE: ABLE:
q1 = p.Pcond q1 = p.Pcond
if q1 != nil { if q1 != nil {
for q1.As == ANOP { for q1.As == obj.ANOP {
q1 = q1.Link q1 = q1.Link
p.Pcond = q1 p.Pcond = q1
} }
@ -426,7 +373,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
o = int(p.As) o = int(p.As)
switch o { switch o {
case ATEXT: case obj.ATEXT:
autosize = int32(p.To.Offset + 4) autosize = int32(p.To.Offset + 4)
if autosize <= 4 { if autosize <= 4 {
if cursym.Text.Mark&LEAF != 0 { if cursym.Text.Mark&LEAF != 0 {
@ -451,8 +398,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
} }
if !(p.Reg&obj.NOSPLIT != 0) { if !(p.From3.Offset&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.Reg&obj.NEEDCTXT != 0))) // emit split check p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0))) // emit split check
} }
// MOVW.W R14,$-autosize(SP) // MOVW.W R14,$-autosize(SP)
@ -460,14 +407,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW p.As = AMOVW
p.Scond |= C_WBIT p.Scond |= C_WBIT
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK p.From.Reg = REGLINK
p.To.Type = D_OREG p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(-autosize) p.To.Offset = int64(-autosize)
p.To.Reg = REGSP p.To.Reg = REGSP
p.Spadj = autosize p.Spadj = autosize
if cursym.Text.Reg&obj.WRAPPER != 0 { if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
// //
// MOVW g_panic(g), R1 // MOVW g_panic(g), R1
@ -488,84 +435,83 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG p.From.Reg = REGG
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 1 p.To.Reg = REG_R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMP p.As = ACMP
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 0 p.From.Offset = 0
p.Reg = 1 p.Reg = REG_R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ABEQ p.As = ABEQ
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p1 = p p1 = p
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Reg = 1 p.From.Reg = REG_R1
p.From.Offset = 0 // Panic.argp p.From.Offset = 0 // Panic.argp
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AADD p.As = AADD
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize) + 4 p.From.Offset = int64(autosize) + 4
p.Reg = 13 p.Reg = REG_R13
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 3 p.To.Reg = REG_R3
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMP p.As = ACMP
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 2 p.From.Reg = REG_R2
p.Reg = 3 p.Reg = REG_R3
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ABNE p.As = ABNE
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p2 = p p2 = p
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AADD p.As = AADD
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 4 p.From.Offset = 4
p.Reg = 13 p.Reg = REG_R13
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 4 p.From.Reg = REG_R4
p.To.Type = D_OREG p.To.Type = obj.TYPE_MEM
p.To.Reg = 1 p.To.Reg = REG_R1
p.To.Offset = 0 // Panic.argp p.To.Offset = 0 // Panic.argp
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ANOP p.As = obj.ANOP
p1.Pcond = p p1.Pcond = p
p2.Pcond = p p2.Pcond = p
} }
case ARET: case obj.ARET:
nocache5(p) nocache5(p)
if cursym.Text.Mark&LEAF != 0 { if cursym.Text.Mark&LEAF != 0 {
if !(autosize != 0) { if !(autosize != 0) {
p.As = AB p.As = AB
p.From = zprg5.From p.From = obj.Zprog.From
if p.To.Sym != nil { // retjmp if p.To.Sym != nil { // retjmp
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
} else { } else {
p.To.Type = obj.TYPE_MEM
p.To.Type = D_OREG
p.To.Offset = 0 p.To.Offset = 0
p.To.Reg = REGLINK p.To.Reg = REGLINK
} }
@ -576,10 +522,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW p.As = AMOVW
p.Scond |= C_PBIT p.Scond |= C_PBIT
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Offset = int64(autosize) p.From.Offset = int64(autosize)
p.From.Reg = REGSP p.From.Reg = REGSP
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGPC p.To.Reg = REGPC
// If there are instructions following // If there are instructions following
@ -589,19 +535,19 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REGLINK p.To.Reg = REGLINK
q2 = obj.Appendp(ctxt, p) q2 = obj.Appendp(ctxt, p)
q2.As = AB q2.As = AB
q2.To.Type = D_BRANCH q2.To.Type = obj.TYPE_BRANCH
q2.To.Sym = p.To.Sym q2.To.Sym = p.To.Sym
p.To.Sym = nil p.To.Sym = nil
p = q2 p = q2
} }
case AADD: case AADD:
if p.From.Type == D_CONST && p.From.Reg == NREG && p.To.Type == D_REG && p.To.Reg == REGSP { if p.From.Type == obj.TYPE_CONST && p.From.Reg == 0 && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP {
p.Spadj = int32(-p.From.Offset) p.Spadj = int32(-p.From.Offset)
} }
case ASUB: case ASUB:
if p.From.Type == D_CONST && p.From.Reg == NREG && p.To.Type == D_REG && p.To.Reg == REGSP { if p.From.Type == obj.TYPE_CONST && p.From.Reg == 0 && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP {
p.Spadj = int32(p.From.Offset) p.Spadj = int32(p.From.Offset)
} }
@ -612,10 +558,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
if ctxt.Debugdivmod != 0 { if ctxt.Debugdivmod != 0 {
break break
} }
if p.From.Type != D_REG { if p.From.Type != obj.TYPE_REG {
break break
} }
if p.To.Type != D_REG { if p.To.Type != obj.TYPE_REG {
break break
} }
q1 = p q1 = p
@ -625,9 +571,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW p.As = AMOVW
p.Lineno = q1.Lineno p.Lineno = q1.Lineno
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = q1.From.Reg p.From.Reg = q1.From.Reg
p.To.Type = D_OREG p.To.Type = obj.TYPE_MEM
p.To.Reg = REGSP p.To.Reg = REGSP
p.To.Offset = 4 p.To.Offset = 4
@ -636,12 +582,12 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW p.As = AMOVW
p.Lineno = q1.Lineno p.Lineno = q1.Lineno
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = int8(q1.Reg) p.From.Reg = q1.Reg
if q1.Reg == NREG { if q1.Reg == 0 {
p.From.Reg = q1.To.Reg p.From.Reg = q1.To.Reg
} }
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP p.To.Reg = REGTMP
p.To.Offset = 0 p.To.Offset = 0
@ -650,7 +596,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = ABL p.As = ABL
p.Lineno = q1.Lineno p.Lineno = q1.Lineno
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
switch o { switch o {
case ADIV: case ADIV:
p.To.Sym = ctxt.Sym_div p.To.Sym = ctxt.Sym_div
@ -671,10 +617,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW p.As = AMOVW
p.Lineno = q1.Lineno p.Lineno = q1.Lineno
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP p.From.Reg = REGTMP
p.From.Offset = 0 p.From.Offset = 0
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = q1.To.Reg p.To.Reg = q1.To.Reg
/* ADD $8,SP */ /* ADD $8,SP */
@ -682,11 +628,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AADD p.As = AADD
p.Lineno = q1.Lineno p.Lineno = q1.Lineno
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Reg = NREG p.From.Reg = 0
p.From.Offset = 8 p.From.Offset = 8
p.Reg = NREG p.Reg = 0
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP p.To.Reg = REGSP
p.Spadj = -8 p.Spadj = -8
@ -695,34 +641,34 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
/* TODO: Remove SP adjustments; see issue 6699. */ /* TODO: Remove SP adjustments; see issue 6699. */
q1.As = AMOVW q1.As = AMOVW
q1.From.Type = D_OREG q1.From.Type = obj.TYPE_MEM
q1.From.Reg = REGSP q1.From.Reg = REGSP
q1.From.Offset = 0 q1.From.Offset = 0
q1.Reg = NREG q1.Reg = 0
q1.To.Type = D_REG q1.To.Type = obj.TYPE_REG
q1.To.Reg = REGTMP q1.To.Reg = REGTMP
/* SUB $8,SP */ /* SUB $8,SP */
q1 = obj.Appendp(ctxt, q1) q1 = obj.Appendp(ctxt, q1)
q1.As = AMOVW q1.As = AMOVW
q1.From.Type = D_REG q1.From.Type = obj.TYPE_REG
q1.From.Reg = REGTMP q1.From.Reg = REGTMP
q1.Reg = NREG q1.Reg = 0
q1.To.Type = D_OREG q1.To.Type = obj.TYPE_MEM
q1.To.Reg = REGSP q1.To.Reg = REGSP
q1.To.Offset = -8 q1.To.Offset = -8
q1.Scond |= C_WBIT q1.Scond |= C_WBIT
q1.Spadj = 8 q1.Spadj = 8
case AMOVW: case AMOVW:
if (p.Scond&C_WBIT != 0) && p.To.Type == D_OREG && p.To.Reg == REGSP { if (p.Scond&C_WBIT != 0) && p.To.Type == obj.TYPE_MEM && p.To.Reg == REGSP {
p.Spadj = int32(-p.To.Offset) p.Spadj = int32(-p.To.Offset)
} }
if (p.Scond&C_PBIT != 0) && p.From.Type == D_OREG && p.From.Reg == REGSP && p.To.Reg != REGPC { if (p.Scond&C_PBIT != 0) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REGSP && p.To.Reg != REGPC {
p.Spadj = int32(-p.From.Offset) p.Spadj = int32(-p.From.Offset)
} }
if p.From.Type == D_CONST && p.From.Reg == REGSP && p.To.Type == D_REG && p.To.Reg == REGSP { if p.From.Type == obj.TYPE_ADDR && p.From.Reg == REGSP && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP {
p.Spadj = int32(-p.From.Offset) p.Spadj = int32(-p.From.Offset)
} }
break break
@ -730,6 +676,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
} }
func isfloatreg(a *obj.Addr) int {
return bool2int(a.Type == obj.TYPE_REG && REG_F0 <= a.Reg && a.Reg <= REG_F15)
}
func softfloat(ctxt *obj.Link, cursym *obj.LSym) { func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
var p *obj.Prog var p *obj.Prog
var next *obj.Prog var next *obj.Prog
@ -751,7 +701,7 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
switch p.As { switch p.As {
case AMOVW: case AMOVW:
if p.To.Type == D_FREG || p.From.Type == D_FREG { if isfloatreg(&p.To) != 0 || isfloatreg(&p.From) != 0 {
goto soft goto soft
} }
goto notsoft goto notsoft
@ -786,15 +736,15 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
soft: soft:
if !(wasfloat != 0) || (p.Mark&LABEL != 0) { if !(wasfloat != 0) || (p.Mark&LABEL != 0) {
next = ctxt.NewProg() next = new(obj.Prog)
*next = *p *next = *p
// BL _sfloat(SB) // BL _sfloat(SB)
*p = zprg5 *p = obj.Zprog
p.Link = next p.Link = next
p.As = ABL p.As = ABL
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p.To.Sym = symsfloat p.To.Sym = symsfloat
p.Lineno = next.Lineno p.Lineno = next.Lineno
@ -814,14 +764,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 { if ctxt.Cursym.Cfunc != 0 {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
} }
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 1 p.To.Reg = REG_R1
if framesize <= obj.StackSmall { if framesize <= obj.StackSmall {
// small stack: SP < stackguard // small stack: SP < stackguard
@ -829,8 +779,8 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMP p.As = ACMP
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 1 p.From.Reg = REG_R1
p.Reg = REGSP p.Reg = REGSP
} else if framesize <= obj.StackBig { } else if framesize <= obj.StackBig {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
@ -839,19 +789,18 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_CONST p.From.Type = obj.TYPE_ADDR
p.From.Reg = REGSP p.From.Reg = REGSP
p.From.Offset = int64(-framesize) p.From.Offset = int64(-framesize)
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMP p.As = ACMP
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 1 p.From.Reg = REG_R1
p.Reg = 2 p.Reg = REG_R2
} else { } else {
// Such a large stack we need to protect against wraparound // Such a large stack we need to protect against wraparound
// if SP is close to zero. // if SP is close to zero.
// SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall) // SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall)
@ -865,40 +814,40 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMP p.As = ACMP
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1))) p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
p.Reg = 1 p.Reg = REG_R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_CONST p.From.Type = obj.TYPE_ADDR
p.From.Reg = REGSP p.From.Reg = REGSP
p.From.Offset = obj.StackGuard p.From.Offset = obj.StackGuard
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 2 p.To.Reg = REG_R2
p.Scond = C_SCOND_NE p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ASUB p.As = ASUB
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 1 p.From.Reg = REG_R1
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 2 p.To.Reg = REG_R2
p.Scond = C_SCOND_NE p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVW p.As = AMOVW
p.From.Type = D_CONST p.From.Type = obj.TYPE_ADDR
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 3 p.To.Reg = REG_R3
p.Scond = C_SCOND_NE p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMP p.As = ACMP
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 3 p.From.Reg = REG_R3
p.Reg = 2 p.Reg = REG_R2
p.Scond = C_SCOND_NE p.Scond = C_SCOND_NE
} }
@ -907,21 +856,20 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p.As = AMOVW p.As = AMOVW
p.Scond = C_SCOND_LS p.Scond = C_SCOND_LS
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK p.From.Reg = REGLINK
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 3 p.To.Reg = REG_R3
// BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted // BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ABL p.As = ABL
p.Scond = C_SCOND_LS p.Scond = C_SCOND_LS
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
if ctxt.Cursym.Cfunc != 0 { if ctxt.Cursym.Cfunc != 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0) p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else { } else {
p.To.Sym = ctxt.Symmorestack[noctxt] p.To.Sym = ctxt.Symmorestack[noctxt]
} }
@ -929,7 +877,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ABLS p.As = ABLS
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = ctxt.Cursym.Text.Link p.Pcond = ctxt.Cursym.Text.Link
return p return p
@ -951,7 +899,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
ctxt.Cursym = s ctxt.Cursym = s
firstp = ctxt.NewProg() firstp = new(obj.Prog)
lastp = firstp lastp = firstp
xfol(ctxt, s.Text, &lastp) xfol(ctxt, s.Text, &lastp)
lastp.Link = nil lastp.Link = nil
@ -1011,7 +959,7 @@ loop:
a = int(p.As) a = int(p.As)
if a == AB { if a == AB {
q = p.Pcond q = p.Pcond
if q != nil && q.As != ATEXT { if q != nil && q.As != obj.ATEXT {
p.Mark |= FOLL p.Mark |= FOLL
p = q p = q
if !(p.Mark&FOLL != 0) { if !(p.Mark&FOLL != 0) {
@ -1028,12 +976,12 @@ loop:
break break
} }
a = int(q.As) a = int(q.As)
if a == ANOP { if a == obj.ANOP {
i-- i--
continue continue
} }
if a == AB || (a == ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF { if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
goto copy goto copy
} }
if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) { if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
@ -1045,7 +993,7 @@ loop:
copy: copy:
for { for {
r = ctxt.NewProg() r = new(obj.Prog)
*r = *p *r = *p
if !(r.Mark&FOLL != 0) { if !(r.Mark&FOLL != 0) {
fmt.Printf("can't happen 1\n") fmt.Printf("can't happen 1\n")
@ -1060,7 +1008,7 @@ loop:
(*last).Link = r (*last).Link = r
*last = r *last = r
if a == AB || (a == ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF { if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
return return
} }
r.As = ABNE r.As = ABNE
@ -1080,10 +1028,10 @@ loop:
} }
a = AB a = AB
q = ctxt.NewProg() q = new(obj.Prog)
q.As = int16(a) q.As = int16(a)
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.To.Type = D_BRANCH q.To.Type = obj.TYPE_BRANCH
q.To.Offset = p.Pc q.To.Offset = p.Pc
q.Pcond = p q.Pcond = p
p = q p = q
@ -1092,14 +1040,14 @@ loop:
p.Mark |= FOLL p.Mark |= FOLL
(*last).Link = p (*last).Link = p
*last = p *last = p
if a == AB || (a == ARET && p.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF { if a == AB || (a == obj.ARET && p.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
return return
} }
if p.Pcond != nil { if p.Pcond != nil {
if a != ABL && a != ABX && p.Link != nil { if a != ABL && a != ABX && p.Link != nil {
q = obj.Brchain(ctxt, p.Link) q = obj.Brchain(ctxt, p.Link)
if a != ATEXT && a != ABCASE { if a != obj.ATEXT && a != ABCASE {
if q != nil && (q.Mark&FOLL != 0) { if q != nil && (q.Mark&FOLL != 0) {
p.As = int16(relinv(a)) p.As = int16(relinv(a))
p.Link = p.Pcond p.Link = p.Pcond
@ -1127,46 +1075,16 @@ loop:
} }
var Linkarm = obj.LinkArch{ var Linkarm = obj.LinkArch{
ByteOrder: binary.LittleEndian, ByteOrder: binary.LittleEndian,
Pconv: Pconv, Pconv: Pconv,
Name: "arm", Name: "arm",
Thechar: '5', Thechar: '5',
Endian: obj.LittleEndian, Endian: obj.LittleEndian,
Addstacksplit: addstacksplit, Preprocess: preprocess,
Assemble: span5, Assemble: span5,
Datasize: datasize, Follow: follow,
Follow: follow, Progedit: progedit,
Iscall: iscall, Minlc: 4,
Isdata: isdata, Ptrsize: 4,
Prg: prg, Regsize: 4,
Progedit: progedit,
Settextflag: settextflag,
Symtype: symtype,
Textflag: textflag,
Minlc: 4,
Ptrsize: 4,
Regsize: 4,
D_ADDR: D_ADDR,
D_AUTO: D_AUTO,
D_BRANCH: D_BRANCH,
D_CONST: D_CONST,
D_EXTERN: D_EXTERN,
D_FCONST: D_FCONST,
D_NONE: D_NONE,
D_PARAM: D_PARAM,
D_SCONST: D_SCONST,
D_STATIC: D_STATIC,
D_OREG: D_OREG,
ACALL: ABL,
ADATA: ADATA,
AEND: AEND,
AFUNCDATA: AFUNCDATA,
AGLOBL: AGLOBL,
AJMP: AB,
ANOP: ANOP,
APCDATA: APCDATA,
ARET: ARET,
ATEXT: ATEXT,
ATYPE: ATYPE,
AUSEFIELD: AUSEFIELD,
} }

View File

@ -37,7 +37,6 @@ import (
) )
func mangle(file string) { func mangle(file string) {
log.Fatalf("%s: mangled input file", file) log.Fatalf("%s: mangled input file", file)
} }
@ -58,7 +57,7 @@ func Symgrow(ctxt *Link, s *LSym, lsiz int64) {
func savedata(ctxt *Link, s *LSym, p *Prog, pn string) { func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
off := int32(p.From.Offset) off := int32(p.From.Offset)
siz := int32(ctxt.Arch.Datasize(p)) siz := int32(p.From3.Offset)
if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 { if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 {
mangle(pn) mangle(pn)
} }
@ -71,7 +70,7 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
default: default:
ctxt.Diag("bad data: %P", p) ctxt.Diag("bad data: %P", p)
case ctxt.Arch.D_FCONST: case TYPE_FCONST:
switch siz { switch siz {
default: default:
ctxt.Diag("unexpected %d-byte floating point constant", siz) ctxt.Diag("unexpected %d-byte floating point constant", siz)
@ -85,11 +84,11 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt) ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt)
} }
case ctxt.Arch.D_SCONST: case TYPE_SCONST:
copy(s.P[off:off+siz], p.To.U.Sval) copy(s.P[off:off+siz], p.To.U.Sval)
case ctxt.Arch.D_CONST, ctxt.Arch.D_ADDR: case TYPE_CONST, TYPE_ADDR:
if p.To.Sym != nil || int(p.To.Type) == ctxt.Arch.D_ADDR { if p.To.Sym != nil || int(p.To.Type) == TYPE_ADDR {
r := Addrel(s) r := Addrel(s)
r.Off = off r.Off = off
r.Siz = uint8(siz) r.Siz = uint8(siz)
@ -119,7 +118,7 @@ func Addrel(s *LSym) *Reloc {
return &s.R[len(s.R)-1] return &s.R[len(s.R)-1]
} }
func setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 { func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
if s.Type == 0 { if s.Type == 0 {
s.Type = SDATA s.Type = SDATA
} }
@ -147,7 +146,7 @@ func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
var off int64 var off int64
off = s.Size off = s.Size
setuintxx(ctxt, s, off, v, int64(wid)) Setuintxx(ctxt, s, off, v, int64(wid))
return off return off
} }
@ -168,19 +167,19 @@ func Adduint64(ctxt *Link, s *LSym, v uint64) int64 {
} }
func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 { func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 {
return setuintxx(ctxt, s, r, uint64(v), 1) return Setuintxx(ctxt, s, r, uint64(v), 1)
} }
func setuint16(ctxt *Link, s *LSym, r int64, v uint16) int64 { func setuint16(ctxt *Link, s *LSym, r int64, v uint16) int64 {
return setuintxx(ctxt, s, r, uint64(v), 2) return Setuintxx(ctxt, s, r, uint64(v), 2)
} }
func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 { func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 {
return setuintxx(ctxt, s, r, uint64(v), 4) return Setuintxx(ctxt, s, r, uint64(v), 4)
} }
func setuint64(ctxt *Link, s *LSym, r int64, v uint64) int64 { func setuint64(ctxt *Link, s *LSym, r int64, v uint64) int64 {
return setuintxx(ctxt, s, r, v, 8) return Setuintxx(ctxt, s, r, v, 8)
} }
func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 { func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {

View File

@ -1,12 +1,13 @@
// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.c from Vita Nuova. // Inferno utils/5c/list.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/list.c
// //
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// Portions Copyright © 1997-1999 Vita Nuova Limited // Portions Copyright © 1997-1999 Vita Nuova Limited
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
// Portions Copyright © 2004,2006 Bruce Ellis // Portions Copyright © 2004,2006 Bruce Ellis
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
// Portions Copyright © 2009 The Go Authors. All rights reserved. // Portions Copyright © 2009 The Go Authors. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -74,5 +75,5 @@ const (
FUNCDATA_ArgsPointerMaps = 0 FUNCDATA_ArgsPointerMaps = 0
FUNCDATA_LocalsPointerMaps = 1 FUNCDATA_LocalsPointerMaps = 1
FUNCDATA_DeadValueMaps = 2 FUNCDATA_DeadValueMaps = 2
ArgsSizeUnknown = 0x80000000 ArgsSizeUnknown = -0x80000000
) )

View File

@ -5,12 +5,75 @@
package obj package obj
import ( import (
"fmt"
"math" "math"
"os"
"strings" "strings"
) )
// go-specific code shared across loaders (5l, 6l, 8l). // go-specific code shared across loaders (5l, 6l, 8l).
var Framepointer_enabled int
var fieldtrack_enabled int
var Zprog Prog
// Toolchain experiments.
// These are controlled by the GOEXPERIMENT environment
// variable recorded when the toolchain is built.
// This list is also known to cmd/gc.
var exper = []struct {
name string
val *int
}{
struct {
name string
val *int
}{"fieldtrack", &fieldtrack_enabled},
struct {
name string
val *int
}{"framepointer", &Framepointer_enabled},
}
func addexp(s string) {
var i int
for i = 0; i < len(exper); i++ {
if exper[i].name == s {
if exper[i].val != nil {
*exper[i].val = 1
}
return
}
}
fmt.Printf("unknown experiment %s\n", s)
os.Exit(2)
}
func linksetexp() {
for _, f := range strings.Split(goexperiment, ",") {
if f != "" {
addexp(f)
}
}
}
func expstring() string {
buf := "X"
for i := range exper {
if *exper[i].val != 0 {
buf += "," + exper[i].name
}
}
if buf == "X" {
buf += ",none"
}
return "X:" + buf[2:]
}
// replace all "". with pkg. // replace all "". with pkg.
func expandpkg(t0 string, pkg string) string { func expandpkg(t0 string, pkg string) string {
return strings.Replace(t0, `"".`, pkg+".", -1) return strings.Replace(t0, `"".`, pkg+".", -1)

View File

@ -30,9 +30,10 @@
package i386 package i386
import "cmd/internal/obj"
const ( const (
AXXX = iota AAAA = obj.A_ARCHSPECIFIC + iota
AAAA
AAAD AAAD
AAAM AAAM
AAAS AAAS
@ -62,7 +63,6 @@ const (
ABTSL ABTSL
ABTSW ABTSW
ABYTE ABYTE
ACALL
ACLC ACLC
ACLD ACLD
ACLI ACLI
@ -76,7 +76,6 @@ const (
ACMPSW ACMPSW
ADAA ADAA
ADAS ADAS
ADATA
ADECB ADECB
ADECL ADECL
ADECW ADECW
@ -84,9 +83,6 @@ const (
ADIVL ADIVL
ADIVW ADIVW
AENTER AENTER
AGLOBL
AGOK
AHISTORY
AHLT AHLT
AIDIVB AIDIVB
AIDIVL AIDIVL
@ -119,7 +115,6 @@ const (
AJLS AJLS
AJLT AJLT
AJMI AJMI
AJMP
AJNE AJNE
AJOC AJOC
AJOS AJOS
@ -159,11 +154,9 @@ const (
AMULB AMULB
AMULL AMULL
AMULW AMULW
ANAME
ANEGB ANEGB
ANEGL ANEGL
ANEGW ANEGW
ANOP
ANOTB ANOTB
ANOTL ANOTL
ANOTW ANOTW
@ -197,7 +190,6 @@ const (
ARCRW ARCRW
AREP AREP
AREPN AREPN
ARET
AROLB AROLB
AROLL AROLL
AROLW AROLW
@ -254,7 +246,6 @@ const (
ATESTB ATESTB
ATESTL ATESTL
ATESTW ATESTW
ATEXT
AVERR AVERR
AVERW AVERW
AWAIT AWAIT
@ -367,10 +358,6 @@ const (
AFXTRACT AFXTRACT
AFYL2X AFYL2X
AFYL2XP1 AFYL2XP1
AEND
ADYNT_
AINIT_
ASIGNAME
ACMPXCHGB ACMPXCHGB
ACMPXCHGL ACMPXCHGL
ACMPXCHGW ACMPXCHGW
@ -429,7 +416,6 @@ const (
APREFETCHT2 APREFETCHT2
APREFETCHNTA APREFETCHNTA
ABSWAPL ABSWAPL
AUNDEF
AADDPD AADDPD
AADDPS AADDPS
AADDSD AADDSD
@ -544,73 +530,53 @@ const (
AAESENC AAESENC
APINSRD APINSRD
APSHUFB APSHUFB
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ALAST ALAST
) )
const ( const (
D_AL = 0 + iota REG_NONE = 0
D_CL REG_AL = 0 + 16 + iota - 1
D_DL REG_CL
D_BL REG_DL
D_AH = 4 + iota - 4 REG_BL
D_CH REG_AH = 4 + 16 + iota - 5
D_DH REG_CH
D_BH REG_DH
D_AX = 8 + iota - 8 REG_BH
D_CX REG_AX = 8 + 16 + iota - 9
D_DX REG_CX
D_BX REG_DX
D_SP REG_BX
D_BP REG_SP
D_SI REG_BP
D_DI REG_SI
D_F0 = 16 REG_DI
D_F7 = D_F0 + 7 REG_F0 = 16 + 16
D_CS = 24 + iota - 18 REG_F7 = REG_F0 + 7 + 16
D_SS REG_CS = 24 + 16 + iota - 19
D_DS REG_SS
D_ES REG_DS
D_FS REG_ES
D_GS REG_FS
D_GDTR REG_GS
D_IDTR REG_GDTR
D_LDTR REG_IDTR
D_MSW REG_LDTR
D_TASK REG_MSW
D_CR = 35 REG_TASK
D_DR = 43 REG_CR = 35 + 16
D_TR = 51 REG_DR = 43 + 16
D_X0 = 59 + iota - 32 REG_TR = 51 + 16
D_X1 REG_X0 = 59 + 16 + iota - 33
D_X2 REG_X1
D_X3 REG_X2
D_X4 REG_X3
D_X5 REG_X4
D_X6 REG_X5
D_X7 REG_X6
D_TLS = 67 REG_X7
D_NONE = 68 REG_TLS = 67 + 16
D_BRANCH = 69 MAXREG = 68 + 16
D_EXTERN = 70
D_STATIC = 71
D_AUTO = 72
D_PARAM = 73
D_CONST = 74
D_FCONST = 75
D_SCONST = 76
D_ADDR = 77 + iota - 50
D_INDIR
D_CONST2 = D_INDIR + D_INDIR + iota - 52
D_LAST
T_TYPE = 1 << 0 T_TYPE = 1 << 0
T_INDEX = 1 << 1 T_INDEX = 1 << 1
T_OFFSET = 1 << 2 T_OFFSET = 1 << 2
@ -620,8 +586,8 @@ const (
T_OFFSET2 = 1 << 6 T_OFFSET2 = 1 << 6
T_GOTYPE = 1 << 7 T_GOTYPE = 1 << 7
REGARG = -1 REGARG = -1
REGRET = D_AX REGRET = REG_AX
FREGRET = D_F0 FREGRET = REG_F0
REGSP = D_SP REGSP = REG_SP
REGTMP = D_DI REGTMP = REG_DI
) )

View File

@ -4,8 +4,26 @@ package i386
* this is the ranlib header * this is the ranlib header
*/ */
var Anames = []string{ var Anames = []string{
"XXX", "XXX ",
"AAA", "CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"AAA ",
"AAD", "AAD",
"AAM", "AAM",
"AAS", "AAS",
@ -35,7 +53,6 @@ var Anames = []string{
"BTSL", "BTSL",
"BTSW", "BTSW",
"BYTE", "BYTE",
"CALL",
"CLC", "CLC",
"CLD", "CLD",
"CLI", "CLI",
@ -49,7 +66,6 @@ var Anames = []string{
"CMPSW", "CMPSW",
"DAA", "DAA",
"DAS", "DAS",
"DATA",
"DECB", "DECB",
"DECL", "DECL",
"DECW", "DECW",
@ -57,9 +73,6 @@ var Anames = []string{
"DIVL", "DIVL",
"DIVW", "DIVW",
"ENTER", "ENTER",
"GLOBL",
"GOK",
"HISTORY",
"HLT", "HLT",
"IDIVB", "IDIVB",
"IDIVL", "IDIVL",
@ -92,7 +105,6 @@ var Anames = []string{
"JLS", "JLS",
"JLT", "JLT",
"JMI", "JMI",
"JMP",
"JNE", "JNE",
"JOC", "JOC",
"JOS", "JOS",
@ -132,11 +144,9 @@ var Anames = []string{
"MULB", "MULB",
"MULL", "MULL",
"MULW", "MULW",
"NAME",
"NEGB", "NEGB",
"NEGL", "NEGL",
"NEGW", "NEGW",
"NOP",
"NOTB", "NOTB",
"NOTL", "NOTL",
"NOTW", "NOTW",
@ -170,7 +180,6 @@ var Anames = []string{
"RCRW", "RCRW",
"REP", "REP",
"REPN", "REPN",
"RET",
"ROLB", "ROLB",
"ROLL", "ROLL",
"ROLW", "ROLW",
@ -227,7 +236,6 @@ var Anames = []string{
"TESTB", "TESTB",
"TESTL", "TESTL",
"TESTW", "TESTW",
"TEXT",
"VERR", "VERR",
"VERW", "VERW",
"WAIT", "WAIT",
@ -340,10 +348,6 @@ var Anames = []string{
"FXTRACT", "FXTRACT",
"FYL2X", "FYL2X",
"FYL2XP1", "FYL2XP1",
"END",
"DYNT_",
"INIT_",
"SIGNAME",
"CMPXCHGB", "CMPXCHGB",
"CMPXCHGL", "CMPXCHGL",
"CMPXCHGW", "CMPXCHGW",
@ -402,7 +406,6 @@ var Anames = []string{
"PREFETCHT2", "PREFETCHT2",
"PREFETCHNTA", "PREFETCHNTA",
"BSWAPL", "BSWAPL",
"UNDEF",
"ADDPD", "ADDPD",
"ADDPS", "ADDPS",
"ADDSD", "ADDSD",
@ -517,68 +520,5 @@ var Anames = []string{
"AESENC", "AESENC",
"PINSRD", "PINSRD",
"PSHUFB", "PSHUFB",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"LAST", "LAST",
} }
var dnames8 = []string{
D_AL: "AL",
D_CL: "CL",
D_DL: "DL",
D_BL: "BL",
D_AH: "AH",
D_CH: "CH",
D_DH: "DH",
D_BH: "BH",
D_AX: "AX",
D_CX: "CX",
D_DX: "DX",
D_BX: "BX",
D_SP: "SP",
D_BP: "BP",
D_SI: "SI",
D_DI: "DI",
D_F0: "F0",
D_CS: "CS",
D_SS: "SS",
D_DS: "DS",
D_ES: "ES",
D_FS: "FS",
D_GS: "GS",
D_GDTR: "GDTR",
D_IDTR: "IDTR",
D_LDTR: "LDTR",
D_MSW: "MSW",
D_TASK: "TASK",
D_CR: "CR",
D_DR: "DR",
D_TR: "TR",
D_X0: "X0",
D_X1: "X1",
D_X2: "X2",
D_X3: "X3",
D_X4: "X4",
D_X5: "X5",
D_X6: "X6",
D_X7: "X7",
D_TLS: "TLS",
D_NONE: "NONE",
D_BRANCH: "BRANCH",
D_EXTERN: "EXTERN",
D_STATIC: "STATIC",
D_AUTO: "AUTO",
D_PARAM: "PARAM",
D_CONST: "CONST",
D_FCONST: "FCONST",
D_SCONST: "SCONST",
D_ADDR: "ADDR",
D_INDIR: "INDIR",
}

File diff suppressed because it is too large Load Diff

View File

@ -46,16 +46,16 @@ func Pconv(p *obj.Prog) string {
var fp string var fp string
switch p.As { switch p.As {
case ADATA: case obj.ADATA:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
case ATEXT: case obj.ATEXT:
if p.From.Scale != 0 { if p.From3.Offset != 0 {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, fmtLong, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
break break
} }
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
default: default:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
@ -78,45 +78,34 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
var s string var s string
var fp string var fp string
var i int switch a.Type {
i = int(a.Type)
if flag&fmtLong != 0 /*untyped*/ {
if i == D_CONST2 {
str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2)
} else {
// ATEXT dst is not constant
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
}
goto brk
}
if i >= D_INDIR {
if a.Offset != 0 {
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR))
} else {
str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR))
}
goto brk
}
switch i {
default: default:
if a.Offset != 0 { str = fmt.Sprintf("type=%d", a.Type)
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
} else {
str = fmt.Sprintf("%v", Rconv(i)) case obj.TYPE_NONE:
}
case D_NONE:
str = "" str = ""
case D_BRANCH: // TODO(rsc): This special case is for instructions like
// PINSRQ CX,$1,X6
// where the $1 is included in the p->to Addr.
// Move into a new field.
case obj.TYPE_REG:
if a.Offset != 0 {
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg)))
break
}
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX
// Remove.
if a.Index != REG_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
case obj.TYPE_BRANCH:
if a.Sym != nil { if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name) str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} else if p != nil && p.Pcond != nil { } else if p != nil && p.Pcond != nil {
@ -124,69 +113,85 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
} else if a.U.Branch != nil { } else if a.U.Branch != nil {
str = fmt.Sprintf("%d", a.U.Branch.Pc) str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else { } else {
str = fmt.Sprintf("%d(PC)", a.Offset) str = fmt.Sprintf("%d(PC)", a.Offset)
} }
case D_EXTERN: case obj.TYPE_MEM:
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset) switch a.Name {
default:
str = fmt.Sprintf("name=%d", a.Name)
case D_STATIC: case obj.NAME_NONE:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset) if a.Offset != 0 {
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg)))
} else {
str = fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
}
case D_AUTO: case obj.NAME_EXTERN:
if a.Sym != nil { str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(SP)", a.Offset) case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
case obj.NAME_AUTO:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(SP)", a.Offset)
}
case obj.NAME_PARAM:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(FP)", a.Offset)
}
break
} }
case D_PARAM: if a.Index != REG_NONE {
if a.Sym != nil { s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset) str += s
} else {
str = fmt.Sprintf("%d(FP)", a.Offset)
} }
case D_CONST: case obj.TYPE_CONST:
str = fmt.Sprintf("$%d", a.Offset) str = fmt.Sprintf("$%d", a.Offset)
case D_CONST2: // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
if !(flag&fmtLong != 0 /*untyped*/) { // SHRQ $32(DX*0), AX
// D_CONST2 outside of ATEXT should not happen // Remove.
str = fmt.Sprintf("!!$%d-%d", a.Offset, a.Offset2) if a.Index != REG_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
} }
case D_FCONST: case obj.TYPE_TEXTSIZE:
if a.U.Argsize == obj.ArgsSizeUnknown {
str = fmt.Sprintf("$%d", a.Offset)
} else {
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
}
case obj.TYPE_FCONST:
str = fmt.Sprintf("$(%.17g)", a.U.Dval) str = fmt.Sprintf("$(%.17g)", a.U.Dval)
case D_SCONST: case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval) str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case D_ADDR: case obj.TYPE_ADDR:
a.Type = int16(a.Index) a.Type = obj.TYPE_MEM
a.Index = D_NONE
str = fmt.Sprintf("$%v", Dconv(p, 0, a)) str = fmt.Sprintf("$%v", Dconv(p, 0, a))
a.Index = uint8(a.Type) a.Type = obj.TYPE_ADDR
a.Type = D_ADDR break
goto conv
} }
brk:
if a.Index != D_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
conv:
fp += str fp += str
return fp return fp
} }
var Register = []string{ var Register = []string{
"AL", /* [D_AL] */ "AL", /* [REG_AL] */
"CL", "CL",
"DL", "DL",
"BL", "BL",
@ -194,7 +199,7 @@ var Register = []string{
"CH", "CH",
"DH", "DH",
"BH", "BH",
"AX", /* [D_AX] */ "AX", /* [REG_AX] */
"CX", "CX",
"DX", "DX",
"BX", "BX",
@ -202,7 +207,7 @@ var Register = []string{
"BP", "BP",
"SI", "SI",
"DI", "DI",
"F0", /* [D_F0] */ "F0", /* [REG_F0] */
"F1", "F1",
"F2", "F2",
"F3", "F3",
@ -210,18 +215,18 @@ var Register = []string{
"F5", "F5",
"F6", "F6",
"F7", "F7",
"CS", /* [D_CS] */ "CS", /* [REG_CS] */
"SS", "SS",
"DS", "DS",
"ES", "ES",
"FS", "FS",
"GS", "GS",
"GDTR", /* [D_GDTR] */ "GDTR", /* [REG_GDTR] */
"IDTR", /* [D_IDTR] */ "IDTR", /* [REG_IDTR] */
"LDTR", /* [D_LDTR] */ "LDTR", /* [REG_LDTR] */
"MSW", /* [D_MSW] */ "MSW", /* [REG_MSW] */
"TASK", /* [D_TASK] */ "TASK", /* [REG_TASK] */
"CR0", /* [D_CR] */ "CR0", /* [REG_CR] */
"CR1", "CR1",
"CR2", "CR2",
"CR3", "CR3",
@ -229,7 +234,7 @@ var Register = []string{
"CR5", "CR5",
"CR6", "CR6",
"CR7", "CR7",
"DR0", /* [D_DR] */ "DR0", /* [REG_DR] */
"DR1", "DR1",
"DR2", "DR2",
"DR3", "DR3",
@ -237,7 +242,7 @@ var Register = []string{
"DR5", "DR5",
"DR6", "DR6",
"DR7", "DR7",
"TR0", /* [D_TR] */ "TR0", /* [REG_TR] */
"TR1", "TR1",
"TR2", "TR2",
"TR3", "TR3",
@ -245,7 +250,7 @@ var Register = []string{
"TR5", "TR5",
"TR6", "TR6",
"TR7", "TR7",
"X0", /* [D_X0] */ "X0", /* [REG_X0] */
"X1", "X1",
"X2", "X2",
"X3", "X3",
@ -253,18 +258,21 @@ var Register = []string{
"X5", "X5",
"X6", "X6",
"X7", "X7",
"TLS", /* [D_TLS] */ "TLS", /* [REG_TLS] */
"NONE", /* [D_NONE] */ "MAXREG", /* [MAXREG] */
} }
func Rconv(r int) string { func Rconv(r int) string {
var str string var str string
var fp string var fp string
if r >= D_AL && r <= D_NONE { if r == REG_NONE {
str = fmt.Sprintf("%s", Register[r-D_AL]) fp += "NONE"
return fp
}
if r >= REG_AL && r-REG_AL < len(Register) {
str = fmt.Sprintf("%s", Register[r-REG_AL])
} else { } else {
str = fmt.Sprintf("gok(%d)", r) str = fmt.Sprintf("gok(%d)", r)
} }

View File

@ -38,51 +38,6 @@ import (
"math" "math"
) )
var zprg = obj.Prog{
Back: 2,
As: AGOK,
From: obj.Addr{
Type: D_NONE,
Index: D_NONE,
Scale: 1,
},
To: obj.Addr{
Type: D_NONE,
Index: D_NONE,
Scale: 1,
},
}
func symtype(a *obj.Addr) int {
var t int
t = int(a.Type)
if t == D_ADDR {
t = int(a.Index)
}
return t
}
func isdata(p *obj.Prog) bool {
return p.As == ADATA || p.As == AGLOBL
}
func iscall(p *obj.Prog) bool {
return p.As == ACALL
}
func datasize(p *obj.Prog) int {
return int(p.From.Scale)
}
func textflag(p *obj.Prog) int {
return int(p.From.Scale)
}
func settextflag(p *obj.Prog, f int) {
p.From.Scale = int8(f)
}
func canuselocaltls(ctxt *obj.Link) int { func canuselocaltls(ctxt *obj.Link) int {
switch ctxt.Headtype { switch ctxt.Headtype {
case obj.Hlinux, case obj.Hlinux,
@ -102,7 +57,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// See obj6.c for discussion of TLS. // See obj6.c for discussion of TLS.
if canuselocaltls(ctxt) != 0 { if canuselocaltls(ctxt) != 0 {
// Reduce TLS initial exec model to TLS local exec model. // Reduce TLS initial exec model to TLS local exec model.
// Sequences like // Sequences like
// MOVL TLS, BX // MOVL TLS, BX
@ -110,26 +64,26 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// become // become
// NOP // NOP
// ... off(TLS) ... // ... off(TLS) ...
if p.As == AMOVL && p.From.Type == D_TLS && D_AX <= p.To.Type && p.To.Type <= D_DI { if p.As == AMOVL && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI {
p.As = obj.ANOP
p.As = ANOP p.From.Type = obj.TYPE_NONE
p.From.Type = D_NONE p.To.Type = obj.TYPE_NONE
p.To.Type = D_NONE
} }
if p.From.Index == D_TLS && D_INDIR+D_AX <= p.From.Type && p.From.Type <= D_INDIR+D_DI { if p.From.Type == obj.TYPE_MEM && p.From.Index == REG_TLS && REG_AX <= p.From.Reg && p.From.Reg <= REG_DI {
p.From.Type = D_INDIR + D_TLS p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_TLS
p.From.Scale = 0 p.From.Scale = 0
p.From.Index = D_NONE p.From.Index = REG_NONE
} }
if p.To.Index == D_TLS && D_INDIR+D_AX <= p.To.Type && p.To.Type <= D_INDIR+D_DI { if p.To.Type == obj.TYPE_MEM && p.To.Index == REG_TLS && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI {
p.To.Type = D_INDIR + D_TLS p.To.Type = obj.TYPE_MEM
p.To.Reg = REG_TLS
p.To.Scale = 0 p.To.Scale = 0
p.To.Index = D_NONE p.To.Index = REG_NONE
} }
} else { } else {
// As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load. // As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load.
// The instruction // The instruction
// MOVL off(TLS), BX // MOVL off(TLS), BX
@ -137,59 +91,52 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// MOVL TLS, BX // MOVL TLS, BX
// MOVL off(BX)(TLS*1), BX // MOVL off(BX)(TLS*1), BX
// This allows the C compilers to emit references to m and g using the direct off(TLS) form. // This allows the C compilers to emit references to m and g using the direct off(TLS) form.
if p.As == AMOVL && p.From.Type == D_INDIR+D_TLS && D_AX <= p.To.Type && p.To.Type <= D_DI { if p.As == AMOVL && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI {
q = obj.Appendp(ctxt, p) q = obj.Appendp(ctxt, p)
q.As = p.As q.As = p.As
q.From = p.From q.From.Type = obj.TYPE_MEM
q.From.Type = D_INDIR + p.To.Type q.From.Reg = p.To.Reg
q.From.Index = D_TLS q.From.Index = REG_TLS
q.From.Scale = 2 // TODO: use 1 q.From.Scale = 2 // TODO: use 1
q.To = p.To q.To = p.To
p.From.Type = D_TLS p.From.Type = obj.TYPE_REG
p.From.Index = D_NONE p.From.Reg = REG_TLS
p.From.Index = REG_NONE
p.From.Offset = 0 p.From.Offset = 0
} }
} }
// TODO: Remove. // TODO: Remove.
if ctxt.Headtype == obj.Hplan9 { if ctxt.Headtype == obj.Hplan9 {
if p.From.Scale == 1 && p.From.Index == REG_TLS {
if p.From.Scale == 1 && p.From.Index == D_TLS {
p.From.Scale = 2 p.From.Scale = 2
} }
if p.To.Scale == 1 && p.To.Index == D_TLS { if p.To.Scale == 1 && p.To.Index == REG_TLS {
p.To.Scale = 2 p.To.Scale = 2
} }
} }
// Rewrite CALL/JMP/RET to symbol as D_BRANCH. // Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH.
switch p.As { switch p.As {
case obj.ACALL,
case ACALL, obj.AJMP,
AJMP, obj.ARET:
ARET: if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil {
if (p.To.Type == D_EXTERN || p.To.Type == D_STATIC) && p.To.Sym != nil { p.To.Type = obj.TYPE_BRANCH
p.To.Type = D_BRANCH
} }
break break
} }
// Rewrite float constants to values stored in memory. // Rewrite float constants to values stored in memory.
switch p.As { switch p.As {
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx // Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
case AMOVSS: case AMOVSS:
if p.From.Type == D_FCONST { if p.From.Type == obj.TYPE_FCONST {
if p.From.U.Dval == 0 { if p.From.U.Dval == 0 {
if p.To.Type >= D_X0 { if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 {
if p.To.Type <= D_X7 { p.As = AXORPS
p.As = AXORPS p.From = p.To
p.From.Type = p.To.Type break
p.From.Index = p.To.Index
break
}
} }
} }
} }
@ -212,8 +159,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
ADIVSS, ADIVSS,
ACOMISS, ACOMISS,
AUCOMISS: AUCOMISS:
if p.From.Type == D_FCONST { if p.From.Type == obj.TYPE_FCONST {
var i32 uint32 var i32 uint32
var f32 float32 var f32 float32
f32 = float32(p.From.U.Dval) f32 = float32(p.From.U.Dval)
@ -226,23 +172,20 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
s.Reachable = 0 s.Reachable = 0
} }
p.From.Type = D_EXTERN p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
p.From.Sym = s p.From.Sym = s
p.From.Offset = 0 p.From.Offset = 0
} }
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx // Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
case AMOVSD: case AMOVSD:
if p.From.Type == D_FCONST { if p.From.Type == obj.TYPE_FCONST {
if p.From.U.Dval == 0 { if p.From.U.Dval == 0 {
if p.To.Type >= D_X0 { if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 {
if p.To.Type <= D_X7 { p.As = AXORPS
p.As = AXORPS p.From = p.To
p.From.Type = p.To.Type break
p.From.Index = p.To.Index
break
}
} }
} }
} }
@ -265,8 +208,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
ADIVSD, ADIVSD,
ACOMISD, ACOMISD,
AUCOMISD: AUCOMISD:
if p.From.Type == D_FCONST { if p.From.Type == obj.TYPE_FCONST {
var i64 uint64 var i64 uint64
i64 = math.Float64bits(p.From.U.Dval) i64 = math.Float64bits(p.From.U.Dval)
literal = fmt.Sprintf("$f64.%016x", i64) literal = fmt.Sprintf("$f64.%016x", i64)
@ -277,7 +219,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
s.Reachable = 0 s.Reachable = 0
} }
p.From.Type = D_EXTERN p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
p.From.Sym = s p.From.Sym = s
p.From.Offset = 0 p.From.Offset = 0
} }
@ -286,12 +229,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
} }
} }
func prg() *obj.Prog { func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p := zprg
return &p
}
func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
var p *obj.Prog var p *obj.Prog
var q *obj.Prog var q *obj.Prog
var p1 *obj.Prog var p1 *obj.Prog
@ -322,37 +260,35 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
cursym.Locals = autoffset cursym.Locals = autoffset
cursym.Args = p.To.Offset2 cursym.Args = p.To.U.Argsize
q = nil q = nil
if !(p.From.Scale&obj.NOSPLIT != 0) || (p.From.Scale&obj.WRAPPER != 0) { if !(p.From3.Offset&obj.NOSPLIT != 0) || (p.From3.Offset&obj.WRAPPER != 0) {
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p = load_g_cx(ctxt, p) // load g into CX p = load_g_cx(ctxt, p) // load g into CX
} }
if !(cursym.Text.From.Scale&obj.NOSPLIT != 0) { if !(cursym.Text.From3.Offset&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autoffset, bool2int(!(cursym.Text.From.Scale&obj.NEEDCTXT != 0)), &q) // emit split check p = stacksplit(ctxt, p, autoffset, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0)), &q) // emit split check
} }
if autoffset != 0 { if autoffset != 0 {
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AADJSP p.As = AADJSP
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autoffset) p.From.Offset = int64(autoffset)
p.Spadj = autoffset p.Spadj = autoffset
} else { } else {
// zero-byte stack adjustment. // zero-byte stack adjustment.
// Insert a fake non-zero adjustment so that stkcheck can // Insert a fake non-zero adjustment so that stkcheck can
// recognize the end of the stack-splitting prolog. // recognize the end of the stack-splitting prolog.
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ANOP p.As = obj.ANOP
p.Spadj = int32(-ctxt.Arch.Ptrsize) p.Spadj = int32(-ctxt.Arch.Ptrsize)
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ANOP p.As = obj.ANOP
p.Spadj = int32(ctxt.Arch.Ptrsize) p.Spadj = int32(ctxt.Arch.Ptrsize)
} }
@ -361,7 +297,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
deltasp = autoffset deltasp = autoffset
if cursym.Text.From.Scale&obj.WRAPPER != 0 { if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
// //
// MOVL g_panic(CX), BX // MOVL g_panic(CX), BX
@ -380,71 +316,85 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVL p.As = AMOVL
p.From.Type = D_INDIR + D_CX p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_CX
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
p.To.Type = D_BX p.To.Type = obj.TYPE_REG
p.To.Reg = REG_BX
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ATESTL p.As = ATESTL
p.From.Type = D_BX p.From.Type = obj.TYPE_REG
p.To.Type = D_BX p.From.Reg = REG_BX
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_BX
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AJEQ p.As = AJEQ
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p1 = p p1 = p
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ALEAL p.As = ALEAL
p.From.Type = D_INDIR + D_SP p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_SP
p.From.Offset = int64(autoffset) + 4 p.From.Offset = int64(autoffset) + 4
p.To.Type = D_DI p.To.Type = obj.TYPE_REG
p.To.Reg = REG_DI
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPL p.As = ACMPL
p.From.Type = D_INDIR + D_BX p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_BX
p.From.Offset = 0 // Panic.argp p.From.Offset = 0 // Panic.argp
p.To.Type = D_DI p.To.Type = obj.TYPE_REG
p.To.Reg = REG_DI
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AJNE p.As = AJNE
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p2 = p p2 = p
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVL p.As = AMOVL
p.From.Type = D_SP p.From.Type = obj.TYPE_REG
p.To.Type = D_INDIR + D_BX p.From.Reg = REG_SP
p.To.Type = obj.TYPE_MEM
p.To.Reg = REG_BX
p.To.Offset = 0 // Panic.argp p.To.Offset = 0 // Panic.argp
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ANOP p.As = obj.ANOP
p1.Pcond = p p1.Pcond = p
p2.Pcond = p p2.Pcond = p
} }
if ctxt.Debugzerostack != 0 && autoffset != 0 && !(cursym.Text.From.Scale&obj.NOSPLIT != 0) { if ctxt.Debugzerostack != 0 && autoffset != 0 && !(cursym.Text.From3.Offset&obj.NOSPLIT != 0) {
// 8l -Z means zero the stack frame on entry. // 8l -Z means zero the stack frame on entry.
// This slows down function calls but can help avoid // This slows down function calls but can help avoid
// false positives in garbage collection. // false positives in garbage collection.
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVL p.As = AMOVL
p.From.Type = D_SP p.From.Type = obj.TYPE_REG
p.To.Type = D_DI p.From.Reg = REG_SP
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_DI
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVL p.As = AMOVL
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autoffset) / 4 p.From.Offset = int64(autoffset) / 4
p.To.Type = D_CX p.To.Type = obj.TYPE_REG
p.To.Reg = REG_CX
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVL p.As = AMOVL
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 0 p.From.Offset = 0
p.To.Type = D_AX p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AREP p.As = AREP
@ -454,18 +404,18 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
for ; p != nil; p = p.Link { for ; p != nil; p = p.Link {
a = int(p.From.Type) a = int(p.From.Name)
if a == D_AUTO { if a == obj.NAME_AUTO {
p.From.Offset += int64(deltasp) p.From.Offset += int64(deltasp)
} }
if a == D_PARAM { if a == obj.NAME_PARAM {
p.From.Offset += int64(deltasp) + 4 p.From.Offset += int64(deltasp) + 4
} }
a = int(p.To.Type) a = int(p.To.Name)
if a == D_AUTO { if a == obj.NAME_AUTO {
p.To.Offset += int64(deltasp) p.To.Offset += int64(deltasp)
} }
if a == D_PARAM { if a == obj.NAME_PARAM {
p.To.Offset += int64(deltasp) + 4 p.To.Offset += int64(deltasp) + 4
} }
@ -497,7 +447,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.Spadj = -2 p.Spadj = -2
continue continue
case ARET: case obj.ARET:
break break
} }
@ -507,11 +457,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
if autoffset != 0 { if autoffset != 0 {
p.As = AADJSP p.As = AADJSP
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-autoffset) p.From.Offset = int64(-autoffset)
p.Spadj = -autoffset p.Spadj = -autoffset
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ARET p.As = obj.ARET
// If there are instructions following // If there are instructions following
// this ARET, they come from a branch // this ARET, they come from a branch
@ -521,7 +471,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
if p.To.Sym != nil { // retjmp if p.To.Sym != nil { // retjmp
p.As = AJMP p.As = obj.AJMP
} }
} }
} }
@ -532,13 +482,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
// prologue (caller must call appendp first) and in the epilogue. // prologue (caller must call appendp first) and in the epilogue.
// Returns last new instruction. // Returns last new instruction.
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
var next *obj.Prog var next *obj.Prog
p.As = AMOVL p.As = AMOVL
p.From.Type = D_INDIR + D_TLS p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_TLS
p.From.Offset = 0 p.From.Offset = 0
p.To.Type = D_CX p.To.Type = obj.TYPE_REG
p.To.Reg = REG_CX
next = p.Link next = p.Link
progedit(ctxt, p) progedit(ctxt, p)
@ -546,7 +497,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
p = p.Link p = p.Link
} }
if p.From.Index == D_TLS { if p.From.Index == REG_TLS {
p.From.Scale = 2 p.From.Scale = 2
} }
@ -560,7 +511,6 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
// On return, *jmpok is the instruction that should jump // On return, *jmpok is the instruction that should jump
// to the stack frame allocation if no split is needed. // to the stack frame allocation if no split is needed.
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok **obj.Prog) *obj.Prog { func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok **obj.Prog) *obj.Prog {
var q *obj.Prog var q *obj.Prog
var q1 *obj.Prog var q1 *obj.Prog
@ -573,23 +523,25 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPL p.As = ACMPL
p.From.Type = D_INDIR + D_CX p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_CX
p.From.Offset = 4 p.From.Offset = 4
p.To.Type = D_SP p.To.Type = obj.TYPE_REG
p.To.Reg = REG_SP
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AJCC p.As = AJCC
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p.To.Offset = 4 p.To.Offset = 4
q1 = p q1 = p
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AINT p.As = AINT
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 3 p.From.Offset = 3
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ANOP p.As = obj.ANOP
q1.Pcond = p q1.Pcond = p
} }
@ -601,8 +553,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPL p.As = ACMPL
p.From.Type = D_SP p.From.Type = obj.TYPE_REG
p.To.Type = D_INDIR + D_CX p.From.Reg = REG_SP
p.To.Type = obj.TYPE_MEM
p.To.Reg = REG_CX
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 { if ctxt.Cursym.Cfunc != 0 {
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
@ -614,20 +568,23 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ALEAL p.As = ALEAL
p.From.Type = D_INDIR + D_SP p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_SP
p.From.Offset = -(int64(framesize) - obj.StackSmall) p.From.Offset = -(int64(framesize) - obj.StackSmall)
p.To.Type = D_AX p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPL p.As = ACMPL
p.From.Type = D_AX p.From.Type = obj.TYPE_REG
p.To.Type = D_INDIR + D_CX p.From.Reg = REG_AX
p.To.Type = obj.TYPE_MEM
p.To.Reg = REG_CX
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 { if ctxt.Cursym.Cfunc != 0 {
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
} }
} else { } else {
// Such a large stack we need to protect against wraparound // Such a large stack we need to protect against wraparound
// if SP is close to zero. // if SP is close to zero.
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) // SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
@ -645,41 +602,49 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVL p.As = AMOVL
p.From.Type = D_INDIR + D_CX p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_CX
p.From.Offset = 0 p.From.Offset = 0
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 { if ctxt.Cursym.Cfunc != 0 {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
} }
p.To.Type = D_SI p.To.Type = obj.TYPE_REG
p.To.Reg = REG_SI
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPL p.As = ACMPL
p.From.Type = D_SI p.From.Type = obj.TYPE_REG
p.To.Type = D_CONST p.From.Reg = REG_SI
p.To.Type = obj.TYPE_CONST
p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1))) p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AJEQ p.As = AJEQ
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
q1 = p q1 = p
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ALEAL p.As = ALEAL
p.From.Type = D_INDIR + D_SP p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_SP
p.From.Offset = obj.StackGuard p.From.Offset = obj.StackGuard
p.To.Type = D_AX p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ASUBL p.As = ASUBL
p.From.Type = D_SI p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SI
p.From.Offset = 0 p.From.Offset = 0
p.To.Type = D_AX p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPL p.As = ACMPL
p.From.Type = D_AX p.From.Type = obj.TYPE_REG
p.To.Type = D_CONST p.From.Reg = REG_AX
p.To.Type = obj.TYPE_CONST
p.To.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) p.To.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
} }
@ -687,23 +652,22 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AJHI p.As = AJHI
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p.To.Offset = 4 p.To.Offset = 4
q = p q = p
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACALL p.As = obj.ACALL
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
if ctxt.Cursym.Cfunc != 0 { if ctxt.Cursym.Cfunc != 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0) p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else { } else {
p.To.Sym = ctxt.Symmorestack[noctxt] p.To.Sym = ctxt.Symmorestack[noctxt]
} }
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AJMP p.As = obj.AJMP
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = ctxt.Cursym.Text.Link p.Pcond = ctxt.Cursym.Text.Link
if q != nil { if q != nil {
@ -723,7 +687,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
ctxt.Cursym = s ctxt.Cursym = s
firstp = ctxt.NewProg() firstp = new(obj.Prog)
lastp = firstp lastp = firstp
xfol(ctxt, s.Text, &lastp) xfol(ctxt, s.Text, &lastp)
lastp.Link = nil lastp.Link = nil
@ -732,11 +696,11 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
func nofollow(a int) int { func nofollow(a int) int {
switch a { switch a {
case AJMP, case obj.AJMP,
ARET, obj.ARET,
AIRETL, AIRETL,
AIRETW, AIRETW,
AUNDEF: obj.AUNDEF:
return 1 return 1
} }
@ -808,9 +772,9 @@ loop:
if p == nil { if p == nil {
return return
} }
if p.As == AJMP { if p.As == obj.AJMP {
q = p.Pcond q = p.Pcond
if q != nil && q.As != ATEXT { if q != nil && q.As != obj.ATEXT {
/* mark instruction as done and continue layout at target of jump */ /* mark instruction as done and continue layout at target of jump */
p.Mark = 1 p.Mark = 1
@ -829,7 +793,6 @@ loop:
i = 0 i = 0
q = p q = p
for ; i < 4; (func() { i++; q = q.Link })() { for ; i < 4; (func() { i++; q = q.Link })() {
if q == nil { if q == nil {
break break
} }
@ -837,7 +800,7 @@ loop:
break break
} }
a = int(q.As) a = int(q.As)
if a == ANOP { if a == obj.ANOP {
i-- i--
continue continue
} }
@ -848,11 +811,11 @@ loop:
if q.Pcond == nil || q.Pcond.Mark != 0 { if q.Pcond == nil || q.Pcond.Mark != 0 {
continue continue
} }
if a == ACALL || a == ALOOP { if a == obj.ACALL || a == ALOOP {
continue continue
} }
for { for {
if p.As == ANOP { if p.As == obj.ANOP {
p = p.Link p = p.Link
continue continue
} }
@ -879,10 +842,10 @@ loop:
/* */ /* */
} }
} }
q = ctxt.NewProg() q = new(obj.Prog)
q.As = AJMP q.As = obj.AJMP
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.To.Type = D_BRANCH q.To.Type = obj.TYPE_BRANCH
q.To.Offset = p.Pc q.To.Offset = p.Pc
q.Pcond = p q.Pcond = p
p = q p = q
@ -897,10 +860,9 @@ loop:
/* continue loop with what comes after p */ /* continue loop with what comes after p */
if nofollow(a) != 0 { if nofollow(a) != 0 {
return return
} }
if p.Pcond != nil && a != ACALL { if p.Pcond != nil && a != obj.ACALL {
/* /*
* some kind of conditional branch. * some kind of conditional branch.
* recurse to follow one path. * recurse to follow one path.
@ -908,14 +870,13 @@ loop:
*/ */
q = obj.Brchain(ctxt, p.Pcond) q = obj.Brchain(ctxt, p.Pcond)
if q != nil { if q != nil {
p.Pcond = q p.Pcond = q
} }
q = obj.Brchain(ctxt, p.Link) q = obj.Brchain(ctxt, p.Link)
if q != nil { if q != nil {
p.Link = q p.Link = q
} }
if p.From.Type == D_CONST { if p.From.Type == obj.TYPE_CONST {
if p.From.Offset == 1 { if p.From.Offset == 1 {
/* /*
* expect conditional jump to be taken. * expect conditional jump to be taken.
@ -928,7 +889,6 @@ loop:
p.Pcond = q p.Pcond = q
} }
} else { } else {
q = p.Link q = p.Link
if q.Mark != 0 { if q.Mark != 0 {
if a != ALOOP { if a != ALOOP {
@ -952,45 +912,16 @@ loop:
} }
var Link386 = obj.LinkArch{ var Link386 = obj.LinkArch{
ByteOrder: binary.LittleEndian, ByteOrder: binary.LittleEndian,
Pconv: Pconv, Pconv: Pconv,
Name: "386", Name: "386",
Thechar: '8', Thechar: '8',
Endian: obj.LittleEndian, Endian: obj.LittleEndian,
Addstacksplit: addstacksplit, Preprocess: preprocess,
Assemble: span8, Assemble: span8,
Datasize: datasize, Follow: follow,
Follow: follow, Progedit: progedit,
Iscall: iscall, Minlc: 1,
Isdata: isdata, Ptrsize: 4,
Prg: prg, Regsize: 4,
Progedit: progedit,
Settextflag: settextflag,
Symtype: symtype,
Textflag: textflag,
Minlc: 1,
Ptrsize: 4,
Regsize: 4,
D_ADDR: D_ADDR,
D_AUTO: D_AUTO,
D_BRANCH: D_BRANCH,
D_CONST: D_CONST,
D_EXTERN: D_EXTERN,
D_FCONST: D_FCONST,
D_NONE: D_NONE,
D_PARAM: D_PARAM,
D_SCONST: D_SCONST,
D_STATIC: D_STATIC,
ACALL: ACALL,
ADATA: ADATA,
AEND: AEND,
AFUNCDATA: AFUNCDATA,
AGLOBL: AGLOBL,
AJMP: AJMP,
ANOP: ANOP,
APCDATA: APCDATA,
ARET: ARET,
ATEXT: ATEXT,
ATYPE: ATYPE,
AUSEFIELD: AUSEFIELD,
} }

View File

@ -116,7 +116,6 @@ func mkfwd(sym *LSym) {
if i == 0 { if i == 0 {
cnt[i] = 1 cnt[i] = 1
} else { } else {
cnt[i] = LOG * cnt[i-1] cnt[i] = LOG * cnt[i-1]
} }
dwn[i] = 1 dwn[i] = 1

View File

@ -33,24 +33,25 @@ package obj
import "encoding/binary" import "encoding/binary"
type Addr struct { type Addr struct {
Type int16
Reg int16
Index int16
Scale int8
Name int8
Offset int64 Offset int64
Sym *LSym
U struct { U struct {
Sval string Sval string
Dval float64 Dval float64
Branch *Prog Branch *Prog
Argsize int32
Bits uint64
} }
Sym *LSym Gotype *LSym
Gotype *LSym Class int8
Type int16 Etype uint8
Index uint8 Node interface{}
Scale int8 Width int64
Reg int8
Name int8
Class int8
Etype uint8
Offset2 int32
Node interface{}
Width int64
} }
type Prog struct { type Prog struct {
@ -61,7 +62,7 @@ type Prog struct {
As int16 As int16
Scond uint8 Scond uint8
From Addr From Addr
Reg uint8 Reg int16
From3 Addr From3 Addr
To Addr To Addr
Opt interface{} Opt interface{}
@ -79,7 +80,6 @@ type Prog struct {
Printed uint8 Printed uint8
Width int8 Width int8
Mode int8 Mode int8
TEXTFLAG uint8
} }
type LSym struct { type LSym struct {
@ -149,7 +149,7 @@ type Auto struct {
Asym *LSym Asym *LSym
Link *Auto Link *Auto
Aoffset int32 Aoffset int32
Type int16 Name int16
Gotype *LSym Gotype *LSym
} }
@ -240,48 +240,18 @@ type Plist struct {
} }
type LinkArch struct { type LinkArch struct {
Pconv func(*Prog) string Pconv func(*Prog) string
Name string ByteOrder binary.ByteOrder
Thechar int Name string
Endian int32 Thechar int
ByteOrder binary.ByteOrder Endian int32
Addstacksplit func(*Link, *LSym) Preprocess func(*Link, *LSym)
Assemble func(*Link, *LSym) Assemble func(*Link, *LSym)
Datasize func(*Prog) int Follow func(*Link, *LSym)
Follow func(*Link, *LSym) Progedit func(*Link, *Prog)
Iscall func(*Prog) bool Minlc int
Isdata func(*Prog) bool Ptrsize int
Prg func() *Prog Regsize int
Progedit func(*Link, *Prog)
Settextflag func(*Prog, int)
Symtype func(*Addr) int
Textflag func(*Prog) int
Minlc int
Ptrsize int
Regsize int
D_ADDR int
D_AUTO int
D_BRANCH int
D_CONST int
D_EXTERN int
D_FCONST int
D_NONE int
D_PARAM int
D_SCONST int
D_STATIC int
D_OREG int
ACALL int
ADATA int
AEND int
AFUNCDATA int
AGLOBL int
AJMP int
ANOP int
APCDATA int
ARET int
ATEXT int
ATYPE int
AUSEFIELD int
} }
type Library struct { type Library struct {
@ -318,7 +288,156 @@ type Pciter struct {
done int done int
} }
// prevent incompatible type signatures between liblink and 8l on Plan 9 // An Addr is an argument to an instruction.
// The general forms and their encodings are:
//
// sym±offset(symkind)(reg)(index*scale)
// Memory reference at address &sym(symkind) + offset + reg + index*scale.
// Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted.
// If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg).
// To force a parsing as index*scale, write (index*1).
// Encoding:
// type = TYPE_MEM
// name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE)
// sym = sym
// offset = ±offset
// reg = reg (REG_*)
// index = index (REG_*)
// scale = scale (1, 2, 4, 8)
//
// $<mem>
// Effective address of memory reference <mem>, defined above.
// Encoding: same as memory reference, but type = TYPE_ADDR.
//
// $<±integer value>
// This is a special case of $<mem>, in which only ±offset is present.
// It has a separate type for easy recognition.
// Encoding:
// type = TYPE_CONST
// offset = ±integer value
//
// *<mem>
// Indirect reference through memory reference <mem>, defined above.
// Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function
// pointer stored in the data word sym(SB), not a function named sym(SB).
// Encoding: same as above, but type = TYPE_INDIR.
//
// $*$<mem>
// No longer used.
// On machines with actual SB registers, $*$<mem> forced the
// instruction encoding to use a full 32-bit constant, never a
// reference relative to SB.
//
// $<floating point literal>
// Floating point constant value.
// Encoding:
// type = TYPE_FCONST
// u.dval = floating point value
//
// $<string literal, up to 8 chars>
// String literal value (raw bytes used for DATA instruction).
// Encoding:
// type = TYPE_SCONST
// u.sval = string
//
// <register name>
// Any register: integer, floating point, control, segment, and so on.
// If looking for specific register kind, must check type and reg value range.
// Encoding:
// type = TYPE_REG
// reg = reg (REG_*)
//
// x(PC)
// Encoding:
// type = TYPE_BRANCH
// u.branch = Prog* reference OR ELSE offset = target pc (branch takes priority)
//
// $±x-±y
// Final argument to TEXT, specifying local frame size x and argument size y.
// In this form, x and y are integer literals only, not arbitrary expressions.
// This avoids parsing ambiguities due to the use of - as a separator.
// The ± are optional.
// If the final argument to TEXT omits the -±y, the encoding should still
// use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown.
// Encoding:
// type = TYPE_TEXTSIZE
// offset = x
// u.argsize = y
//
// reg<<shift, reg>>shift, reg->shift, reg@>shift
// Shifted register value, for ARM.
// In this form, reg must be a register and shift can be a register or an integer constant.
// Encoding:
// type = TYPE_SHIFT
// offset = (reg&15) | shifttype<<5 | count
// shifttype = 0, 1, 2, 3 for <<, >>, ->, @>
// count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant.
//
// (reg, reg)
// A destination register pair. When used as the last argument of an instruction,
// this form makes clear that both registers are destinations.
// Encoding:
// type = TYPE_REGREG
// reg = first register
// offset = second register
//
// reg, reg
// TYPE_REGREG2, to be removed.
//
const (
NAME_NONE = 0 + iota
NAME_EXTERN
NAME_STATIC
NAME_AUTO
NAME_PARAM
)
const (
TYPE_NONE = 0
TYPE_BRANCH = 5 + iota - 1
TYPE_TEXTSIZE
TYPE_MEM
TYPE_CONST
TYPE_FCONST
TYPE_SCONST
TYPE_REG
TYPE_ADDR
TYPE_SHIFT
TYPE_REGREG
TYPE_REGREG2
TYPE_INDIR
)
// TODO(rsc): Describe prog.
// TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3.
// Prog.as opcodes.
// These are the portable opcodes, common to all architectures.
// Each architecture defines many more arch-specific opcodes,
// with values starting at A_ARCHSPECIFIC.
const (
AXXX = 0 + iota
ACALL
ACHECKNIL
ADATA
ADUFFCOPY
ADUFFZERO
AEND
AFUNCDATA
AGLOBL
AJMP
ANOP
APCDATA
ARET
ATEXT
ATYPE
AUNDEF
AUSEFIELD
AVARDEF
AVARKILL
A_ARCHSPECIFIC
)
// prevent incompatible type signatures between liblink and 8l on Plan 9 // prevent incompatible type signatures between liblink and 8l on Plan 9
@ -397,7 +516,7 @@ const (
RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1 RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1
) )
// Auto.type // Auto.name
const ( const (
A_AUTO = 1 + iota A_AUTO = 1 + iota
A_PARAM A_PARAM
@ -461,3 +580,17 @@ const (
// go.c // go.c
// ld.c // ld.c
// list[5689].c
// obj.c
// objfile.c
// pass.c
// pcln.c
// sym.c
var linkbasepointer int

View File

@ -15,7 +15,7 @@ const (
NSYM = 50 NSYM = 50
) )
func linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string { func Linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string {
var a [HISTSZ]struct { var a [HISTSZ]struct {
incl *Hist incl *Hist
idel int32 idel int32
@ -222,11 +222,9 @@ func Linklinehist(ctxt *Link, lineno int, f string, offset int) {
if offset != 0 { if offset != 0 {
fmt.Printf("%4d: %s (#line %d)\n", lineno, f, offset) fmt.Printf("%4d: %s (#line %d)\n", lineno, f, offset)
} else { } else {
fmt.Printf("%4d: %s\n", lineno, f) fmt.Printf("%4d: %s\n", lineno, f)
} }
} else { } else {
fmt.Printf("%4d: <pop>\n", lineno) fmt.Printf("%4d: <pop>\n", lineno)
} }
} }
@ -297,7 +295,6 @@ func Linkprfile(ctxt *Link, line int) {
* start a new Prog list. * start a new Prog list.
*/ */
func Linknewplist(ctxt *Link) *Plist { func Linknewplist(ctxt *Link) *Plist {
var pl *Plist var pl *Plist
pl = new(Plist) pl = new(Plist)
@ -305,7 +302,6 @@ func Linknewplist(ctxt *Link) *Plist {
if ctxt.Plist == nil { if ctxt.Plist == nil {
ctxt.Plist = pl ctxt.Plist = pl
} else { } else {
ctxt.Plast.Link = pl ctxt.Plast.Link = pl
} }
ctxt.Plast = pl ctxt.Plast = pl

View File

@ -17,7 +17,6 @@ var outfile string
// out a Go object file. The linker does not call this; the linker // out a Go object file. The linker does not call this; the linker
// does not write out object files. // does not write out object files.
func Writeobjdirect(ctxt *Link, b *Biobuf) { func Writeobjdirect(ctxt *Link, b *Biobuf) {
var flag int var flag int
var found int var found int
var h *Hist var h *Hist
@ -44,16 +43,16 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
for pl = ctxt.Plist; pl != nil; pl = pl.Link { for pl = ctxt.Plist; pl != nil; pl = pl.Link {
for p = pl.Firstpc; p != nil; p = plink { for p = pl.Firstpc; p != nil; p = plink {
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 { if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
fmt.Printf("obj: %p %v\n", p, p) fmt.Printf("obj: %v\n", p)
} }
plink = p.Link plink = p.Link
p.Link = nil p.Link = nil
if int(p.As) == ctxt.Arch.AEND { if p.As == AEND {
continue continue
} }
if int(p.As) == ctxt.Arch.ATYPE { if p.As == ATYPE {
// Assume each TYPE instruction describes // Assume each TYPE instruction describes
// a different local variable or parameter, // a different local variable or parameter,
// so no dedup. // so no dedup.
@ -66,20 +65,19 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
// If something else could use them, we could arrange to // If something else could use them, we could arrange to
// preserve them. // preserve them.
if curtext == nil { if curtext == nil {
continue continue
} }
a = new(Auto) a = new(Auto)
a.Asym = p.From.Sym a.Asym = p.From.Sym
a.Aoffset = int32(p.From.Offset) a.Aoffset = int32(p.From.Offset)
a.Type = int16(ctxt.Arch.Symtype(&p.From)) a.Name = int16(p.From.Name)
a.Gotype = p.From.Gotype a.Gotype = p.From.Gotype
a.Link = curtext.Autom a.Link = curtext.Autom
curtext.Autom = a curtext.Autom = a
continue continue
} }
if int(p.As) == ctxt.Arch.AGLOBL { if p.As == AGLOBL {
s = p.From.Sym s = p.From.Sym
tmp6 := s.Seenglobl tmp6 := s.Seenglobl
s.Seenglobl++ s.Seenglobl++
@ -93,7 +91,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
if data == nil { if data == nil {
data = s data = s
} else { } else {
edata.Next = s edata.Next = s
} }
s.Next = nil s.Next = nil
@ -101,7 +98,7 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
if s.Type == 0 || s.Type == SXREF { if s.Type == 0 || s.Type == SXREF {
s.Type = SBSS s.Type = SBSS
} }
flag = ctxt.Arch.Textflag(p) flag = int(p.From3.Offset)
if flag&DUPOK != 0 { if flag&DUPOK != 0 {
s.Dupok = 1 s.Dupok = 1
} }
@ -114,12 +111,12 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
continue continue
} }
if int(p.As) == ctxt.Arch.ADATA { if p.As == ADATA {
savedata(ctxt, p.From.Sym, p, "<input>") savedata(ctxt, p.From.Sym, p, "<input>")
continue continue
} }
if int(p.As) == ctxt.Arch.ATEXT { if p.As == ATEXT {
s = p.From.Sym s = p.From.Sym
if s == nil { if s == nil {
// func _() { } // func _() { }
@ -138,11 +135,10 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
if text == nil { if text == nil {
text = s text = s
} else { } else {
etext.Next = s etext.Next = s
} }
etext = s etext = s
flag = ctxt.Arch.Textflag(p) flag = int(p.From3.Offset)
if flag&DUPOK != 0 { if flag&DUPOK != 0 {
s.Dupok = 1 s.Dupok = 1
} }
@ -157,16 +153,16 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
continue continue
} }
if int(p.As) == ctxt.Arch.AFUNCDATA { if p.As == AFUNCDATA {
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information. // Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
if curtext == nil { // func _() {} if curtext == nil { // func _() {}
continue continue
} }
if p.To.Sym.Name == "go_args_stackmap" { if p.To.Sym.Name == "go_args_stackmap" {
if int(p.From.Type) != ctxt.Arch.D_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps { if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps") ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
} }
p.To.Sym = Linklookup(ctxt, string(fmt.Sprintf("%s.args_stackmap", curtext.Name)), int(curtext.Version)) p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version))
} }
} }
@ -181,13 +177,12 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
// Add reference to Go arguments for C or assembly functions without them. // Add reference to Go arguments for C or assembly functions without them.
for s = text; s != nil; s = s.Next { for s = text; s != nil; s = s.Next {
if !strings.HasPrefix(s.Name, "\"\".") { if !strings.HasPrefix(s.Name, "\"\".") {
continue continue
} }
found = 0 found = 0
for p = s.Text; p != nil; p = p.Link { for p = s.Text; p != nil; p = p.Link {
if int(p.As) == ctxt.Arch.AFUNCDATA && int(p.From.Type) == ctxt.Arch.D_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps { if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps {
found = 1 found = 1
break break
} }
@ -195,28 +190,21 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
if !(found != 0) { if !(found != 0) {
p = Appendp(ctxt, s.Text) p = Appendp(ctxt, s.Text)
p.As = int16(ctxt.Arch.AFUNCDATA) p.As = AFUNCDATA
p.From.Type = int16(ctxt.Arch.D_CONST) p.From.Type = TYPE_CONST
p.From.Offset = FUNCDATA_ArgsPointerMaps p.From.Offset = FUNCDATA_ArgsPointerMaps
if ctxt.Arch.Thechar == '6' || ctxt.Arch.Thechar == '8' { p.To.Type = TYPE_MEM
p.To.Type = int16(ctxt.Arch.D_EXTERN) p.To.Name = NAME_EXTERN
} else { p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version))
p.To.Type = int16(ctxt.Arch.D_OREG)
p.To.Name = int8(ctxt.Arch.D_EXTERN)
}
p.To.Sym = Linklookup(ctxt, string(fmt.Sprintf("%s.args_stackmap", s.Name)), int(s.Version))
} }
} }
// Turn functions into machine code images. // Turn functions into machine code images.
for s = text; s != nil; s = s.Next { for s = text; s != nil; s = s.Next {
mkfwd(s) mkfwd(s)
linkpatch(ctxt, s) linkpatch(ctxt, s)
ctxt.Arch.Follow(ctxt, s) ctxt.Arch.Follow(ctxt, s)
ctxt.Arch.Addstacksplit(ctxt, s) ctxt.Arch.Preprocess(ctxt, s)
ctxt.Arch.Assemble(ctxt, s) ctxt.Arch.Assemble(ctxt, s)
linkpcln(ctxt, s) linkpcln(ctxt, s)
} }
@ -230,7 +218,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
// Emit autolib. // Emit autolib.
for h = ctxt.Hist; h != nil; h = h.Link { for h = ctxt.Hist; h != nil; h = h.Link {
if h.Offset < 0 { if h.Offset < 0 {
wrstring(b, h.Name) wrstring(b, h.Name)
} }
@ -239,7 +226,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
// Emit symbols. // Emit symbols.
for s = text; s != nil; s = s.Next { for s = text; s != nil; s = s.Next {
writesym(ctxt, b, s) writesym(ctxt, b, s)
} }
for s = data; s != nil; s = s.Next { for s = data; s != nil; s = s.Next {
@ -307,7 +293,6 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) {
if ' ' <= c && c <= 0x7e { if ' ' <= c && c <= 0x7e {
fmt.Fprintf(ctxt.Bso, "%c", c) fmt.Fprintf(ctxt.Bso, "%c", c)
} else { } else {
fmt.Fprintf(ctxt.Bso, ".") fmt.Fprintf(ctxt.Bso, ".")
} }
} }
@ -325,7 +310,6 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) {
if ctxt.Arch.Thechar == '5' || ctxt.Arch.Thechar == '9' { if ctxt.Arch.Thechar == '5' || ctxt.Arch.Thechar == '9' {
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(int64(r.Add))) fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(int64(r.Add)))
} else { } else {
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, int64(r.Add)) fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, int64(r.Add))
} }
} }
@ -365,13 +349,12 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) {
for a = s.Autom; a != nil; a = a.Link { for a = s.Autom; a != nil; a = a.Link {
wrsym(b, a.Asym) wrsym(b, a.Asym)
wrint(b, int64(a.Aoffset)) wrint(b, int64(a.Aoffset))
if int(a.Type) == ctxt.Arch.D_AUTO { if a.Name == NAME_AUTO {
wrint(b, A_AUTO) wrint(b, A_AUTO)
} else if int(a.Type) == ctxt.Arch.D_PARAM { } else if a.Name == NAME_PARAM {
wrint(b, A_PARAM) wrint(b, A_PARAM)
} else { } else {
log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name)
log.Fatalf("%s: invalid local variable type %d", s.Name, a.Type)
} }
wrsym(b, a.Gotype) wrsym(b, a.Gotype)
} }

View File

@ -33,11 +33,10 @@ package obj
// Code and data passes. // Code and data passes.
func Brchain(ctxt *Link, p *Prog) *Prog { func Brchain(ctxt *Link, p *Prog) *Prog {
var i int var i int
for i = 0; i < 20; i++ { for i = 0; i < 20; i++ {
if p == nil || int(p.As) != ctxt.Arch.AJMP || p.Pcond == nil { if p == nil || p.As != AJMP || p.Pcond == nil {
return p return p
} }
p = p.Pcond p = p.Pcond
@ -52,7 +51,7 @@ func brloop(ctxt *Link, p *Prog) *Prog {
c = 0 c = 0
for q = p; q != nil; q = q.Pcond { for q = p; q != nil; q = q.Pcond {
if int(q.As) != ctxt.Arch.AJMP || q.Pcond == nil { if q.As != AJMP || q.Pcond == nil {
break break
} }
c++ c++
@ -64,6 +63,92 @@ func brloop(ctxt *Link, p *Prog) *Prog {
return q return q
} }
func checkaddr(ctxt *Link, p *Prog, a *Addr) {
// Check expected encoding, especially TYPE_CONST vs TYPE_ADDR.
switch a.Type {
case TYPE_NONE:
return
case TYPE_BRANCH:
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 {
break
}
return
case TYPE_TEXTSIZE:
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 {
break
}
return
//if(a->u.bits != 0)
// break;
case TYPE_MEM:
return
// TODO(rsc): After fixing SHRQ, check a->index != 0 too.
case TYPE_CONST:
if a.Name != 0 || a.Sym != nil || a.Reg != 0 {
ctxt.Diag("argument is TYPE_CONST, should be TYPE_ADDR, in %v", p)
return
}
if a.Reg != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 {
break
}
return
case TYPE_FCONST,
TYPE_SCONST:
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Offset != 0 || a.Sym != nil {
break
}
return
// TODO(rsc): After fixing PINSRQ, check a->offset != 0 too.
// TODO(rsc): After fixing SHRQ, check a->index != 0 too.
case TYPE_REG:
if a.Scale != 0 || a.Name != 0 || a.Sym != nil {
break
}
return
case TYPE_ADDR:
if a.U.Bits != 0 {
break
}
if a.Reg == 0 && a.Index == 0 && a.Scale == 0 && a.Name == 0 && a.Sym == nil {
ctxt.Diag("argument is TYPE_ADDR, should be TYPE_CONST, in %v", p)
}
return
case TYPE_SHIFT:
if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 {
break
}
return
case TYPE_REGREG:
if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 {
break
}
return
case TYPE_REGREG2:
return
// Expect sym and name to be set, nothing else.
// Technically more is allowed, but this is only used for *name(SB).
case TYPE_INDIR:
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name == 0 || a.Offset != 0 || a.Sym == nil || a.U.Bits != 0 {
break
}
return
}
ctxt.Diag("invalid encoding for argument %v", p)
}
func linkpatch(ctxt *Link, sym *LSym) { func linkpatch(ctxt *Link, sym *LSym) {
var c int32 var c int32
var name string var name string
@ -73,10 +158,14 @@ func linkpatch(ctxt *Link, sym *LSym) {
ctxt.Cursym = sym ctxt.Cursym = sym
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.From3)
checkaddr(ctxt, p, &p.To)
if ctxt.Arch.Progedit != nil { if ctxt.Arch.Progedit != nil {
ctxt.Arch.Progedit(ctxt, p) ctxt.Arch.Progedit(ctxt, p)
} }
if int(p.To.Type) != ctxt.Arch.D_BRANCH { if p.To.Type != TYPE_BRANCH {
continue continue
} }
if p.To.U.Branch != nil { if p.To.U.Branch != nil {
@ -97,7 +186,6 @@ func linkpatch(ctxt *Link, sym *LSym) {
if q.Forwd != nil && int64(c) >= q.Forwd.Pc { if q.Forwd != nil && int64(c) >= q.Forwd.Pc {
q = q.Forwd q = q.Forwd
} else { } else {
q = q.Link q = q.Link
} }
} }
@ -108,7 +196,7 @@ func linkpatch(ctxt *Link, sym *LSym) {
name = p.To.Sym.Name name = p.To.Sym.Name
} }
ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name) ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name)
p.To.Type = int16(ctxt.Arch.D_NONE) p.To.Type = TYPE_NONE
} }
p.To.U.Branch = q p.To.U.Branch = q
@ -120,7 +208,7 @@ func linkpatch(ctxt *Link, sym *LSym) {
if p.Pcond != nil { if p.Pcond != nil {
p.Pcond = brloop(ctxt, p.Pcond) p.Pcond = brloop(ctxt, p.Pcond)
if p.Pcond != nil { if p.Pcond != nil {
if int(p.To.Type) == ctxt.Arch.D_BRANCH { if p.To.Type == TYPE_BRANCH {
p.To.Offset = p.Pcond.Pc p.To.Offset = p.Pcond.Pc
} }
} }

View File

@ -28,7 +28,6 @@ func addvarint(ctxt *Link, d *Pcdata, val uint32) {
// where func is the function, val is the current value, p is the instruction being // where func is the function, val is the current value, p is the instruction being
// considered, and arg can be used to further parameterize valfunc. // considered, and arg can be used to further parameterize valfunc.
func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) { func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) {
var dbg int var dbg int
var i int var i int
var oldval int32 var oldval int32
@ -83,7 +82,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
// instruction. Keep going, so that we only emit a delta // instruction. Keep going, so that we only emit a delta
// for a true instruction boundary in the program. // for a true instruction boundary in the program.
if p.Link != nil && p.Link.Pc == p.Pc { if p.Link != nil && p.Link.Pc == p.Pc {
val = valfunc(ctxt, func_, val, p, 1, arg) val = valfunc(ctxt, func_, val, p, 1, arg)
if ctxt.Debugpcln != 0 { if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "%6x %6s %v\n", uint64(int64(p.Pc)), "", p) fmt.Fprintf(ctxt.Bso, "%6x %6s %v\n", uint64(int64(p.Pc)), "", p)
@ -106,7 +104,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
// where the 0x80 bit indicates that the integer continues. // where the 0x80 bit indicates that the integer continues.
if ctxt.Debugpcln != 0 { if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "%6x %6d %v\n", uint64(int64(p.Pc)), val, p) fmt.Fprintf(ctxt.Bso, "%6x %6d %v\n", uint64(int64(p.Pc)), val, p)
} }
@ -119,7 +116,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
if delta>>31 != 0 { if delta>>31 != 0 {
delta = 1 | ^(delta << 1) delta = 1 | ^(delta << 1)
} else { } else {
delta <<= 1 delta <<= 1
} }
addvarint(ctxt, dst, delta) addvarint(ctxt, dst, delta)
@ -152,13 +148,12 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
// Because p->lineno applies to p, phase == 0 (before p) // Because p->lineno applies to p, phase == 0 (before p)
// takes care of the update. // takes care of the update.
func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
var i int32 var i int32
var l int32 var l int32
var f *LSym var f *LSym
var pcln *Pcln var pcln *Pcln
if int(p.As) == ctxt.Arch.ATEXT || int(p.As) == ctxt.Arch.ANOP || int(p.As) == ctxt.Arch.AUSEFIELD || p.Lineno == 0 || phase == 1 { if p.As == ATEXT || p.As == ANOP || p.As == AUSEFIELD || p.Lineno == 0 || phase == 1 {
return oldval return oldval
} }
linkgetline(ctxt, p.Lineno, &f, &l) linkgetline(ctxt, p.Lineno, &f, &l)
@ -195,7 +190,6 @@ func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg
// The adjustment by p takes effect only after p, so we // The adjustment by p takes effect only after p, so we
// apply the change during phase == 1. // apply the change during phase == 1.
func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
if oldval == -1 { // starting if oldval == -1 { // starting
oldval = 0 oldval = 0
} }
@ -216,8 +210,7 @@ func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg in
// Since PCDATA instructions have no width in the final code, // Since PCDATA instructions have no width in the final code,
// it does not matter which phase we use for the update. // it does not matter which phase we use for the update.
func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
if phase == 0 || p.As != APCDATA || p.From.Offset != int64(arg.(uint32)) {
if phase == 0 || int(p.As) != ctxt.Arch.APCDATA || p.From.Offset != int64(arg.(uint32)) {
return oldval return oldval
} }
if int64(int32(p.To.Offset)) != p.To.Offset { if int64(int32(p.To.Offset)) != p.To.Offset {
@ -243,10 +236,10 @@ func linkpcln(ctxt *Link, cursym *LSym) {
npcdata = 0 npcdata = 0
nfuncdata = 0 nfuncdata = 0
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
if int(p.As) == ctxt.Arch.APCDATA && p.From.Offset >= int64(npcdata) { if p.As == APCDATA && p.From.Offset >= int64(npcdata) {
npcdata = int(p.From.Offset + 1) npcdata = int(p.From.Offset + 1)
} }
if int(p.As) == ctxt.Arch.AFUNCDATA && p.From.Offset >= int64(nfuncdata) { if p.As == AFUNCDATA && p.From.Offset >= int64(nfuncdata) {
nfuncdata = int(p.From.Offset + 1) nfuncdata = int(p.From.Offset + 1)
} }
} }
@ -265,21 +258,20 @@ func linkpcln(ctxt *Link, cursym *LSym) {
havepc := make([]uint32, (npcdata+31)/32) havepc := make([]uint32, (npcdata+31)/32)
havefunc := make([]uint32, (nfuncdata+31)/32) havefunc := make([]uint32, (nfuncdata+31)/32)
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
if int(p.As) == ctxt.Arch.AFUNCDATA { if p.As == AFUNCDATA {
if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 { if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 {
ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset) ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset)
} }
havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32) havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
} }
if int(p.As) == ctxt.Arch.APCDATA { if p.As == APCDATA {
havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32) havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
} }
} }
// pcdata. // pcdata.
for i = 0; i < npcdata; i++ { for i = 0; i < npcdata; i++ {
if (havepc[i/32]>>uint(i%32))&1 == 0 { if (havepc[i/32]>>uint(i%32))&1 == 0 {
continue continue
} }
@ -288,12 +280,11 @@ func linkpcln(ctxt *Link, cursym *LSym) {
// funcdata // funcdata
if nfuncdata > 0 { if nfuncdata > 0 {
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
if int(p.As) == ctxt.Arch.AFUNCDATA { if p.As == AFUNCDATA {
i = int(p.From.Offset) i = int(p.From.Offset)
pcln.Funcdataoff[i] = p.To.Offset pcln.Funcdataoff[i] = p.To.Offset
if int(p.To.Type) != ctxt.Arch.D_CONST { if p.To.Type != TYPE_CONST {
// TODO: Dedup. // TODO: Dedup.
//funcdata_bytes += p->to.sym->size; //funcdata_bytes += p->to.sym->size;
pcln.Funcdata[i] = p.To.Sym pcln.Funcdata[i] = p.To.Sym
@ -306,7 +297,6 @@ func linkpcln(ctxt *Link, cursym *LSym) {
// iteration over encoded pcdata tables. // iteration over encoded pcdata tables.
func getvarint(pp *[]byte) uint32 { func getvarint(pp *[]byte) uint32 {
var p []byte var p []byte
var shift int var shift int
var v uint32 var v uint32

View File

@ -29,6 +29,8 @@
package ppc64 package ppc64
import "cmd/internal/obj"
// auto generated by go tool dist // auto generated by go tool dist
/* /*
@ -41,30 +43,112 @@ const (
NFREG = 32 NFREG = 32
) )
// avoid conflict with ucontext.h. sigh.
const ( const (
REGZERO = 0 REG_R0 = 32 + iota
REGSP = 1 REG_R1
REGSB = 2 REG_R2
REGRET = 3 REG_R3
REG_R4
REG_R5
REG_R6
REG_R7
REG_R8
REG_R9
REG_R10
REG_R11
REG_R12
REG_R13
REG_R14
REG_R15
REG_R16
REG_R17
REG_R18
REG_R19
REG_R20
REG_R21
REG_R22
REG_R23
REG_R24
REG_R25
REG_R26
REG_R27
REG_R28
REG_R29
REG_R30
REG_R31
REG_F0 = 64 + iota - 32
REG_F1
REG_F2
REG_F3
REG_F4
REG_F5
REG_F6
REG_F7
REG_F8
REG_F9
REG_F10
REG_F11
REG_F12
REG_F13
REG_F14
REG_F15
REG_F16
REG_F17
REG_F18
REG_F19
REG_F20
REG_F21
REG_F22
REG_F23
REG_F24
REG_F25
REG_F26
REG_F27
REG_F28
REG_F29
REG_F30
REG_F31
REG_SPECIAL = 96
REG_C0 = 96 + iota - 65
REG_C1
REG_C2
REG_C3
REG_C4
REG_C5
REG_C6
REG_C7
REG_MSR = 104 + iota - 73
REG_FPSCR
REG_CR
REG_SPR0 = 1024
REG_DCR0 = 2048
REG_XER = REG_SPR0 + 1
REG_LR = REG_SPR0 + 8
REG_CTR = REG_SPR0 + 9
REGZERO = REG_R0
REGSP = REG_R1
REGSB = REG_R2
REGRET = REG_R3
REGARG = -1 REGARG = -1
REGRT1 = 3 REGRT1 = REG_R3
REGRT2 = 4 REGRT2 = REG_R4
REGMIN = 7 REGMIN = REG_R7
REGENV = 11 REGENV = REG_R11
REGTLS = 13 REGTLS = REG_R13
REGMAX = 27 REGMAX = REG_R27
REGEXT = 30 REGEXT = REG_R30
REGG = 30 REGG = REG_R30
REGTMP = 31 REGTMP = REG_R31
FREGRET = 0 FREGRET = REG_F0
FREGMIN = 17 FREGMIN = REG_F17
FREGMAX = 26 FREGMAX = REG_F26
FREGEXT = 26 FREGEXT = REG_F26
FREGCVI = 27 FREGCVI = REG_F27
FREGZERO = 28 FREGZERO = REG_F28
FREGHALF = 29 FREGHALF = REG_F29
FREGONE = 30 FREGONE = REG_F30
FREGTWO = 31 FREGTWO = REG_F31
) )
/* /*
@ -129,12 +213,12 @@ const (
C_ANY C_ANY
C_GOK C_GOK
C_ADDR C_ADDR
C_TEXTSIZE
C_NCLASS C_NCLASS
) )
const ( const (
AXXX = iota AADD = obj.A_ARCHSPECIFIC + iota
AADD
AADDCC AADDCC
AADDV AADDV
AADDVCC AADDVCC
@ -163,11 +247,9 @@ const (
ABEQ ABEQ
ABGE ABGE
ABGT ABGT
ABL
ABLE ABLE
ABLT ABLT
ABNE ABNE
ABR
ABVC ABVC
ABVS ABVS
ACMP ACMP
@ -349,19 +431,7 @@ const (
ATLBSYNC ATLBSYNC
ATW ATW
ASYSCALL ASYSCALL
ADATA
AGLOBL
AGOK
AHISTORY
ANAME
ANOP
ARETURN
ATEXT
AWORD AWORD
AEND
ADYNT
AINIT
ASIGNAME
ARFCI ARFCI
AFRES AFRES
AFRESCC AFRESCC
@ -438,48 +508,8 @@ const (
AREMDUV AREMDUV
AREMDUVCC AREMDUVCC
AHRFID AHRFID
AUNDEF
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ALAST ALAST
) ABR = obj.AJMP
ABL = obj.ACALL
/* type/name */ ARETURN = obj.ARET
const (
D_GOK = 0 + iota
D_NONE
D_EXTERN
D_STATIC
D_AUTO
D_PARAM
D_BRANCH
D_OREG
D_CONST
D_FCONST
D_SCONST
D_REG
D_FPSCR
D_MSR
D_FREG
D_CREG
D_SPR
D_OPT
D_FILE
D_FILE1
D_DCR
D_DCONST
D_ADDR
D_LAST
D_R0 = 0
D_F0 = D_R0 + NREG
D_XER = 1
D_LR = 8
D_CTR = 9
) )

View File

@ -1,13 +1,29 @@
package ppc64 package ppc64
/* and many supervisor level registers */
/* /*
* this is the ranlib header * this is the ranlib header
*/ */
var Anames = []string{ var Anames = []string{
"XXX", "XXX ",
"ADD", "CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"ADD ",
"ADDCC", "ADDCC",
"ADDV", "ADDV",
"ADDVCC", "ADDVCC",
@ -36,11 +52,9 @@ var Anames = []string{
"BEQ", "BEQ",
"BGE", "BGE",
"BGT", "BGT",
"BL",
"BLE", "BLE",
"BLT", "BLT",
"BNE", "BNE",
"BR",
"BVC", "BVC",
"BVS", "BVS",
"CMP", "CMP",
@ -222,19 +236,7 @@ var Anames = []string{
"TLBSYNC", "TLBSYNC",
"TW", "TW",
"SYSCALL", "SYSCALL",
"DATA",
"GLOBL",
"GOK",
"HISTORY",
"NAME",
"NOP",
"RETURN",
"TEXT",
"WORD", "WORD",
"END",
"DYNT",
"INIT",
"SIGNAME",
"RFCI", "RFCI",
"FRES", "FRES",
"FRESCC", "FRESCC",
@ -311,16 +313,6 @@ var Anames = []string{
"REMDUV", "REMDUV",
"REMDUVCC", "REMDUVCC",
"HRFID", "HRFID",
"UNDEF",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"LAST", "LAST",
} }
@ -359,31 +351,6 @@ var cnames9 = []string{
"ANY", "ANY",
"GOK", "GOK",
"ADDR", "ADDR",
"TEXTSIZE",
"NCLASS", "NCLASS",
} }
var dnames9 = []string{
D_GOK: "GOK/R0",
D_NONE: "NONE/XER",
D_EXTERN: "EXTERN",
D_STATIC: "STATIC",
D_AUTO: "AUTO",
D_PARAM: "PARAM",
D_BRANCH: "BRANCH",
D_OREG: "OREG",
D_CONST: "CONST/LR",
D_FCONST: "FCONST/CTR",
D_SCONST: "SCONST",
D_REG: "REG",
D_FPSCR: "FPSCR",
D_MSR: "MSR",
D_FREG: "FREG",
D_CREG: "CREG",
D_SPR: "SPR",
D_OPT: "OPT",
D_FILE: "FILE",
D_FILE1: "FILE1",
D_DCR: "DCR",
D_DCONST: "DCONST",
D_ADDR: "ADDR",
}

View File

@ -58,14 +58,10 @@ type Optab struct {
} }
var optab = []Optab{ var optab = []Optab{
Optab{ATEXT, C_LEXT, C_NONE, C_NONE, C_LCON, 0, 0, 0}, Optab{obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
Optab{ATEXT, C_LEXT, C_REG, C_NONE, C_LCON, 0, 0, 0}, Optab{obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
Optab{ATEXT, C_LEXT, C_NONE, C_LCON, C_LCON, 0, 0, 0}, Optab{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
Optab{ATEXT, C_LEXT, C_REG, C_LCON, C_LCON, 0, 0, 0}, Optab{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
Optab{ATEXT, C_ADDR, C_NONE, C_NONE, C_LCON, 0, 0, 0},
Optab{ATEXT, C_ADDR, C_REG, C_NONE, C_LCON, 0, 0, 0},
Optab{ATEXT, C_ADDR, C_NONE, C_LCON, C_LCON, 0, 0, 0},
Optab{ATEXT, C_ADDR, C_REG, C_LCON, C_LCON, 0, 0, 0},
/* move register */ /* move register */
Optab{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0}, Optab{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
Optab{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0}, Optab{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
@ -389,15 +385,15 @@ var optab = []Optab{
Optab{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0}, Optab{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
Optab{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, Optab{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
Optab{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0}, Optab{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
Optab{AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0}, Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
Optab{AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0}, Optab{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0},
Optab{APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0}, Optab{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
Optab{AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0}, Optab{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
Optab{ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0}, Optab{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
Optab{ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL Optab{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
Optab{ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL Optab{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
Optab{AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0}, Optab{obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
} }
type Oprang struct { type Oprang struct {
@ -426,7 +422,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
return return
} }
ctxt.Cursym = cursym ctxt.Cursym = cursym
ctxt.Autosize = int32(p.To.Offset&0xffffffff) + 8 ctxt.Autosize = int32(p.To.Offset + 8)
if oprange[AANDN].start == nil { if oprange[AANDN].start == nil {
buildop(ctxt) buildop(ctxt)
@ -441,7 +437,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
o = oplook(ctxt, p) o = oplook(ctxt, p)
m = int(o.size) m = int(o.size)
if m == 0 { if m == 0 {
if p.As != ANOP && p.As != AFUNCDATA && p.As != APCDATA { if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p) ctxt.Diag("zero-width instruction\n%v", p)
} }
continue continue
@ -472,21 +468,20 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
// very large conditional branches // very large conditional branches
if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil { if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
otxt = p.Pcond.Pc - c otxt = p.Pcond.Pc - c
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 { if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
q = ctxt.NewProg() q = new(obj.Prog)
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
q.As = ABR q.As = ABR
q.To.Type = D_BRANCH q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Pcond q.Pcond = p.Pcond
p.Pcond = q p.Pcond = q
q = ctxt.NewProg() q = new(obj.Prog)
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
q.As = ABR q.As = ABR
q.To.Type = D_BRANCH q.To.Type = obj.TYPE_BRANCH
q.Pcond = q.Link.Link q.Pcond = q.Link.Link
//addnop(p->link); //addnop(p->link);
@ -497,7 +492,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
m = int(o.size) m = int(o.size)
if m == 0 { if m == 0 {
if p.As != ANOP && p.As != AFUNCDATA && p.As != APCDATA { if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p) ctxt.Diag("zero-width instruction\n%v", p)
} }
continue continue
@ -516,7 +511,6 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
* lay out the code, emitting code and data relocations. * lay out the code, emitting code and data relocations.
*/ */
if ctxt.Tlsg == nil { if ctxt.Tlsg == nil {
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0) ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
} }
@ -550,43 +544,49 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
var s *obj.LSym var s *obj.LSym
switch a.Type { switch a.Type {
case D_NONE: case obj.TYPE_NONE:
return C_NONE return C_NONE
case D_REG: case obj.TYPE_REG:
return C_REG if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
return C_REG
case D_FREG:
return C_FREG
case D_CREG:
return C_CREG
case D_SPR:
if a.Offset == D_LR {
return C_LR
} }
if a.Offset == D_XER { if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
return C_XER return C_FREG
} }
if a.Offset == D_CTR { if REG_C0 <= a.Reg && a.Reg <= REG_C7 || a.Reg == REG_CR {
return C_CTR return C_CREG
} }
return C_SPR if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
switch a.Reg {
case REG_LR:
return C_LR
case D_DCR: case REG_XER:
return C_SPR return C_XER
case D_FPSCR: case REG_CTR:
return C_FPSCR return C_CTR
}
case D_MSR: return C_SPR
return C_MSR }
case D_OREG: if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
return C_SPR
}
if a.Reg == REG_FPSCR {
return C_FPSCR
}
if a.Reg == REG_MSR {
return C_MSR
}
return C_GOK
case obj.TYPE_MEM:
switch a.Name { switch a.Name {
case D_EXTERN, case obj.NAME_EXTERN,
D_STATIC: obj.NAME_STATIC:
if a.Sym == nil { if a.Sym == nil {
break break
} }
@ -596,21 +596,21 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
} }
return C_LEXT return C_LEXT
case D_AUTO: case obj.NAME_AUTO:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SAUTO return C_SAUTO
} }
return C_LAUTO return C_LAUTO
case D_PARAM: case obj.NAME_PARAM:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SAUTO return C_SAUTO
} }
return C_LAUTO return C_LAUTO
case D_NONE: case obj.TYPE_NONE:
ctxt.Instoffset = a.Offset ctxt.Instoffset = a.Offset
if ctxt.Instoffset == 0 { if ctxt.Instoffset == 0 {
return C_ZOREG return C_ZOREG
@ -623,18 +623,15 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
return C_GOK return C_GOK
case D_OPT: case obj.TYPE_TEXTSIZE:
ctxt.Instoffset = a.Offset & 31 return C_TEXTSIZE
if a.Name == D_NONE {
return C_SCON
}
return C_GOK
case D_CONST: case obj.TYPE_CONST,
obj.TYPE_ADDR:
switch a.Name { switch a.Name {
case D_NONE: case obj.TYPE_NONE:
ctxt.Instoffset = a.Offset ctxt.Instoffset = a.Offset
if a.Reg != NREG { if a.Reg != 0 {
if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG { if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG {
return C_SACON return C_SACON
} }
@ -646,8 +643,8 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
goto consize goto consize
case D_EXTERN, case obj.NAME_EXTERN,
D_STATIC: obj.NAME_STATIC:
s = a.Sym s = a.Sym
if s == nil { if s == nil {
break break
@ -662,14 +659,14 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
/* not sure why this barfs */ /* not sure why this barfs */
return C_LCON return C_LCON
case D_AUTO: case obj.NAME_AUTO:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SACON return C_SACON
} }
return C_LACON return C_LACON
case D_PARAM: case obj.NAME_PARAM:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SACON return C_SACON
@ -710,7 +707,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
} }
return C_DCON return C_DCON
case D_BRANCH: case obj.TYPE_BRANCH:
return C_SBRA return C_SBRA
} }
@ -759,7 +756,7 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
a4-- a4--
a2 = C_NONE a2 = C_NONE
if p.Reg != NREG { if p.Reg != 0 {
a2 = C_REG a2 = C_REG
} }
@ -924,8 +921,7 @@ func buildop(ctxt *obj.Link) {
} }
} }
} }
for n = 0; optab[n].as != AXXX; n++ { for n = 0; optab[n].as != obj.AXXX; n++ {
} }
sort.Sort(ocmp(optab[:n])) sort.Sort(ocmp(optab[:n]))
for i = 0; i < n; i++ { for i = 0; i < n; i++ {
@ -1295,14 +1291,14 @@ func buildop(ctxt *obj.Link) {
ASLBMTE, ASLBMTE,
AWORD, AWORD,
ADWORD, ADWORD,
ANOP, obj.ANOP,
ATEXT, obj.ATEXT,
AUNDEF, obj.AUNDEF,
AUSEFIELD, obj.AUSEFIELD,
AFUNCDATA, obj.AFUNCDATA,
APCDATA, obj.APCDATA,
ADUFFZERO, obj.ADUFFZERO,
ADUFFCOPY: obj.ADUFFCOPY:
break break
} }
} }
@ -1322,7 +1318,6 @@ func OP(o uint32, xo uint32) uint32 {
/* the order is dest, a/s, b/imm for both arithmetic and logical operations */ /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 { func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
} }
@ -1397,7 +1392,6 @@ func oclass(a *obj.Addr) int {
// add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2. // add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2.
func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) { func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
var rel *obj.Reloc var rel *obj.Reloc
rel = obj.Addrel(ctxt.Cursym) rel = obj.Addrel(ctxt.Cursym)
@ -1412,7 +1406,6 @@ func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
* 32-bit masks * 32-bit masks
*/ */
func getmask(m []byte, v uint32) int { func getmask(m []byte, v uint32) int {
var i int var i int
m[1] = 0 m[1] = 0
@ -1461,7 +1454,6 @@ func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) {
* 64-bit masks (rldic etc) * 64-bit masks (rldic etc)
*/ */
func getmask64(m []byte, v uint64) int { func getmask64(m []byte, v uint64) int {
var i int var i int
m[1] = 0 m[1] = 0
@ -1534,7 +1526,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
//print("%P => case %d\n", p, o->type); //print("%P => case %d\n", p, o->type);
switch o.type_ { switch o.type_ {
default: default:
ctxt.Diag("unknown type %d", o.type_) ctxt.Diag("unknown type %d", o.type_)
prasm(p) prasm(p)
@ -1543,8 +1534,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
break break
case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */ case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
if p.To.Reg == REGZERO && p.From.Type == D_CONST { if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 { if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
//nerrors--; //nerrors--;
@ -1560,7 +1550,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 2: /* int/cr/fp op Rb,[Ra],Rd */ case 2: /* int/cr/fp op Rb,[Ra],Rd */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
@ -1570,7 +1560,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = int32(d) v = int32(d)
r = int(p.From.Reg) r = int(p.From.Reg)
if r == NREG { if r == 0 {
r = int(o.param) r = int(o.param)
} }
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) { if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
@ -1589,7 +1579,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
a = OP_ADDIS a = OP_ADDIS
} else { } else {
if int64(int16(d)) != d { if int64(int16(d)) != d {
log.Fatalf("invalid handling of %v", p) log.Fatalf("invalid handling of %v", p)
} }
@ -1601,7 +1590,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 { if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
@ -1618,7 +1607,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 6: /* logical op Rb,[Rs,]Ra; no literal */ case 6: /* logical op Rb,[Rs,]Ra; no literal */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
@ -1626,17 +1615,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 7: /* mov r, soreg ==> stw o(r) */ case 7: /* mov r, soreg ==> stw o(r) */
r = int(p.To.Reg) r = int(p.To.Reg)
if r == NREG { if r == 0 {
r = int(o.param) r = int(o.param)
} }
v = regoff(ctxt, &p.To) v = regoff(ctxt, &p.To)
if p.To.Type == D_OREG && p.Reg != NREG { if p.To.Type == obj.TYPE_MEM && p.Reg != 0 {
if v != 0 { if v != 0 {
ctxt.Diag("illegal indexed instruction\n%v", p) ctxt.Diag("illegal indexed instruction\n%v", p)
} }
o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.Reg), uint32(r)) o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.Reg), uint32(r))
} else { } else {
if int32(int16(v)) != v { if int32(int16(v)) != v {
log.Fatalf("mishandled instruction %v", p) log.Fatalf("mishandled instruction %v", p)
} }
@ -1646,17 +1634,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */ case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
r = int(p.From.Reg) r = int(p.From.Reg)
if r == NREG { if r == 0 {
r = int(o.param) r = int(o.param)
} }
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
if p.From.Type == D_OREG && p.Reg != NREG { if p.From.Type == obj.TYPE_MEM && p.Reg != 0 {
if v != 0 { if v != 0 {
ctxt.Diag("illegal indexed instruction\n%v", p) ctxt.Diag("illegal indexed instruction\n%v", p)
} }
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r)) o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r))
} else { } else {
if int32(int16(v)) != v { if int32(int16(v)) != v {
log.Fatalf("mishandled instruction %v", p) log.Fatalf("mishandled instruction %v", p)
} }
@ -1666,17 +1653,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */ case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
r = int(p.From.Reg) r = int(p.From.Reg)
if r == NREG { if r == 0 {
r = int(o.param) r = int(o.param)
} }
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
if p.From.Type == D_OREG && p.Reg != NREG { if p.From.Type == obj.TYPE_MEM && p.Reg != 0 {
if v != 0 { if v != 0 {
ctxt.Diag("illegal indexed instruction\n%v", p) ctxt.Diag("illegal indexed instruction\n%v", p)
} }
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r)) o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r))
} else { } else {
o1 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v)) o1 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
} }
o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
@ -1684,7 +1670,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */ case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r)) o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
@ -1721,8 +1707,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
} }
case 12: /* movb r,r (extsb); movw r,r (extsw) */ case 12: /* movb r,r (extsb); movw r,r (extsw) */
if p.To.Reg == REGZERO && p.From.Type == D_CONST { if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 { if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
ctxt.Diag("literal operation on R0\n%v", p) ctxt.Diag("literal operation on R0\n%v", p)
@ -1735,13 +1720,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
if p.As == AMOVW { if p.As == AMOVW {
o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0) o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
} else { } else {
o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0) o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
} }
case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */ case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
if p.As == AMOVBZ { if p.As == AMOVBZ {
o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31) o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
} else if p.As == AMOVH { } else if p.As == AMOVH {
o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0) o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
@ -1750,14 +1733,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
} else if p.As == AMOVWZ { } else if p.As == AMOVWZ {
o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */ o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
} else { } else {
ctxt.Diag("internal: bad mov[bhw]z\n%v", p) ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
} }
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */ case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
d = vregoff(ctxt, &p.From3) d = vregoff(ctxt, &p.From3)
@ -1792,11 +1774,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
16: /* bc bo,bi,sbra */ 16: /* bc bo,bi,sbra */
a = 0 a = 0
if p.From.Type == D_CONST { if p.From.Type == obj.TYPE_CONST {
a = int(regoff(ctxt, &p.From)) a = int(regoff(ctxt, &p.From))
} }
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = 0 r = 0
} }
v = 0 v = 0
@ -1815,17 +1797,15 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */ case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
if p.As == ABC || p.As == ABCL { if p.As == ABC || p.As == ABCL {
v = regoff(ctxt, &p.To) & 31 v = regoff(ctxt, &p.To) & 31
} else { } else {
v = 20 /* unconditional */ v = 20 /* unconditional */
} }
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = 0 r = 0
} }
o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (D_LR&0x1f)<<16 | ((D_LR>>5)&0x1f)<<11 o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
o2 = OPVCC(19, 16, 0, 0) o2 = OPVCC(19, 16, 0, 0)
if p.As == ABL || p.As == ABCL { if p.As == ABL || p.As == ABCL {
o2 |= 1 o2 |= 1
@ -1834,14 +1814,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */ case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
if p.As == ABC || p.As == ABCL { if p.As == ABC || p.As == ABCL {
v = regoff(ctxt, &p.From) & 31 v = regoff(ctxt, &p.From) & 31
} else { } else {
v = 20 /* unconditional */ v = 20 /* unconditional */
} }
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = 0 r = 0
} }
switch oclass(&p.To) { switch oclass(&p.To) {
@ -1868,7 +1846,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = loadu32(int(p.To.Reg), d) o1 = loadu32(int(p.To.Reg), d)
o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d))) o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
} else { } else {
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(int32(d)))) o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(int32(d))))
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(d)) o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(d))
addaddrreloc(ctxt, p.From.Sym, &o1, &o2) addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
@ -1880,24 +1857,23 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
if p.As == AADD && (!(r0iszero != 0 /*TypeKind(100016)*/) && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) { if p.As == AADD && (!(r0iszero != 0 /*TypeKind(100016)*/) && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
ctxt.Diag("literal operation on R0\n%v", p) ctxt.Diag("literal operation on R0\n%v", p)
} }
o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As)+AEND)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */ case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
if p.To.Reg == REGTMP || p.Reg == REGTMP { if p.To.Reg == REGTMP || p.Reg == REGTMP {
ctxt.Diag("cant synthesize large constant\n%v", p) ctxt.Diag("cant synthesize large constant\n%v", p)
} }
d = vregoff(ctxt, &p.From) d = vregoff(ctxt, &p.From)
o1 = loadu32(REGTMP, d) o1 = loadu32(REGTMP, d)
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d))) o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r)) o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r))
@ -1909,14 +1885,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */ case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
if p.To.Reg == REGTMP || p.Reg == REGTMP { if p.To.Reg == REGTMP || p.Reg == REGTMP {
ctxt.Diag("cant synthesize large constant\n%v", p) ctxt.Diag("cant synthesize large constant\n%v", p)
} }
d = vregoff(ctxt, &p.From) d = vregoff(ctxt, &p.From)
o1 = loadu32(REGTMP, d) o1 = loadu32(REGTMP, d)
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d))) o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o3 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r)) o3 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r))
@ -1937,7 +1912,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = 63 v = 63
} }
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
switch p.As { switch p.As {
@ -1972,12 +1947,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */ case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
if p.To.Reg == REGTMP { if p.To.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.From) v = regoff(ctxt, &p.From)
r = int(p.From.Reg) r = int(p.From.Reg)
if r == NREG { if r == 0 {
r = int(o.param) r = int(o.param)
} }
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
@ -1991,7 +1965,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */ case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
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)
@ -2069,7 +2042,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = uint32(d >> 32) o1 = uint32(d >> 32)
o2 = uint32(d) o2 = uint32(d)
} else { } else {
o1 = uint32(d) o1 = uint32(d)
o2 = uint32(d >> 32) o2 = uint32(d >> 32)
} }
@ -2088,7 +2060,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 32: /* fmul frc,fra,frd */ case 32: /* fmul frc,fra,frd */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6 o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
@ -2108,7 +2080,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.To) v = regoff(ctxt, &p.To)
r = int(p.To.Reg) r = int(p.To.Reg)
if r == NREG { if r == 0 {
r = int(o.param) r = int(o.param)
} }
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
@ -2118,7 +2090,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
r = int(p.From.Reg) r = int(p.From.Reg)
if r == NREG { if r == 0 {
r = int(o.param) r = int(o.param)
} }
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
@ -2128,7 +2100,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
r = int(p.From.Reg) r = int(p.From.Reg)
if r == NREG { if r == 0 {
r = int(o.param) r = int(o.param)
} }
o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
@ -2147,7 +2119,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */ case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = 0 r = 0
} }
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(r), uint32(p.From.Reg)) o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(r), uint32(p.From.Reg))
@ -2155,7 +2127,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 44: /* indexed store */ case 44: /* indexed store */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = 0 r = 0
} }
o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg)) o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
@ -2163,7 +2135,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 45: /* indexed load */ case 45: /* indexed load */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = 0 r = 0
} }
o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
@ -2174,7 +2146,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 47: /* op Ra, Rd; also op [Ra,] Rd */ case 47: /* op Ra, Rd; also op [Ra,] Rd */
r = int(p.From.Reg) r = int(p.From.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
@ -2182,24 +2154,23 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 48: /* op Rs, Ra */ case 48: /* op Rs, Ra */
r = int(p.From.Reg) r = int(p.From.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
case 49: /* op Rb; op $n, Rb */ case 49: /* op Rb; op $n, Rb */
if p.From.Type != D_REG { /* tlbie $L, rB */ if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
v = regoff(ctxt, &p.From) & 1 v = regoff(ctxt, &p.From) & 1
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21 o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
} else { } else {
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg)) o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg))
} }
case 50: /* rem[u] r1[,r2],r3 */ case 50: /* rem[u] r1[,r2],r3 */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
v = oprrr(ctxt, int(p.As)) v = oprrr(ctxt, int(p.As))
@ -2217,7 +2188,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 51: /* remd[u] r1[,r2],r3 */ case 51: /* remd[u] r1[,r2],r3 */
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
v = oprrr(ctxt, int(p.As)) v = oprrr(ctxt, int(p.As))
@ -2236,15 +2207,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 54: /* mov msr,r1; mov r1, msr*/ case 54: /* mov msr,r1; mov r1, msr*/
if oclass(&p.From) == C_REG { if oclass(&p.From) == C_REG {
if p.As == AMOVD { if p.As == AMOVD {
o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0) o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
} else { } else {
o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0) o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
} }
} else { } else {
o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0) o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
} }
@ -2255,7 +2223,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.To.Reg), uint32(v)&31) o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.To.Reg), uint32(v)&31)
@ -2267,7 +2235,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
@ -2279,7 +2247,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
ctxt->diag("illegal shift %ld\n%P", v, p); ctxt->diag("illegal shift %ld\n%P", v, p);
*/ */
if v < 0 { if v < 0 {
v = 0 v = 0
} else if v > 32 { } else if v > 32 {
v = 32 v = 32
@ -2289,7 +2256,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
mask[1] = 31 mask[1] = 31
v = 32 - v v = 32 - v
} else { } else {
mask[0] = 0 mask[0] = 0
mask[1] = uint8(31 - v) mask[1] = uint8(31 - v)
} }
@ -2303,7 +2269,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v)) o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
@ -2312,10 +2278,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.From) v = regoff(ctxt, &p.From)
r = int(p.Reg) r = int(p.Reg)
if r == NREG { if r == 0 {
r = int(p.To.Reg) r = int(p.To.Reg)
} }
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+AEND)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */ o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */
case 60: /* tw to,a,b */ case 60: /* tw to,a,b */
r = int(regoff(ctxt, &p.From) & 31) r = int(regoff(ctxt, &p.From) & 31)
@ -2342,41 +2308,34 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
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} */
if p.From3.Type != D_NONE { if p.From3.Type != obj.TYPE_NONE {
v = regoff(ctxt, &p.From3) & 255 v = regoff(ctxt, &p.From3) & 255
} else { } else {
v = 255 v = 255
} }
o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */ case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
if p.To.Reg == NREG { if p.To.Reg == 0 {
ctxt.Diag("must specify FPSCR(n)\n%v", p) ctxt.Diag("must specify FPSCR(n)\n%v", p)
} }
o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12
case 66: /* mov spr,r1; mov r1,spr, also dcr */ case 66: /* mov spr,r1; mov r1,spr, also dcr */
if p.From.Type == D_REG { if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
r = int(p.From.Reg) r = int(p.From.Reg)
v = int32(p.To.Offset) v = int32(p.To.Reg)
if p.To.Type == D_DCR { if REG_DCR0 <= v && v <= REG_DCR0+1023 {
o1 = OPVCC(31, 451, 0, 0) /* mtdcr */ o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
} else { } else {
o1 = OPVCC(31, 467, 0, 0) /* mtspr */ o1 = OPVCC(31, 467, 0, 0) /* mtspr */
} }
} else { } else {
r = int(p.To.Reg) r = int(p.To.Reg)
v = int32(p.From.Offset) v = int32(p.From.Reg)
if p.From.Type == D_DCR { if REG_DCR0 <= v && v <= REG_DCR0+1023 {
o1 = OPVCC(31, 323, 0, 0) /* mfdcr */ o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
} else { } else {
o1 = OPVCC(31, 339, 0, 0) /* mfspr */ o1 = OPVCC(31, 339, 0, 0) /* mfspr */
} }
} }
@ -2384,35 +2343,29 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
case 67: /* mcrf crfD,crfS */ case 67: /* mcrf crfD,crfS */
if p.From.Type != D_CREG || p.From.Reg == NREG || p.To.Type != D_CREG || p.To.Reg == NREG { if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_C0 || REG_C7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_C0 || REG_C7 < p.To.Reg {
ctxt.Diag("illegal CR field number\n%v", p) ctxt.Diag("illegal CR field number\n%v", p)
} }
o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0) o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
case 68: /* mfcr rD; mfocrf CRM,rD */ case 68: /* mfcr rD; mfocrf CRM,rD */
if p.From.Type == D_CREG && p.From.Reg != NREG { if p.From.Type == obj.TYPE_REG && REG_C0 <= p.From.Reg && p.From.Reg <= REG_C7 {
v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */ v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */ o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
} else { } else {
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */ o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
} }
case 69: /* mtcrf CRM,rS */ case 69: /* mtcrf CRM,rS */
if p.From3.Type != D_NONE { if p.From3.Type != obj.TYPE_NONE {
if p.To.Reg != 0 {
if p.To.Reg != NREG {
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 == NREG {
v = 0xff /* CR */ v = 0xff /* CR */
} else { } else {
v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */ v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
} }
} }
@ -2420,21 +2373,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
case 70: /* [f]cmp r,r,cr*/ case 70: /* [f]cmp r,r,cr*/
if p.Reg == NREG { if p.Reg == 0 {
r = 0 r = 0
} else { } else {
r = (int(p.Reg) & 7) << 2 r = (int(p.Reg) & 7) << 2
} }
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg)) o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
case 71: /* cmp[l] r,i,cr*/ case 71: /* cmp[l] r,i,cr*/
if p.Reg == NREG { if p.Reg == 0 {
r = 0 r = 0
} else { } else {
r = (int(p.Reg) & 7) << 2 r = (int(p.Reg) & 7) << 2
} }
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff
@ -2443,23 +2392,20 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.From.Reg), 0, uint32(p.To.Reg)) o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.From.Reg), 0, uint32(p.To.Reg))
case 73: /* mcrfs crfD,crfS */ case 73: /* mcrfs crfD,crfS */
if p.From.Type != D_FPSCR || p.From.Reg == NREG || p.To.Type != D_CREG || p.To.Reg == NREG { if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_C0 || REG_C7 < p.To.Reg {
ctxt.Diag("illegal FPSCR/CR field number\n%v", p) ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
} }
o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0) o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
case 77: /* syscall $scon, syscall Rx */ case 77: /* syscall $scon, syscall Rx */
if p.From.Type == D_CONST { if p.From.Type == obj.TYPE_CONST {
if p.From.Offset > BIG || p.From.Offset < -BIG { if p.From.Offset > BIG || p.From.Offset < -BIG {
ctxt.Diag("illegal syscall, sysnum too large: %v", p) ctxt.Diag("illegal syscall, sysnum too large: %v", p)
} }
o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset)) o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
} else if p.From.Type == D_REG { } else if p.From.Type == obj.TYPE_REG {
o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg)) o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
} else { } else {
ctxt.Diag("illegal syscall: %v", p) ctxt.Diag("illegal syscall: %v", p)
o1 = 0x7fe00008 // trap always o1 = 0x7fe00008 // trap always
} }
@ -3046,21 +2992,21 @@ func opirr(ctxt *obj.Link, a int) int32 {
return int32(OPVCC(12, 0, 0, 0)) return int32(OPVCC(12, 0, 0, 0))
case AADDCCC: case AADDCCC:
return int32(OPVCC(13, 0, 0, 0)) return int32(OPVCC(13, 0, 0, 0))
case AADD + AEND: case AADD + ALAST:
return int32(OPVCC(15, 0, 0, 0)) /* ADDIS/CAU */ return int32(OPVCC(15, 0, 0, 0)) /* ADDIS/CAU */
case AANDCC: case AANDCC:
return int32(OPVCC(28, 0, 0, 0)) return int32(OPVCC(28, 0, 0, 0))
case AANDCC + AEND: case AANDCC + ALAST:
return int32(OPVCC(29, 0, 0, 0)) /* ANDIS./ANDIU. */ return int32(OPVCC(29, 0, 0, 0)) /* ANDIS./ANDIU. */
case ABR: case ABR:
return int32(OPVCC(18, 0, 0, 0)) return int32(OPVCC(18, 0, 0, 0))
case ABL: case ABL:
return int32(OPVCC(18, 0, 0, 0) | 1) return int32(OPVCC(18, 0, 0, 0) | 1)
case ADUFFZERO: case obj.ADUFFZERO:
return int32(OPVCC(18, 0, 0, 0) | 1) return int32(OPVCC(18, 0, 0, 0) | 1)
case ADUFFCOPY: case obj.ADUFFCOPY:
return int32(OPVCC(18, 0, 0, 0) | 1) return int32(OPVCC(18, 0, 0, 0) | 1)
case ABC: case ABC:
return int32(OPVCC(16, 0, 0, 0)) return int32(OPVCC(16, 0, 0, 0))
@ -3100,7 +3046,7 @@ func opirr(ctxt *obj.Link, a int) int32 {
case AOR: case AOR:
return int32(OPVCC(24, 0, 0, 0)) return int32(OPVCC(24, 0, 0, 0))
case AOR + AEND: case AOR + ALAST:
return int32(OPVCC(25, 0, 0, 0)) /* ORIS/ORIU */ return int32(OPVCC(25, 0, 0, 0)) /* ORIS/ORIU */
case ARLWMI: case ARLWMI:
@ -3152,7 +3098,7 @@ func opirr(ctxt *obj.Link, a int) int32 {
case AXOR: case AXOR:
return int32(OPVCC(26, 0, 0, 0)) /* XORIL */ return int32(OPVCC(26, 0, 0, 0)) /* XORIL */
case AXOR + AEND: case AXOR + ALAST:
return int32(OPVCC(27, 0, 0, 0)) /* XORIU */ return int32(OPVCC(27, 0, 0, 0)) /* XORIU */
} }
@ -3164,7 +3110,6 @@ func opirr(ctxt *obj.Link, a int) int32 {
* load o(a),d * load o(a),d
*/ */
func opload(ctxt *obj.Link, a int) int32 { func opload(ctxt *obj.Link, a int) int32 {
switch a { switch a {
case AMOVD: case AMOVD:
return int32(OPVCC(58, 0, 0, 0)) /* ld */ return int32(OPVCC(58, 0, 0, 0)) /* ld */
@ -3214,7 +3159,6 @@ func opload(ctxt *obj.Link, a int) int32 {
* indexed load a(b),d * indexed load a(b),d
*/ */
func oploadx(ctxt *obj.Link, a int) int32 { func oploadx(ctxt *obj.Link, a int) int32 {
switch a { switch a {
case AMOVWZ: case AMOVWZ:
return int32(OPVCC(31, 23, 0, 0)) /* lwzx */ return int32(OPVCC(31, 23, 0, 0)) /* lwzx */
@ -3274,7 +3218,6 @@ func oploadx(ctxt *obj.Link, a int) int32 {
* store s,o(d) * store s,o(d)
*/ */
func opstore(ctxt *obj.Link, a int) int32 { func opstore(ctxt *obj.Link, a int) int32 {
switch a { switch a {
case AMOVB, case AMOVB,
AMOVBZ: AMOVBZ:
@ -3325,7 +3268,6 @@ func opstore(ctxt *obj.Link, a int) int32 {
* indexed store s,a(b) * indexed store s,a(b)
*/ */
func opstorex(ctxt *obj.Link, a int) int32 { func opstorex(ctxt *obj.Link, a int) int32 {
switch a { switch a {
case AMOVB, case AMOVB,
AMOVBZ: AMOVBZ:

View File

@ -43,7 +43,6 @@ const (
// %A int Opcodes (instruction mnemonics) // %A int Opcodes (instruction mnemonics)
// //
// %D Addr* Addresses (instruction operands) // %D Addr* Addresses (instruction operands)
// Flags: "%lD": seperate the high and low words of a constant by "-"
// //
// %P Prog* Instructions // %P Prog* Instructions
// //
@ -59,49 +58,34 @@ func Pconv(p *obj.Prog) string {
var fp string var fp string
var a int var a int
var ch int
a = int(p.As) a = int(p.As)
if a == ADATA || a == AINIT || a == ADYNT { str = ""
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) if a == obj.ADATA {
} else if a == ATEXT { str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
if p.Reg != 0 { } else if a == obj.ATEXT || a == obj.AGLOBL {
str = fmt.Sprintf("%.5d (%v) %v %v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, fmtLong, &p.To)) if p.From3.Offset != 0 {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
} else { } else {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
str = fmt.Sprintf("%.5d (%v) %v %v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To))
}
} else if a == AGLOBL {
if p.Reg != 0 {
str = fmt.Sprintf("%.5d (%v) %v %v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To))
} else {
str = fmt.Sprintf("%.5d (%v) %v %v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
} }
} else { } else {
if p.Mark&NOSCHED != 0 { if p.Mark&NOSCHED != 0 {
str += fmt.Sprintf("*") str += fmt.Sprintf("*")
} }
if p.Reg == NREG && p.From3.Type == D_NONE { if p.Reg == 0 && p.From3.Type == obj.TYPE_NONE {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
} else if a != ATEXT && p.From.Type == D_OREG { } else if a != obj.ATEXT && p.From.Type == obj.TYPE_MEM {
str += fmt.Sprintf("%.5d (%v)\t%v\t%d(R%d+R%d),%v", p.Pc, p.Line(), Aconv(a), p.From.Offset, p.From.Reg, p.Reg, Dconv(p, 0, &p.To)) str += fmt.Sprintf("%.5d (%v)\t%v\t%d(%v+%v),%v", p.Pc, p.Line(), Aconv(a), p.From.Offset, Rconv(int(p.From.Reg)), Rconv(int(p.Reg)), Dconv(p, 0, &p.To))
} else if p.To.Type == D_OREG { } else if p.To.Type == obj.TYPE_MEM {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%d(R%d+R%d)", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.To.Offset, p.To.Reg, p.Reg) str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%d(%v+%v)", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.To.Offset, Rconv(int(p.To.Reg)), Rconv(int(p.Reg)))
} else { } else {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From)) str += fmt.Sprintf("%.5d (%v)\t%v\t%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From))
if p.Reg != NREG { if p.Reg != 0 {
ch = 'R' str += fmt.Sprintf(",%v", Rconv(int(p.Reg)))
if p.From.Type == D_FREG {
ch = 'F'
}
str += fmt.Sprintf(",%c%d", ch, p.Reg)
} }
if p.From3.Type != obj.TYPE_NONE {
if p.From3.Type != D_NONE {
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.From3)) str += fmt.Sprintf(",%v", Dconv(p, 0, &p.From3))
} }
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.To)) str += fmt.Sprintf(",%v", Dconv(p, 0, &p.To))
@ -122,7 +106,7 @@ func Aconv(a int) string {
var fp string var fp string
s = "???" s = "???"
if a >= AXXX && a < ALAST { if a >= obj.AXXX && a < ALAST {
s = Anames[a] s = Anames[a]
} }
fp += s fp += s
@ -135,126 +119,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
var v int32 var v int32
if flag&fmtLong != 0 /*untyped*/ {
if a.Type == D_CONST {
str = fmt.Sprintf("$%d-%d", int32(a.Offset), int32(a.Offset>>32))
} else {
// ATEXT dst is not constant
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
}
goto ret
}
switch a.Type { switch a.Type {
default: default:
str = fmt.Sprintf("GOK-type(%d)", a.Type) str = fmt.Sprintf("GOK-type(%d)", a.Type)
case D_NONE: case obj.TYPE_NONE:
str = "" str = ""
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil { if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg) str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
} }
case D_CONST, case obj.TYPE_CONST,
D_DCONST: obj.TYPE_ADDR:
if a.Reg != NREG { if a.Reg != 0 {
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg) str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else { } else {
str = fmt.Sprintf("$%v", Mconv(a)) str = fmt.Sprintf("$%v", Mconv(a))
} }
case D_OREG: case obj.TYPE_TEXTSIZE:
if a.Reg != NREG { if a.U.Argsize == obj.ArgsSizeUnknown {
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg) str = fmt.Sprintf("$%d", a.Offset)
} else { } else {
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
}
case obj.TYPE_MEM:
if a.Reg != 0 {
str = fmt.Sprintf("%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else {
str = fmt.Sprintf("%v", Mconv(a)) str = fmt.Sprintf("%v", Mconv(a))
} }
case D_REG: case obj.TYPE_REG:
str = fmt.Sprintf("R%d", a.Reg) str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
if a.Name != D_NONE || a.Sym != nil { if a.Name != obj.TYPE_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg) str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
} }
case D_FREG: case obj.TYPE_BRANCH:
str = fmt.Sprintf("F%d", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(F%d)(REG)", Mconv(a), a.Reg)
}
case D_CREG:
if a.Reg == NREG {
str = "CR"
} else {
str = fmt.Sprintf("CR%d", a.Reg)
}
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(C%d)(REG)", Mconv(a), a.Reg)
}
case D_SPR:
if a.Name == D_NONE && a.Sym == nil {
switch uint32(a.Offset) {
case D_XER:
str = fmt.Sprintf("XER")
case D_LR:
str = fmt.Sprintf("LR")
case D_CTR:
str = fmt.Sprintf("CTR")
default:
str = fmt.Sprintf("SPR(%d)", a.Offset)
break
}
break
}
str = fmt.Sprintf("SPR-GOK(%d)", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(SPR-GOK%d)(REG)", Mconv(a), a.Reg)
}
case D_DCR:
if a.Name == D_NONE && a.Sym == nil {
str = fmt.Sprintf("DCR(%d)", a.Offset)
break
}
str = fmt.Sprintf("DCR-GOK(%d)", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(DCR-GOK%d)(REG)", Mconv(a), a.Reg)
}
case D_OPT:
str = fmt.Sprintf("OPT(%d)", a.Reg)
case D_FPSCR:
if a.Reg == NREG {
str = "FPSCR"
} else {
str = fmt.Sprintf("FPSCR(%d)", a.Reg)
}
case D_MSR:
str = fmt.Sprintf("MSR")
case D_BRANCH:
if p.Pcond != nil { if p.Pcond != nil {
v = int32(p.Pcond.Pc) v = int32(p.Pcond.Pc)
//if(v >= INITTEXT) //if(v >= INITTEXT)
// v -= INITTEXT-HEADR; // v -= INITTEXT-HEADR;
if a.Sym != nil { if a.Sym != nil {
str = fmt.Sprintf("%s+%.5x(BRANCH)", a.Sym.Name, uint32(v)) str = fmt.Sprintf("%s+%.5x(BRANCH)", a.Sym.Name, uint32(v))
} else { } else {
str = fmt.Sprintf("%.5x(BRANCH)", uint32(v)) str = fmt.Sprintf("%.5x(BRANCH)", uint32(v))
} }
} else if a.U.Branch != nil { } else if a.U.Branch != nil {
@ -262,20 +173,18 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
} else if a.Sym != nil { } else if a.Sym != nil {
str = fmt.Sprintf("%s+%d(APC)", a.Sym.Name, a.Offset) str = fmt.Sprintf("%s+%d(APC)", a.Sym.Name, a.Offset)
} else { } else {
str = fmt.Sprintf("%d(APC)", a.Offset) str = fmt.Sprintf("%d(APC)", a.Offset)
} }
//sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l); //sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
case D_FCONST: case obj.TYPE_FCONST:
str = fmt.Sprintf("$%.17g", a.U.Dval) str = fmt.Sprintf("$%.17g", a.U.Dval)
case D_SCONST: case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval) str = fmt.Sprintf("$\"%q\"", a.U.Sval)
break break
} }
ret:
fp += str fp += str
return fp return fp
} }
@ -298,43 +207,38 @@ func Mconv(a *obj.Addr) string {
// goto out; // goto out;
//} //}
switch a.Name { switch a.Name {
default: default:
str = fmt.Sprintf("GOK-name(%d)", a.Name) str = fmt.Sprintf("GOK-name(%d)", a.Name)
case D_NONE: case obj.TYPE_NONE:
l = int32(a.Offset) l = int32(a.Offset)
if int64(l) != a.Offset { if int64(l) != a.Offset {
str = fmt.Sprintf("0x%x", uint64(a.Offset)) str = fmt.Sprintf("0x%x", uint64(a.Offset))
} else { } else {
str = fmt.Sprintf("%d", a.Offset) str = fmt.Sprintf("%d", a.Offset)
} }
case D_EXTERN: case obj.NAME_EXTERN:
if a.Offset != 0 { if a.Offset != 0 {
str = fmt.Sprintf("%s+%d(SB)", s.Name, a.Offset) str = fmt.Sprintf("%s+%d(SB)", s.Name, a.Offset)
} else { } else {
str = fmt.Sprintf("%s(SB)", s.Name) str = fmt.Sprintf("%s(SB)", s.Name)
} }
case D_STATIC: case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, a.Offset) str = fmt.Sprintf("%s<>+%d(SB)", s.Name, a.Offset)
case D_AUTO: case obj.NAME_AUTO:
if s == nil { if s == nil {
str = fmt.Sprintf("%d(SP)", -a.Offset) str = fmt.Sprintf("%d(SP)", -a.Offset)
} else { } else {
str = fmt.Sprintf("%s-%d(SP)", s.Name, -a.Offset) str = fmt.Sprintf("%s-%d(SP)", s.Name, -a.Offset)
} }
case D_PARAM: case obj.NAME_PARAM:
if s == nil { if s == nil {
str = fmt.Sprintf("%d(FP)", a.Offset) str = fmt.Sprintf("%d(FP)", a.Offset)
} else { } else {
str = fmt.Sprintf("%s+%d(FP)", s.Name, a.Offset) str = fmt.Sprintf("%s+%d(FP)", s.Name, a.Offset)
} }
break break
@ -346,16 +250,61 @@ func Mconv(a *obj.Addr) string {
} }
func Rconv(r int) string { func Rconv(r int) string {
var str string
var fp string var fp string
if r < NREG { if r == 0 {
str = fmt.Sprintf("r%d", r) fp += "NONE"
} else { return fp
str = fmt.Sprintf("f%d", r-NREG)
} }
fp += str if REG_R0 <= r && r <= REG_R31 {
fp += fmt.Sprintf("R%d", r-REG_R0)
return fp
}
if REG_F0 <= r && r <= REG_F31 {
fp += fmt.Sprintf("F%d", r-REG_F0)
return fp
}
if REG_C0 <= r && r <= REG_C7 {
fp += fmt.Sprintf("C%d", r-REG_C0)
return fp
}
if r == REG_CR {
fp += "CR"
return fp
}
if REG_SPR0 <= r && r <= REG_SPR0+1023 {
switch r {
case REG_XER:
fp += "XER"
return fp
case REG_LR:
fp += "LR"
return fp
case REG_CTR:
fp += "CTR"
return fp
}
fp += fmt.Sprintf("SPR(%d)", r-REG_SPR0)
return fp
}
if REG_DCR0 <= r && r <= REG_DCR0+1023 {
fp += fmt.Sprintf("DCR(%d)", r-REG_DCR0)
return fp
}
if r == REG_FPSCR {
fp += "FPSCR"
return fp
}
if r == REG_MSR {
fp += "MSR"
return fp
}
fp += fmt.Sprintf("badreg(%d)", r)
return fp return fp
} }

View File

@ -36,50 +36,6 @@ import (
"math" "math"
) )
var zprg = obj.Prog{
As: AGOK,
Reg: NREG,
From: obj.Addr{
Name: D_NONE,
Type: D_NONE,
Reg: NREG,
},
From3: obj.Addr{
Name: D_NONE,
Type: D_NONE,
Reg: NREG,
},
To: obj.Addr{
Name: D_NONE,
Type: D_NONE,
Reg: NREG,
},
}
func symtype(a *obj.Addr) int {
return int(a.Name)
}
func isdata(p *obj.Prog) bool {
return p.As == ADATA || p.As == AGLOBL
}
func iscall(p *obj.Prog) bool {
return p.As == ABL
}
func datasize(p *obj.Prog) int {
return int(p.Reg)
}
func textflag(p *obj.Prog) int {
return int(p.Reg)
}
func settextflag(p *obj.Prog, f int) {
p.Reg = uint8(f)
}
func progedit(ctxt *obj.Link, p *obj.Prog) { func progedit(ctxt *obj.Link, p *obj.Prog) {
var literal string var literal string
var s *obj.LSym var s *obj.LSym
@ -87,25 +43,23 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p.From.Class = 0 p.From.Class = 0
p.To.Class = 0 p.To.Class = 0
// Rewrite BR/BL to symbol as D_BRANCH. // Rewrite BR/BL to symbol as TYPE_BRANCH.
switch p.As { switch p.As {
case ABR, case ABR,
ABL, ABL,
ARETURN, ARETURN,
ADUFFZERO, obj.ADUFFZERO,
ADUFFCOPY: obj.ADUFFCOPY:
if p.To.Sym != nil { if p.To.Sym != nil {
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
} }
break break
} }
// Rewrite float constants to values stored in memory. // Rewrite float constants to values stored in memory.
switch p.As { switch p.As {
case AFMOVS: case AFMOVS:
if p.From.Type == D_FCONST { if p.From.Type == obj.TYPE_FCONST {
var i32 uint32 var i32 uint32
var f32 float32 var f32 float32
f32 = float32(p.From.U.Dval) f32 = float32(p.From.U.Dval)
@ -113,56 +67,54 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
literal = fmt.Sprintf("$f32.%08x", i32) literal = fmt.Sprintf("$f32.%08x", i32)
s = obj.Linklookup(ctxt, literal, 0) s = obj.Linklookup(ctxt, literal, 0)
s.Size = 4 s.Size = 4
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Sym = s p.From.Sym = s
p.From.Name = D_EXTERN p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0 p.From.Offset = 0
} }
case AFMOVD: case AFMOVD:
if p.From.Type == D_FCONST { if p.From.Type == obj.TYPE_FCONST {
var i64 uint64 var i64 uint64
i64 = math.Float64bits(p.From.U.Dval) i64 = math.Float64bits(p.From.U.Dval)
literal = fmt.Sprintf("$f64.%016x", i64) literal = fmt.Sprintf("$f64.%016x", i64)
s = obj.Linklookup(ctxt, literal, 0) s = obj.Linklookup(ctxt, literal, 0)
s.Size = 8 s.Size = 8
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Sym = s p.From.Sym = s
p.From.Name = D_EXTERN p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0 p.From.Offset = 0
} }
// Put >32-bit constants in memory and load them // Put >32-bit constants in memory and load them
case AMOVD: case AMOVD:
if p.From.Type == D_CONST && p.From.Name == D_NONE && p.From.Reg == NREG && int64(int32(p.From.Offset)) != p.From.Offset { if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset {
literal = fmt.Sprintf("$i64.%016x", uint64(p.From.Offset)) literal = fmt.Sprintf("$i64.%016x", uint64(p.From.Offset))
s = obj.Linklookup(ctxt, literal, 0) s = obj.Linklookup(ctxt, literal, 0)
s.Size = 8 s.Size = 8
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Sym = s p.From.Sym = s
p.From.Name = D_EXTERN p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0 p.From.Offset = 0
} }
} }
// Rewrite SUB constants into ADD. // Rewrite SUB constants into ADD.
switch p.As { switch p.As {
case ASUBC: case ASUBC:
if p.From.Type == D_CONST { if p.From.Type == obj.TYPE_CONST {
p.From.Offset = -p.From.Offset p.From.Offset = -p.From.Offset
p.As = AADDC p.As = AADDC
} }
case ASUBCCC: case ASUBCCC:
if p.From.Type == D_CONST { if p.From.Type == obj.TYPE_CONST {
p.From.Offset = -p.From.Offset p.From.Offset = -p.From.Offset
p.As = AADDCCC p.As = AADDCCC
} }
case ASUB: case ASUB:
if p.From.Type == D_CONST { if p.From.Type == obj.TYPE_CONST {
p.From.Offset = -p.From.Offset p.From.Offset = -p.From.Offset
p.As = AADD p.As = AADD
} }
@ -171,20 +123,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
} }
} }
func parsetextconst(arg int64, textstksiz *int64, textarg *int64) { func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
*textstksiz = arg & 0xffffffff
if *textstksiz&0x80000000 != 0 {
*textstksiz = -(-*textstksiz & 0xffffffff)
}
*textarg = (arg >> 32) & 0xffffffff
if *textarg&0x80000000 != 0 {
*textarg = 0
}
*textarg = (*textarg + 7) &^ 7
}
func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
var p *obj.Prog var p *obj.Prog
var q *obj.Prog var q *obj.Prog
var p1 *obj.Prog var p1 *obj.Prog
@ -194,7 +133,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
var mov int var mov int
var aoffset int var aoffset int
var textstksiz int64 var textstksiz int64
var textarg int64
var autosize int32 var autosize int32
if ctxt.Symmorestack[0] == nil { if ctxt.Symmorestack[0] == nil {
@ -210,9 +148,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
p = cursym.Text p = cursym.Text
parsetextconst(p.To.Offset, &textstksiz, &textarg) textstksiz = p.To.Offset
cursym.Args = int32(p.To.Offset >> 32) cursym.Args = p.To.U.Argsize
cursym.Locals = int32(textstksiz) cursym.Locals = int32(textstksiz)
/* /*
@ -222,7 +160,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
* expand BECOME pseudo * expand BECOME pseudo
*/ */
if ctxt.Debugvlog != 0 { if ctxt.Debugvlog != 0 {
fmt.Fprintf(ctxt.Bso, "%5.2f noops\n", obj.Cputime()) fmt.Fprintf(ctxt.Bso, "%5.2f noops\n", obj.Cputime())
} }
obj.Bflush(ctxt.Bso) obj.Bflush(ctxt.Bso)
@ -231,7 +168,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
switch p.As { switch p.As {
/* too hard, just leave alone */ /* too hard, just leave alone */
case ATEXT: case obj.ATEXT:
q = p q = p
p.Mark |= LABEL | LEAF | SYNC p.Mark |= LABEL | LEAF | SYNC
@ -241,7 +178,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
case ANOR: case ANOR:
q = p q = p
if p.To.Type == D_REG { if p.To.Type == obj.TYPE_REG {
if p.To.Reg == REGZERO { if p.To.Reg == REGZERO {
p.Mark |= LABEL | SYNC p.Mark |= LABEL | SYNC
} }
@ -284,24 +221,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
AMOVWZ, AMOVWZ,
AMOVD: AMOVD:
q = p q = p
switch p.From.Type { if p.From.Reg >= REG_SPECIAL || p.To.Reg >= REG_SPECIAL {
case D_MSR,
D_SPR,
D_FPSCR,
D_CREG,
D_DCR:
p.Mark |= LABEL | SYNC p.Mark |= LABEL | SYNC
} }
switch p.To.Type {
case D_MSR,
D_SPR,
D_FPSCR,
D_CREG,
D_DCR:
p.Mark |= LABEL | SYNC
}
continue continue
case AFABS, case AFABS,
@ -346,8 +268,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
case ABL, case ABL,
ABCL, ABCL,
ADUFFZERO, obj.ADUFFZERO,
ADUFFCOPY: obj.ADUFFCOPY:
cursym.Text.Mark &^= LEAF cursym.Text.Mark &^= LEAF
fallthrough fallthrough
@ -365,7 +287,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q = p q = p
q1 = p.Pcond q1 = p.Pcond
if q1 != nil { if q1 != nil {
for q1.As == ANOP { for q1.As == obj.ANOP {
q1 = q1.Link q1 = q1.Link
p.Pcond = q1 p.Pcond = q1
} }
@ -374,7 +296,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q1.Mark |= LABEL q1.Mark |= LABEL
} }
} else { } else {
p.Mark |= LABEL p.Mark |= LABEL
} }
q1 = p.Link q1 = p.Link
@ -396,7 +317,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
continue continue
case ANOP: case obj.ANOP:
q1 = p.Link q1 = p.Link
q.Link = q1 /* q is non-nop */ q.Link = q1 /* q is non-nop */
q1.Mark |= p.Mark q1.Mark |= p.Mark
@ -412,7 +333,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
o = int(p.As) o = int(p.As)
switch o { switch o {
case ATEXT: case obj.ATEXT:
mov = AMOVD mov = AMOVD
aoffset = 0 aoffset = 0
autosize = int32(textstksiz + 8) autosize = int32(textstksiz + 8)
@ -421,10 +342,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} else if autosize&4 != 0 { } else if autosize&4 != 0 {
autosize += 4 autosize += 4
} }
p.To.Offset = int64(uint64(p.To.Offset)&(0xffffffff<<32) | uint64(uint32(autosize-8))) p.To.Offset = int64(autosize) - 8
if !(p.Reg&obj.NOSPLIT != 0) { if !(p.From3.Offset&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.Reg&obj.NEEDCTXT != 0))) // emit split check p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0))) // emit split check
} }
q = p q = p
@ -432,17 +353,15 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
if autosize != 0 { if autosize != 0 {
/* use MOVDU to adjust R1 when saving R31, if autosize is small */ /* use MOVDU to adjust R1 when saving R31, if autosize is small */
if !(cursym.Text.Mark&LEAF != 0) && autosize >= -BIG && autosize <= BIG { if !(cursym.Text.Mark&LEAF != 0) && autosize >= -BIG && autosize <= BIG {
mov = AMOVDU mov = AMOVDU
aoffset = int(-autosize) aoffset = int(-autosize)
} else { } else {
q = obj.Appendp(ctxt, p) q = obj.Appendp(ctxt, p)
q.As = AADD q.As = AADD
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.From.Type = D_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(-autosize) q.From.Offset = int64(-autosize)
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REGSP q.To.Reg = REGSP
q.Spadj = +autosize q.Spadj = +autosize
} }
@ -463,24 +382,24 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = AMOVD q.As = AMOVD
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.From.Type = D_SPR q.From.Type = obj.TYPE_REG
q.From.Offset = D_LR q.From.Reg = REG_LR
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REGTMP q.To.Reg = REGTMP
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = int16(mov) q.As = int16(mov)
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.From.Type = D_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REGTMP q.From.Reg = REGTMP
q.To.Type = D_OREG q.To.Type = obj.TYPE_MEM
q.To.Offset = int64(aoffset) q.To.Offset = int64(aoffset)
q.To.Reg = REGSP q.To.Reg = REGSP
if q.As == AMOVDU { if q.As == AMOVDU {
q.Spadj = int32(-aoffset) q.Spadj = int32(-aoffset)
} }
if cursym.Text.Reg&obj.WRAPPER != 0 { if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
// //
// MOVD g_panic(g), R3 // MOVD g_panic(g), R3
@ -501,109 +420,109 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = AMOVD q.As = AMOVD
q.From.Type = D_OREG q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = 3 q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = ACMP q.As = ACMP
q.From.Type = D_REG q.From.Type = obj.TYPE_REG
q.From.Reg = 0 q.From.Reg = REG_R0
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = 3 q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = ABEQ q.As = ABEQ
q.To.Type = D_BRANCH q.To.Type = obj.TYPE_BRANCH
p1 = q p1 = q
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = AMOVD q.As = AMOVD
q.From.Type = D_OREG q.From.Type = obj.TYPE_MEM
q.From.Reg = 3 q.From.Reg = REG_R3
q.From.Offset = 0 // Panic.argp q.From.Offset = 0 // Panic.argp
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = 4 q.To.Reg = REG_R4
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = AADD q.As = AADD
q.From.Type = D_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) + 8 q.From.Offset = int64(autosize) + 8
q.Reg = REGSP q.Reg = REGSP
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = 5 q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = ACMP q.As = ACMP
q.From.Type = D_REG q.From.Type = obj.TYPE_REG
q.From.Reg = 4 q.From.Reg = REG_R4
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = 5 q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = ABNE q.As = ABNE
q.To.Type = D_BRANCH q.To.Type = obj.TYPE_BRANCH
p2 = q p2 = q
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = AADD q.As = AADD
q.From.Type = D_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = 8 q.From.Offset = 8
q.Reg = REGSP q.Reg = REGSP
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = 6 q.To.Reg = REG_R6
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = AMOVD q.As = AMOVD
q.From.Type = D_REG q.From.Type = obj.TYPE_REG
q.From.Reg = 6 q.From.Reg = REG_R6
q.To.Type = D_OREG q.To.Type = obj.TYPE_MEM
q.To.Reg = 3 q.To.Reg = REG_R3
q.To.Offset = 0 // Panic.argp q.To.Offset = 0 // Panic.argp
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = ANOP q.As = obj.ANOP
p1.Pcond = q p1.Pcond = q
p2.Pcond = q p2.Pcond = q
} }
case ARETURN: case ARETURN:
if p.From.Type == D_CONST { if p.From.Type == obj.TYPE_CONST {
ctxt.Diag("using BECOME (%v) is not supported!", p) ctxt.Diag("using BECOME (%v) is not supported!", p)
break break
} }
if p.To.Sym != nil { // retjmp if p.To.Sym != nil { // retjmp
p.As = ABR p.As = ABR
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
break break
} }
if cursym.Text.Mark&LEAF != 0 { if cursym.Text.Mark&LEAF != 0 {
if !(autosize != 0) { if !(autosize != 0) {
p.As = ABR p.As = ABR
p.From = zprg.From p.From = obj.Zprog.From
p.To.Type = D_SPR p.To.Type = obj.TYPE_REG
p.To.Offset = D_LR p.To.Reg = REG_LR
p.Mark |= BRANCH p.Mark |= BRANCH
break break
} }
p.As = AADD p.As = AADD
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize) p.From.Offset = int64(autosize)
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP p.To.Reg = REGSP
p.Spadj = -autosize p.Spadj = -autosize
q = ctxt.NewProg() q = new(obj.Prog)
q.As = ABR q.As = ABR
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.To.Type = D_SPR q.To.Type = obj.TYPE_REG
q.To.Offset = D_LR q.To.Reg = REG_LR
q.Mark |= BRANCH q.Mark |= BRANCH
q.Spadj = +autosize q.Spadj = +autosize
@ -613,19 +532,19 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
p.As = AMOVD p.As = AMOVD
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Offset = 0 p.From.Offset = 0
p.From.Reg = REGSP p.From.Reg = REGSP
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP p.To.Reg = REGTMP
q = ctxt.NewProg() q = new(obj.Prog)
q.As = AMOVD q.As = AMOVD
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.From.Type = D_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REGTMP q.From.Reg = REGTMP
q.To.Type = D_SPR q.To.Type = obj.TYPE_REG
q.To.Offset = D_LR q.To.Reg = REG_LR
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
@ -633,14 +552,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
if false { if false {
// Debug bad returns // Debug bad returns
q = ctxt.NewProg() q = new(obj.Prog)
q.As = AMOVD q.As = AMOVD
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.From.Type = D_OREG q.From.Type = obj.TYPE_MEM
q.From.Offset = 0 q.From.Offset = 0
q.From.Reg = REGTMP q.From.Reg = REGTMP
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REGTMP q.To.Reg = REGTMP
q.Link = p.Link q.Link = p.Link
@ -649,12 +568,12 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
if autosize != 0 { if autosize != 0 {
q = ctxt.NewProg() q = new(obj.Prog)
q.As = AADD q.As = AADD
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.From.Type = D_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) q.From.Offset = int64(autosize)
q.To.Type = D_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REGSP q.To.Reg = REGSP
q.Spadj = -autosize q.Spadj = -autosize
@ -662,11 +581,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.Link = q p.Link = q
} }
q1 = ctxt.NewProg() q1 = new(obj.Prog)
q1.As = ABR q1.As = ABR
q1.Lineno = p.Lineno q1.Lineno = p.Lineno
q1.To.Type = D_SPR q1.To.Type = obj.TYPE_REG
q1.To.Offset = D_LR q1.To.Reg = REG_LR
q1.Mark |= BRANCH q1.Mark |= BRANCH
q1.Spadj = +autosize q1.Spadj = +autosize
@ -674,7 +593,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q.Link = q1 q.Link = q1
case AADD: case AADD:
if p.To.Type == D_REG && p.To.Reg == REGSP && p.From.Type == D_CONST { if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST {
p.Spadj = int32(-p.From.Offset) p.Spadj = int32(-p.From.Offset)
} }
break break
@ -728,7 +647,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} }
*/ */
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.Prog { func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.Prog {
var q *obj.Prog var q *obj.Prog
var q1 *obj.Prog var q1 *obj.Prog
@ -736,14 +654,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVD p.As = AMOVD
p.From.Type = D_OREG p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 { if ctxt.Cursym.Cfunc != 0 {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
} }
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 3 p.To.Reg = REG_R3
q = nil q = nil
if framesize <= obj.StackSmall { if framesize <= obj.StackSmall {
@ -752,9 +670,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPU p.As = ACMPU
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 3 p.From.Reg = REG_R3
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP p.To.Reg = REGSP
} else if framesize <= obj.StackBig { } else if framesize <= obj.StackBig {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
@ -763,20 +681,19 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AADD p.As = AADD
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-framesize) p.From.Offset = int64(-framesize)
p.Reg = REGSP p.Reg = REGSP
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPU p.As = ACMPU
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 3 p.From.Reg = REG_R3
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 4 p.To.Reg = REG_R4
} else { } else {
// Such a large stack we need to protect against wraparound. // Such a large stack we need to protect against wraparound.
// If SP is close to zero: // If SP is close to zero:
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) // SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
@ -795,44 +712,44 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMP p.As = ACMP
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 3 p.From.Reg = REG_R3
p.To.Type = D_CONST p.To.Type = obj.TYPE_CONST
p.To.Offset = obj.StackPreempt p.To.Offset = obj.StackPreempt
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
q = p q = p
p.As = ABEQ p.As = ABEQ
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AADD p.As = AADD
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard p.From.Offset = obj.StackGuard
p.Reg = REGSP p.Reg = REGSP
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ASUB p.As = ASUB
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = 3 p.From.Reg = REG_R3
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVD p.As = AMOVD
p.From.Type = D_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP p.To.Reg = REGTMP
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ACMPU p.As = ACMPU
p.From.Type = D_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP p.From.Reg = REGTMP
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 4 p.To.Reg = REG_R4
} }
// q1: BLT done // q1: BLT done
@ -840,16 +757,16 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
q1 = p q1 = p
p.As = ABLT p.As = ABLT
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
// MOVD LR, R5 // MOVD LR, R5
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = AMOVD p.As = AMOVD
p.From.Type = D_SPR p.From.Type = obj.TYPE_REG
p.From.Offset = D_LR p.From.Reg = REG_LR
p.To.Type = D_REG p.To.Type = obj.TYPE_REG
p.To.Reg = 5 p.To.Reg = REG_R5
if q != nil { if q != nil {
q.Pcond = p q.Pcond = p
} }
@ -858,11 +775,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ABL p.As = ABL
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
if ctxt.Cursym.Cfunc != 0 { if ctxt.Cursym.Cfunc != 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0) p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else { } else {
p.To.Sym = ctxt.Symmorestack[noctxt] p.To.Sym = ctxt.Symmorestack[noctxt]
} }
@ -870,13 +786,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ABR p.As = ABR
p.To.Type = D_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = ctxt.Cursym.Text.Link p.Pcond = ctxt.Cursym.Text.Link
// placeholder for q1's jump target // placeholder for q1's jump target
p = obj.Appendp(ctxt, p) p = obj.Appendp(ctxt, p)
p.As = ANOP // zero-width place holder p.As = obj.ANOP // zero-width place holder
q1.Pcond = p q1.Pcond = p
return p return p
@ -888,7 +804,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
ctxt.Cursym = s ctxt.Cursym = s
firstp = ctxt.NewProg() firstp = new(obj.Prog)
lastp = firstp lastp = firstp
xfol(ctxt, s.Text, &lastp) xfol(ctxt, s.Text, &lastp)
lastp.Link = nil lastp.Link = nil
@ -966,7 +882,7 @@ loop:
} }
b = 0 /* set */ b = 0 /* set */
a = int(q.As) a = int(q.As)
if a == ANOP { if a == obj.ANOP {
i-- i--
continue continue
} }
@ -984,7 +900,7 @@ loop:
copy: copy:
for { for {
r = ctxt.NewProg() r = new(obj.Prog)
*r = *p *r = *p
if !(r.Mark&FOLL != 0) { if !(r.Mark&FOLL != 0) {
fmt.Printf("cant happen 1\n") fmt.Printf("cant happen 1\n")
@ -1016,10 +932,10 @@ loop:
} }
a = ABR a = ABR
q = ctxt.NewProg() q = new(obj.Prog)
q.As = int16(a) q.As = int16(a)
q.Lineno = p.Lineno q.Lineno = p.Lineno
q.To.Type = D_BRANCH q.To.Type = obj.TYPE_BRANCH
q.To.Offset = p.Pc q.To.Offset = p.Pc
q.Pcond = p q.Pcond = p
p = q p = q
@ -1052,97 +968,32 @@ loop:
goto loop goto loop
} }
func prg() *obj.Prog {
p := zprg
return &p
}
var Linkppc64 = obj.LinkArch{ var Linkppc64 = obj.LinkArch{
ByteOrder: binary.BigEndian, ByteOrder: binary.BigEndian,
Pconv: Pconv, Pconv: Pconv,
Name: "ppc64", Name: "ppc64",
Thechar: '9', Thechar: '9',
Endian: obj.BigEndian, Endian: obj.BigEndian,
Addstacksplit: addstacksplit, Preprocess: preprocess,
Assemble: span9, Assemble: span9,
Datasize: datasize, Follow: follow,
Follow: follow, Progedit: progedit,
Iscall: iscall, Minlc: 4,
Isdata: isdata, Ptrsize: 8,
Prg: prg, Regsize: 8,
Progedit: progedit,
Settextflag: settextflag,
Symtype: symtype,
Textflag: textflag,
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
D_ADDR: D_ADDR,
D_AUTO: D_AUTO,
D_BRANCH: D_BRANCH,
D_CONST: D_CONST,
D_EXTERN: D_EXTERN,
D_FCONST: D_FCONST,
D_NONE: D_NONE,
D_PARAM: D_PARAM,
D_SCONST: D_SCONST,
D_STATIC: D_STATIC,
D_OREG: D_OREG,
ACALL: ABL,
ADATA: ADATA,
AEND: AEND,
AFUNCDATA: AFUNCDATA,
AGLOBL: AGLOBL,
AJMP: ABR,
ANOP: ANOP,
APCDATA: APCDATA,
ARET: ARETURN,
ATEXT: ATEXT,
ATYPE: ATYPE,
AUSEFIELD: AUSEFIELD,
} }
var Linkppc64le = obj.LinkArch{ var Linkppc64le = obj.LinkArch{
ByteOrder: binary.LittleEndian, ByteOrder: binary.LittleEndian,
Pconv: Pconv, Pconv: Pconv,
Name: "ppc64le", Name: "ppc64le",
Thechar: '9', Thechar: '9',
Endian: obj.LittleEndian, Endian: obj.LittleEndian,
Addstacksplit: addstacksplit, Preprocess: preprocess,
Assemble: span9, Assemble: span9,
Datasize: datasize, Follow: follow,
Follow: follow, Progedit: progedit,
Iscall: iscall, Minlc: 4,
Isdata: isdata, Ptrsize: 8,
Prg: prg, Regsize: 8,
Progedit: progedit,
Settextflag: settextflag,
Symtype: symtype,
Textflag: textflag,
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
D_ADDR: D_ADDR,
D_AUTO: D_AUTO,
D_BRANCH: D_BRANCH,
D_CONST: D_CONST,
D_EXTERN: D_EXTERN,
D_FCONST: D_FCONST,
D_NONE: D_NONE,
D_PARAM: D_PARAM,
D_SCONST: D_SCONST,
D_STATIC: D_STATIC,
D_OREG: D_OREG,
ACALL: ABL,
ADATA: ADATA,
AEND: AEND,
AFUNCDATA: AFUNCDATA,
AGLOBL: AGLOBL,
AJMP: ABR,
ANOP: ANOP,
APCDATA: APCDATA,
ARET: ARETURN,
ATEXT: ATEXT,
ATYPE: ATYPE,
AUSEFIELD: AUSEFIELD,
} }

View File

@ -46,10 +46,6 @@ var headers = []struct {
name string name string
val int val int
}{ }{
struct {
name string
val int
}{"android", Hlinux},
struct { struct {
name string name string
val int val int
@ -70,6 +66,10 @@ var headers = []struct {
name string name string
val int val int
}{"linux", Hlinux}, }{"linux", Hlinux},
struct {
name string
val int
}{"android", Hlinux}, // must be after "linux" entry or else headstr(Hlinux) == "android"
struct { struct {
name string name string
val int val int
@ -129,6 +129,8 @@ func Linknew(arch *LinkArch) *Link {
var p string var p string
var buf string var buf string
linksetexp()
ctxt = new(Link) ctxt = new(Link)
ctxt.Arch = arch ctxt.Arch = arch
ctxt.Version = HistVersion ctxt.Version = HistVersion
@ -151,7 +153,6 @@ func Linknew(arch *LinkArch) *Link {
// Record thread-local storage offset. // Record thread-local storage offset.
// TODO(rsc): Move tlsoffset back into the linker. // TODO(rsc): Move tlsoffset back into the linker.
switch ctxt.Headtype { switch ctxt.Headtype {
default: default:
log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype)) log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype))
@ -194,7 +195,6 @@ func Linknew(arch *LinkArch) *Link {
*/ */
case Hdarwin: case Hdarwin:
switch ctxt.Arch.Thechar { switch ctxt.Arch.Thechar {
default: default:
log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name) log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name)
@ -211,12 +211,10 @@ func Linknew(arch *LinkArch) *Link {
// On arm, record goarm. // On arm, record goarm.
if ctxt.Arch.Thechar == '5' { if ctxt.Arch.Thechar == '5' {
p = Getgoarm() p = Getgoarm()
if p != "" { if p != "" {
ctxt.Goarm = int32(Atoi(p)) ctxt.Goarm = int32(Atoi(p))
} else { } else {
ctxt.Goarm = 6 ctxt.Goarm = 6
} }
} }
@ -281,6 +279,5 @@ func Linklookup(ctxt *Link, name string, v int) *LSym {
// read-only lookup // read-only lookup
func linkrlookup(ctxt *Link, name string, v int) *LSym { func linkrlookup(ctxt *Link, name string, v int) *LSym {
return _lookup(ctxt, name, v, 0) return _lookup(ctxt, name, v, 0)
} }

View File

@ -25,10 +25,19 @@ func Cputime() float64 {
type Biobuf struct { type Biobuf struct {
unget int unget int
haveUnget bool haveUnget bool
f *os.File
r *bufio.Reader r *bufio.Reader
w *bufio.Writer w *bufio.Writer
} }
func Bopenw(name string) (*Biobuf, error) {
f, err := os.Open(name)
if err != nil {
return nil, err
}
return &Biobuf{f: f, w: bufio.NewWriter(f)}, nil
}
func Binitw(w io.Writer) *Biobuf { func Binitw(w io.Writer) *Biobuf {
return &Biobuf{w: bufio.NewWriter(w)} return &Biobuf{w: bufio.NewWriter(w)}
} }
@ -75,6 +84,15 @@ func Bflush(b *Biobuf) error {
return b.w.Flush() return b.w.Flush()
} }
func Bterm(b *Biobuf) error {
err := b.w.Flush()
err1 := b.f.Close()
if err == nil {
err = err1
}
return err
}
func envOr(key, value string) string { func envOr(key, value string) string {
if x := os.Getenv(key); x != "" { if x := os.Getenv(key); x != "" {
return x return x
@ -108,7 +126,7 @@ func Atoi(s string) int {
} }
func (p *Prog) Line() string { func (p *Prog) Line() string {
return linklinefmt(p.Ctxt, int(p.Lineno), false, false) return Linklinefmt(p.Ctxt, int(p.Lineno), false, false)
} }
func (p *Prog) String() string { func (p *Prog) String() string {
@ -119,7 +137,11 @@ func (p *Prog) String() string {
} }
func (ctxt *Link) NewProg() *Prog { func (ctxt *Link) NewProg() *Prog {
p := ctxt.Arch.Prg() // should be the only call to this; all others should use ctxt.NewProg p := new(Prog) // should be the only call to this; all others should use ctxt.NewProg
p.Ctxt = ctxt p.Ctxt = ctxt
return p return p
} }
func (ctxt *Link) Line(n int) string {
return Linklinefmt(ctxt, n, false, false)
}

View File

@ -30,12 +30,13 @@
package x86 package x86
import "cmd/internal/obj"
/* /*
* amd64 * amd64
*/ */
const ( const (
AXXX = iota AAAA = obj.A_ARCHSPECIFIC + iota
AAAA
AAAD AAAD
AAAM AAAM
AAAS AAAS
@ -65,7 +66,6 @@ const (
ABTSL ABTSL
ABTSW ABTSW
ABYTE ABYTE
ACALL
ACLC ACLC
ACLD ACLD
ACLI ACLI
@ -79,7 +79,6 @@ const (
ACMPSW ACMPSW
ADAA ADAA
ADAS ADAS
ADATA
ADECB ADECB
ADECL ADECL
ADECQ ADECQ
@ -88,9 +87,6 @@ const (
ADIVL ADIVL
ADIVW ADIVW
AENTER AENTER
AGLOBL
AGOK
AHISTORY
AHLT AHLT
AIDIVB AIDIVB
AIDIVL AIDIVL
@ -123,7 +119,6 @@ const (
AJLS AJLS
AJLT AJLT
AJMI AJMI
AJMP
AJNE AJNE
AJOC AJOC
AJOS AJOS
@ -166,11 +161,9 @@ const (
AMULB AMULB
AMULL AMULL
AMULW AMULW
ANAME
ANEGB ANEGB
ANEGL ANEGL
ANEGW ANEGW
ANOP
ANOTB ANOTB
ANOTL ANOTL
ANOTW ANOTW
@ -204,7 +197,6 @@ const (
ARCRW ARCRW
AREP AREP
AREPN AREPN
ARET
AROLB AROLB
AROLL AROLL
AROLW AROLW
@ -261,7 +253,6 @@ const (
ATESTB ATESTB
ATESTL ATESTL
ATESTW ATESTW
ATEXT
AVERR AVERR
AVERW AVERW
AWAIT AWAIT
@ -370,10 +361,6 @@ const (
AFXTRACT AFXTRACT
AFYL2X AFYL2X
AFYL2XP1 AFYL2XP1
AEND
ADYNT_
AINIT_
ASIGNAME
ACMPXCHGB ACMPXCHGB
ACMPXCHGL ACMPXCHGL
ACMPXCHGW ACMPXCHGW
@ -714,7 +701,6 @@ const (
AMOVQL AMOVQL
ABSWAPL ABSWAPL
ABSWAPQ ABSWAPQ
AUNDEF
AAESENC AAESENC
AAESENCLAST AAESENCLAST
AAESDEC AAESDEC
@ -723,100 +709,89 @@ const (
AAESKEYGENASSIST AAESKEYGENASSIST
APSHUFD APSHUFD
APCLMULQDQ APCLMULQDQ
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ALAST ALAST
) )
const ( const (
D_AL = 0 + iota REG_NONE = 0
D_CL REG_AL = 0 + 16 + iota - 1
D_DL REG_CL
D_BL REG_DL
D_SPB REG_BL
D_BPB REG_SPB
D_SIB REG_BPB
D_DIB REG_SIB
D_R8B REG_DIB
D_R9B REG_R8B
D_R10B REG_R9B
D_R11B REG_R10B
D_R12B REG_R11B
D_R13B REG_R12B
D_R14B REG_R13B
D_R15B REG_R14B
D_AX = 16 + iota - 16 REG_R15B
D_CX REG_AX = 16 + 16 + iota - 17
D_DX REG_CX
D_BX REG_DX
D_SP REG_BX
D_BP REG_SP
D_SI REG_BP
D_DI REG_SI
D_R8 REG_DI
D_R9 REG_R8
D_R10 REG_R9
D_R11 REG_R10
D_R12 REG_R11
D_R13 REG_R12
D_R14 REG_R13
D_R15 REG_R14
D_AH = 32 + iota - 32 REG_R15
D_CH REG_AH = 32 + 16 + iota - 33
D_DH REG_CH
D_BH REG_DH
D_F0 = 36 REG_BH
D_M0 = 44 REG_F0 = 36 + 16
D_X0 = 52 + iota - 38 REG_M0 = 44 + 16
D_X1 REG_X0 = 52 + 16 + iota - 39
D_X2 REG_X1
D_X3 REG_X2
D_X4 REG_X3
D_X5 REG_X4
D_X6 REG_X5
D_X7 REG_X6
D_X8 REG_X7
D_X9 REG_X8
D_X10 REG_X9
D_X11 REG_X10
D_X12 REG_X11
D_X13 REG_X12
D_X14 REG_X13
D_X15 REG_X14
D_CS = 68 + iota - 54 REG_X15
D_SS REG_CS = 68 + 16 + iota - 55
D_DS REG_SS
D_ES REG_DS
D_FS REG_ES
D_GS REG_FS
D_GDTR REG_GS
D_IDTR REG_GDTR
D_LDTR REG_IDTR
D_MSW REG_LDTR
D_TASK REG_MSW
D_CR = 79 REG_TASK
D_DR = 95 REG_CR = 79 + 16
D_TR = 103 REG_DR = 95 + 16
D_TLS = 111 REG_TR = 103 + 16
D_NONE = 112 REG_TLS = 111 + 16 + iota - 69
D_BRANCH = 113 MAXREG
D_EXTERN = 114 REGARG = -1
D_STATIC = 115 REGRET = REG_AX
D_AUTO = 116 FREGRET = REG_X0
D_PARAM = 117 REGSP = REG_SP
D_CONST = 118 REGTMP = REG_DI
D_FCONST = 119 REGEXT = REG_R15
D_SCONST = 120 FREGMIN = REG_X0 + 5
D_ADDR = 121 + iota - 78 FREGEXT = REG_X0 + 15
D_INDIR
D_LAST
T_TYPE = 1 << 0 T_TYPE = 1 << 0
T_INDEX = 1 << 1 T_INDEX = 1 << 1
T_OFFSET = 1 << 2 T_OFFSET = 1 << 2
@ -825,12 +800,4 @@ const (
T_SCONST = 1 << 5 T_SCONST = 1 << 5
T_64 = 1 << 6 T_64 = 1 << 6
T_GOTYPE = 1 << 7 T_GOTYPE = 1 << 7
REGARG = -1
REGRET = D_AX
FREGRET = D_X0
REGSP = D_SP
REGTMP = D_DI
REGEXT = D_R15
FREGMIN = D_X0 + 5
FREGEXT = D_X0 + 15
) )

View File

@ -4,8 +4,26 @@ package x86
* this is the ranlib header * this is the ranlib header
*/ */
var Anames = []string{ var Anames = []string{
"XXX", "XXX ",
"AAA", "CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"AAA ",
"AAD", "AAD",
"AAM", "AAM",
"AAS", "AAS",
@ -35,7 +53,6 @@ var Anames = []string{
"BTSL", "BTSL",
"BTSW", "BTSW",
"BYTE", "BYTE",
"CALL",
"CLC", "CLC",
"CLD", "CLD",
"CLI", "CLI",
@ -49,7 +66,6 @@ var Anames = []string{
"CMPSW", "CMPSW",
"DAA", "DAA",
"DAS", "DAS",
"DATA",
"DECB", "DECB",
"DECL", "DECL",
"DECQ", "DECQ",
@ -58,9 +74,6 @@ var Anames = []string{
"DIVL", "DIVL",
"DIVW", "DIVW",
"ENTER", "ENTER",
"GLOBL",
"GOK",
"HISTORY",
"HLT", "HLT",
"IDIVB", "IDIVB",
"IDIVL", "IDIVL",
@ -93,7 +106,6 @@ var Anames = []string{
"JLS", "JLS",
"JLT", "JLT",
"JMI", "JMI",
"JMP",
"JNE", "JNE",
"JOC", "JOC",
"JOS", "JOS",
@ -136,11 +148,9 @@ var Anames = []string{
"MULB", "MULB",
"MULL", "MULL",
"MULW", "MULW",
"NAME",
"NEGB", "NEGB",
"NEGL", "NEGL",
"NEGW", "NEGW",
"NOP",
"NOTB", "NOTB",
"NOTL", "NOTL",
"NOTW", "NOTW",
@ -174,7 +184,6 @@ var Anames = []string{
"RCRW", "RCRW",
"REP", "REP",
"REPN", "REPN",
"RET",
"ROLB", "ROLB",
"ROLL", "ROLL",
"ROLW", "ROLW",
@ -231,7 +240,6 @@ var Anames = []string{
"TESTB", "TESTB",
"TESTL", "TESTL",
"TESTW", "TESTW",
"TEXT",
"VERR", "VERR",
"VERW", "VERW",
"WAIT", "WAIT",
@ -340,10 +348,6 @@ var Anames = []string{
"FXTRACT", "FXTRACT",
"FYL2X", "FYL2X",
"FYL2XP1", "FYL2XP1",
"END",
"DYNT_",
"INIT_",
"SIGNAME",
"CMPXCHGB", "CMPXCHGB",
"CMPXCHGL", "CMPXCHGL",
"CMPXCHGW", "CMPXCHGW",
@ -684,7 +688,6 @@ var Anames = []string{
"MOVQL", "MOVQL",
"BSWAPL", "BSWAPL",
"BSWAPQ", "BSWAPQ",
"UNDEF",
"AESENC", "AESENC",
"AESENCLAST", "AESENCLAST",
"AESDEC", "AESDEC",
@ -693,97 +696,5 @@ var Anames = []string{
"AESKEYGENASSIST", "AESKEYGENASSIST",
"PSHUFD", "PSHUFD",
"PCLMULQDQ", "PCLMULQDQ",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"LAST", "LAST",
} }
var dnames6 = []string{
D_AL: "AL",
D_CL: "CL",
D_DL: "DL",
D_BL: "BL",
D_SPB: "SPB",
D_BPB: "BPB",
D_SIB: "SIB",
D_DIB: "DIB",
D_R8B: "R8B",
D_R9B: "R9B",
D_R10B: "R10B",
D_R11B: "R11B",
D_R12B: "R12B",
D_R13B: "R13B",
D_R14B: "R14B",
D_R15B: "R15B",
D_AX: "AX",
D_CX: "CX",
D_DX: "DX",
D_BX: "BX",
D_SP: "SP",
D_BP: "BP",
D_SI: "SI",
D_DI: "DI",
D_R8: "R8",
D_R9: "R9",
D_R10: "R10",
D_R11: "R11",
D_R12: "R12",
D_R13: "R13",
D_R14: "R14",
D_R15: "R15",
D_AH: "AH",
D_CH: "CH",
D_DH: "DH",
D_BH: "BH",
D_F0: "F0",
D_M0: "M0",
D_X0: "X0",
D_X1: "X1",
D_X2: "X2",
D_X3: "X3",
D_X4: "X4",
D_X5: "X5",
D_X6: "X6",
D_X7: "X7",
D_X8: "X8",
D_X9: "X9",
D_X10: "X10",
D_X11: "X11",
D_X12: "X12",
D_X13: "X13",
D_X14: "X14",
D_X15: "X15",
D_CS: "CS",
D_SS: "SS",
D_DS: "DS",
D_ES: "ES",
D_FS: "FS",
D_GS: "GS",
D_GDTR: "GDTR",
D_IDTR: "IDTR",
D_LDTR: "LDTR",
D_MSW: "MSW",
D_TASK: "TASK",
D_CR: "CR",
D_DR: "DR",
D_TR: "TR",
D_TLS: "TLS",
D_NONE: "NONE",
D_BRANCH: "BRANCH",
D_EXTERN: "EXTERN",
D_STATIC: "STATIC",
D_AUTO: "AUTO",
D_PARAM: "PARAM",
D_CONST: "CONST",
D_FCONST: "FCONST",
D_SCONST: "SCONST",
D_ADDR: "ADDR",
D_INDIR: "INDIR",
}

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,6 @@ import (
// %A int Opcodes (instruction mnemonics) // %A int Opcodes (instruction mnemonics)
// //
// %D Addr* Addresses (instruction operands) // %D Addr* Addresses (instruction operands)
// Flags: "%lD": seperate the high and low words of a constant by "-"
// //
// %P Prog* Instructions // %P Prog* Instructions
// //
@ -59,16 +58,16 @@ func Pconv(p *obj.Prog) string {
var fp string var fp string
switch p.As { switch p.As {
case ADATA: case obj.ADATA:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
case ATEXT: case obj.ATEXT:
if p.From.Scale != 0 { if p.From3.Offset != 0 {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, fmtLong, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To))
break break
} }
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
default: default:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To))
@ -91,45 +90,26 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
var s string var s string
var fp string var fp string
var i int switch a.Type {
i = int(a.Type)
if flag&fmtLong != 0 /*untyped*/ {
if i == D_CONST {
str = fmt.Sprintf("$%d-%d", a.Offset&0xffffffff, a.Offset>>32)
} else {
// ATEXT dst is not constant
str = fmt.Sprintf("!!%v", Dconv(p, 0, a))
}
goto brk
}
if i >= D_INDIR {
if a.Offset != 0 {
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR))
} else {
str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR))
}
goto brk
}
switch i {
default: default:
if a.Offset != 0 { str = fmt.Sprintf("type=%d", a.Type)
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
} else {
str = fmt.Sprintf("%v", Rconv(i)) case obj.TYPE_NONE:
}
case D_NONE:
str = "" str = ""
case D_BRANCH: // TODO(rsc): This special case is for instructions like
// PINSRQ CX,$1,X6
// where the $1 is included in the p->to Addr.
// Move into a new field.
case obj.TYPE_REG:
if a.Offset != 0 {
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg)))
break
}
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
case obj.TYPE_BRANCH:
if a.Sym != nil { if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name) str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} else if p != nil && p.Pcond != nil { } else if p != nil && p.Pcond != nil {
@ -137,57 +117,79 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
} else if a.U.Branch != nil { } else if a.U.Branch != nil {
str = fmt.Sprintf("%d", a.U.Branch.Pc) str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else { } else {
str = fmt.Sprintf("%d(PC)", a.Offset) str = fmt.Sprintf("%d(PC)", a.Offset)
} }
case D_EXTERN: case obj.TYPE_MEM:
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset) switch a.Name {
default:
str = fmt.Sprintf("name=%d", a.Name)
case D_STATIC: case obj.NAME_NONE:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset) if a.Offset != 0 {
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg)))
} else {
str = fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
}
case D_AUTO: case obj.NAME_EXTERN:
if a.Sym != nil { str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(SP)", a.Offset) case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
case obj.NAME_AUTO:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(SP)", a.Offset)
}
case obj.NAME_PARAM:
if a.Sym != nil {
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(FP)", a.Offset)
}
break
} }
case D_PARAM: if a.Index != REG_NONE {
if a.Sym != nil { s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset) str += s
} else {
str = fmt.Sprintf("%d(FP)", a.Offset)
} }
case D_CONST: case obj.TYPE_CONST:
str = fmt.Sprintf("$%d", a.Offset) str = fmt.Sprintf("$%d", a.Offset)
case D_FCONST: // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX
// Remove.
if a.Index != REG_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
case obj.TYPE_TEXTSIZE:
if a.U.Argsize == obj.ArgsSizeUnknown {
str = fmt.Sprintf("$%d", a.Offset)
} else {
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
}
case obj.TYPE_FCONST:
str = fmt.Sprintf("$(%.17g)", a.U.Dval) str = fmt.Sprintf("$(%.17g)", a.U.Dval)
case D_SCONST: case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval) str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case D_ADDR: case obj.TYPE_ADDR:
a.Type = int16(a.Index) a.Type = obj.TYPE_MEM
a.Index = D_NONE
str = fmt.Sprintf("$%v", Dconv(p, 0, a)) str = fmt.Sprintf("$%v", Dconv(p, 0, a))
a.Index = uint8(a.Type) a.Type = obj.TYPE_ADDR
a.Type = D_ADDR break
goto conv
} }
brk:
if a.Index != D_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
conv:
fp += str fp += str
return fp return fp
} }
@ -304,18 +306,22 @@ var Register = []string{
"TR5", "TR5",
"TR6", "TR6",
"TR7", "TR7",
"TLS", /* [D_TLS] */ "TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */ "MAXREG", /* [MAXREG] */
} }
func Rconv(r int) string { func Rconv(r int) string {
var str string var str string
var fp string var fp string
if r >= D_AL && r <= D_NONE { if r == REG_NONE {
str = fmt.Sprintf("%s", Register[r-D_AL]) fp += "NONE"
} else { return fp
}
if REG_AL <= r && r-REG_AL < len(Register) {
str = fmt.Sprintf("%s", Register[r-REG_AL])
} else {
str = fmt.Sprintf("gok(%d)", r) str = fmt.Sprintf("gok(%d)", r)
} }

File diff suppressed because it is too large Load Diff

View File

@ -59,13 +59,13 @@ import (
%token <lval> LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD %token <lval> LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
%token <lval> LCONST LSP LSB LFP LPC %token <lval> LCONST LSP LSB LFP LPC
%token <lval> LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR %token <lval> LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
%token <lval> LCOND LS LAT %token <lval> LCOND LS LAT LGLOBL
%token <dval> LFCONST %token <dval> LFCONST
%token <sval> LSCONST %token <sval> LSCONST
%token <sym> LNAME LLAB LVAR %token <sym> LNAME LLAB LVAR
%type <lval> con expr oexpr pointer offset sreg spreg creg %type <lval> con expr oexpr pointer offset sreg spreg creg
%type <lval> rcon cond reglist %type <lval> rcon cond reglist
%type <addr> gen rel reg regreg freg shift fcon frcon %type <addr> gen rel reg regreg freg shift fcon frcon textsize
%type <addr> imm ximm name oreg ireg nireg ioreg imsr %type <addr> imm ximm name oreg ireg nireg ioreg imsr
%% %%
prog: prog:
@ -116,53 +116,53 @@ inst:
} }
| LTYPE1 cond imsr ',' reg | LTYPE1 cond imsr ',' reg
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
/* /*
* MVN * MVN
*/ */
| LTYPE2 cond imsr ',' reg | LTYPE2 cond imsr ',' reg
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
/* /*
* MOVW * MOVW
*/ */
| LTYPE3 cond gen ',' gen | LTYPE3 cond gen ',' gen
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
/* /*
* B/BL * B/BL
*/ */
| LTYPE4 cond comma rel | LTYPE4 cond comma rel
{ {
outcode($1, $2, &nullgen, NREG, &$4); outcode($1, $2, &nullgen, 0, &$4);
} }
| LTYPE4 cond comma nireg | LTYPE4 cond comma nireg
{ {
outcode($1, $2, &nullgen, NREG, &$4); outcode($1, $2, &nullgen, 0, &$4);
} }
/* /*
* BX * BX
*/ */
| LTYPEBX comma ireg | LTYPEBX comma ireg
{ {
outcode($1, Always, &nullgen, NREG, &$3); outcode($1, Always, &nullgen, 0, &$3);
} }
/* /*
* BEQ * BEQ
*/ */
| LTYPE5 comma rel | LTYPE5 comma rel
{ {
outcode($1, Always, &nullgen, NREG, &$3); outcode($1, Always, &nullgen, 0, &$3);
} }
/* /*
* SWI * SWI
*/ */
| LTYPE6 cond comma gen | LTYPE6 cond comma gen
{ {
outcode($1, $2, &nullgen, NREG, &$4); outcode($1, $2, &nullgen, 0, &$4);
} }
/* /*
* CMP * CMP
@ -179,18 +179,18 @@ inst:
var g obj.Addr var g obj.Addr
g = nullgen; g = nullgen;
g.Type = D_CONST; g.Type = obj.TYPE_CONST;
g.Offset = int64($6); g.Offset = int64($6);
outcode($1, $2, &$3, NREG, &g); outcode($1, $2, &$3, 0, &g);
} }
| LTYPE8 cond '[' reglist ']' ',' ioreg | LTYPE8 cond '[' reglist ']' ',' ioreg
{ {
var g obj.Addr var g obj.Addr
g = nullgen; g = nullgen;
g.Type = D_CONST; g.Type = obj.TYPE_CONST;
g.Offset = int64($4); g.Offset = int64($4);
outcode($1, $2, &g, NREG, &$7); outcode($1, $2, &g, 0, &$7);
} }
/* /*
* SWAP * SWAP
@ -212,63 +212,78 @@ inst:
*/ */
| LTYPEA cond comma | LTYPEA cond comma
{ {
outcode($1, $2, &nullgen, NREG, &nullgen); outcode($1, $2, &nullgen, 0, &nullgen);
} }
/* /*
* TEXT/GLOBL * TEXT
*/ */
| LTYPEB name ',' imm | LTYPEB name ',' '$' textsize
{ {
asm.Settext($2.Sym); asm.Settext($2.Sym);
$4.Type = D_CONST2; outcode($1, Always, &$2, 0, &$5);
$4.Offset2 = -obj.ArgsSizeUnknown;
outcode($1, Always, &$2, 0, &$4);
} }
| LTYPEB name ',' con ',' imm | LTYPEB name ',' con ',' '$' textsize
{ {
asm.Settext($2.Sym); asm.Settext($2.Sym);
$6.Type = D_CONST2; outcode($1, Always, &$2, 0, &$7);
$6.Offset2 = -obj.ArgsSizeUnknown; if asm.Pass > 1 {
outcode($1, Always, &$2, $4, &$6); lastpc.From3.Type = obj.TYPE_CONST;
lastpc.From3.Offset = int64($4)
}
} }
| LTYPEB name ',' con ',' imm '-' con /*
* GLOBL
*/
| LGLOBL name ',' imm
{ {
asm.Settext($2.Sym); asm.Settext($2.Sym)
$6.Type = D_CONST2; outcode($1, Always, &$2, 0, &$4)
$6.Offset2 = $8;
outcode($1, Always, &$2, $4, &$6);
} }
| LGLOBL name ',' con ',' imm
{
asm.Settext($2.Sym)
outcode($1, Always, &$2, 0, &$6)
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = int64($4)
}
}
/* /*
* DATA * DATA
*/ */
| LTYPEC name '/' con ',' ximm | LTYPEC name '/' con ',' ximm
{ {
outcode($1, Always, &$2, $4, &$6); outcode($1, Always, &$2, 0, &$6)
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = int64($4)
}
} }
/* /*
* CASE * CASE
*/ */
| LTYPED cond reg comma | LTYPED cond reg comma
{ {
outcode($1, $2, &$3, NREG, &nullgen); outcode($1, $2, &$3, 0, &nullgen);
} }
/* /*
* word * word
*/ */
| LTYPEH comma ximm | LTYPEH comma ximm
{ {
outcode($1, Always, &nullgen, NREG, &$3); outcode($1, Always, &nullgen, 0, &$3);
} }
/* /*
* floating-point coprocessor * floating-point coprocessor
*/ */
| LTYPEI cond freg ',' freg | LTYPEI cond freg ',' freg
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
| LTYPEK cond frcon ',' freg | LTYPEK cond frcon ',' freg
{ {
outcode($1, $2, &$3, NREG, &$5); outcode($1, $2, &$3, 0, &$5);
} }
| LTYPEK cond frcon ',' LFREG ',' freg | LTYPEK cond frcon ',' LFREG ',' freg
{ {
@ -286,11 +301,11 @@ inst:
var g obj.Addr var g obj.Addr
g = nullgen; g = nullgen;
g.Type = D_CONST; g.Type = obj.TYPE_CONST;
g.Offset = int64( g.Offset = int64(
(0xe << 24) | /* opcode */ (0xe << 24) | /* opcode */
($1 << 20) | /* MCR/MRC */ ($1 << 20) | /* MCR/MRC */
($2 << 28) | /* scond */ (($2^C_SCOND_XOR) << 28) | /* scond */
(($3 & 15) << 8) | /* coprocessor number */ (($3 & 15) << 8) | /* coprocessor number */
(($5 & 7) << 21) | /* coprocessor operation */ (($5 & 7) << 21) | /* coprocessor operation */
(($7 & 15) << 12) | /* arm register */ (($7 & 15) << 12) | /* arm register */
@ -298,7 +313,7 @@ inst:
(($11 & 15) << 0) | /* Crm */ (($11 & 15) << 0) | /* Crm */
(($12 & 7) << 5) | /* coprocessor information */ (($12 & 7) << 5) | /* coprocessor information */
(1<<4)); /* must be set */ (1<<4)); /* must be set */
outcode(AMRC, Always, &nullgen, NREG, &g); outcode(AMRC, Always, &nullgen, 0, &g);
} }
/* /*
* MULL r1,r2,(hi,lo) * MULL r1,r2,(hi,lo)
@ -313,7 +328,7 @@ inst:
*/ */
| LTYPEN cond reg ',' reg ',' reg ',' spreg | LTYPEN cond reg ',' reg ',' reg ',' spreg
{ {
$7.Type = D_REGREG2; $7.Type = obj.TYPE_REGREG2;
$7.Offset = int64($9); $7.Offset = int64($9);
outcode($1, $2, &$3, int32($5.Reg), &$7); outcode($1, $2, &$3, int32($5.Reg), &$7);
} }
@ -322,37 +337,67 @@ inst:
*/ */
| LTYPEPLD oreg | LTYPEPLD oreg
{ {
outcode($1, Always, &$2, NREG, &nullgen); outcode($1, Always, &$2, 0, &nullgen);
} }
/* /*
* PCDATA * PCDATA
*/ */
| LTYPEPC gen ',' gen | LTYPEPC gen ',' gen
{ {
if $2.Type != D_CONST || $4.Type != D_CONST { if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
yyerror("arguments to PCDATA must be integer constants") yyerror("arguments to PCDATA must be integer constants")
} }
outcode($1, Always, &$2, NREG, &$4); outcode($1, Always, &$2, 0, &$4);
} }
/* /*
* FUNCDATA * FUNCDATA
*/ */
| LTYPEF gen ',' gen | LTYPEF gen ',' gen
{ {
if $2.Type != D_CONST { if $2.Type != obj.TYPE_CONST {
yyerror("index for FUNCDATA must be integer constant") yyerror("index for FUNCDATA must be integer constant")
} }
if $4.Type != D_EXTERN && $4.Type != D_STATIC && $4.Type != D_OREG { if $4.Type != obj.NAME_EXTERN && $4.Type != obj.NAME_STATIC && $4.Type != obj.TYPE_MEM {
yyerror("value for FUNCDATA must be symbol reference") yyerror("value for FUNCDATA must be symbol reference")
} }
outcode($1, Always, &$2, NREG, &$4); outcode($1, Always, &$2, 0, &$4);
} }
/* /*
* END * END
*/ */
| LTYPEE comma | LTYPEE comma
{ {
outcode($1, Always, &nullgen, NREG, &nullgen); outcode($1, Always, &nullgen, 0, &nullgen);
}
textsize:
LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = int64($1)
$$.U.Argsize = obj.ArgsSizeUnknown;
}
| '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -int64($2)
$$.U.Argsize = obj.ArgsSizeUnknown;
}
| LCONST '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = int64($1)
$$.U.Argsize = int32($3);
}
| '-' LCONST '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -int64($2)
$$.U.Argsize = int32($4);
} }
cond: cond:
@ -375,7 +420,7 @@ rel:
con '(' LPC ')' con '(' LPC ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_BRANCH; $$.Type = obj.TYPE_BRANCH;
$$.Offset = int64($1) + int64(asm.PC); $$.Offset = int64($1) + int64(asm.PC);
} }
| LNAME offset | LNAME offset
@ -385,30 +430,25 @@ rel:
if asm.Pass == 2 && $1.Type != LLAB { if asm.Pass == 2 && $1.Type != LLAB {
yyerror("undefined label: %s", $1.Labelname) yyerror("undefined label: %s", $1.Labelname)
} }
$$.Type = D_BRANCH; $$.Type = obj.TYPE_BRANCH;
$$.Offset = $1.Value + int64($2); $$.Offset = $1.Value + int64($2);
} }
ximm: '$' con ximm: '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_CONST; $$.Type = obj.TYPE_CONST;
$$.Offset = int64($2); $$.Offset = int64($2);
} }
| '$' oreg | '$' oreg
{ {
$$ = $2; $$ = $2;
$$.Type = D_CONST; $$.Type = obj.TYPE_ADDR;
}
| '$' '*' '$' oreg
{
$$ = $4;
$$.Type = D_OCONST;
} }
| '$' LSCONST | '$' LSCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SCONST; $$.Type = obj.TYPE_SCONST;
$$.U.Sval = $2 $$.U.Sval = $2
} }
| fcon | fcon
@ -417,34 +457,34 @@ fcon:
'$' LFCONST '$' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = $2; $$.U.Dval = $2;
} }
| '$' '-' LFCONST | '$' '-' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = -$3; $$.U.Dval = -$3;
} }
reglist: reglist:
spreg spreg
{ {
$$ = 1 << uint($1); $$ = 1 << uint($1&15);
} }
| spreg '-' spreg | spreg '-' spreg
{ {
$$=0; $$=0;
for i:=$1; i<=$3; i++ { for i:=$1; i<=$3; i++ {
$$ |= 1<<uint(i) $$ |= 1<<uint(i&15)
} }
for i:=$3; i<=$1; i++ { for i:=$3; i<=$1; i++ {
$$ |= 1<<uint(i) $$ |= 1<<uint(i&15)
} }
} }
| spreg comma reglist | spreg comma reglist
{ {
$$ = (1<<uint($1)) | $3; $$ = (1<<uint($1&15)) | $3;
} }
gen: gen:
@ -454,24 +494,24 @@ gen:
| shift '(' spreg ')' | shift '(' spreg ')'
{ {
$$ = $1; $$ = $1;
$$.Reg = int8($3); $$.Reg = int16($3);
} }
| LPSR | LPSR
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_PSR; $$.Type = obj.TYPE_REG
$$.Reg = int8($1); $$.Reg = int16($1);
} }
| LFCR | LFCR
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FPCR; $$.Type = obj.TYPE_REG
$$.Reg = int8($1); $$.Reg = int16($1);
} }
| con | con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Offset = int64($1); $$.Offset = int64($1);
} }
| oreg | oreg
@ -482,7 +522,7 @@ nireg:
| name | name
{ {
$$ = $1; $$ = $1;
if($1.Name != D_EXTERN && $1.Name != D_STATIC) { if($1.Name != obj.NAME_EXTERN && $1.Name != obj.NAME_STATIC) {
} }
} }
@ -490,8 +530,8 @@ ireg:
'(' spreg ')' '(' spreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Reg = int8($2); $$.Reg = int16($2);
$$.Offset = 0; $$.Offset = 0;
} }
@ -500,8 +540,8 @@ ioreg:
| con '(' sreg ')' | con '(' sreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Reg = int8($3); $$.Reg = int16($3);
$$.Offset = int64($1); $$.Offset = int64($1);
} }
@ -510,8 +550,8 @@ oreg:
| name '(' sreg ')' | name '(' sreg ')'
{ {
$$ = $1; $$ = $1;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Reg = int8($3); $$.Reg = int16($3);
} }
| ioreg | ioreg
@ -523,7 +563,7 @@ imsr:
imm: '$' con imm: '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_CONST; $$.Type = obj.TYPE_CONST;
$$.Offset = int64($2); $$.Offset = int64($2);
} }
@ -531,16 +571,16 @@ reg:
spreg spreg
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_REG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($1); $$.Reg = int16($1);
} }
regreg: regreg:
'(' spreg ',' spreg ')' '(' spreg ',' spreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_REGREG; $$.Type = obj.TYPE_REGREG;
$$.Reg = int8($2); $$.Reg = int16($2);
$$.Offset = int64($4); $$.Offset = int64($4);
} }
@ -548,32 +588,32 @@ shift:
spreg '<' '<' rcon spreg '<' '<' rcon
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SHIFT; $$.Type = obj.TYPE_SHIFT;
$$.Offset = int64($1) | int64($4) | (0 << 5); $$.Offset = int64($1&15) | int64($4) | (0 << 5);
} }
| spreg '>' '>' rcon | spreg '>' '>' rcon
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SHIFT; $$.Type = obj.TYPE_SHIFT;
$$.Offset = int64($1) | int64($4) | (1 << 5); $$.Offset = int64($1&15) | int64($4) | (1 << 5);
} }
| spreg '-' '>' rcon | spreg '-' '>' rcon
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SHIFT; $$.Type = obj.TYPE_SHIFT;
$$.Offset = int64($1) | int64($4) | (2 << 5); $$.Offset = int64($1&15) | int64($4) | (2 << 5);
} }
| spreg LAT '>' rcon | spreg LAT '>' rcon
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SHIFT; $$.Type = obj.TYPE_SHIFT;
$$.Offset = int64($1) | int64($4) | (3 << 5); $$.Offset = int64($1&15) | int64($4) | (3 << 5);
} }
rcon: rcon:
spreg spreg
{ {
if $$ < 0 || $$ >= 16 { if $$ < REG_R0 || $$ > REG_R15 {
print("register value out of range\n") print("register value out of range\n")
} }
$$ = (($1&15) << 8) | (1 << 4); $$ = (($1&15) << 8) | (1 << 4);
@ -597,7 +637,7 @@ sreg:
if $3 < 0 || $3 >= NREG { if $3 < 0 || $3 >= NREG {
print("register value out of range\n") print("register value out of range\n")
} }
$$ = $3; $$ = REG_R0 + $3;
} }
spreg: spreg:
@ -614,7 +654,7 @@ creg:
if $3 < 0 || $3 >= NREG { if $3 < 0 || $3 >= NREG {
print("register value out of range\n") print("register value out of range\n")
} }
$$ = $3; $$ = $3; // TODO(rsc): REG_C0+$3
} }
frcon: frcon:
@ -625,21 +665,21 @@ freg:
LFREG LFREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FREG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($1); $$.Reg = int16($1);
} }
| LF '(' con ')' | LF '(' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FREG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($3); $$.Reg = int16(REG_F0 + $3);
} }
name: name:
con '(' pointer ')' con '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Name = int8($3); $$.Name = int8($3);
$$.Sym = nil; $$.Sym = nil;
$$.Offset = int64($1); $$.Offset = int64($1);
@ -647,7 +687,7 @@ name:
| LNAME offset '(' pointer ')' | LNAME offset '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Name = int8($4); $$.Name = int8($4);
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0); $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
$$.Offset = int64($2); $$.Offset = int64($2);
@ -655,8 +695,8 @@ name:
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Name = D_STATIC; $$.Name = obj.NAME_STATIC;
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1); $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
$$.Offset = int64($4); $$.Offset = int64($4);
} }

View File

@ -44,7 +44,7 @@ var (
stmtline int32 stmtline int32
) )
const Always = 14 const Always = arm.C_SCOND_NONE
func main() { func main() {
cinit() cinit()
@ -88,44 +88,46 @@ func yyparse() {
} }
var lexinit = []asm.Lextab{ var lexinit = []asm.Lextab{
{"SP", LSP, arm.D_AUTO}, {"SP", LSP, obj.NAME_AUTO},
{"SB", LSB, arm.D_EXTERN}, {"SB", LSB, obj.NAME_EXTERN},
{"FP", LFP, arm.D_PARAM}, {"FP", LFP, obj.NAME_PARAM},
{"PC", LPC, arm.D_BRANCH}, {"PC", LPC, obj.TYPE_BRANCH},
{"R", LR, 0}, {"R", LR, 0},
{"R0", LREG, 0},
{"R1", LREG, 1}, {"R0", LREG, arm.REG_R0},
{"R2", LREG, 2}, {"R1", LREG, arm.REG_R1},
{"R3", LREG, 3}, {"R2", LREG, arm.REG_R2},
{"R4", LREG, 4}, {"R3", LREG, arm.REG_R3},
{"R5", LREG, 5}, {"R4", LREG, arm.REG_R4},
{"R6", LREG, 6}, {"R5", LREG, arm.REG_R5},
{"R7", LREG, 7}, {"R6", LREG, arm.REG_R6},
{"R8", LREG, 8}, {"R7", LREG, arm.REG_R7},
{"R9", LREG, 9}, {"R8", LREG, arm.REG_R8},
{"g", LREG, 10}, // avoid unintentionally clobber g using R10 {"R9", LREG, arm.REG_R9},
{"R11", LREG, 11}, {"g", LREG, arm.REG_R10}, // avoid unintentionally clobber g using R10
{"R12", LREG, 12}, {"R11", LREG, arm.REG_R11},
{"R13", LREG, 13}, {"R12", LREG, arm.REG_R12},
{"R14", LREG, 14}, {"R13", LREG, arm.REG_R13},
{"R15", LREG, 15}, {"R14", LREG, arm.REG_R14},
{"R15", LREG, arm.REG_R15},
{"F", LF, 0}, {"F", LF, 0},
{"F0", LFREG, 0}, {"F0", LFREG, arm.REG_F0},
{"F1", LFREG, 1}, {"F1", LFREG, arm.REG_F1},
{"F2", LFREG, 2}, {"F2", LFREG, arm.REG_F2},
{"F3", LFREG, 3}, {"F3", LFREG, arm.REG_F3},
{"F4", LFREG, 4}, {"F4", LFREG, arm.REG_F4},
{"F5", LFREG, 5}, {"F5", LFREG, arm.REG_F5},
{"F6", LFREG, 6}, {"F6", LFREG, arm.REG_F6},
{"F7", LFREG, 7}, {"F7", LFREG, arm.REG_F7},
{"F8", LFREG, 8}, {"F8", LFREG, arm.REG_F8},
{"F9", LFREG, 9}, {"F9", LFREG, arm.REG_F9},
{"F10", LFREG, 10}, {"F10", LFREG, arm.REG_F10},
{"F11", LFREG, 11}, {"F11", LFREG, arm.REG_F11},
{"F12", LFREG, 12}, {"F12", LFREG, arm.REG_F12},
{"F13", LFREG, 13}, {"F13", LFREG, arm.REG_F13},
{"F14", LFREG, 14}, {"F14", LFREG, arm.REG_F14},
{"F15", LFREG, 15}, {"F15", LFREG, arm.REG_F15},
{"C", LC, 0}, {"C", LC, 0},
{"C0", LCREG, 0}, {"C0", LCREG, 0},
{"C1", LCREG, 1}, {"C1", LCREG, 1},
@ -143,27 +145,27 @@ var lexinit = []asm.Lextab{
{"C13", LCREG, 13}, {"C13", LCREG, 13},
{"C14", LCREG, 14}, {"C14", LCREG, 14},
{"C15", LCREG, 15}, {"C15", LCREG, 15},
{"CPSR", LPSR, 0}, {"CPSR", LPSR, arm.REG_CPSR},
{"SPSR", LPSR, 1}, {"SPSR", LPSR, arm.REG_SPSR},
{"FPSR", LFCR, 0}, {"FPSR", LFCR, arm.REG_FPSR},
{"FPCR", LFCR, 1}, {"FPCR", LFCR, arm.REG_FPCR},
{".EQ", LCOND, 0}, {".EQ", LCOND, arm.C_SCOND_EQ},
{".NE", LCOND, 1}, {".NE", LCOND, arm.C_SCOND_NE},
{".CS", LCOND, 2}, {".CS", LCOND, arm.C_SCOND_HS},
{".HS", LCOND, 2}, {".HS", LCOND, arm.C_SCOND_HS},
{".CC", LCOND, 3}, {".CC", LCOND, arm.C_SCOND_LO},
{".LO", LCOND, 3}, {".LO", LCOND, arm.C_SCOND_LO},
{".MI", LCOND, 4}, {".MI", LCOND, arm.C_SCOND_MI},
{".PL", LCOND, 5}, {".PL", LCOND, arm.C_SCOND_PL},
{".VS", LCOND, 6}, {".VS", LCOND, arm.C_SCOND_VS},
{".VC", LCOND, 7}, {".VC", LCOND, arm.C_SCOND_VC},
{".HI", LCOND, 8}, {".HI", LCOND, arm.C_SCOND_HI},
{".LS", LCOND, 9}, {".LS", LCOND, arm.C_SCOND_LS},
{".GE", LCOND, 10}, {".GE", LCOND, arm.C_SCOND_GE},
{".LT", LCOND, 11}, {".LT", LCOND, arm.C_SCOND_LT},
{".GT", LCOND, 12}, {".GT", LCOND, arm.C_SCOND_GT},
{".LE", LCOND, 13}, {".LE", LCOND, arm.C_SCOND_LE},
{".AL", LCOND, Always}, {".AL", LCOND, arm.C_SCOND_NONE},
{".U", LS, arm.C_UBIT}, {".U", LS, arm.C_UBIT},
{".S", LS, arm.C_SBIT}, {".S", LS, arm.C_SBIT},
{".W", LS, arm.C_WBIT}, {".W", LS, arm.C_WBIT},
@ -274,33 +276,30 @@ var lexinit = []asm.Lextab{
{"MOVM", LTYPE8, arm.AMOVM}, {"MOVM", LTYPE8, arm.AMOVM},
{"SWPBU", LTYPE9, arm.ASWPBU}, {"SWPBU", LTYPE9, arm.ASWPBU},
{"SWPW", LTYPE9, arm.ASWPW}, {"SWPW", LTYPE9, arm.ASWPW},
{"RET", LTYPEA, arm.ARET}, {"RET", LTYPEA, obj.ARET},
{"RFE", LTYPEA, arm.ARFE}, {"RFE", LTYPEA, arm.ARFE},
{"TEXT", LTYPEB, arm.ATEXT}, {"TEXT", LTYPEB, obj.ATEXT},
{"GLOBL", LTYPEB, arm.AGLOBL}, {"GLOBL", LGLOBL, obj.AGLOBL},
{"DATA", LTYPEC, arm.ADATA}, {"DATA", LTYPEC, obj.ADATA},
{"CASE", LTYPED, arm.ACASE}, {"CASE", LTYPED, arm.ACASE},
{"END", LTYPEE, arm.AEND}, {"END", LTYPEE, obj.AEND},
{"WORD", LTYPEH, arm.AWORD}, {"WORD", LTYPEH, arm.AWORD},
{"NOP", LTYPEI, arm.ANOP}, {"NOP", LTYPEI, obj.ANOP},
{"MCR", LTYPEJ, 0}, {"MCR", LTYPEJ, 0},
{"MRC", LTYPEJ, 1}, {"MRC", LTYPEJ, 1},
{"PLD", LTYPEPLD, arm.APLD}, {"PLD", LTYPEPLD, arm.APLD},
{"UNDEF", LTYPEE, arm.AUNDEF}, {"UNDEF", LTYPEE, obj.AUNDEF},
{"CLZ", LTYPE2, arm.ACLZ}, {"CLZ", LTYPE2, arm.ACLZ},
{"MULWT", LTYPE1, arm.AMULWT}, {"MULWT", LTYPE1, arm.AMULWT},
{"MULWB", LTYPE1, arm.AMULWB}, {"MULWB", LTYPE1, arm.AMULWB},
{"MULAWT", LTYPEN, arm.AMULAWT}, {"MULAWT", LTYPEN, arm.AMULAWT},
{"MULAWB", LTYPEN, arm.AMULAWB}, {"MULAWB", LTYPEN, arm.AMULAWB},
{"USEFIELD", LTYPEN, arm.AUSEFIELD}, {"USEFIELD", LTYPEN, obj.AUSEFIELD},
{"PCDATA", LTYPEPC, arm.APCDATA}, {"PCDATA", LTYPEPC, obj.APCDATA},
{"FUNCDATA", LTYPEF, arm.AFUNCDATA}, {"FUNCDATA", LTYPEF, obj.AFUNCDATA},
} }
func cinit() { func cinit() {
nullgen.Type = arm.D_NONE
nullgen.Name = arm.D_NONE
nullgen.Reg = arm.NREG
} }
func isreg(g *obj.Addr) bool { func isreg(g *obj.Addr) bool {
@ -308,7 +307,7 @@ func isreg(g *obj.Addr) bool {
} }
func cclean() { func cclean() {
outcode(arm.AEND, Always, &nullgen, arm.NREG, &nullgen) outcode(obj.AEND, Always, &nullgen, 0, &nullgen)
} }
var bcode = []int{ var bcode = []int{
@ -327,7 +326,7 @@ var bcode = []int{
arm.ABGT, arm.ABGT,
arm.ABLE, arm.ABLE,
arm.AB, arm.AB,
arm.ANOP, obj.ANOP,
} }
var lastpc *obj.Prog var lastpc *obj.Prog
@ -338,7 +337,7 @@ func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
/* hack to make B.NE etc. work: turn it into the corresponding conditional */ /* hack to make B.NE etc. work: turn it into the corresponding conditional */
if a == arm.AB { if a == arm.AB {
a = int32(bcode[scond&0xf]) a = int32(bcode[(scond^arm.C_SCOND_XOR)&0xf])
scond = (scond &^ 0xf) | Always scond = (scond &^ 0xf) | Always
} }
@ -353,7 +352,7 @@ func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
p.Lineno = stmtline p.Lineno = stmtline
p.Scond = uint8(scond) p.Scond = uint8(scond)
p.From = *g1 p.From = *g1
p.Reg = uint8(reg) p.Reg = int16(reg)
p.To = *g2 p.To = *g2
p.Pc = int64(asm.PC) p.Pc = int64(asm.PC)
@ -366,7 +365,7 @@ func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
lastpc = p lastpc = p
out: out:
if a != arm.AGLOBL && a != arm.ADATA { if a != obj.AGLOBL && a != obj.ADATA {
asm.PC++ asm.PC++
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -61,11 +61,11 @@ import (
%token <dval> LFCONST %token <dval> LFCONST
%token <sval> LSCONST LSP %token <sval> LSCONST LSP
%token <sym> LNAME LLAB LVAR %token <sym> LNAME LLAB LVAR
%type <lval> con con2 expr pointer offset %type <lval> con expr pointer offset
%type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem %type <addr> mem imm textsize reg nam rel rem rim rom omem nmem
%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim %type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
%type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 %type <addr2> spec3 spec4 spec5 spec6 spec7 spec8 spec9
%type <addr2> spec10 spec11 spec12 spec13 %type <addr2> spec10 spec12 spec13
%% %%
prog: prog:
| prog | prog
@ -108,8 +108,8 @@ inst:
| LTYPE3 rimrem { outcode(int($1), &$2); } | LTYPE3 rimrem { outcode(int($1), &$2); }
| LTYPE4 remrim { outcode(int($1), &$2); } | LTYPE4 remrim { outcode(int($1), &$2); }
| LTYPER nonrel { outcode(int($1), &$2); } | LTYPER nonrel { outcode(int($1), &$2); }
| LTYPED spec1 { outcode(int($1), &$2); } | spec1
| LTYPET spec2 { outcode(int($1), &$2); } | spec2
| LTYPEC spec3 { outcode(int($1), &$2); } | LTYPEC spec3 { outcode(int($1), &$2); }
| LTYPEN spec4 { outcode(int($1), &$2); } | LTYPEN spec4 { outcode(int($1), &$2); }
| LTYPES spec5 { outcode(int($1), &$2); } | LTYPES spec5 { outcode(int($1), &$2); }
@ -118,7 +118,7 @@ inst:
| LTYPEXC spec8 { outcode(int($1), &$2); } | LTYPEXC spec8 { outcode(int($1), &$2); }
| LTYPEX spec9 { outcode(int($1), &$2); } | LTYPEX spec9 { outcode(int($1), &$2); }
| LTYPERT spec10 { outcode(int($1), &$2); } | LTYPERT spec10 { outcode(int($1), &$2); }
| LTYPEG spec11 { outcode(int($1), &$2); } | spec11
| LTYPEPC spec12 { outcode(int($1), &$2); } | LTYPEPC spec12 { outcode(int($1), &$2); }
| LTYPEF spec13 { outcode(int($1), &$2); } | LTYPEF spec13 { outcode(int($1), &$2); }
@ -189,26 +189,48 @@ nonrel:
} }
spec1: /* DATA */ spec1: /* DATA */
nam '/' con ',' imm LTYPED nam '/' con ',' imm
{ {
$$.from = $1; var a Addr2
$$.from.Scale = int8($3); a.from = $2
$$.to = $5; a.to = $6
outcode(obj.ADATA, &a)
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
} }
spec2: /* TEXT */ spec2: /* TEXT */
mem ',' imm2 LTYPET mem ',' '$' textsize
{ {
asm.Settext($1.Sym); asm.Settext($2.Sym);
$$.from = $1; outcode(obj.ATEXT, &Addr2{$2, $5})
$$.to = $3;
} }
| mem ',' con ',' imm2 | LTYPET mem ',' con ',' '$' textsize
{ {
asm.Settext($1.Sym); asm.Settext($2.Sym);
$$.from = $1; outcode(obj.ATEXT, &Addr2{$2, $7})
$$.from.Scale = int8($3); if asm.Pass > 1 {
$$.to = $5; lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
}
spec11: /* GLOBL */
LTYPEG mem ',' imm
{
asm.Settext($2.Sym)
outcode(obj.AGLOBL, &Addr2{$2, $4})
}
| LTYPEG mem ',' con ',' imm
{
asm.Settext($2.Sym)
outcode(obj.AGLOBL, &Addr2{$2, $6})
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
} }
spec3: /* JMP/CALL */ spec3: /* JMP/CALL */
@ -237,10 +259,10 @@ spec5: /* SHL/SHR */
{ {
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
if $$.from.Index != x86.D_NONE { if $$.from.Index != obj.TYPE_NONE {
yyerror("dp shift with lhs index"); yyerror("dp shift with lhs index");
} }
$$.from.Index = uint8($5); $$.from.Index = int16($5);
} }
spec6: /* MOVW/MOVL */ spec6: /* MOVW/MOVL */
@ -253,10 +275,10 @@ spec6: /* MOVW/MOVL */
{ {
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
if $$.to.Index != x86.D_NONE { if $$.to.Index != obj.TYPE_NONE {
yyerror("dp move with lhs index"); yyerror("dp move with lhs index");
} }
$$.to.Index = uint8($5); $$.to.Index = int16($5);
} }
spec7: spec7:
@ -289,7 +311,7 @@ spec9: /* shufl */
{ {
$$.from = $3; $$.from = $3;
$$.to = $5; $$.to = $5;
if $1.Type != x86.D_CONST { if $1.Type != obj.TYPE_CONST {
yyerror("illegal constant"); yyerror("illegal constant");
} }
$$.to.Offset = $1.Offset; $$.to.Offset = $1.Offset;
@ -306,23 +328,10 @@ spec10: /* RET/RETF */
$$.to = nullgen; $$.to = nullgen;
} }
spec11: /* GLOBL */
mem ',' imm
{
$$.from = $1;
$$.to = $3;
}
| mem ',' con ',' imm
{
$$.from = $1;
$$.from.Scale = int8($3);
$$.to = $5;
}
spec12: /* asm.PCDATA */ spec12: /* asm.PCDATA */
rim ',' rim rim ',' rim
{ {
if $1.Type != x86.D_CONST || $3.Type != x86.D_CONST { if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
yyerror("arguments to asm.PCDATA must be integer constants"); yyerror("arguments to asm.PCDATA must be integer constants");
} }
$$.from = $1; $$.from = $1;
@ -332,10 +341,10 @@ spec12: /* asm.PCDATA */
spec13: /* FUNCDATA */ spec13: /* FUNCDATA */
rim ',' rim rim ',' rim
{ {
if $1.Type != x86.D_CONST { if $1.Type != obj.TYPE_CONST {
yyerror("index for FUNCDATA must be integer constant"); yyerror("index for FUNCDATA must be integer constant");
} }
if $3.Type != x86.D_EXTERN && $3.Type != x86.D_STATIC { if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
yyerror("value for FUNCDATA must be symbol reference"); yyerror("value for FUNCDATA must be symbol reference");
} }
$$.from = $1; $$.from = $1;
@ -368,7 +377,7 @@ rel:
con '(' LPC ')' con '(' LPC ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_BRANCH; $$.Type = obj.TYPE_BRANCH;
$$.Offset = $1 + int64(asm.PC); $$.Offset = $1 + int64(asm.PC);
} }
| LNAME offset | LNAME offset
@ -378,7 +387,7 @@ rel:
if asm.Pass == 2 && $1.Type != LLAB { if asm.Pass == 2 && $1.Type != LLAB {
yyerror("undefined label: %s", $1.Labelname); yyerror("undefined label: %s", $1.Labelname);
} }
$$.Type = x86.D_BRANCH; $$.Type = obj.TYPE_BRANCH;
$$.Offset = $1.Value + $2; $$.Offset = $1.Value + $2;
} }
@ -386,58 +395,57 @@ reg:
LBREG LBREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LFREG | LFREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LLREG | LLREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LMREG | LMREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LSP | LSP
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_SP; $$.Type = obj.TYPE_REG
$$.Reg = x86.REG_SP;
} }
| LSREG | LSREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LXREG | LXREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
} $$.Reg = int16($1);
imm2:
'$' con2
{
$$ = nullgen;
$$.Type = x86.D_CONST;
$$.Offset = $2;
} }
imm: imm:
'$' con '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_CONST; $$.Type = obj.TYPE_CONST;
$$.Offset = $2; $$.Offset = $2;
} }
| '$' nam | '$' nam
{ {
$$ = $2; $$ = $2;
$$.Index = uint8($2.Type); $$.Type = obj.TYPE_ADDR;
$$.Type = x86.D_ADDR;
/* /*
if($2.Type == x86.D_AUTO || $2.Type == x86.D_PARAM) if($2.Type == x86.D_AUTO || $2.Type == x86.D_PARAM)
yyerror("constant cannot be automatic: %s", yyerror("constant cannot be automatic: %s",
@ -447,31 +455,31 @@ imm:
| '$' LSCONST | '$' LSCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_SCONST; $$.Type = obj.TYPE_SCONST;
$$.U.Sval = ($2+"\x00\x00\x00\x00\x00\x00\x00\x00")[:8] $$.U.Sval = ($2+"\x00\x00\x00\x00\x00\x00\x00\x00")[:8]
} }
| '$' LFCONST | '$' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = $2; $$.U.Dval = $2;
} }
| '$' '(' LFCONST ')' | '$' '(' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = $3; $$.U.Dval = $3;
} }
| '$' '(' '-' LFCONST ')' | '$' '(' '-' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = -$4; $$.U.Dval = -$4;
} }
| '$' '-' LFCONST | '$' '-' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = -$3; $$.U.Dval = -$3;
} }
@ -483,77 +491,85 @@ omem:
con con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_INDIR+x86.D_NONE; $$.Type = obj.TYPE_MEM
$$.Offset = $1; $$.Offset = $1;
} }
| con '(' LLREG ')' | con '(' LLREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+$3); $$.Type = obj.TYPE_MEM
$$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
} }
| con '(' LSP ')' | con '(' LSP ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+x86.D_SP); $$.Type = obj.TYPE_MEM
$$.Reg = x86.REG_SP
$$.Offset = $1; $$.Offset = $1;
} }
| con '(' LSREG ')' | con '(' LSREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+$3); $$.Type = obj.TYPE_MEM
$$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
} }
| con '(' LLREG '*' con ')' | con '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+x86.D_NONE); $$.Type = obj.TYPE_MEM
$$.Offset = $1; $$.Offset = $1;
$$.Index = uint8($3); $$.Index = int16($3);
$$.Scale = int8($5); $$.Scale = int8($5);
checkscale($$.Scale); checkscale($$.Scale);
} }
| con '(' LLREG ')' '(' LLREG '*' con ')' | con '(' LLREG ')' '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+$3); $$.Type = obj.TYPE_MEM
$$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
$$.Index = uint8($6); $$.Index = int16($6);
$$.Scale = int8($8); $$.Scale = int8($8);
checkscale($$.Scale); checkscale($$.Scale);
} }
| con '(' LLREG ')' '(' LSREG '*' con ')' | con '(' LLREG ')' '(' LSREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+$3); $$.Type = obj.TYPE_MEM
$$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
$$.Index = uint8($6); $$.Index = int16($6);
$$.Scale = int8($8); $$.Scale = int8($8);
checkscale($$.Scale); checkscale($$.Scale);
} }
| '(' LLREG ')' | '(' LLREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+$2); $$.Type = obj.TYPE_MEM
$$.Reg = int16($2)
} }
| '(' LSP ')' | '(' LSP ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+x86.D_SP); $$.Type = obj.TYPE_MEM
$$.Reg = x86.REG_SP
} }
| '(' LLREG '*' con ')' | '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+x86.D_NONE); $$.Type = obj.TYPE_MEM
$$.Index = uint8($2); $$.Index = int16($2);
$$.Scale = int8($4); $$.Scale = int8($4);
checkscale($$.Scale); checkscale($$.Scale);
} }
| '(' LLREG ')' '(' LLREG '*' con ')' | '(' LLREG ')' '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(x86.D_INDIR+$2); $$.Type = obj.TYPE_MEM
$$.Index = uint8($5); $$.Reg = int16($2)
$$.Index = int16($5);
$$.Scale = int8($7); $$.Scale = int8($7);
checkscale($$.Scale); checkscale($$.Scale);
} }
@ -566,7 +582,7 @@ nmem:
| nam '(' LLREG '*' con ')' | nam '(' LLREG '*' con ')'
{ {
$$ = $1; $$ = $1;
$$.Index = uint8($3); $$.Index = int16($3);
$$.Scale = int8($5); $$.Scale = int8($5);
checkscale($$.Scale); checkscale($$.Scale);
} }
@ -575,14 +591,16 @@ nam:
LNAME offset '(' pointer ')' LNAME offset '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($4); $$.Type = obj.TYPE_MEM
$$.Name = int8($4)
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0); $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
$$.Offset = $2; $$.Offset = $2;
} }
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = x86.D_STATIC; $$.Type = obj.TYPE_MEM
$$.Name = obj.NAME_STATIC
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1); $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
$$.Offset = $4; $$.Offset = $4;
} }
@ -604,7 +622,7 @@ pointer:
LSB LSB
| LSP | LSP
{ {
$$ = x86.D_AUTO; $$ = obj.NAME_AUTO;
} }
| LFP | LFP
@ -631,22 +649,34 @@ con:
$$ = $2; $$ = $2;
} }
con2: textsize:
LCONST LCONST
{ {
$$ = int64(uint64($1 & 0xffffffff) + (obj.ArgsSizeUnknown<<32)) $$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = $1;
$$.U.Argsize = obj.ArgsSizeUnknown;
} }
| '-' LCONST | '-' LCONST
{ {
$$ = int64(uint64(-$2 & 0xffffffff) + (obj.ArgsSizeUnknown<<32)) $$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -$2;
$$.U.Argsize = obj.ArgsSizeUnknown;
} }
| LCONST '-' LCONST | LCONST '-' LCONST
{ {
$$ = ($1 & 0xffffffff) + (($3 & 0xffff) << 32); $$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = $1;
$$.U.Argsize = int32($3);
} }
| '-' LCONST '-' LCONST | '-' LCONST '-' LCONST
{ {
$$ = (-$2 & 0xffffffff) + (($4 & 0xffff) << 32); $$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -$2;
$$.U.Argsize = int32($4);
} }
expr: expr:

View File

@ -89,124 +89,125 @@ func yyparse() {
} }
var lexinit = []asm.Lextab{ var lexinit = []asm.Lextab{
{"SP", LSP, x86.D_AUTO}, {"SP", LSP, obj.NAME_AUTO},
{"SB", LSB, x86.D_EXTERN}, {"SB", LSB, obj.NAME_EXTERN},
{"FP", LFP, x86.D_PARAM}, {"FP", LFP, obj.NAME_PARAM},
{"PC", LPC, x86.D_BRANCH}, {"PC", LPC, obj.TYPE_BRANCH},
{"AL", LBREG, x86.D_AL},
{"CL", LBREG, x86.D_CL},
{"DL", LBREG, x86.D_DL},
{"BL", LBREG, x86.D_BL},
/* "SPB", LBREG, D_SPB, */
{"SIB", LBREG, x86.D_SIB},
{"DIB", LBREG, x86.D_DIB},
{"BPB", LBREG, x86.D_BPB},
{"R8B", LBREG, x86.D_R8B},
{"R9B", LBREG, x86.D_R9B},
{"R10B", LBREG, x86.D_R10B},
{"R11B", LBREG, x86.D_R11B},
{"R12B", LBREG, x86.D_R12B},
{"R13B", LBREG, x86.D_R13B},
{"R14B", LBREG, x86.D_R14B},
{"R15B", LBREG, x86.D_R15B},
{"AH", LBREG, x86.D_AH},
{"CH", LBREG, x86.D_CH},
{"DH", LBREG, x86.D_DH},
{"BH", LBREG, x86.D_BH},
{"AX", LLREG, x86.D_AX},
{"CX", LLREG, x86.D_CX},
{"DX", LLREG, x86.D_DX},
{"BX", LLREG, x86.D_BX},
/* "SP", LLREG, D_SP, */ {"AL", LBREG, x86.REG_AL},
{"BP", LLREG, x86.D_BP}, {"CL", LBREG, x86.REG_CL},
{"SI", LLREG, x86.D_SI}, {"DL", LBREG, x86.REG_DL},
{"DI", LLREG, x86.D_DI}, {"BL", LBREG, x86.REG_BL},
{"R8", LLREG, x86.D_R8}, /* "SPB", LBREG, REG_SPB, */
{"R9", LLREG, x86.D_R9}, {"SIB", LBREG, x86.REG_SIB},
{"R10", LLREG, x86.D_R10}, {"DIB", LBREG, x86.REG_DIB},
{"R11", LLREG, x86.D_R11}, {"BPB", LBREG, x86.REG_BPB},
{"R12", LLREG, x86.D_R12}, {"R8B", LBREG, x86.REG_R8B},
{"R13", LLREG, x86.D_R13}, {"R9B", LBREG, x86.REG_R9B},
{"R14", LLREG, x86.D_R14}, {"R10B", LBREG, x86.REG_R10B},
{"R15", LLREG, x86.D_R15}, {"R11B", LBREG, x86.REG_R11B},
{"R12B", LBREG, x86.REG_R12B},
{"R13B", LBREG, x86.REG_R13B},
{"R14B", LBREG, x86.REG_R14B},
{"R15B", LBREG, x86.REG_R15B},
{"AH", LBREG, x86.REG_AH},
{"CH", LBREG, x86.REG_CH},
{"DH", LBREG, x86.REG_DH},
{"BH", LBREG, x86.REG_BH},
{"AX", LLREG, x86.REG_AX},
{"CX", LLREG, x86.REG_CX},
{"DX", LLREG, x86.REG_DX},
{"BX", LLREG, x86.REG_BX},
/* "SP", LLREG, REG_SP, */
{"BP", LLREG, x86.REG_BP},
{"SI", LLREG, x86.REG_SI},
{"DI", LLREG, x86.REG_DI},
{"R8", LLREG, x86.REG_R8},
{"R9", LLREG, x86.REG_R9},
{"R10", LLREG, x86.REG_R10},
{"R11", LLREG, x86.REG_R11},
{"R12", LLREG, x86.REG_R12},
{"R13", LLREG, x86.REG_R13},
{"R14", LLREG, x86.REG_R14},
{"R15", LLREG, x86.REG_R15},
{"RARG", LLREG, x86.REGARG}, {"RARG", LLREG, x86.REGARG},
{"F0", LFREG, x86.D_F0 + 0}, {"F0", LFREG, x86.REG_F0 + 0},
{"F1", LFREG, x86.D_F0 + 1}, {"F1", LFREG, x86.REG_F0 + 1},
{"F2", LFREG, x86.D_F0 + 2}, {"F2", LFREG, x86.REG_F0 + 2},
{"F3", LFREG, x86.D_F0 + 3}, {"F3", LFREG, x86.REG_F0 + 3},
{"F4", LFREG, x86.D_F0 + 4}, {"F4", LFREG, x86.REG_F0 + 4},
{"F5", LFREG, x86.D_F0 + 5}, {"F5", LFREG, x86.REG_F0 + 5},
{"F6", LFREG, x86.D_F0 + 6}, {"F6", LFREG, x86.REG_F0 + 6},
{"F7", LFREG, x86.D_F0 + 7}, {"F7", LFREG, x86.REG_F0 + 7},
{"M0", LMREG, x86.D_M0 + 0}, {"M0", LMREG, x86.REG_M0 + 0},
{"M1", LMREG, x86.D_M0 + 1}, {"M1", LMREG, x86.REG_M0 + 1},
{"M2", LMREG, x86.D_M0 + 2}, {"M2", LMREG, x86.REG_M0 + 2},
{"M3", LMREG, x86.D_M0 + 3}, {"M3", LMREG, x86.REG_M0 + 3},
{"M4", LMREG, x86.D_M0 + 4}, {"M4", LMREG, x86.REG_M0 + 4},
{"M5", LMREG, x86.D_M0 + 5}, {"M5", LMREG, x86.REG_M0 + 5},
{"M6", LMREG, x86.D_M0 + 6}, {"M6", LMREG, x86.REG_M0 + 6},
{"M7", LMREG, x86.D_M0 + 7}, {"M7", LMREG, x86.REG_M0 + 7},
{"X0", LXREG, x86.D_X0 + 0}, {"X0", LXREG, x86.REG_X0 + 0},
{"X1", LXREG, x86.D_X0 + 1}, {"X1", LXREG, x86.REG_X0 + 1},
{"X2", LXREG, x86.D_X0 + 2}, {"X2", LXREG, x86.REG_X0 + 2},
{"X3", LXREG, x86.D_X0 + 3}, {"X3", LXREG, x86.REG_X0 + 3},
{"X4", LXREG, x86.D_X0 + 4}, {"X4", LXREG, x86.REG_X0 + 4},
{"X5", LXREG, x86.D_X0 + 5}, {"X5", LXREG, x86.REG_X0 + 5},
{"X6", LXREG, x86.D_X0 + 6}, {"X6", LXREG, x86.REG_X0 + 6},
{"X7", LXREG, x86.D_X0 + 7}, {"X7", LXREG, x86.REG_X0 + 7},
{"X8", LXREG, x86.D_X0 + 8}, {"X8", LXREG, x86.REG_X0 + 8},
{"X9", LXREG, x86.D_X0 + 9}, {"X9", LXREG, x86.REG_X0 + 9},
{"X10", LXREG, x86.D_X0 + 10}, {"X10", LXREG, x86.REG_X0 + 10},
{"X11", LXREG, x86.D_X0 + 11}, {"X11", LXREG, x86.REG_X0 + 11},
{"X12", LXREG, x86.D_X0 + 12}, {"X12", LXREG, x86.REG_X0 + 12},
{"X13", LXREG, x86.D_X0 + 13}, {"X13", LXREG, x86.REG_X0 + 13},
{"X14", LXREG, x86.D_X0 + 14}, {"X14", LXREG, x86.REG_X0 + 14},
{"X15", LXREG, x86.D_X0 + 15}, {"X15", LXREG, x86.REG_X0 + 15},
{"CS", LSREG, x86.D_CS}, {"CS", LSREG, x86.REG_CS},
{"SS", LSREG, x86.D_SS}, {"SS", LSREG, x86.REG_SS},
{"DS", LSREG, x86.D_DS}, {"DS", LSREG, x86.REG_DS},
{"ES", LSREG, x86.D_ES}, {"ES", LSREG, x86.REG_ES},
{"FS", LSREG, x86.D_FS}, {"FS", LSREG, x86.REG_FS},
{"GS", LSREG, x86.D_GS}, {"GS", LSREG, x86.REG_GS},
{"GDTR", LBREG, x86.D_GDTR}, {"GDTR", LBREG, x86.REG_GDTR},
{"IDTR", LBREG, x86.D_IDTR}, {"IDTR", LBREG, x86.REG_IDTR},
{"LDTR", LBREG, x86.D_LDTR}, {"LDTR", LBREG, x86.REG_LDTR},
{"MSW", LBREG, x86.D_MSW}, {"MSW", LBREG, x86.REG_MSW},
{"TASK", LBREG, x86.D_TASK}, {"TASK", LBREG, x86.REG_TASK},
{"CR0", LBREG, x86.D_CR + 0}, {"CR0", LBREG, x86.REG_CR + 0},
{"CR1", LBREG, x86.D_CR + 1}, {"CR1", LBREG, x86.REG_CR + 1},
{"CR2", LBREG, x86.D_CR + 2}, {"CR2", LBREG, x86.REG_CR + 2},
{"CR3", LBREG, x86.D_CR + 3}, {"CR3", LBREG, x86.REG_CR + 3},
{"CR4", LBREG, x86.D_CR + 4}, {"CR4", LBREG, x86.REG_CR + 4},
{"CR5", LBREG, x86.D_CR + 5}, {"CR5", LBREG, x86.REG_CR + 5},
{"CR6", LBREG, x86.D_CR + 6}, {"CR6", LBREG, x86.REG_CR + 6},
{"CR7", LBREG, x86.D_CR + 7}, {"CR7", LBREG, x86.REG_CR + 7},
{"CR8", LBREG, x86.D_CR + 8}, {"CR8", LBREG, x86.REG_CR + 8},
{"CR9", LBREG, x86.D_CR + 9}, {"CR9", LBREG, x86.REG_CR + 9},
{"CR10", LBREG, x86.D_CR + 10}, {"CR10", LBREG, x86.REG_CR + 10},
{"CR11", LBREG, x86.D_CR + 11}, {"CR11", LBREG, x86.REG_CR + 11},
{"CR12", LBREG, x86.D_CR + 12}, {"CR12", LBREG, x86.REG_CR + 12},
{"CR13", LBREG, x86.D_CR + 13}, {"CR13", LBREG, x86.REG_CR + 13},
{"CR14", LBREG, x86.D_CR + 14}, {"CR14", LBREG, x86.REG_CR + 14},
{"CR15", LBREG, x86.D_CR + 15}, {"CR15", LBREG, x86.REG_CR + 15},
{"DR0", LBREG, x86.D_DR + 0}, {"DR0", LBREG, x86.REG_DR + 0},
{"DR1", LBREG, x86.D_DR + 1}, {"DR1", LBREG, x86.REG_DR + 1},
{"DR2", LBREG, x86.D_DR + 2}, {"DR2", LBREG, x86.REG_DR + 2},
{"DR3", LBREG, x86.D_DR + 3}, {"DR3", LBREG, x86.REG_DR + 3},
{"DR4", LBREG, x86.D_DR + 4}, {"DR4", LBREG, x86.REG_DR + 4},
{"DR5", LBREG, x86.D_DR + 5}, {"DR5", LBREG, x86.REG_DR + 5},
{"DR6", LBREG, x86.D_DR + 6}, {"DR6", LBREG, x86.REG_DR + 6},
{"DR7", LBREG, x86.D_DR + 7}, {"DR7", LBREG, x86.REG_DR + 7},
{"TR0", LBREG, x86.D_TR + 0}, {"TR0", LBREG, x86.REG_TR + 0},
{"TR1", LBREG, x86.D_TR + 1}, {"TR1", LBREG, x86.REG_TR + 1},
{"TR2", LBREG, x86.D_TR + 2}, {"TR2", LBREG, x86.REG_TR + 2},
{"TR3", LBREG, x86.D_TR + 3}, {"TR3", LBREG, x86.REG_TR + 3},
{"TR4", LBREG, x86.D_TR + 4}, {"TR4", LBREG, x86.REG_TR + 4},
{"TR5", LBREG, x86.D_TR + 5}, {"TR5", LBREG, x86.REG_TR + 5},
{"TR6", LBREG, x86.D_TR + 6}, {"TR6", LBREG, x86.REG_TR + 6},
{"TR7", LBREG, x86.D_TR + 7}, {"TR7", LBREG, x86.REG_TR + 7},
{"TLS", LSREG, x86.D_TLS}, {"TLS", LSREG, x86.REG_TLS},
{"AAA", LTYPE0, x86.AAAA}, {"AAA", LTYPE0, x86.AAAA},
{"AAD", LTYPE0, x86.AAAD}, {"AAD", LTYPE0, x86.AAAD},
{"AAM", LTYPE0, x86.AAAM}, {"AAM", LTYPE0, x86.AAAM},
@ -248,7 +249,7 @@ var lexinit = []asm.Lextab{
{"BTSW", LTYPE3, x86.ABTSW}, {"BTSW", LTYPE3, x86.ABTSW},
{"BTW", LTYPE3, x86.ABTW}, {"BTW", LTYPE3, x86.ABTW},
{"BYTE", LTYPE2, x86.ABYTE}, {"BYTE", LTYPE2, x86.ABYTE},
{"CALL", LTYPEC, x86.ACALL}, {"CALL", LTYPEC, obj.ACALL},
{"CLC", LTYPE0, x86.ACLC}, {"CLC", LTYPE0, x86.ACLC},
{"CLD", LTYPE0, x86.ACLD}, {"CLD", LTYPE0, x86.ACLD},
{"CLI", LTYPE0, x86.ACLI}, {"CLI", LTYPE0, x86.ACLI},
@ -270,7 +271,7 @@ var lexinit = []asm.Lextab{
{"CPUID", LTYPE0, x86.ACPUID}, {"CPUID", LTYPE0, x86.ACPUID},
{"DAA", LTYPE0, x86.ADAA}, {"DAA", LTYPE0, x86.ADAA},
{"DAS", LTYPE0, x86.ADAS}, {"DAS", LTYPE0, x86.ADAS},
{"DATA", LTYPED, x86.ADATA}, {"DATA", LTYPED, obj.ADATA},
{"DECB", LTYPE1, x86.ADECB}, {"DECB", LTYPE1, x86.ADECB},
{"DECL", LTYPE1, x86.ADECL}, {"DECL", LTYPE1, x86.ADECL},
{"DECQ", LTYPE1, x86.ADECQ}, {"DECQ", LTYPE1, x86.ADECQ},
@ -280,9 +281,9 @@ var lexinit = []asm.Lextab{
{"DIVQ", LTYPE2, x86.ADIVQ}, {"DIVQ", LTYPE2, x86.ADIVQ},
{"DIVW", LTYPE2, x86.ADIVW}, {"DIVW", LTYPE2, x86.ADIVW},
{"EMMS", LTYPE0, x86.AEMMS}, {"EMMS", LTYPE0, x86.AEMMS},
{"END", LTYPE0, x86.AEND}, {"END", LTYPE0, obj.AEND},
{"ENTER", LTYPE2, x86.AENTER}, {"ENTER", LTYPE2, x86.AENTER},
{"GLOBL", LTYPEG, x86.AGLOBL}, {"GLOBL", LTYPEG, obj.AGLOBL},
{"HLT", LTYPE0, x86.AHLT}, {"HLT", LTYPE0, x86.AHLT},
{"IDIVB", LTYPE2, x86.AIDIVB}, {"IDIVB", LTYPE2, x86.AIDIVB},
{"IDIVL", LTYPE2, x86.AIDIVL}, {"IDIVL", LTYPE2, x86.AIDIVL},
@ -357,7 +358,7 @@ var lexinit = []asm.Lextab{
{"JNLE", LTYPER, x86.AJGT}, /* alternate */ {"JNLE", LTYPER, x86.AJGT}, /* alternate */
{"JCXZL", LTYPER, x86.AJCXZL}, {"JCXZL", LTYPER, x86.AJCXZL},
{"JCXZQ", LTYPER, x86.AJCXZQ}, {"JCXZQ", LTYPER, x86.AJCXZQ},
{"JMP", LTYPEC, x86.AJMP}, {"JMP", LTYPEC, obj.AJMP},
{"LAHF", LTYPE0, x86.ALAHF}, {"LAHF", LTYPE0, x86.ALAHF},
{"LARL", LTYPE3, x86.ALARL}, {"LARL", LTYPE3, x86.ALARL},
{"LARW", LTYPE3, x86.ALARW}, {"LARW", LTYPE3, x86.ALARW},
@ -412,7 +413,7 @@ var lexinit = []asm.Lextab{
{"NEGL", LTYPE1, x86.ANEGL}, {"NEGL", LTYPE1, x86.ANEGL},
{"NEGQ", LTYPE1, x86.ANEGQ}, {"NEGQ", LTYPE1, x86.ANEGQ},
{"NEGW", LTYPE1, x86.ANEGW}, {"NEGW", LTYPE1, x86.ANEGW},
{"NOP", LTYPEN, x86.ANOP}, {"NOP", LTYPEN, obj.ANOP},
{"NOTB", LTYPE1, x86.ANOTB}, {"NOTB", LTYPE1, x86.ANOTB},
{"NOTL", LTYPE1, x86.ANOTL}, {"NOTL", LTYPE1, x86.ANOTL},
{"NOTQ", LTYPE1, x86.ANOTQ}, {"NOTQ", LTYPE1, x86.ANOTQ},
@ -457,7 +458,7 @@ var lexinit = []asm.Lextab{
{"RDTSC", LTYPE0, x86.ARDTSC}, {"RDTSC", LTYPE0, x86.ARDTSC},
{"REP", LTYPE0, x86.AREP}, {"REP", LTYPE0, x86.AREP},
{"REPN", LTYPE0, x86.AREPN}, {"REPN", LTYPE0, x86.AREPN},
{"RET", LTYPE0, x86.ARET}, {"RET", LTYPE0, obj.ARET},
{"RETFL", LTYPERT, x86.ARETFL}, {"RETFL", LTYPERT, x86.ARETFL},
{"RETFW", LTYPERT, x86.ARETFW}, {"RETFW", LTYPERT, x86.ARETFW},
{"RETFQ", LTYPERT, x86.ARETFQ}, {"RETFQ", LTYPERT, x86.ARETFQ},
@ -533,7 +534,7 @@ var lexinit = []asm.Lextab{
{"TESTL", LTYPE3, x86.ATESTL}, {"TESTL", LTYPE3, x86.ATESTL},
{"TESTQ", LTYPE3, x86.ATESTQ}, {"TESTQ", LTYPE3, x86.ATESTQ},
{"TESTW", LTYPE3, x86.ATESTW}, {"TESTW", LTYPE3, x86.ATESTW},
{"TEXT", LTYPET, x86.ATEXT}, {"TEXT", LTYPET, obj.ATEXT},
{"VERR", LTYPE2, x86.AVERR}, {"VERR", LTYPE2, x86.AVERR},
{"VERW", LTYPE2, x86.AVERW}, {"VERW", LTYPE2, x86.AVERW},
{"QUAD", LTYPE2, x86.AQUAD}, {"QUAD", LTYPE2, x86.AQUAD},
@ -900,7 +901,7 @@ var lexinit = []asm.Lextab{
{"PREFETCHT1", LTYPE2, x86.APREFETCHT1}, {"PREFETCHT1", LTYPE2, x86.APREFETCHT1},
{"PREFETCHT2", LTYPE2, x86.APREFETCHT2}, {"PREFETCHT2", LTYPE2, x86.APREFETCHT2},
{"PREFETCHNTA", LTYPE2, x86.APREFETCHNTA}, {"PREFETCHNTA", LTYPE2, x86.APREFETCHNTA},
{"UNDEF", LTYPE0, x86.AUNDEF}, {"UNDEF", LTYPE0, obj.AUNDEF},
{"AESENC", LTYPE3, x86.AAESENC}, {"AESENC", LTYPE3, x86.AAESENC},
{"AESENCLAST", LTYPE3, x86.AAESENCLAST}, {"AESENCLAST", LTYPE3, x86.AAESENCLAST},
{"AESDEC", LTYPE3, x86.AAESDEC}, {"AESDEC", LTYPE3, x86.AAESDEC},
@ -908,15 +909,13 @@ var lexinit = []asm.Lextab{
{"AESIMC", LTYPE3, x86.AAESIMC}, {"AESIMC", LTYPE3, x86.AAESIMC},
{"AESKEYGENASSIST", LTYPEX, x86.AAESKEYGENASSIST}, {"AESKEYGENASSIST", LTYPEX, x86.AAESKEYGENASSIST},
{"PSHUFD", LTYPEX, x86.APSHUFD}, {"PSHUFD", LTYPEX, x86.APSHUFD},
{"USEFIELD", LTYPEN, x86.AUSEFIELD}, {"USEFIELD", LTYPEN, obj.AUSEFIELD},
{"PCLMULQDQ", LTYPEX, x86.APCLMULQDQ}, {"PCLMULQDQ", LTYPEX, x86.APCLMULQDQ},
{"PCDATA", LTYPEPC, x86.APCDATA}, {"PCDATA", LTYPEPC, obj.APCDATA},
{"FUNCDATA", LTYPEF, x86.AFUNCDATA}, {"FUNCDATA", LTYPEF, obj.AFUNCDATA},
} }
func cinit() { func cinit() {
nullgen.Type = x86.D_NONE
nullgen.Index = x86.D_NONE
} }
func checkscale(scale int8) { func checkscale(scale int8) {
@ -936,7 +935,7 @@ func cclean() {
g2.from = nullgen g2.from = nullgen
g2.to = nullgen g2.to = nullgen
outcode(x86.AEND, &g2) outcode(obj.AEND, &g2)
} }
var lastpc *obj.Prog var lastpc *obj.Prog
@ -973,7 +972,7 @@ func outcode(a int, g2 *Addr2) {
lastpc = p lastpc = p
out: out:
if a != x86.AGLOBL && a != x86.ADATA { if a != obj.AGLOBL && a != obj.ADATA {
asm.PC++ asm.PC++
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -65,10 +65,9 @@ import (
%token <sval> LSCONST LSP %token <sval> LSCONST LSP
%token <sym> LNAME LLAB LVAR %token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset %type <lval> con expr pointer offset
%type <con2> con2 %type <addr> mem imm reg nam rel rem rim rom omem nmem textsize
%type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim %type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
%type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12 %type <addr2> spec3 spec4 spec5 spec6 spec7 spec9 spec10 spec11 spec12
%% %%
prog: prog:
| prog | prog
@ -111,14 +110,14 @@ inst:
| LTYPE3 rimrem { outcode(int($1), &$2); } | LTYPE3 rimrem { outcode(int($1), &$2); }
| LTYPE4 remrim { outcode(int($1), &$2); } | LTYPE4 remrim { outcode(int($1), &$2); }
| LTYPER nonrel { outcode(int($1), &$2); } | LTYPER nonrel { outcode(int($1), &$2); }
| LTYPED spec1 { outcode(int($1), &$2); } | spec1
| LTYPET spec2 { outcode(int($1), &$2); } | spec2
| LTYPEC spec3 { outcode(int($1), &$2); } | LTYPEC spec3 { outcode(int($1), &$2); }
| LTYPEN spec4 { outcode(int($1), &$2); } | LTYPEN spec4 { outcode(int($1), &$2); }
| LTYPES spec5 { outcode(int($1), &$2); } | LTYPES spec5 { outcode(int($1), &$2); }
| LTYPEM spec6 { outcode(int($1), &$2); } | LTYPEM spec6 { outcode(int($1), &$2); }
| LTYPEI spec7 { outcode(int($1), &$2); } | LTYPEI spec7 { outcode(int($1), &$2); }
| LTYPEG spec8 { outcode(int($1), &$2); } | spec8
| LTYPEXC spec9 { outcode(int($1), &$2); } | LTYPEXC spec9 { outcode(int($1), &$2); }
| LTYPEX spec10 { outcode(int($1), &$2); } | LTYPEX spec10 { outcode(int($1), &$2); }
| LTYPEPC spec11 { outcode(int($1), &$2); } | LTYPEPC spec11 { outcode(int($1), &$2); }
@ -191,28 +190,48 @@ nonrel:
} }
spec1: /* DATA */ spec1: /* DATA */
nam '/' con ',' imm LTYPED nam '/' con ',' imm
{ {
$$.from = $1; outcode(obj.ADATA, &Addr2{$2, $6})
$$.from.Scale = int8($3); if asm.Pass > 1 {
$$.to = $5; lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
} }
spec2: /* TEXT */ spec2: /* TEXT */
mem ',' imm2 LTYPET mem ',' '$' textsize
{ {
asm.Settext($1.Sym); asm.Settext($2.Sym);
$$.from = $1; outcode(obj.ATEXT, &Addr2{$2, $5})
$$.to = $3;
} }
| mem ',' con ',' imm2 | LTYPET mem ',' con ',' '$' textsize
{ {
asm.Settext($1.Sym); asm.Settext($2.Sym);
$$.from = $1; outcode(obj.ATEXT, &Addr2{$2, $7})
$$.from.Scale = int8($3); if asm.Pass > 1 {
$$.to = $5; lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
} }
spec8: /* GLOBL */
LTYPEG mem ',' imm
{
asm.Settext($2.Sym);
outcode(obj.AGLOBL, &Addr2{$2, $4})
}
| LTYPEG mem ',' con ',' imm
{
asm.Settext($2.Sym);
outcode(obj.AGLOBL, &Addr2{$2, $6})
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
}
spec3: /* JMP/CALL */ spec3: /* JMP/CALL */
',' rom ',' rom
{ {
@ -228,8 +247,7 @@ spec3: /* JMP/CALL */
{ {
$$.from = nullgen; $$.from = nullgen;
$$.to = $2; $$.to = $2;
$$.to.Index = uint8($2.Type) $$.to.Type = obj.TYPE_INDIR
$$.to.Type = D_INDIR+D_ADDR;
} }
spec4: /* NOP */ spec4: /* NOP */
@ -246,10 +264,10 @@ spec5: /* SHL/SHR */
{ {
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
if $$.from.Index != D_NONE { if $$.from.Index != obj.TYPE_NONE {
yyerror("dp shift with lhs index"); yyerror("dp shift with lhs index");
} }
$$.from.Index = uint8($5); $$.from.Index = int16($5);
} }
spec6: /* MOVW/MOVL */ spec6: /* MOVW/MOVL */
@ -262,10 +280,10 @@ spec6: /* MOVW/MOVL */
{ {
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
if $$.to.Index != D_NONE { if $$.to.Index != obj.TYPE_NONE {
yyerror("dp move with lhs index"); yyerror("dp move with lhs index");
} }
$$.to.Index = uint8($5); $$.to.Index = int16($5);
} }
spec7: spec7:
@ -285,19 +303,6 @@ spec7:
$$.to = $3; $$.to = $3;
} }
spec8: /* GLOBL */
mem ',' imm
{
$$.from = $1;
$$.to = $3;
}
| mem ',' con ',' imm
{
$$.from = $1;
$$.from.Scale = int8($3);
$$.to = $5;
}
spec9: /* CMPPS/CMPPD */ spec9: /* CMPPS/CMPPD */
reg ',' rem ',' con reg ',' rem ',' con
{ {
@ -311,7 +316,7 @@ spec10: /* PINSRD */
{ {
$$.from = $3; $$.from = $3;
$$.to = $5; $$.to = $5;
if $1.Type != D_CONST { if $1.Type != obj.TYPE_CONST {
yyerror("illegal constant") yyerror("illegal constant")
} }
$$.to.Offset = $1.Offset; $$.to.Offset = $1.Offset;
@ -320,7 +325,7 @@ spec10: /* PINSRD */
spec11: /* PCDATA */ spec11: /* PCDATA */
rim ',' rim rim ',' rim
{ {
if $1.Type != D_CONST || $3.Type != D_CONST { if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
yyerror("arguments to PCDATA must be integer constants"); yyerror("arguments to PCDATA must be integer constants");
} }
$$.from = $1; $$.from = $1;
@ -330,10 +335,10 @@ spec11: /* PCDATA */
spec12: /* FUNCDATA */ spec12: /* FUNCDATA */
rim ',' rim rim ',' rim
{ {
if $1.Type != D_CONST { if $1.Type != obj.TYPE_CONST {
yyerror("index for FUNCDATA must be integer constant"); yyerror("index for FUNCDATA must be integer constant");
} }
if $3.Type != D_EXTERN && $3.Type != D_STATIC { if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
yyerror("value for FUNCDATA must be symbol reference"); yyerror("value for FUNCDATA must be symbol reference");
} }
$$.from = $1; $$.from = $1;
@ -367,7 +372,7 @@ rel:
con '(' LPC ')' con '(' LPC ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_BRANCH; $$.Type = obj.TYPE_BRANCH;
$$.Offset = $1 + int64(asm.PC); $$.Offset = $1 + int64(asm.PC);
} }
| LNAME offset | LNAME offset
@ -377,7 +382,7 @@ rel:
if asm.Pass == 2 && $1.Type != LLAB { if asm.Pass == 2 && $1.Type != LLAB {
yyerror("undefined label: %s", $1.Labelname); yyerror("undefined label: %s", $1.Labelname);
} }
$$.Type = D_BRANCH; $$.Type = obj.TYPE_BRANCH;
$$.Offset = $1.Value + $2; $$.Offset = $1.Value + $2;
} }
@ -385,46 +390,51 @@ reg:
LBREG LBREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LFREG | LFREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LLREG | LLREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LXREG | LXREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
| LSP | LSP
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SP; $$.Type = obj.TYPE_REG
$$.Reg = REG_SP;
} }
| LSREG | LSREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Reg = int16($1);
} }
imm: imm:
'$' con '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_CONST; $$.Type = obj.TYPE_CONST;
$$.Offset = $2; $$.Offset = $2;
} }
| '$' nam | '$' nam
{ {
$$ = $2; $$ = $2;
$$.Index = uint8($2.Type); $$.Type = obj.TYPE_ADDR
$$.Type = D_ADDR;
/* /*
if($2.Type == D_AUTO || $2.Type == D_PARAM) if($2.Type == D_AUTO || $2.Type == D_PARAM)
yyerror("constant cannot be automatic: %s", yyerror("constant cannot be automatic: %s",
@ -434,65 +444,65 @@ imm:
| '$' LSCONST | '$' LSCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SCONST; $$.Type = obj.TYPE_SCONST;
$$.U.Sval = $2 $$.U.Sval = $2
} }
| '$' LFCONST | '$' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = $2; $$.U.Dval = $2;
} }
| '$' '(' LFCONST ')' | '$' '(' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = $3; $$.U.Dval = $3;
} }
| '$' '(' '-' LFCONST ')' | '$' '(' '-' LFCONST ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = -$4; $$.U.Dval = -$4;
} }
| '$' '-' LFCONST | '$' '-' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = -$3; $$.U.Dval = -$3;
} }
imm2: textsize:
'$' con2
{
$$ = nullgen;
$$.Type = D_CONST2;
$$.Offset = int64($2.v1);
$$.Offset2 = int32($2.v2);
}
con2:
LCONST LCONST
{ {
$$.v1 = int32($1); $$ = nullgen;
$$.v2 = -obj.ArgsSizeUnknown $$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = $1;
$$.U.Argsize = obj.ArgsSizeUnknown;
} }
| '-' LCONST | '-' LCONST
{ {
$$.v1 = int32(-$2); $$ = nullgen;
$$.v2 = -obj.ArgsSizeUnknown; $$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -$2;
$$.U.Argsize = obj.ArgsSizeUnknown;
} }
| LCONST '-' LCONST | LCONST '-' LCONST
{ {
$$.v1 = int32($1); $$ = nullgen;
$$.v2 = int32($3); $$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = $1;
$$.U.Argsize = int32($3);
} }
| '-' LCONST '-' LCONST | '-' LCONST '-' LCONST
{ {
$$.v1 = int32(-$2); $$ = nullgen;
$$.v2 = int32($4); $$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -$2;
$$.U.Argsize = int32($4);
} }
mem: mem:
omem omem
| nmem | nmem
@ -501,77 +511,85 @@ omem:
con con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_INDIR+D_NONE; $$.Type = obj.TYPE_MEM
$$.Offset = $1; $$.Offset = $1;
} }
| con '(' LLREG ')' | con '(' LLREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(D_INDIR+$3); $$.Type = obj.TYPE_MEM
$$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
} }
| con '(' LSP ')' | con '(' LSP ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_INDIR+D_SP; $$.Type = obj.TYPE_MEM
$$.Reg = REG_SP
$$.Offset = $1; $$.Offset = $1;
} }
| con '(' LLREG '*' con ')' | con '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_INDIR+D_NONE; $$.Type = obj.TYPE_MEM
$$.Offset = $1; $$.Offset = $1;
$$.Index = uint8($3); $$.Index = int16($3);
$$.Scale = int8($5); $$.Scale = int8($5);
checkscale($$.Scale); checkscale($$.Scale);
} }
| con '(' LLREG ')' '(' LLREG '*' con ')' | con '(' LLREG ')' '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(D_INDIR+$3); $$.Type = obj.TYPE_MEM
$$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
$$.Index = uint8($6); $$.Index = int16($6);
$$.Scale = int8($8); $$.Scale = int8($8);
checkscale($$.Scale); checkscale($$.Scale);
} }
| con '(' LLREG ')' '(' LSREG '*' con ')' | con '(' LLREG ')' '(' LSREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(D_INDIR+$3); $$.Type = obj.TYPE_MEM
$$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
$$.Index = uint8($6); $$.Index = int16($6);
$$.Scale = int8($8); $$.Scale = int8($8);
checkscale($$.Scale); checkscale($$.Scale);
} }
| '(' LLREG ')' | '(' LLREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(D_INDIR+$2); $$.Type = obj.TYPE_MEM
$$.Reg = int16($2);
} }
| '(' LSP ')' | '(' LSP ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_INDIR+D_SP; $$.Type = obj.TYPE_MEM
$$.Reg = REG_SP
} }
| con '(' LSREG ')' | con '(' LSREG ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(D_INDIR+$3); $$.Type = obj.TYPE_MEM
$$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
} }
| '(' LLREG '*' con ')' | '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_INDIR+D_NONE; $$.Type = obj.TYPE_MEM
$$.Index = uint8($2); $$.Index = int16($2);
$$.Scale = int8($4); $$.Scale = int8($4);
checkscale($$.Scale); checkscale($$.Scale);
} }
| '(' LLREG ')' '(' LLREG '*' con ')' | '(' LLREG ')' '(' LLREG '*' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16(D_INDIR+$2); $$.Type = obj.TYPE_MEM
$$.Index = uint8($5); $$.Reg = int16($2)
$$.Index = int16($5);
$$.Scale = int8($7); $$.Scale = int8($7);
checkscale($$.Scale); checkscale($$.Scale);
} }
@ -584,7 +602,7 @@ nmem:
| nam '(' LLREG '*' con ')' | nam '(' LLREG '*' con ')'
{ {
$$ = $1; $$ = $1;
$$.Index = uint8($3); $$.Index = int16($3);
$$.Scale = int8($5); $$.Scale = int8($5);
checkscale($$.Scale); checkscale($$.Scale);
} }
@ -593,14 +611,16 @@ nam:
LNAME offset '(' pointer ')' LNAME offset '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = int16($4); $$.Type = obj.TYPE_MEM
$$.Name = int8($4);
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0); $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
$$.Offset = $2; $$.Offset = $2;
} }
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_STATIC; $$.Type = obj.TYPE_MEM
$$.Name = obj.NAME_STATIC
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1); $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
$$.Offset = $4; $$.Offset = $4;
} }
@ -622,7 +642,7 @@ pointer:
LSB LSB
| LSP | LSP
{ {
$$ = D_AUTO; $$ = obj.NAME_AUTO;
} }
| LFP | LFP

View File

@ -86,78 +86,78 @@ func yyparse() {
} }
var lexinit = []asm.Lextab{ var lexinit = []asm.Lextab{
{"SP", LSP, i386.D_AUTO}, {"SP", LSP, obj.NAME_AUTO},
{"SB", LSB, i386.D_EXTERN}, {"SB", LSB, obj.NAME_EXTERN},
{"FP", LFP, i386.D_PARAM}, {"FP", LFP, obj.NAME_PARAM},
{"PC", LPC, i386.D_BRANCH}, {"PC", LPC, obj.TYPE_BRANCH},
{"AL", LBREG, i386.D_AL}, {"AL", LBREG, i386.REG_AL},
{"CL", LBREG, i386.D_CL}, {"CL", LBREG, i386.REG_CL},
{"DL", LBREG, i386.D_DL}, {"DL", LBREG, i386.REG_DL},
{"BL", LBREG, i386.D_BL}, {"BL", LBREG, i386.REG_BL},
{"AH", LBREG, i386.D_AH}, {"AH", LBREG, i386.REG_AH},
{"CH", LBREG, i386.D_CH}, {"CH", LBREG, i386.REG_CH},
{"DH", LBREG, i386.D_DH}, {"DH", LBREG, i386.REG_DH},
{"BH", LBREG, i386.D_BH}, {"BH", LBREG, i386.REG_BH},
{"AX", LLREG, i386.D_AX}, {"AX", LLREG, i386.REG_AX},
{"CX", LLREG, i386.D_CX}, {"CX", LLREG, i386.REG_CX},
{"DX", LLREG, i386.D_DX}, {"DX", LLREG, i386.REG_DX},
{"BX", LLREG, i386.D_BX}, {"BX", LLREG, i386.REG_BX},
/* "SP", LLREG, D_SP, */ /* "SP", LLREG, REG_SP, */
{"BP", LLREG, i386.D_BP}, {"BP", LLREG, i386.REG_BP},
{"SI", LLREG, i386.D_SI}, {"SI", LLREG, i386.REG_SI},
{"DI", LLREG, i386.D_DI}, {"DI", LLREG, i386.REG_DI},
{"F0", LFREG, i386.D_F0 + 0}, {"F0", LFREG, i386.REG_F0 + 0},
{"F1", LFREG, i386.D_F0 + 1}, {"F1", LFREG, i386.REG_F0 + 1},
{"F2", LFREG, i386.D_F0 + 2}, {"F2", LFREG, i386.REG_F0 + 2},
{"F3", LFREG, i386.D_F0 + 3}, {"F3", LFREG, i386.REG_F0 + 3},
{"F4", LFREG, i386.D_F0 + 4}, {"F4", LFREG, i386.REG_F0 + 4},
{"F5", LFREG, i386.D_F0 + 5}, {"F5", LFREG, i386.REG_F0 + 5},
{"F6", LFREG, i386.D_F0 + 6}, {"F6", LFREG, i386.REG_F0 + 6},
{"F7", LFREG, i386.D_F0 + 7}, {"F7", LFREG, i386.REG_F0 + 7},
{"X0", LXREG, i386.D_X0 + 0}, {"X0", LXREG, i386.REG_X0 + 0},
{"X1", LXREG, i386.D_X0 + 1}, {"X1", LXREG, i386.REG_X0 + 1},
{"X2", LXREG, i386.D_X0 + 2}, {"X2", LXREG, i386.REG_X0 + 2},
{"X3", LXREG, i386.D_X0 + 3}, {"X3", LXREG, i386.REG_X0 + 3},
{"X4", LXREG, i386.D_X0 + 4}, {"X4", LXREG, i386.REG_X0 + 4},
{"X5", LXREG, i386.D_X0 + 5}, {"X5", LXREG, i386.REG_X0 + 5},
{"X6", LXREG, i386.D_X0 + 6}, {"X6", LXREG, i386.REG_X0 + 6},
{"X7", LXREG, i386.D_X0 + 7}, {"X7", LXREG, i386.REG_X0 + 7},
{"CS", LSREG, i386.D_CS}, {"CS", LSREG, i386.REG_CS},
{"SS", LSREG, i386.D_SS}, {"SS", LSREG, i386.REG_SS},
{"DS", LSREG, i386.D_DS}, {"DS", LSREG, i386.REG_DS},
{"ES", LSREG, i386.D_ES}, {"ES", LSREG, i386.REG_ES},
{"FS", LSREG, i386.D_FS}, {"FS", LSREG, i386.REG_FS},
{"GS", LSREG, i386.D_GS}, {"GS", LSREG, i386.REG_GS},
{"TLS", LSREG, i386.D_TLS}, {"TLS", LSREG, i386.REG_TLS},
{"GDTR", LBREG, i386.D_GDTR}, {"GDTR", LBREG, i386.REG_GDTR},
{"IDTR", LBREG, i386.D_IDTR}, {"IDTR", LBREG, i386.REG_IDTR},
{"LDTR", LBREG, i386.D_LDTR}, {"LDTR", LBREG, i386.REG_LDTR},
{"MSW", LBREG, i386.D_MSW}, {"MSW", LBREG, i386.REG_MSW},
{"TASK", LBREG, i386.D_TASK}, {"TASK", LBREG, i386.REG_TASK},
{"CR0", LBREG, i386.D_CR + 0}, {"CR0", LBREG, i386.REG_CR + 0},
{"CR1", LBREG, i386.D_CR + 1}, {"CR1", LBREG, i386.REG_CR + 1},
{"CR2", LBREG, i386.D_CR + 2}, {"CR2", LBREG, i386.REG_CR + 2},
{"CR3", LBREG, i386.D_CR + 3}, {"CR3", LBREG, i386.REG_CR + 3},
{"CR4", LBREG, i386.D_CR + 4}, {"CR4", LBREG, i386.REG_CR + 4},
{"CR5", LBREG, i386.D_CR + 5}, {"CR5", LBREG, i386.REG_CR + 5},
{"CR6", LBREG, i386.D_CR + 6}, {"CR6", LBREG, i386.REG_CR + 6},
{"CR7", LBREG, i386.D_CR + 7}, {"CR7", LBREG, i386.REG_CR + 7},
{"DR0", LBREG, i386.D_DR + 0}, {"DR0", LBREG, i386.REG_DR + 0},
{"DR1", LBREG, i386.D_DR + 1}, {"DR1", LBREG, i386.REG_DR + 1},
{"DR2", LBREG, i386.D_DR + 2}, {"DR2", LBREG, i386.REG_DR + 2},
{"DR3", LBREG, i386.D_DR + 3}, {"DR3", LBREG, i386.REG_DR + 3},
{"DR4", LBREG, i386.D_DR + 4}, {"DR4", LBREG, i386.REG_DR + 4},
{"DR5", LBREG, i386.D_DR + 5}, {"DR5", LBREG, i386.REG_DR + 5},
{"DR6", LBREG, i386.D_DR + 6}, {"DR6", LBREG, i386.REG_DR + 6},
{"DR7", LBREG, i386.D_DR + 7}, {"DR7", LBREG, i386.REG_DR + 7},
{"TR0", LBREG, i386.D_TR + 0}, {"TR0", LBREG, i386.REG_TR + 0},
{"TR1", LBREG, i386.D_TR + 1}, {"TR1", LBREG, i386.REG_TR + 1},
{"TR2", LBREG, i386.D_TR + 2}, {"TR2", LBREG, i386.REG_TR + 2},
{"TR3", LBREG, i386.D_TR + 3}, {"TR3", LBREG, i386.REG_TR + 3},
{"TR4", LBREG, i386.D_TR + 4}, {"TR4", LBREG, i386.REG_TR + 4},
{"TR5", LBREG, i386.D_TR + 5}, {"TR5", LBREG, i386.REG_TR + 5},
{"TR6", LBREG, i386.D_TR + 6}, {"TR6", LBREG, i386.REG_TR + 6},
{"TR7", LBREG, i386.D_TR + 7}, {"TR7", LBREG, i386.REG_TR + 7},
{"AAA", LTYPE0, i386.AAAA}, {"AAA", LTYPE0, i386.AAAA},
{"AAD", LTYPE0, i386.AAAD}, {"AAD", LTYPE0, i386.AAAD},
{"AAM", LTYPE0, i386.AAAM}, {"AAM", LTYPE0, i386.AAAM},
@ -189,7 +189,7 @@ var lexinit = []asm.Lextab{
{"BTSW", LTYPE3, i386.ABTSW}, {"BTSW", LTYPE3, i386.ABTSW},
{"BTW", LTYPE3, i386.ABTW}, {"BTW", LTYPE3, i386.ABTW},
{"BYTE", LTYPE2, i386.ABYTE}, {"BYTE", LTYPE2, i386.ABYTE},
{"CALL", LTYPEC, i386.ACALL}, {"CALL", LTYPEC, obj.ACALL},
{"CLC", LTYPE0, i386.ACLC}, {"CLC", LTYPE0, i386.ACLC},
{"CLD", LTYPE0, i386.ACLD}, {"CLD", LTYPE0, i386.ACLD},
{"CLI", LTYPE0, i386.ACLI}, {"CLI", LTYPE0, i386.ACLI},
@ -208,16 +208,16 @@ var lexinit = []asm.Lextab{
{"CPUID", LTYPE0, i386.ACPUID}, {"CPUID", LTYPE0, i386.ACPUID},
{"DAA", LTYPE0, i386.ADAA}, {"DAA", LTYPE0, i386.ADAA},
{"DAS", LTYPE0, i386.ADAS}, {"DAS", LTYPE0, i386.ADAS},
{"DATA", LTYPED, i386.ADATA}, {"DATA", LTYPED, obj.ADATA},
{"DECB", LTYPE1, i386.ADECB}, {"DECB", LTYPE1, i386.ADECB},
{"DECL", LTYPE1, i386.ADECL}, {"DECL", LTYPE1, i386.ADECL},
{"DECW", LTYPE1, i386.ADECW}, {"DECW", LTYPE1, i386.ADECW},
{"DIVB", LTYPE2, i386.ADIVB}, {"DIVB", LTYPE2, i386.ADIVB},
{"DIVL", LTYPE2, i386.ADIVL}, {"DIVL", LTYPE2, i386.ADIVL},
{"DIVW", LTYPE2, i386.ADIVW}, {"DIVW", LTYPE2, i386.ADIVW},
{"END", LTYPE0, i386.AEND}, {"END", LTYPE0, obj.AEND},
{"ENTER", LTYPE2, i386.AENTER}, {"ENTER", LTYPE2, i386.AENTER},
{"GLOBL", LTYPEG, i386.AGLOBL}, {"GLOBL", LTYPEG, obj.AGLOBL},
{"HLT", LTYPE0, i386.AHLT}, {"HLT", LTYPE0, i386.AHLT},
{"IDIVB", LTYPE2, i386.AIDIVB}, {"IDIVB", LTYPE2, i386.AIDIVB},
{"IDIVL", LTYPE2, i386.AIDIVL}, {"IDIVL", LTYPE2, i386.AIDIVL},
@ -285,7 +285,7 @@ var lexinit = []asm.Lextab{
{"JNLE", LTYPER, i386.AJGT}, /* alternate */ {"JNLE", LTYPER, i386.AJGT}, /* alternate */
{"JCXZL", LTYPER, i386.AJCXZL}, {"JCXZL", LTYPER, i386.AJCXZL},
{"JCXZW", LTYPER, i386.AJCXZW}, {"JCXZW", LTYPER, i386.AJCXZW},
{"JMP", LTYPEC, i386.AJMP}, {"JMP", LTYPEC, obj.AJMP},
{"LAHF", LTYPE0, i386.ALAHF}, {"LAHF", LTYPE0, i386.ALAHF},
{"LARL", LTYPE3, i386.ALARL}, {"LARL", LTYPE3, i386.ALARL},
{"LARW", LTYPE3, i386.ALARW}, {"LARW", LTYPE3, i386.ALARW},
@ -322,7 +322,7 @@ var lexinit = []asm.Lextab{
{"NEGB", LTYPE1, i386.ANEGB}, {"NEGB", LTYPE1, i386.ANEGB},
{"NEGL", LTYPE1, i386.ANEGL}, {"NEGL", LTYPE1, i386.ANEGL},
{"NEGW", LTYPE1, i386.ANEGW}, {"NEGW", LTYPE1, i386.ANEGW},
{"NOP", LTYPEN, i386.ANOP}, {"NOP", LTYPEN, obj.ANOP},
{"NOTB", LTYPE1, i386.ANOTB}, {"NOTB", LTYPE1, i386.ANOTB},
{"NOTL", LTYPE1, i386.ANOTL}, {"NOTL", LTYPE1, i386.ANOTL},
{"NOTW", LTYPE1, i386.ANOTW}, {"NOTW", LTYPE1, i386.ANOTW},
@ -358,7 +358,7 @@ var lexinit = []asm.Lextab{
{"RDTSC", LTYPE0, i386.ARDTSC}, {"RDTSC", LTYPE0, i386.ARDTSC},
{"REP", LTYPE0, i386.AREP}, {"REP", LTYPE0, i386.AREP},
{"REPN", LTYPE0, i386.AREPN}, {"REPN", LTYPE0, i386.AREPN},
{"RET", LTYPE0, i386.ARET}, {"RET", LTYPE0, obj.ARET},
{"ROLB", LTYPE3, i386.AROLB}, {"ROLB", LTYPE3, i386.AROLB},
{"ROLL", LTYPE3, i386.AROLL}, {"ROLL", LTYPE3, i386.AROLL},
{"ROLW", LTYPE3, i386.AROLW}, {"ROLW", LTYPE3, i386.AROLW},
@ -415,7 +415,7 @@ var lexinit = []asm.Lextab{
{"TESTB", LTYPE3, i386.ATESTB}, {"TESTB", LTYPE3, i386.ATESTB},
{"TESTL", LTYPE3, i386.ATESTL}, {"TESTL", LTYPE3, i386.ATESTL},
{"TESTW", LTYPE3, i386.ATESTW}, {"TESTW", LTYPE3, i386.ATESTW},
{"TEXT", LTYPET, i386.ATEXT}, {"TEXT", LTYPET, obj.ATEXT},
{"VERR", LTYPE2, i386.AVERR}, {"VERR", LTYPE2, i386.AVERR},
{"VERW", LTYPE2, i386.AVERW}, {"VERW", LTYPE2, i386.AVERW},
{"WAIT", LTYPE0, i386.AWAIT}, {"WAIT", LTYPE0, i386.AWAIT},
@ -579,7 +579,7 @@ var lexinit = []asm.Lextab{
{"PREFETCHT1", LTYPE2, i386.APREFETCHT1}, {"PREFETCHT1", LTYPE2, i386.APREFETCHT1},
{"PREFETCHT2", LTYPE2, i386.APREFETCHT2}, {"PREFETCHT2", LTYPE2, i386.APREFETCHT2},
{"PREFETCHNTA", LTYPE2, i386.APREFETCHNTA}, {"PREFETCHNTA", LTYPE2, i386.APREFETCHNTA},
{"UNDEF", LTYPE0, i386.AUNDEF}, {"UNDEF", LTYPE0, obj.AUNDEF},
{"ADDPD", LTYPE3, i386.AADDPD}, {"ADDPD", LTYPE3, i386.AADDPD},
{"ADDPS", LTYPE3, i386.AADDPS}, {"ADDPS", LTYPE3, i386.AADDPS},
{"ADDSD", LTYPE3, i386.AADDSD}, {"ADDSD", LTYPE3, i386.AADDSD},
@ -696,14 +696,14 @@ var lexinit = []asm.Lextab{
{"UNPCKLPS", LTYPE3, i386.AUNPCKLPS}, {"UNPCKLPS", LTYPE3, i386.AUNPCKLPS},
{"XORPD", LTYPE3, i386.AXORPD}, {"XORPD", LTYPE3, i386.AXORPD},
{"XORPS", LTYPE3, i386.AXORPS}, {"XORPS", LTYPE3, i386.AXORPS},
{"USEFIELD", LTYPEN, i386.AUSEFIELD}, {"USEFIELD", LTYPEN, obj.AUSEFIELD},
{"PCDATA", LTYPEPC, i386.APCDATA}, {"PCDATA", LTYPEPC, obj.APCDATA},
{"FUNCDATA", LTYPEF, i386.AFUNCDATA}, {"FUNCDATA", LTYPEF, obj.AFUNCDATA},
} }
func cinit() { func cinit() {
nullgen.Type = i386.D_NONE nullgen.Type = i386.REG_NONE
nullgen.Index = i386.D_NONE nullgen.Index = i386.REG_NONE
} }
func checkscale(scale int8) { func checkscale(scale int8) {
@ -728,7 +728,7 @@ func cclean() {
g2.from = nullgen g2.from = nullgen
g2.to = nullgen g2.to = nullgen
outcode(i386.AEND, &g2) outcode(obj.AEND, &g2)
} }
var lastpc *obj.Prog var lastpc *obj.Prog
@ -765,7 +765,7 @@ func outcode(a int, g2 *Addr2) {
lastpc = p lastpc = p
out: out:
if a != i386.AGLOBL && a != i386.ADATA { if a != obj.AGLOBL && a != obj.ADATA {
asm.PC++ asm.PC++
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,7 @@ import (
%left '*' '/' '%' %left '*' '/' '%'
%token <lval> LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP %token <lval> LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
%token <lval> LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW %token <lval> LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
%token <lval> LNOP LEND LRETT LWORD LTEXT LDATA LRETRN %token <lval> LNOP LEND LRETT LWORD LTEXT LDATA LGLOBL LRETRN
%token <lval> LCONST LSP LSB LFP LPC LCREG LFLUSH %token <lval> LCONST LSP LSB LFP LPC LCREG LFLUSH
%token <lval> LREG LFREG LR LCR LF LFPSCR %token <lval> LREG LFREG LR LCR LF LFPSCR
%token <lval> LLR LCTR LSPR LSPREG LSEG LMSR %token <lval> LLR LCTR LSPR LSPREG LSEG LMSR
@ -64,8 +64,8 @@ import (
%token <sval> LSCONST %token <sval> LSCONST
%token <sym> LNAME LLAB LVAR %token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset sreg %type <lval> con expr pointer offset sreg
%type <addr> addr rreg regaddr name creg freg xlreg lr ctr %type <addr> addr rreg regaddr name creg freg xlreg lr ctr textsize
%type <addr> imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask %type <addr> imm ximm fimm rel psr lcr cbit fpscr msr mask
%% %%
prog: prog:
| prog line | prog line
@ -107,107 +107,103 @@ inst:
*/ */
LMOVW rreg ',' rreg LMOVW rreg ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW addr ',' rreg | LMOVW addr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW regaddr ',' rreg | LMOVW regaddr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVB rreg ',' rreg | LMOVB rreg ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVB addr ',' rreg | LMOVB addr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVB regaddr ',' rreg | LMOVB regaddr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* load floats * load floats
*/ */
| LFMOV addr ',' freg | LFMOV addr ',' freg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LFMOV regaddr ',' freg | LFMOV regaddr ',' freg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LFMOV fimm ',' freg | LFMOV fimm ',' freg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LFMOV freg ',' freg | LFMOV freg ',' freg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LFMOV freg ',' addr | LFMOV freg ',' addr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LFMOV freg ',' regaddr | LFMOV freg ',' regaddr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* store ints and bytes * store ints and bytes
*/ */
| LMOVW rreg ',' addr | LMOVW rreg ',' addr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW rreg ',' regaddr | LMOVW rreg ',' regaddr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVB rreg ',' addr | LMOVB rreg ',' addr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVB rreg ',' regaddr | LMOVB rreg ',' regaddr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* store floats * store floats
*/ */
| LMOVW freg ',' addr | LMOVW freg ',' addr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW freg ',' regaddr | LMOVW freg ',' regaddr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* floating point status * floating point status
*/ */
| LMOVW fpscr ',' freg | LMOVW fpscr ',' freg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW freg ',' fpscr | LMOVW freg ',' fpscr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW freg ',' imm ',' fpscr | LMOVW freg ',' imm ',' fpscr
{ {
outgcode(int($1), &$2, NREG, &$4, &$6); outgcode(int($1), &$2, 0, &$4, &$6);
} }
| LMOVW fpscr ',' creg | LMOVW fpscr ',' creg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
}
| LMOVW imm ',' fpscrf
{
outcode(int($1), &$2, NREG, &$4);
} }
| LMTFSB imm ',' con | LMTFSB imm ',' con
{ {
@ -218,15 +214,15 @@ inst:
*/ */
| LMOVW rreg ',' imm ',' lcr | LMOVW rreg ',' imm ',' lcr
{ {
outgcode(int($1), &$2, NREG, &$4, &$6); outgcode(int($1), &$2, 0, &$4, &$6);
} }
| LMOVW rreg ',' creg | LMOVW rreg ',' creg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW rreg ',' lcr | LMOVW rreg ',' lcr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* integer operations * integer operations
@ -244,15 +240,15 @@ inst:
} }
| LADDW rreg ',' imm ',' rreg | LADDW rreg ',' imm ',' rreg
{ {
outgcode(int($1), &$2, NREG, &$4, &$6); outgcode(int($1), &$2, 0, &$4, &$6);
} }
| LADDW rreg ',' rreg | LADDW rreg ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LADDW imm ',' rreg | LADDW imm ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LLOGW rreg ',' sreg ',' rreg | LLOGW rreg ',' sreg ',' rreg
{ {
@ -260,7 +256,7 @@ inst:
} }
| LLOGW rreg ',' rreg | LLOGW rreg ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LSHW rreg ',' sreg ',' rreg | LSHW rreg ',' sreg ',' rreg
{ {
@ -268,7 +264,7 @@ inst:
} }
| LSHW rreg ',' rreg | LSHW rreg ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LSHW imm ',' sreg ',' rreg | LSHW imm ',' sreg ',' rreg
{ {
@ -276,15 +272,15 @@ inst:
} }
| LSHW imm ',' rreg | LSHW imm ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LABS rreg ',' rreg | LABS rreg ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LABS rreg | LABS rreg
{ {
outcode(int($1), &$2, NREG, &$2); outcode(int($1), &$2, 0, &$2);
} }
/* /*
* multiply-accumulate * multiply-accumulate
@ -298,11 +294,11 @@ inst:
*/ */
| LMOVW imm ',' rreg | LMOVW imm ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW ximm ',' rreg | LMOVW ximm ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* condition register operations * condition register operations
@ -321,35 +317,35 @@ inst:
*/ */
| LMOVW creg ',' creg | LMOVW creg ',' creg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW psr ',' creg | LMOVW psr ',' creg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW lcr ',' rreg | LMOVW lcr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW psr ',' rreg | LMOVW psr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW xlreg ',' rreg | LMOVW xlreg ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW rreg ',' xlreg | LMOVW rreg ',' xlreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW creg ',' psr | LMOVW creg ',' psr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVW rreg ',' psr | LMOVW rreg ',' psr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* branch, branch conditional * branch, branch conditional
@ -358,39 +354,39 @@ inst:
*/ */
| LBRA rel | LBRA rel
{ {
outcode(int($1), &nullgen, NREG, &$2); outcode(int($1), &nullgen, 0, &$2);
} }
| LBRA addr | LBRA addr
{ {
outcode(int($1), &nullgen, NREG, &$2); outcode(int($1), &nullgen, 0, &$2);
} }
| LBRA '(' xlreg ')' | LBRA '(' xlreg ')'
{ {
outcode(int($1), &nullgen, NREG, &$3); outcode(int($1), &nullgen, 0, &$3);
} }
| LBRA ',' rel | LBRA ',' rel
{ {
outcode(int($1), &nullgen, NREG, &$3); outcode(int($1), &nullgen, 0, &$3);
} }
| LBRA ',' addr | LBRA ',' addr
{ {
outcode(int($1), &nullgen, NREG, &$3); outcode(int($1), &nullgen, 0, &$3);
} }
| LBRA ',' '(' xlreg ')' | LBRA ',' '(' xlreg ')'
{ {
outcode(int($1), &nullgen, NREG, &$4); outcode(int($1), &nullgen, 0, &$4);
} }
| LBRA creg ',' rel | LBRA creg ',' rel
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LBRA creg ',' addr | LBRA creg ',' addr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LBRA creg ',' '(' xlreg ')' | LBRA creg ',' '(' xlreg ')'
{ {
outcode(int($1), &$2, NREG, &$5); outcode(int($1), &$2, 0, &$5);
} }
| LBRA con ',' rel | LBRA con ',' rel
{ {
@ -408,25 +404,25 @@ inst:
{ {
var g obj.Addr var g obj.Addr
g = nullgen; g = nullgen;
g.Type = D_CONST; g.Type = obj.TYPE_CONST;
g.Offset = $2; g.Offset = $2;
outcode(int($1), &g, int($4), &$6); outcode(int($1), &g, int(REG_R0+$4), &$6);
} }
| LBRA con ',' con ',' addr | LBRA con ',' con ',' addr
{ {
var g obj.Addr var g obj.Addr
g = nullgen; g = nullgen;
g.Type = D_CONST; g.Type = obj.TYPE_CONST;
g.Offset = $2; g.Offset = $2;
outcode(int($1), &g, int($4), &$6); outcode(int($1), &g, int(REG_R0+$4), &$6);
} }
| LBRA con ',' con ',' '(' xlreg ')' | LBRA con ',' con ',' '(' xlreg ')'
{ {
var g obj.Addr var g obj.Addr
g = nullgen; g = nullgen;
g.Type = D_CONST; g.Type = obj.TYPE_CONST;
g.Offset = $2; g.Offset = $2;
outcode(int($1), &g, int($4), &$7); outcode(int($1), &g, int(REG_R0+$4), &$7);
} }
/* /*
* conditional trap * conditional trap
@ -441,22 +437,22 @@ inst:
} }
| LTRAP rreg comma | LTRAP rreg comma
{ {
outcode(int($1), &$2, NREG, &nullgen); outcode(int($1), &$2, 0, &nullgen);
} }
| LTRAP comma | LTRAP comma
{ {
outcode(int($1), &nullgen, NREG, &nullgen); outcode(int($1), &nullgen, 0, &nullgen);
} }
/* /*
* floating point operate * floating point operate
*/ */
| LFCONV freg ',' freg | LFCONV freg ',' freg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LFADD freg ',' freg | LFADD freg ',' freg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LFADD freg ',' freg ',' freg | LFADD freg ',' freg ',' freg
{ {
@ -468,7 +464,7 @@ inst:
} }
| LFCMP freg ',' freg | LFCMP freg ',' freg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LFCMP freg ',' freg ',' creg | LFCMP freg ',' freg ',' creg
{ {
@ -479,11 +475,11 @@ inst:
*/ */
| LCMP rreg ',' rreg | LCMP rreg ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LCMP rreg ',' imm | LCMP rreg ',' imm
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LCMP rreg ',' rreg ',' creg | LCMP rreg ',' rreg ',' creg
{ {
@ -517,11 +513,11 @@ inst:
*/ */
| LMOVMW addr ',' rreg | LMOVMW addr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LMOVMW rreg ',' addr | LMOVMW rreg ',' addr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* various indexed load/store * various indexed load/store
@ -529,150 +525,175 @@ inst:
*/ */
| LXLD regaddr ',' rreg | LXLD regaddr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LXLD regaddr ',' imm ',' rreg | LXLD regaddr ',' imm ',' rreg
{ {
outgcode(int($1), &$2, NREG, &$4, &$6); outgcode(int($1), &$2, 0, &$4, &$6);
} }
| LXST rreg ',' regaddr | LXST rreg ',' regaddr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LXST rreg ',' imm ',' regaddr | LXST rreg ',' imm ',' regaddr
{ {
outgcode(int($1), &$2, NREG, &$4, &$6); outgcode(int($1), &$2, 0, &$4, &$6);
} }
| LXMV regaddr ',' rreg | LXMV regaddr ',' rreg
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LXMV rreg ',' regaddr | LXMV rreg ',' regaddr
{ {
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
| LXOP regaddr | LXOP regaddr
{ {
outcode(int($1), &$2, NREG, &nullgen); outcode(int($1), &$2, 0, &nullgen);
} }
/* /*
* NOP * NOP
*/ */
| LNOP comma | LNOP comma
{ {
outcode(int($1), &nullgen, NREG, &nullgen); outcode(int($1), &nullgen, 0, &nullgen);
} }
| LNOP rreg comma | LNOP rreg comma
{ {
outcode(int($1), &$2, NREG, &nullgen); outcode(int($1), &$2, 0, &nullgen);
} }
| LNOP freg comma | LNOP freg comma
{ {
outcode(int($1), &$2, NREG, &nullgen); outcode(int($1), &$2, 0, &nullgen);
} }
| LNOP ',' rreg | LNOP ',' rreg
{ {
outcode(int($1), &nullgen, NREG, &$3); outcode(int($1), &nullgen, 0, &$3);
} }
| LNOP ',' freg | LNOP ',' freg
{ {
outcode(int($1), &nullgen, NREG, &$3); outcode(int($1), &nullgen, 0, &$3);
} }
| LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */ | LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
{ {
outcode(int($1), &$2, NREG, &nullgen); outcode(int($1), &$2, 0, &nullgen);
} }
/* /*
* word * word
*/ */
| LWORD imm comma | LWORD imm comma
{ {
outcode(int($1), &$2, NREG, &nullgen); outcode(int($1), &$2, 0, &nullgen);
} }
| LWORD ximm comma | LWORD ximm comma
{ {
outcode(int($1), &$2, NREG, &nullgen); outcode(int($1), &$2, 0, &nullgen);
} }
/* /*
* PCDATA * PCDATA
*/ */
| LPCDAT imm ',' imm | LPCDAT imm ',' imm
{ {
if $2.Type != D_CONST || $4.Type != D_CONST { if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
yyerror("arguments to PCDATA must be integer constants") yyerror("arguments to PCDATA must be integer constants")
} }
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* FUNCDATA * FUNCDATA
*/ */
| LFUNCDAT imm ',' addr | LFUNCDAT imm ',' addr
{ {
if $2.Type != D_CONST { if $2.Type != obj.TYPE_CONST {
yyerror("index for FUNCDATA must be integer constant") yyerror("index for FUNCDATA must be integer constant")
} }
if $4.Type != D_EXTERN && $4.Type != D_STATIC && $4.Type != D_OREG { if $4.Type != obj.TYPE_MEM || ($4.Name != obj.NAME_EXTERN && $4.Name != obj.NAME_STATIC) {
yyerror("value for FUNCDATA must be symbol reference") yyerror("value for FUNCDATA must be symbol reference")
} }
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$4);
} }
/* /*
* END * END
*/ */
| LEND comma | LEND comma
{ {
outcode(int($1), &nullgen, NREG, &nullgen); outcode(int($1), &nullgen, 0, &nullgen);
} }
/* /*
* TEXT/GLOBL * TEXT
*/ */
| LTEXT name ',' imm | LTEXT name ',' '$' textsize
{ {
asm.Settext($2.Sym); asm.Settext($2.Sym);
outcode(int($1), &$2, NREG, &$4); outcode(int($1), &$2, 0, &$5);
} }
| LTEXT name ',' con ',' imm | LTEXT name ',' con ',' '$' textsize
{ {
asm.Settext($2.Sym); asm.Settext($2.Sym);
$6.Offset &= 0xffffffff; outcode(int($1), &$2, int($4), &$7);
$6.Offset |= -obj.ArgsSizeUnknown << 32; if asm.Pass > 1 {
outcode(int($1), &$2, int($4), &$6); lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
} }
| LTEXT name ',' con ',' imm '-' con /*
* GLOBL
*/
| LGLOBL name ',' imm
{ {
asm.Settext($2.Sym); asm.Settext($2.Sym)
$6.Offset &= 0xffffffff; outcode(int($1), &$2, 0, &$4)
$6.Offset |= ($8 & 0xffffffff) << 32;
outcode(int($1), &$2, int($4), &$6);
} }
| LGLOBL name ',' con ',' imm
{
asm.Settext($2.Sym)
outcode(int($1), &$2, 0, &$6)
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
}
/* /*
* DATA * DATA
*/ */
| LDATA name '/' con ',' imm | LDATA name '/' con ',' imm
{ {
outcode(int($1), &$2, int($4), &$6); outcode(int($1), &$2, 0, &$6);
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
} }
| LDATA name '/' con ',' ximm | LDATA name '/' con ',' ximm
{ {
outcode(int($1), &$2, int($4), &$6); outcode(int($1), &$2, 0, &$6);
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
} }
| LDATA name '/' con ',' fimm | LDATA name '/' con ',' fimm
{ {
outcode(int($1), &$2, int($4), &$6); outcode(int($1), &$2, 0, &$6);
if asm.Pass > 1 {
lastpc.From3.Type = obj.TYPE_CONST
lastpc.From3.Offset = $4
}
} }
/* /*
* RETURN * RETURN
*/ */
| LRETRN comma | LRETRN comma
{ {
outcode(int($1), &nullgen, NREG, &nullgen); outcode(int($1), &nullgen, 0, &nullgen);
} }
rel: rel:
con '(' LPC ')' con '(' LPC ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_BRANCH; $$.Type = obj.TYPE_BRANCH;
$$.Offset = $1 + int64(asm.PC); $$.Offset = $1 + int64(asm.PC);
} }
| LNAME offset | LNAME offset
@ -682,7 +703,7 @@ rel:
if asm.Pass == 2 && $1.Type != LLAB { if asm.Pass == 2 && $1.Type != LLAB {
yyerror("undefined label: %s", $1.Labelname) yyerror("undefined label: %s", $1.Labelname)
} }
$$.Type = D_BRANCH; $$.Type = obj.TYPE_BRANCH;
$$.Offset = $1.Value + $2; $$.Offset = $1.Value + $2;
} }
@ -690,8 +711,8 @@ rreg:
sreg sreg
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_REG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($1); $$.Reg = int16($1);
} }
xlreg: xlreg:
@ -702,45 +723,49 @@ lr:
LLR LLR
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SPR; $$.Type = obj.TYPE_REG;
$$.Offset = $1; $$.Reg = int16($1);
} }
lcr: lcr:
LCR LCR
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_CREG; $$.Type = obj.TYPE_REG;
$$.Reg = NREG; /* whole register */ $$.Reg = int16($1); /* whole register */
} }
ctr: ctr:
LCTR LCTR
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SPR; $$.Type = obj.TYPE_REG;
$$.Offset = $1; $$.Reg = int16($1);
} }
msr: msr:
LMSR LMSR
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_MSR; $$.Type = obj.TYPE_REG;
$$.Reg = int16($1)
} }
psr: psr:
LSPREG LSPREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SPR; $$.Type = obj.TYPE_REG;
$$.Offset = $1; $$.Reg = int16($1);
} }
| LSPR '(' con ')' | LSPR '(' con ')'
{ {
if $3 < 0 || $3 >= 1024 {
yyerror("SPR/DCR out of range")
}
$$ = nullgen; $$ = nullgen;
$$.Type = int16($1); $$.Type = obj.TYPE_REG
$$.Offset = $3; $$.Reg = int16($1 + $3);
} }
| msr | msr
@ -748,52 +773,44 @@ fpscr:
LFPSCR LFPSCR
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FPSCR; $$.Type = obj.TYPE_REG;
$$.Reg = NREG; $$.Reg = int16($1);
}
fpscrf:
LFPSCR '(' con ')'
{
$$ = nullgen;
$$.Type = D_FPSCR;
$$.Reg = int8($3);
} }
freg: freg:
LFREG LFREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FREG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($1); $$.Reg = int16($1);
} }
| LF '(' con ')' | LF '(' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FREG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($3); $$.Reg = int16(REG_F0 + $3);
} }
creg: creg:
LCREG LCREG
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_CREG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($1); $$.Reg = int16($1);
} }
| LCR '(' con ')' | LCR '(' con ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_CREG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($3); $$.Reg = int16(REG_C0 + $3);
} }
cbit: con cbit: con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_REG; $$.Type = obj.TYPE_REG;
$$.Reg = int8($1); $$.Reg = int16($1);
} }
mask: mask:
@ -803,7 +820,7 @@ mask:
var v uint32 var v uint32
$$ = nullgen; $$ = nullgen;
$$.Type = D_CONST; $$.Type = obj.TYPE_CONST;
mb = int($1); mb = int($1);
me = int($3); me = int($3);
if(mb < 0 || mb > 31 || me < 0 || me > 31){ if(mb < 0 || mb > 31 || me < 0 || me > 31){
@ -819,16 +836,46 @@ mask:
$$.Offset = int64(v); $$.Offset = int64(v);
} }
textsize:
LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = int64($1)
$$.U.Argsize = obj.ArgsSizeUnknown;
}
| '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -int64($2)
$$.U.Argsize = obj.ArgsSizeUnknown;
}
| LCONST '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = int64($1)
$$.U.Argsize = int32($3);
}
| '-' LCONST '-' LCONST
{
$$ = nullgen;
$$.Type = obj.TYPE_TEXTSIZE;
$$.Offset = -int64($2)
$$.U.Argsize = int32($4);
}
ximm: ximm:
'$' addr '$' addr
{ {
$$ = $2; $$ = $2;
$$.Type = D_CONST; $$.Type = obj.TYPE_ADDR;
} }
| '$' LSCONST | '$' LSCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_SCONST; $$.Type = obj.TYPE_SCONST;
$$.U.Sval = $2 $$.U.Sval = $2
} }
@ -836,20 +883,20 @@ fimm:
'$' LFCONST '$' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = $2; $$.U.Dval = $2;
} }
| '$' '-' LFCONST | '$' '-' LFCONST
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_FCONST; $$.Type = obj.TYPE_FCONST;
$$.U.Dval = -$3; $$.U.Dval = -$3;
} }
imm: '$' con imm: '$' con
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_CONST; $$.Type = obj.TYPE_CONST;
$$.Offset = $2; $$.Offset = $2;
} }
@ -860,22 +907,22 @@ sreg:
if $$ < 0 || $$ >= NREG { if $$ < 0 || $$ >= NREG {
print("register value out of range\n") print("register value out of range\n")
} }
$$ = $3; $$ = REG_R0 + $3;
} }
regaddr: regaddr:
'(' sreg ')' '(' sreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Reg = int8($2); $$.Reg = int16($2);
$$.Offset = 0; $$.Offset = 0;
} }
| '(' sreg '+' sreg ')' | '(' sreg '+' sreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Reg = int8($2); $$.Reg = int16($2);
$$.Scale = int8($4); $$.Scale = int8($4);
$$.Offset = 0; $$.Offset = 0;
} }
@ -885,8 +932,8 @@ addr:
| con '(' sreg ')' | con '(' sreg ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Reg = int8($3); $$.Reg = int16($3);
$$.Offset = $1; $$.Offset = $1;
} }
@ -894,7 +941,7 @@ name:
con '(' pointer ')' con '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Name = int8($3); $$.Name = int8($3);
$$.Sym = nil; $$.Sym = nil;
$$.Offset = $1; $$.Offset = $1;
@ -902,7 +949,7 @@ name:
| LNAME offset '(' pointer ')' | LNAME offset '(' pointer ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Name = int8($4); $$.Name = int8($4);
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0); $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
$$.Offset = $2; $$.Offset = $2;
@ -910,8 +957,8 @@ name:
| LNAME '<' '>' offset '(' LSB ')' | LNAME '<' '>' offset '(' LSB ')'
{ {
$$ = nullgen; $$ = nullgen;
$$.Type = D_OREG; $$.Type = obj.TYPE_MEM;
$$.Name = D_STATIC; $$.Name = obj.NAME_STATIC;
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0); $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
$$.Offset = $4; $$.Offset = $4;
} }

View File

@ -88,92 +88,92 @@ func yyparse() {
} }
var lexinit = []asm.Lextab{ var lexinit = []asm.Lextab{
{"SP", LSP, ppc64.D_AUTO}, {"SP", LSP, obj.NAME_AUTO},
{"SB", LSB, ppc64.D_EXTERN}, {"SB", LSB, obj.NAME_EXTERN},
{"FP", LFP, ppc64.D_PARAM}, {"FP", LFP, obj.NAME_PARAM},
{"PC", LPC, ppc64.D_BRANCH}, {"PC", LPC, obj.TYPE_BRANCH},
{"LR", LLR, ppc64.D_LR}, {"LR", LLR, ppc64.REG_LR},
{"CTR", LCTR, ppc64.D_CTR}, {"CTR", LCTR, ppc64.REG_CTR},
{"XER", LSPREG, ppc64.D_XER}, {"XER", LSPREG, ppc64.REG_XER},
{"MSR", LMSR, ppc64.D_MSR}, {"MSR", LMSR, ppc64.REG_MSR},
{"FPSCR", LFPSCR, ppc64.D_FPSCR}, {"FPSCR", LFPSCR, ppc64.REG_FPSCR},
{"SPR", LSPR, ppc64.D_SPR}, {"SPR", LSPR, ppc64.REG_SPR0},
{"DCR", LSPR, ppc64.D_DCR}, {"DCR", LSPR, ppc64.REG_DCR0},
{"CR", LCR, 0}, {"CR", LCR, ppc64.REG_CR},
{"CR0", LCREG, 0}, {"CR0", LCREG, ppc64.REG_C0},
{"CR1", LCREG, 1}, {"CR1", LCREG, ppc64.REG_C1},
{"CR2", LCREG, 2}, {"CR2", LCREG, ppc64.REG_C2},
{"CR3", LCREG, 3}, {"CR3", LCREG, ppc64.REG_C3},
{"CR4", LCREG, 4}, {"CR4", LCREG, ppc64.REG_C4},
{"CR5", LCREG, 5}, {"CR5", LCREG, ppc64.REG_C5},
{"CR6", LCREG, 6}, {"CR6", LCREG, ppc64.REG_C6},
{"CR7", LCREG, 7}, {"CR7", LCREG, ppc64.REG_C7},
{"R", LR, 0}, {"R", LR, 0},
{"R0", LREG, 0}, {"R0", LREG, ppc64.REG_R0},
{"R1", LREG, 1}, {"R1", LREG, ppc64.REG_R1},
{"R2", LREG, 2}, {"R2", LREG, ppc64.REG_R2},
{"R3", LREG, 3}, {"R3", LREG, ppc64.REG_R3},
{"R4", LREG, 4}, {"R4", LREG, ppc64.REG_R4},
{"R5", LREG, 5}, {"R5", LREG, ppc64.REG_R5},
{"R6", LREG, 6}, {"R6", LREG, ppc64.REG_R6},
{"R7", LREG, 7}, {"R7", LREG, ppc64.REG_R7},
{"R8", LREG, 8}, {"R8", LREG, ppc64.REG_R8},
{"R9", LREG, 9}, {"R9", LREG, ppc64.REG_R9},
{"R10", LREG, 10}, {"R10", LREG, ppc64.REG_R10},
{"R11", LREG, 11}, {"R11", LREG, ppc64.REG_R11},
{"R12", LREG, 12}, {"R12", LREG, ppc64.REG_R12},
{"R13", LREG, 13}, {"R13", LREG, ppc64.REG_R13},
{"R14", LREG, 14}, {"R14", LREG, ppc64.REG_R14},
{"R15", LREG, 15}, {"R15", LREG, ppc64.REG_R15},
{"R16", LREG, 16}, {"R16", LREG, ppc64.REG_R16},
{"R17", LREG, 17}, {"R17", LREG, ppc64.REG_R17},
{"R18", LREG, 18}, {"R18", LREG, ppc64.REG_R18},
{"R19", LREG, 19}, {"R19", LREG, ppc64.REG_R19},
{"R20", LREG, 20}, {"R20", LREG, ppc64.REG_R20},
{"R21", LREG, 21}, {"R21", LREG, ppc64.REG_R21},
{"R22", LREG, 22}, {"R22", LREG, ppc64.REG_R22},
{"R23", LREG, 23}, {"R23", LREG, ppc64.REG_R23},
{"R24", LREG, 24}, {"R24", LREG, ppc64.REG_R24},
{"R25", LREG, 25}, {"R25", LREG, ppc64.REG_R25},
{"R26", LREG, 26}, {"R26", LREG, ppc64.REG_R26},
{"R27", LREG, 27}, {"R27", LREG, ppc64.REG_R27},
{"R28", LREG, 28}, {"R28", LREG, ppc64.REG_R28},
{"R29", LREG, 29}, {"R29", LREG, ppc64.REG_R29},
{"g", LREG, 30}, // avoid unintentionally clobbering g using R30 {"g", LREG, ppc64.REG_R30}, // avoid unintentionally clobbering g using R30
{"R31", LREG, 31}, {"R31", LREG, ppc64.REG_R31},
{"F", LF, 0}, {"F", LF, 0},
{"F0", LFREG, 0}, {"F0", LFREG, ppc64.REG_F0},
{"F1", LFREG, 1}, {"F1", LFREG, ppc64.REG_F1},
{"F2", LFREG, 2}, {"F2", LFREG, ppc64.REG_F2},
{"F3", LFREG, 3}, {"F3", LFREG, ppc64.REG_F3},
{"F4", LFREG, 4}, {"F4", LFREG, ppc64.REG_F4},
{"F5", LFREG, 5}, {"F5", LFREG, ppc64.REG_F5},
{"F6", LFREG, 6}, {"F6", LFREG, ppc64.REG_F6},
{"F7", LFREG, 7}, {"F7", LFREG, ppc64.REG_F7},
{"F8", LFREG, 8}, {"F8", LFREG, ppc64.REG_F8},
{"F9", LFREG, 9}, {"F9", LFREG, ppc64.REG_F9},
{"F10", LFREG, 10}, {"F10", LFREG, ppc64.REG_F10},
{"F11", LFREG, 11}, {"F11", LFREG, ppc64.REG_F11},
{"F12", LFREG, 12}, {"F12", LFREG, ppc64.REG_F12},
{"F13", LFREG, 13}, {"F13", LFREG, ppc64.REG_F13},
{"F14", LFREG, 14}, {"F14", LFREG, ppc64.REG_F14},
{"F15", LFREG, 15}, {"F15", LFREG, ppc64.REG_F15},
{"F16", LFREG, 16}, {"F16", LFREG, ppc64.REG_F16},
{"F17", LFREG, 17}, {"F17", LFREG, ppc64.REG_F17},
{"F18", LFREG, 18}, {"F18", LFREG, ppc64.REG_F18},
{"F19", LFREG, 19}, {"F19", LFREG, ppc64.REG_F19},
{"F20", LFREG, 20}, {"F20", LFREG, ppc64.REG_F20},
{"F21", LFREG, 21}, {"F21", LFREG, ppc64.REG_F21},
{"F22", LFREG, 22}, {"F22", LFREG, ppc64.REG_F22},
{"F23", LFREG, 23}, {"F23", LFREG, ppc64.REG_F23},
{"F24", LFREG, 24}, {"F24", LFREG, ppc64.REG_F24},
{"F25", LFREG, 25}, {"F25", LFREG, ppc64.REG_F25},
{"F26", LFREG, 26}, {"F26", LFREG, ppc64.REG_F26},
{"F27", LFREG, 27}, {"F27", LFREG, ppc64.REG_F27},
{"F28", LFREG, 28}, {"F28", LFREG, ppc64.REG_F28},
{"F29", LFREG, 29}, {"F29", LFREG, ppc64.REG_F29},
{"F30", LFREG, 30}, {"F30", LFREG, ppc64.REG_F30},
{"F31", LFREG, 31}, {"F31", LFREG, ppc64.REG_F31},
{"CREQV", LCROP, ppc64.ACREQV}, {"CREQV", LCROP, ppc64.ACREQV},
{"CRXOR", LCROP, ppc64.ACRXOR}, {"CRXOR", LCROP, ppc64.ACRXOR},
{"CRAND", LCROP, ppc64.ACRAND}, {"CRAND", LCROP, ppc64.ACRAND},
@ -321,7 +321,7 @@ var lexinit = []asm.Lextab{
{"FMOVD", LFMOV, ppc64.AFMOVD}, {"FMOVD", LFMOV, ppc64.AFMOVD},
{"FMOVS", LFMOV, ppc64.AFMOVS}, {"FMOVS", LFMOV, ppc64.AFMOVS},
{"FMOVDCC", LFCONV, ppc64.AFMOVDCC}, /* fmr. */ {"FMOVDCC", LFCONV, ppc64.AFMOVDCC}, /* fmr. */
{"GLOBL", LTEXT, ppc64.AGLOBL}, {"GLOBL", LGLOBL, obj.AGLOBL},
{"MOVB", LMOVB, ppc64.AMOVB}, {"MOVB", LMOVB, ppc64.AMOVB},
{"MOVBZ", LMOVB, ppc64.AMOVBZ}, {"MOVBZ", LMOVB, ppc64.AMOVBZ},
{"MOVBU", LMOVB, ppc64.AMOVBU}, {"MOVBU", LMOVB, ppc64.AMOVBU},
@ -348,16 +348,16 @@ var lexinit = []asm.Lextab{
{"NEGV", LABS, ppc64.ANEGV}, {"NEGV", LABS, ppc64.ANEGV},
{"NEGCC", LABS, ppc64.ANEGCC}, {"NEGCC", LABS, ppc64.ANEGCC},
{"NEGVCC", LABS, ppc64.ANEGVCC}, {"NEGVCC", LABS, ppc64.ANEGVCC},
{"NOP", LNOP, ppc64.ANOP}, /* ori 0,0,0 */ {"NOP", LNOP, obj.ANOP}, /* ori 0,0,0 */
{"SYSCALL", LNOP, ppc64.ASYSCALL}, {"SYSCALL", LNOP, ppc64.ASYSCALL},
{"UNDEF", LNOP, ppc64.AUNDEF}, {"UNDEF", LNOP, obj.AUNDEF},
{"RET", LRETRN, ppc64.ARETURN}, {"RET", LRETRN, obj.ARET},
{"RETURN", LRETRN, ppc64.ARETURN}, {"RETURN", LRETRN, obj.ARET},
{"RFI", LRETRN, ppc64.ARFI}, {"RFI", LRETRN, ppc64.ARFI},
{"RFCI", LRETRN, ppc64.ARFCI}, {"RFCI", LRETRN, ppc64.ARFCI},
{"DATA", LDATA, ppc64.ADATA}, {"DATA", LDATA, obj.ADATA},
{"END", LEND, ppc64.AEND}, {"END", LEND, obj.AEND},
{"TEXT", LTEXT, ppc64.ATEXT}, {"TEXT", LTEXT, obj.ATEXT},
/* 64-bit instructions */ /* 64-bit instructions */
{"CNTLZD", LABS, ppc64.ACNTLZD}, {"CNTLZD", LABS, ppc64.ACNTLZD},
@ -460,19 +460,15 @@ var lexinit = []asm.Lextab{
{"DWORD", LWORD, ppc64.ADWORD}, {"DWORD", LWORD, ppc64.ADWORD},
{"SCHED", LSCHED, 0}, {"SCHED", LSCHED, 0},
{"NOSCHED", LSCHED, 0x80}, {"NOSCHED", LSCHED, 0x80},
{"PCDATA", LPCDAT, ppc64.APCDATA}, {"PCDATA", LPCDAT, obj.APCDATA},
{"FUNCDATA", LFUNCDAT, ppc64.AFUNCDATA}, {"FUNCDATA", LFUNCDAT, obj.AFUNCDATA},
} }
func cinit() { func cinit() {
nullgen.Type = ppc64.D_NONE
nullgen.Name = ppc64.D_NONE
nullgen.Reg = ppc64.NREG
nullgen.Scale = ppc64.NREG // replaced Gen.xreg with Prog.scale
} }
func cclean() { func cclean() {
outcode(ppc64.AEND, &nullgen, ppc64.NREG, &nullgen) outcode(obj.AEND, &nullgen, 0, &nullgen)
} }
var lastpc *obj.Prog var lastpc *obj.Prog
@ -486,13 +482,13 @@ func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
goto out goto out
} }
if g1.Scale != ppc64.NREG { if g1.Scale != 0 {
if reg != ppc64.NREG || g2.Scale != ppc64.NREG { if reg != 0 || g2.Scale != 0 {
yyerror("bad addressing modes") yyerror("bad addressing modes")
} }
reg = int(g1.Scale) reg = int(g1.Scale)
} else if g2.Scale != ppc64.NREG { } else if g2.Scale != 0 {
if reg != ppc64.NREG { if reg != 0 {
yyerror("bad addressing modes") yyerror("bad addressing modes")
} }
reg = int(g2.Scale) reg = int(g2.Scale)
@ -505,7 +501,7 @@ func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
p.Mark |= ppc64.NOSCHED p.Mark |= ppc64.NOSCHED
} }
p.From = *g1 p.From = *g1
p.Reg = uint8(reg) p.Reg = int16(reg)
p.To = *g2 p.To = *g2
p.Pc = int64(asm.PC) p.Pc = int64(asm.PC)
@ -518,7 +514,7 @@ func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
lastpc = p lastpc = p
out: out:
if a != ppc64.AGLOBL && a != ppc64.ADATA { if a != obj.AGLOBL && a != obj.ADATA {
asm.PC++ asm.PC++
} }
} }
@ -538,7 +534,7 @@ func outgcode(a int, g1 *obj.Addr, reg int, g2, g3 *obj.Addr) {
p.Mark |= ppc64.NOSCHED p.Mark |= ppc64.NOSCHED
} }
p.From = *g1 p.From = *g1
p.Reg = uint8(reg) p.Reg = int16(reg)
p.From3 = *g2 p.From3 = *g2
p.To = *g3 p.To = *g3
p.Pc = int64(asm.PC) p.Pc = int64(asm.PC)
@ -552,7 +548,7 @@ func outgcode(a int, g1 *obj.Addr, reg int, g2, g3 *obj.Addr) {
lastpc = p lastpc = p
out: out:
if a != ppc64.AGLOBL && a != ppc64.ADATA { if a != obj.AGLOBL && a != obj.ADATA {
asm.PC++ asm.PC++
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -364,7 +364,7 @@ func readprog(b *bufio.Reader, p *obj.Prog) {
p.Lineno = int32(rdint(b)) p.Lineno = int32(rdint(b))
p.Link = rdprog(b) p.Link = rdprog(b)
p.As = int16(rdint(b)) p.As = int16(rdint(b))
p.Reg = uint8(rdint(b)) p.Reg = int16(rdint(b))
p.Scond = uint8(rdint(b)) p.Scond = uint8(rdint(b))
p.Width = int8(rdint(b)) p.Width = int8(rdint(b))
readaddr(b, &p.From) readaddr(b, &p.From)
@ -385,13 +385,13 @@ func readaddr(b *bufio.Reader, a *obj.Addr) {
a.Sym = rdsym(b) a.Sym = rdsym(b)
a.Gotype = rdsym(b) a.Gotype = rdsym(b)
a.Type = int16(rdint(b)) a.Type = int16(rdint(b))
a.Index = uint8(rdint(b)) a.Index = int16(rdint(b))
a.Scale = int8(rdint(b)) a.Scale = int8(rdint(b))
a.Reg = int8(rdint(b)) a.Reg = int16(rdint(b))
a.Name = int8(rdint(b)) a.Name = int8(rdint(b))
a.Class = int8(rdint(b)) a.Class = int8(rdint(b))
a.Etype = uint8(rdint(b)) a.Etype = uint8(rdint(b))
a.Offset2 = int32(rdint(b)) a.U.Argsize = int32(rdint(b))
a.Width = rdint(b) a.Width = rdint(b)
} }

View File

@ -1930,11 +1930,13 @@ prefixof(Link *ctxt, Addr *a)
} }
static int static int
oclass(Link *ctxt, Addr *a) oclass(Link *ctxt, Prog *p, Addr *a)
{ {
vlong v; vlong v;
int32 l; int32 l;
USED(p);
// TODO(rsc): This special case is for SHRQ $3, AX:DX, // TODO(rsc): This special case is for SHRQ $3, AX:DX,
// which encodes as SHRQ $32(DX*0), AX. // which encodes as SHRQ $32(DX*0), AX.
// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX. // Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
@ -2756,9 +2758,9 @@ doasm(Link *ctxt, Prog *p)
*ctxt->andptr++ = pre; *ctxt->andptr++ = pre;
if(p->ft == 0) if(p->ft == 0)
p->ft = oclass(ctxt, &p->from); p->ft = oclass(ctxt, p, &p->from);
if(p->tt == 0) if(p->tt == 0)
p->tt = oclass(ctxt, &p->to); p->tt = oclass(ctxt, p, &p->to);
ft = p->ft * Ymax; ft = p->ft * Ymax;
tt = p->tt * Ymax; tt = p->tt * Ymax;
@ -3291,7 +3293,7 @@ bad:
return; return;
} }
} }
ctxt->diag("doasm: notfound ft=%d tt=%d %P %d %d", p->ft, p->tt, p, oclass(ctxt, &p->from), oclass(ctxt, &p->to)); ctxt->diag("doasm: notfound ft=%d tt=%d %P %d %d", p->ft, p->tt, p, oclass(ctxt, p, &p->from), oclass(ctxt, p, &p->to));
return; return;
mfound: mfound:

View File

@ -1485,10 +1485,12 @@ prefixof(Link *ctxt, Addr *a)
} }
static int static int
oclass(Link *ctxt, Addr *a) oclass(Link *ctxt, Prog *p, Addr *a)
{ {
int32 v; int32 v;
USED(p);
// TODO(rsc): This special case is for SHRQ $3, AX:DX, // TODO(rsc): This special case is for SHRQ $3, AX:DX,
// which encodes as SHRQ $32(DX*0), AX. // which encodes as SHRQ $32(DX*0), AX.
// Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX. // Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
@ -2192,9 +2194,9 @@ doasm(Link *ctxt, Prog *p)
*ctxt->andptr++ = pre; *ctxt->andptr++ = pre;
if(p->ft == 0) if(p->ft == 0)
p->ft = oclass(ctxt, &p->from); p->ft = oclass(ctxt, p, &p->from);
if(p->tt == 0) if(p->tt == 0)
p->tt = oclass(ctxt, &p->to); p->tt = oclass(ctxt, p, &p->to);
ft = p->ft * Ymax; ft = p->ft * Ymax;
tt = p->tt * Ymax; tt = p->tt * Ymax;

View File

@ -143,7 +143,7 @@ writeobj(Link *ctxt, Biobuf *b)
// we will hard code the GOOBJ=1 behavior. // we will hard code the GOOBJ=1 behavior.
env = getenv("GOOBJ"); env = getenv("GOOBJ");
if(env == nil) if(env == nil)
env = "0"; env = "2";
if(atoi(env) == 0) { if(atoi(env) == 0) {
writeobjdirect(ctxt, b); writeobjdirect(ctxt, b);
return; return;