[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.
// Use of this source code is governed by a BSD-style
// 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.
// Use of this source code is governed by a BSD-style
// 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.
// Use of this source code is governed by a BSD-style
// 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.
// Use of this source code is governed by a BSD-style
// 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.
// Use of this source code is governed by a BSD-style
// 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.
// Use of this source code is governed by a BSD-style
// 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
// 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.
const verifyAsm = false
const verifyAsm = true
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.
@ -1691,8 +1691,8 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
if verifyAsm {
newArgs := make([]interface{}, len(args))
copy(newArgs, args)
newArgs[0] = tool("new" + archChar + "a")
newArgs[2] = ofile + ".new" // x.6 becomes x.6.new
newArgs[1] = tool("new" + archChar + "a")
newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
return err
}
@ -1705,7 +1705,7 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
return err
}
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

View File

@ -30,17 +30,7 @@
package arm
// list[5689].c
// obj.c
// objfile.c
// pass.c
// pcln.c
// sym.c
import "cmd/internal/obj"
// TODO(ality): remove this workaround.
// It's here because Pconv in liblink/list?.c references %L.
@ -57,18 +47,54 @@ const (
)
const (
REGRET = 0
REGEXT = 10
REG_R0 = 32 + iota
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
REGM = REGEXT - 1
REGTMP = 11
REGSP = 13
REGLINK = 14
REGPC = 15
REGTMP = REG_R11
REGSP = REG_R13
REGLINK = REG_R14
REGPC = REG_R15
NFREG = 16
FREGRET = 0
FREGEXT = 7
FREGTMP = 15
FREGRET = REG_F0
FREGEXT = REG_F7
FREGTMP = REG_F15
)
/* compiler allocates register variables F0 up */
@ -110,13 +136,13 @@ const (
C_SP
C_HREG
C_ADDR
C_TEXTSIZE
C_GOK
C_NCLASS
)
const (
AXXX = iota
AAND
AAND = obj.A_ARCHSPECIFIC + iota
AEOR
ASUB
ARSB
@ -131,8 +157,6 @@ const (
AORR
ABIC
AMVN
AB
ABL
ABEQ
ABNE
ABCS
@ -190,23 +214,12 @@ const (
AMOVM
ASWPBU
ASWPW
ANOP
ARFE
ASWI
AMULA
ADATA
AGLOBL
AGOK
AHISTORY
ANAME
ARET
ATEXT
AWORD
ADYNT_
AINIT_
ABCASE
ACASE
AEND
AMULL
AMULAL
AMULLU
@ -214,31 +227,22 @@ const (
ABX
ABXRET
ADWORD
ASIGNAME
ALDREX
ASTREX
ALDREXD
ASTREXD
APLD
AUNDEF
ACLZ
AMULWT
AMULWB
AMULAWT
AMULAWB
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ADATABUNDLE
ADATABUNDLEEND
AMRC
ALAST
AB = obj.AJMP
ABL = obj.ACALL
)
/* scond byte */
@ -249,56 +253,29 @@ const (
C_WBIT = 1 << 6
C_FBIT = 1 << 7
C_UBIT = 1 << 7
C_SCOND_EQ = 0
C_SCOND_NE = 1
C_SCOND_HS = 2
C_SCOND_LO = 3
C_SCOND_MI = 4
C_SCOND_PL = 5
C_SCOND_VS = 6
C_SCOND_VC = 7
C_SCOND_HI = 8
C_SCOND_LS = 9
C_SCOND_GE = 10
C_SCOND_LT = 11
C_SCOND_GT = 12
C_SCOND_LE = 13
C_SCOND_NONE = 14
C_SCOND_NV = 15
C_SCOND_XOR = 14
C_SCOND_EQ = 0 ^ C_SCOND_XOR
C_SCOND_NE = 1 ^ C_SCOND_XOR
C_SCOND_HS = 2 ^ C_SCOND_XOR
C_SCOND_LO = 3 ^ C_SCOND_XOR
C_SCOND_MI = 4 ^ C_SCOND_XOR
C_SCOND_PL = 5 ^ C_SCOND_XOR
C_SCOND_VS = 6 ^ C_SCOND_XOR
C_SCOND_VC = 7 ^ C_SCOND_XOR
C_SCOND_HI = 8 ^ C_SCOND_XOR
C_SCOND_LS = 9 ^ C_SCOND_XOR
C_SCOND_GE = 10 ^ C_SCOND_XOR
C_SCOND_LT = 11 ^ C_SCOND_XOR
C_SCOND_GT = 12 ^ C_SCOND_XOR
C_SCOND_LE = 13 ^ C_SCOND_XOR
C_SCOND_NONE = 14 ^ C_SCOND_XOR
C_SCOND_NV = 15 ^ C_SCOND_XOR
SHIFT_LL = 0 << 5
SHIFT_LR = 1 << 5
SHIFT_AR = 2 << 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
*/

View File

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

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)
s = int(p.Scond)
sc = extra[s&C_SCOND]
sc = extra[(s&C_SCOND)^C_SCOND_XOR]
if s&C_SBIT != 0 {
sc += ".S"
}
@ -84,25 +84,21 @@ func Pconv(p *obj.Prog) string {
sc += ".U"
}
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))
} 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))
} 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))
}
} else if a == 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))
} else if p.As == 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))
} else if p.Reg == NREG {
} 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.From3.Offset, Dconv(p, 0, &p.To))
} 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.From3.Offset, Dconv(p, 0, &p.To))
} 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))
} 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 {
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))
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))
}
fp += str
@ -114,7 +110,7 @@ func Aconv(a int) string {
var fp string
s = "???"
if a >= AXXX && a < ALAST {
if a >= obj.AXXX && a < ALAST {
s = Anames[a]
}
fp += s
@ -132,63 +128,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
default:
str = fmt.Sprintf("GOK-type(%d)", a.Type)
case D_NONE:
case obj.TYPE_NONE:
str = ""
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg)
if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil {
str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
}
case D_CONST:
if a.Reg != NREG {
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg)
case obj.TYPE_CONST,
obj.TYPE_ADDR:
if a.Reg != 0 {
str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else {
str = fmt.Sprintf("$%v", Mconv(a))
}
case D_CONST2:
str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2)
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 D_SHIFT:
case obj.TYPE_SHIFT:
v = int(a.Offset)
op = string("<<>>->@>"[((v>>5)&3)<<1:])
if v&(1<<4) != 0 {
str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15)
} else {
str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31)
}
if a.Reg != NREG {
str += fmt.Sprintf("(R%d)", a.Reg)
if a.Reg != 0 {
str += fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
}
case D_OREG:
if a.Reg != NREG {
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg)
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))
}
case D_REG:
str = fmt.Sprintf("R%d", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
case obj.TYPE_REG:
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
if a.Name != obj.TYPE_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
}
case D_FREG:
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:
case obj.TYPE_BRANCH:
if a.Sym != nil {
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} 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 {
str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else {
str = fmt.Sprintf("%d(PC)", a.Offset) /*-pc*/
}
case D_FCONST:
case obj.TYPE_FCONST:
str = fmt.Sprintf("$%.17g", a.U.Dval)
case D_SCONST:
case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
break
}
@ -221,9 +206,8 @@ func RAconv(a *obj.Addr) string {
str = fmt.Sprintf("GOK-reglist")
switch a.Type {
case D_CONST,
D_CONST2:
if a.Reg != NREG {
case obj.TYPE_CONST:
if a.Reg != 0 {
break
}
if a.Sym != nil {
@ -233,10 +217,9 @@ func RAconv(a *obj.Addr) string {
str = ""
for i = 0; i < NREG; i++ {
if v&(1<<uint(i)) != 0 {
if str[0] == 0 {
if str == "" {
str += "[R"
} else {
str += ",R"
}
str += fmt.Sprintf("%d", i)
@ -253,10 +236,38 @@ func RAconv(a *obj.Addr) string {
func Rconv(r int) 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)
fp += str
switch r {
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
}
@ -288,19 +299,19 @@ func Mconv(a *obj.Addr) string {
default:
str = fmt.Sprintf("GOK-name(%d)", a.Name)
case D_NONE:
case obj.NAME_NONE:
str = fmt.Sprintf("%d", a.Offset)
case D_EXTERN:
case obj.NAME_EXTERN:
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))
case D_AUTO:
case obj.NAME_AUTO:
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))
break
}

View File

@ -38,46 +38,6 @@ import (
"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) {
var literal string
var s *obj.LSym
@ -86,53 +46,48 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p.From.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 {
case AB,
ABL,
ADUFFZERO,
ADUFFCOPY:
if p.To.Type == D_OREG && (p.To.Name == D_EXTERN || p.To.Name == D_STATIC) && p.To.Sym != nil {
p.To.Type = D_BRANCH
obj.ADUFFZERO,
obj.ADUFFCOPY:
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 = obj.TYPE_BRANCH
}
break
}
// Replace TLS register fetches on older ARM procesors.
switch p.As {
// Treat MRC 15, 0, <reg>, C13, C0, 3 specially.
case AMRC:
if p.To.Offset&0xffff0fff == 0xee1d0f70 {
// Because the instruction might be rewriten to a BL which returns in R0
// the register must be zero.
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())
}
if ctxt.Goarm < 7 {
// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
if tlsfallback == nil {
tlsfallback = obj.Linklookup(ctxt, "runtime.read_tls_fallback", 0)
}
// MOVW LR, R11
p.As = AMOVW
p.From.Type = D_REG
p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK
p.To.Type = D_REG
p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP
// BL runtime.read_tls_fallback(SB)
p = obj.Appendp(ctxt, p)
p.As = ABL
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p.To.Sym = tlsfallback
p.To.Offset = 0
@ -140,9 +95,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_REG
p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP
p.To.Type = D_REG
p.To.Type = obj.TYPE_REG
p.To.Reg = REGLINK
break
}
@ -156,9 +111,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// Rewrite float constants to values stored in memory.
switch p.As {
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 f32 float32
f32 = float32(p.From.U.Dval)
@ -171,14 +125,14 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
s.Reachable = 0
}
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Name = D_EXTERN
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
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
i64 = math.Float64bits(p.From.U.Dval)
literal = fmt.Sprintf("$f64.%016x", i64)
@ -189,9 +143,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
s.Reachable = 0
}
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Name = D_EXTERN
p.From.Name = obj.NAME_EXTERN
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
// compensate.
if ctxt.Tlsg == nil {
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
}
if p.From.Type == D_CONST && p.From.Name == D_EXTERN && p.From.Sym == ctxt.Tlsg {
p.From.Type = D_OREG
if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && p.From.Sym == ctxt.Tlsg {
p.From.Type = obj.TYPE_MEM
}
if p.To.Type == D_CONST && p.To.Name == D_EXTERN && p.To.Sym == ctxt.Tlsg {
p.To.Type = D_OREG
if p.To.Type == obj.TYPE_ADDR && p.To.Name == obj.NAME_EXTERN && p.To.Sym == ctxt.Tlsg {
p.To.Type = obj.TYPE_MEM
}
}
}
func prg() *obj.Prog {
p := zprg
return &p
}
// Prog.mark
const (
FOLL = 1 << 0
@ -249,7 +197,7 @@ func nocache5(p *obj.Prog) {
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 pl *obj.Prog
var p1 *obj.Prog
@ -284,38 +232,38 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
autoffset = 0
}
cursym.Locals = autoffset
cursym.Args = p.To.Offset2
cursym.Args = p.To.U.Argsize
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
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_CONST
p.From.Reg = 13
p.From.Type = obj.TYPE_ADDR
p.From.Reg = REG_R13
p.From.Offset = 4
p.To.Type = D_REG
p.To.Reg = 1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
// MOVW $n(R13), R2
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_CONST
p.From.Reg = 13
p.From.Type = obj.TYPE_ADDR
p.From.Reg = REG_R13
p.From.Offset = 4 + int64(autoffset)
p.To.Type = D_REG
p.To.Reg = 2
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
// MOVW $0, R3
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = 0
p.To.Type = D_REG
p.To.Reg = 3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
// L:
// MOVW.nil R3, 0(R1) +4
@ -325,22 +273,22 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p = pl
p.As = AMOVW
p.From.Type = D_REG
p.From.Reg = 3
p.To.Type = D_OREG
p.To.Reg = 1
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_MEM
p.To.Reg = REG_R1
p.To.Offset = 4
p.Scond |= C_PBIT
p = obj.Appendp(ctxt, p)
p.As = ACMP
p.From.Type = D_REG
p.From.Reg = 1
p.Reg = 2
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.Reg = REG_R2
p = obj.Appendp(ctxt, p)
p.As = ABNE
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p.Pcond = pl
}
}
@ -352,17 +300,16 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
* expand BECOME pseudo
*/
for p = cursym.Text; p != nil; p = p.Link {
switch p.As {
case ACASE:
if ctxt.Flag_shared != 0 {
linkcase(p)
}
case ATEXT:
case obj.ATEXT:
p.Mark |= LEAF
case ARET:
case obj.ARET:
break
case ADIV,
@ -376,7 +323,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
cursym.Text.Mark &^= LEAF
continue
case ANOP:
case obj.ANOP:
q1 = p.Link
q.Link = q1 /* q is non-nop */
if q1 != nil {
@ -386,8 +333,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
case ABL,
ABX,
ADUFFZERO,
ADUFFCOPY:
obj.ADUFFZERO,
obj.ADUFFCOPY:
cursym.Text.Mark &^= LEAF
fallthrough
@ -411,7 +358,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
ABLE:
q1 = p.Pcond
if q1 != nil {
for q1.As == ANOP {
for q1.As == obj.ANOP {
q1 = q1.Link
p.Pcond = q1
}
@ -426,7 +373,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
for p = cursym.Text; p != nil; p = p.Link {
o = int(p.As)
switch o {
case ATEXT:
case obj.ATEXT:
autosize = int32(p.To.Offset + 4)
if autosize <= 4 {
if cursym.Text.Mark&LEAF != 0 {
@ -451,8 +398,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
}
}
if !(p.Reg&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.Reg&obj.NEEDCTXT != 0))) // emit split check
if !(p.From3.Offset&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0))) // emit split check
}
// MOVW.W R14,$-autosize(SP)
@ -460,14 +407,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW
p.Scond |= C_WBIT
p.From.Type = D_REG
p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK
p.To.Type = D_OREG
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(-autosize)
p.To.Reg = REGSP
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
//
// MOVW g_panic(g), R1
@ -488,84 +435,83 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
p.To.Type = D_REG
p.To.Reg = 1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
p = obj.Appendp(ctxt, p)
p.As = ACMP
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = 0
p.Reg = 1
p.Reg = REG_R1
p = obj.Appendp(ctxt, p)
p.As = ABEQ
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p1 = p
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_OREG
p.From.Reg = 1
p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_R1
p.From.Offset = 0 // Panic.argp
p.To.Type = D_REG
p.To.Reg = 2
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p)
p.As = AADD
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize) + 4
p.Reg = 13
p.To.Type = D_REG
p.To.Reg = 3
p.Reg = REG_R13
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
p = obj.Appendp(ctxt, p)
p.As = ACMP
p.From.Type = D_REG
p.From.Reg = 2
p.Reg = 3
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R2
p.Reg = REG_R3
p = obj.Appendp(ctxt, p)
p.As = ABNE
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p2 = p
p = obj.Appendp(ctxt, p)
p.As = AADD
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = 4
p.Reg = 13
p.To.Type = D_REG
p.To.Reg = 4
p.Reg = REG_R13
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_REG
p.From.Reg = 4
p.To.Type = D_OREG
p.To.Reg = 1
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R4
p.To.Type = obj.TYPE_MEM
p.To.Reg = REG_R1
p.To.Offset = 0 // Panic.argp
p = obj.Appendp(ctxt, p)
p.As = ANOP
p.As = obj.ANOP
p1.Pcond = p
p2.Pcond = p
}
case ARET:
case obj.ARET:
nocache5(p)
if cursym.Text.Mark&LEAF != 0 {
if !(autosize != 0) {
p.As = AB
p.From = zprg5.From
p.From = obj.Zprog.From
if p.To.Sym != nil { // retjmp
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
} else {
p.To.Type = D_OREG
p.To.Type = obj.TYPE_MEM
p.To.Offset = 0
p.To.Reg = REGLINK
}
@ -576,10 +522,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW
p.Scond |= C_PBIT
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Offset = int64(autosize)
p.From.Reg = REGSP
p.To.Type = D_REG
p.To.Type = obj.TYPE_REG
p.To.Reg = REGPC
// If there are instructions following
@ -589,19 +535,19 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REGLINK
q2 = obj.Appendp(ctxt, p)
q2.As = AB
q2.To.Type = D_BRANCH
q2.To.Type = obj.TYPE_BRANCH
q2.To.Sym = p.To.Sym
p.To.Sym = nil
p = q2
}
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)
}
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)
}
@ -612,10 +558,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
if ctxt.Debugdivmod != 0 {
break
}
if p.From.Type != D_REG {
if p.From.Type != obj.TYPE_REG {
break
}
if p.To.Type != D_REG {
if p.To.Type != obj.TYPE_REG {
break
}
q1 = p
@ -625,9 +571,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW
p.Lineno = q1.Lineno
p.From.Type = D_REG
p.From.Type = obj.TYPE_REG
p.From.Reg = q1.From.Reg
p.To.Type = D_OREG
p.To.Type = obj.TYPE_MEM
p.To.Reg = REGSP
p.To.Offset = 4
@ -636,12 +582,12 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW
p.Lineno = q1.Lineno
p.From.Type = D_REG
p.From.Reg = int8(q1.Reg)
if q1.Reg == NREG {
p.From.Type = obj.TYPE_REG
p.From.Reg = q1.Reg
if q1.Reg == 0 {
p.From.Reg = q1.To.Reg
}
p.To.Type = D_REG
p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP
p.To.Offset = 0
@ -650,7 +596,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = ABL
p.Lineno = q1.Lineno
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
switch o {
case ADIV:
p.To.Sym = ctxt.Sym_div
@ -671,10 +617,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW
p.Lineno = q1.Lineno
p.From.Type = D_REG
p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP
p.From.Offset = 0
p.To.Type = D_REG
p.To.Type = obj.TYPE_REG
p.To.Reg = q1.To.Reg
/* ADD $8,SP */
@ -682,11 +628,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AADD
p.Lineno = q1.Lineno
p.From.Type = D_CONST
p.From.Reg = NREG
p.From.Type = obj.TYPE_CONST
p.From.Reg = 0
p.From.Offset = 8
p.Reg = NREG
p.To.Type = D_REG
p.Reg = 0
p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP
p.Spadj = -8
@ -695,34 +641,34 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
/* TODO: Remove SP adjustments; see issue 6699. */
q1.As = AMOVW
q1.From.Type = D_OREG
q1.From.Type = obj.TYPE_MEM
q1.From.Reg = REGSP
q1.From.Offset = 0
q1.Reg = NREG
q1.To.Type = D_REG
q1.Reg = 0
q1.To.Type = obj.TYPE_REG
q1.To.Reg = REGTMP
/* SUB $8,SP */
q1 = obj.Appendp(ctxt, q1)
q1.As = AMOVW
q1.From.Type = D_REG
q1.From.Type = obj.TYPE_REG
q1.From.Reg = REGTMP
q1.Reg = NREG
q1.To.Type = D_OREG
q1.Reg = 0
q1.To.Type = obj.TYPE_MEM
q1.To.Reg = REGSP
q1.To.Offset = -8
q1.Scond |= C_WBIT
q1.Spadj = 8
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)
}
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)
}
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)
}
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) {
var p *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 {
switch p.As {
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 notsoft
@ -786,15 +736,15 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
soft:
if !(wasfloat != 0) || (p.Mark&LABEL != 0) {
next = ctxt.NewProg()
next = new(obj.Prog)
*next = *p
// BL _sfloat(SB)
*p = zprg5
*p = obj.Zprog
p.Link = next
p.As = ABL
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p.To.Sym = symsfloat
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.As = AMOVW
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
}
p.To.Type = D_REG
p.To.Reg = 1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
if framesize <= obj.StackSmall {
// 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.As = ACMP
p.From.Type = D_REG
p.From.Reg = 1
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.Reg = REGSP
} else if framesize <= obj.StackBig {
// 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.As = AMOVW
p.From.Type = D_CONST
p.From.Type = obj.TYPE_ADDR
p.From.Reg = REGSP
p.From.Offset = int64(-framesize)
p.To.Type = D_REG
p.To.Reg = 2
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p)
p.As = ACMP
p.From.Type = D_REG
p.From.Reg = 1
p.Reg = 2
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.Reg = REG_R2
} else {
// Such a large stack we need to protect against wraparound
// if SP is close to zero.
// 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.As = ACMP
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
p.Reg = 1
p.Reg = REG_R1
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_CONST
p.From.Type = obj.TYPE_ADDR
p.From.Reg = REGSP
p.From.Offset = obj.StackGuard
p.To.Type = D_REG
p.To.Reg = 2
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p)
p.As = ASUB
p.From.Type = D_REG
p.From.Reg = 1
p.To.Type = D_REG
p.To.Reg = 2
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p)
p.As = AMOVW
p.From.Type = D_CONST
p.From.Type = obj.TYPE_ADDR
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
p.To.Type = D_REG
p.To.Reg = 3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p)
p.As = ACMP
p.From.Type = D_REG
p.From.Reg = 3
p.Reg = 2
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.Reg = REG_R2
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.Scond = C_SCOND_LS
p.From.Type = D_REG
p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK
p.To.Type = D_REG
p.To.Reg = 3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
// BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted
p = obj.Appendp(ctxt, p)
p.As = ABL
p.Scond = C_SCOND_LS
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
if ctxt.Cursym.Cfunc != 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else {
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.As = ABLS
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p.Pcond = ctxt.Cursym.Text.Link
return p
@ -951,7 +899,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
ctxt.Cursym = s
firstp = ctxt.NewProg()
firstp = new(obj.Prog)
lastp = firstp
xfol(ctxt, s.Text, &lastp)
lastp.Link = nil
@ -1011,7 +959,7 @@ loop:
a = int(p.As)
if a == AB {
q = p.Pcond
if q != nil && q.As != ATEXT {
if q != nil && q.As != obj.ATEXT {
p.Mark |= FOLL
p = q
if !(p.Mark&FOLL != 0) {
@ -1028,12 +976,12 @@ loop:
break
}
a = int(q.As)
if a == ANOP {
if a == obj.ANOP {
i--
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
}
if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
@ -1045,7 +993,7 @@ loop:
copy:
for {
r = ctxt.NewProg()
r = new(obj.Prog)
*r = *p
if !(r.Mark&FOLL != 0) {
fmt.Printf("can't happen 1\n")
@ -1060,7 +1008,7 @@ loop:
(*last).Link = 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
}
r.As = ABNE
@ -1080,10 +1028,10 @@ loop:
}
a = AB
q = ctxt.NewProg()
q = new(obj.Prog)
q.As = int16(a)
q.Lineno = p.Lineno
q.To.Type = D_BRANCH
q.To.Type = obj.TYPE_BRANCH
q.To.Offset = p.Pc
q.Pcond = p
p = q
@ -1092,14 +1040,14 @@ loop:
p.Mark |= FOLL
(*last).Link = 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
}
if p.Pcond != nil {
if a != ABL && a != ABX && p.Link != nil {
q = obj.Brchain(ctxt, p.Link)
if a != ATEXT && a != ABCASE {
if a != obj.ATEXT && a != ABCASE {
if q != nil && (q.Mark&FOLL != 0) {
p.As = int16(relinv(a))
p.Link = p.Pcond
@ -1132,41 +1080,11 @@ var Linkarm = obj.LinkArch{
Name: "arm",
Thechar: '5',
Endian: obj.LittleEndian,
Addstacksplit: addstacksplit,
Preprocess: preprocess,
Assemble: span5,
Datasize: datasize,
Follow: follow,
Iscall: iscall,
Isdata: isdata,
Prg: prg,
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) {
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) {
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 {
mangle(pn)
}
@ -71,7 +70,7 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
default:
ctxt.Diag("bad data: %P", p)
case ctxt.Arch.D_FCONST:
case TYPE_FCONST:
switch siz {
default:
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)
}
case ctxt.Arch.D_SCONST:
case TYPE_SCONST:
copy(s.P[off:off+siz], p.To.U.Sval)
case ctxt.Arch.D_CONST, ctxt.Arch.D_ADDR:
if p.To.Sym != nil || int(p.To.Type) == ctxt.Arch.D_ADDR {
case TYPE_CONST, TYPE_ADDR:
if p.To.Sym != nil || int(p.To.Type) == TYPE_ADDR {
r := Addrel(s)
r.Off = off
r.Siz = uint8(siz)
@ -119,7 +118,7 @@ func Addrel(s *LSym) *Reloc {
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 {
s.Type = SDATA
}
@ -147,7 +146,7 @@ func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
var off int64
off = s.Size
setuintxx(ctxt, s, off, v, int64(wid))
Setuintxx(ctxt, s, off, v, int64(wid))
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 {
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 {
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 {
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 {
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 {

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.
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
// 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 © 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.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@ -74,5 +75,5 @@ const (
FUNCDATA_ArgsPointerMaps = 0
FUNCDATA_LocalsPointerMaps = 1
FUNCDATA_DeadValueMaps = 2
ArgsSizeUnknown = 0x80000000
ArgsSizeUnknown = -0x80000000
)

View File

@ -5,12 +5,75 @@
package obj
import (
"fmt"
"math"
"os"
"strings"
)
// 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.
func expandpkg(t0 string, pkg string) string {
return strings.Replace(t0, `"".`, pkg+".", -1)

View File

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

View File

@ -5,6 +5,24 @@ package i386
*/
var Anames = []string{
"XXX ",
"CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"AAA ",
"AAD",
"AAM",
@ -35,7 +53,6 @@ var Anames = []string{
"BTSL",
"BTSW",
"BYTE",
"CALL",
"CLC",
"CLD",
"CLI",
@ -49,7 +66,6 @@ var Anames = []string{
"CMPSW",
"DAA",
"DAS",
"DATA",
"DECB",
"DECL",
"DECW",
@ -57,9 +73,6 @@ var Anames = []string{
"DIVL",
"DIVW",
"ENTER",
"GLOBL",
"GOK",
"HISTORY",
"HLT",
"IDIVB",
"IDIVL",
@ -92,7 +105,6 @@ var Anames = []string{
"JLS",
"JLT",
"JMI",
"JMP",
"JNE",
"JOC",
"JOS",
@ -132,11 +144,9 @@ var Anames = []string{
"MULB",
"MULL",
"MULW",
"NAME",
"NEGB",
"NEGL",
"NEGW",
"NOP",
"NOTB",
"NOTL",
"NOTW",
@ -170,7 +180,6 @@ var Anames = []string{
"RCRW",
"REP",
"REPN",
"RET",
"ROLB",
"ROLL",
"ROLW",
@ -227,7 +236,6 @@ var Anames = []string{
"TESTB",
"TESTL",
"TESTW",
"TEXT",
"VERR",
"VERW",
"WAIT",
@ -340,10 +348,6 @@ var Anames = []string{
"FXTRACT",
"FYL2X",
"FYL2XP1",
"END",
"DYNT_",
"INIT_",
"SIGNAME",
"CMPXCHGB",
"CMPXCHGL",
"CMPXCHGW",
@ -402,7 +406,6 @@ var Anames = []string{
"PREFETCHT2",
"PREFETCHNTA",
"BSWAPL",
"UNDEF",
"ADDPD",
"ADDPS",
"ADDSD",
@ -517,68 +520,5 @@ var Anames = []string{
"AESENC",
"PINSRD",
"PSHUFB",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"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
switch p.As {
case 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))
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.From3.Offset, Dconv(p, 0, &p.To))
case ATEXT:
if p.From.Scale != 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))
case obj.ATEXT:
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.From3.Offset, Dconv(p, 0, &p.To))
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:
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 fp string
var i int
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 {
switch a.Type {
default:
if a.Offset != 0 {
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
} else {
str = fmt.Sprintf("type=%d", a.Type)
str = fmt.Sprintf("%v", Rconv(i))
}
case D_NONE:
case obj.TYPE_NONE:
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 {
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} 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 {
str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else {
str = fmt.Sprintf("%d(PC)", a.Offset)
}
case D_EXTERN:
case obj.TYPE_MEM:
switch a.Name {
default:
str = fmt.Sprintf("name=%d", a.Name)
case obj.NAME_NONE:
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 obj.NAME_EXTERN:
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
case D_STATIC:
case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
case D_AUTO:
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 D_PARAM:
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)
}
case D_CONST:
str = fmt.Sprintf("$%d", a.Offset)
case D_CONST2:
if !(flag&fmtLong != 0 /*untyped*/) {
// D_CONST2 outside of ATEXT should not happen
str = fmt.Sprintf("!!$%d-%d", a.Offset, a.Offset2)
break
}
case D_FCONST:
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
case D_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case D_ADDR:
a.Type = int16(a.Index)
a.Index = D_NONE
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
a.Index = uint8(a.Type)
a.Type = D_ADDR
goto conv
}
brk:
if a.Index != D_NONE {
if a.Index != REG_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
conv:
case obj.TYPE_CONST:
str = fmt.Sprintf("$%d", a.Offset)
// 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)
case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case obj.TYPE_ADDR:
a.Type = obj.TYPE_MEM
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
a.Type = obj.TYPE_ADDR
break
}
fp += str
return fp
}
var Register = []string{
"AL", /* [D_AL] */
"AL", /* [REG_AL] */
"CL",
"DL",
"BL",
@ -194,7 +199,7 @@ var Register = []string{
"CH",
"DH",
"BH",
"AX", /* [D_AX] */
"AX", /* [REG_AX] */
"CX",
"DX",
"BX",
@ -202,7 +207,7 @@ var Register = []string{
"BP",
"SI",
"DI",
"F0", /* [D_F0] */
"F0", /* [REG_F0] */
"F1",
"F2",
"F3",
@ -210,18 +215,18 @@ var Register = []string{
"F5",
"F6",
"F7",
"CS", /* [D_CS] */
"CS", /* [REG_CS] */
"SS",
"DS",
"ES",
"FS",
"GS",
"GDTR", /* [D_GDTR] */
"IDTR", /* [D_IDTR] */
"LDTR", /* [D_LDTR] */
"MSW", /* [D_MSW] */
"TASK", /* [D_TASK] */
"CR0", /* [D_CR] */
"GDTR", /* [REG_GDTR] */
"IDTR", /* [REG_IDTR] */
"LDTR", /* [REG_LDTR] */
"MSW", /* [REG_MSW] */
"TASK", /* [REG_TASK] */
"CR0", /* [REG_CR] */
"CR1",
"CR2",
"CR3",
@ -229,7 +234,7 @@ var Register = []string{
"CR5",
"CR6",
"CR7",
"DR0", /* [D_DR] */
"DR0", /* [REG_DR] */
"DR1",
"DR2",
"DR3",
@ -237,7 +242,7 @@ var Register = []string{
"DR5",
"DR6",
"DR7",
"TR0", /* [D_TR] */
"TR0", /* [REG_TR] */
"TR1",
"TR2",
"TR3",
@ -245,7 +250,7 @@ var Register = []string{
"TR5",
"TR6",
"TR7",
"X0", /* [D_X0] */
"X0", /* [REG_X0] */
"X1",
"X2",
"X3",
@ -253,18 +258,21 @@ var Register = []string{
"X5",
"X6",
"X7",
"TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */
"TLS", /* [REG_TLS] */
"MAXREG", /* [MAXREG] */
}
func Rconv(r int) string {
var str string
var fp string
if r >= D_AL && r <= D_NONE {
str = fmt.Sprintf("%s", Register[r-D_AL])
if r == REG_NONE {
fp += "NONE"
return fp
}
if r >= REG_AL && r-REG_AL < len(Register) {
str = fmt.Sprintf("%s", Register[r-REG_AL])
} else {
str = fmt.Sprintf("gok(%d)", r)
}

View File

@ -38,51 +38,6 @@ import (
"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 {
switch ctxt.Headtype {
case obj.Hlinux,
@ -102,7 +57,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// See obj6.c for discussion of TLS.
if canuselocaltls(ctxt) != 0 {
// Reduce TLS initial exec model to TLS local exec model.
// Sequences like
// MOVL TLS, BX
@ -110,26 +64,26 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// become
// NOP
// ... off(TLS) ...
if p.As == AMOVL && p.From.Type == D_TLS && D_AX <= p.To.Type && p.To.Type <= D_DI {
p.As = ANOP
p.From.Type = D_NONE
p.To.Type = D_NONE
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.From.Type = obj.TYPE_NONE
p.To.Type = obj.TYPE_NONE
}
if p.From.Index == D_TLS && D_INDIR+D_AX <= p.From.Type && p.From.Type <= D_INDIR+D_DI {
p.From.Type = D_INDIR + D_TLS
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 = obj.TYPE_MEM
p.From.Reg = REG_TLS
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 {
p.To.Type = D_INDIR + D_TLS
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 = obj.TYPE_MEM
p.To.Reg = REG_TLS
p.To.Scale = 0
p.To.Index = D_NONE
p.To.Index = REG_NONE
}
} else {
// As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load.
// The instruction
// MOVL off(TLS), BX
@ -137,62 +91,55 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// MOVL TLS, 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.
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.As = p.As
q.From = p.From
q.From.Type = D_INDIR + p.To.Type
q.From.Index = D_TLS
q.From.Type = obj.TYPE_MEM
q.From.Reg = p.To.Reg
q.From.Index = REG_TLS
q.From.Scale = 2 // TODO: use 1
q.To = p.To
p.From.Type = D_TLS
p.From.Index = D_NONE
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_TLS
p.From.Index = REG_NONE
p.From.Offset = 0
}
}
// TODO: Remove.
if ctxt.Headtype == obj.Hplan9 {
if p.From.Scale == 1 && p.From.Index == D_TLS {
if p.From.Scale == 1 && p.From.Index == REG_TLS {
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
}
}
// Rewrite CALL/JMP/RET to symbol as D_BRANCH.
// Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH.
switch p.As {
case ACALL,
AJMP,
ARET:
if (p.To.Type == D_EXTERN || p.To.Type == D_STATIC) && p.To.Sym != nil {
p.To.Type = D_BRANCH
case obj.ACALL,
obj.AJMP,
obj.ARET:
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 = obj.TYPE_BRANCH
}
break
}
// Rewrite float constants to values stored in memory.
switch p.As {
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
case AMOVSS:
if p.From.Type == D_FCONST {
if p.From.Type == obj.TYPE_FCONST {
if p.From.U.Dval == 0 {
if p.To.Type >= D_X0 {
if p.To.Type <= D_X7 {
if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 {
p.As = AXORPS
p.From.Type = p.To.Type
p.From.Index = p.To.Index
p.From = p.To
break
}
}
}
}
fallthrough
// fallthrough
@ -212,8 +159,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
ADIVSS,
ACOMISS,
AUCOMISS:
if p.From.Type == D_FCONST {
if p.From.Type == obj.TYPE_FCONST {
var i32 uint32
var f32 float32
f32 = float32(p.From.U.Dval)
@ -226,26 +172,23 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
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.Offset = 0
}
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
case AMOVSD:
if p.From.Type == D_FCONST {
if p.From.Type == obj.TYPE_FCONST {
if p.From.U.Dval == 0 {
if p.To.Type >= D_X0 {
if p.To.Type <= D_X7 {
if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 {
p.As = AXORPS
p.From.Type = p.To.Type
p.From.Index = p.To.Index
p.From = p.To
break
}
}
}
}
fallthrough
// fallthrough
@ -265,8 +208,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
ADIVSD,
ACOMISD,
AUCOMISD:
if p.From.Type == D_FCONST {
if p.From.Type == obj.TYPE_FCONST {
var i64 uint64
i64 = math.Float64bits(p.From.U.Dval)
literal = fmt.Sprintf("$f64.%016x", i64)
@ -277,7 +219,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
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.Offset = 0
}
@ -286,12 +229,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
}
}
func prg() *obj.Prog {
p := zprg
return &p
}
func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
var p *obj.Prog
var q *obj.Prog
var p1 *obj.Prog
@ -322,37 +260,35 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
}
cursym.Locals = autoffset
cursym.Args = p.To.Offset2
cursym.Args = p.To.U.Argsize
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 = load_g_cx(ctxt, p) // load g into CX
}
if !(cursym.Text.From.Scale&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autoffset, bool2int(!(cursym.Text.From.Scale&obj.NEEDCTXT != 0)), &q) // emit split check
if !(cursym.Text.From3.Offset&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autoffset, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0)), &q) // emit split check
}
if autoffset != 0 {
p = obj.Appendp(ctxt, p)
p.As = AADJSP
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autoffset)
p.Spadj = autoffset
} else {
// zero-byte stack adjustment.
// Insert a fake non-zero adjustment so that stkcheck can
// recognize the end of the stack-splitting prolog.
p = obj.Appendp(ctxt, p)
p.As = ANOP
p.As = obj.ANOP
p.Spadj = int32(-ctxt.Arch.Ptrsize)
p = obj.Appendp(ctxt, p)
p.As = ANOP
p.As = obj.ANOP
p.Spadj = int32(ctxt.Arch.Ptrsize)
}
@ -361,7 +297,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
}
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
//
// MOVL g_panic(CX), BX
@ -380,71 +316,85 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p = obj.Appendp(ctxt, p)
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.To.Type = D_BX
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_BX
p = obj.Appendp(ctxt, p)
p.As = ATESTL
p.From.Type = D_BX
p.To.Type = D_BX
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_BX
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_BX
p = obj.Appendp(ctxt, p)
p.As = AJEQ
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p1 = p
p = obj.Appendp(ctxt, p)
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.To.Type = D_DI
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_DI
p = obj.Appendp(ctxt, p)
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.To.Type = D_DI
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_DI
p = obj.Appendp(ctxt, p)
p.As = AJNE
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p2 = p
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type = D_SP
p.To.Type = D_INDIR + D_BX
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SP
p.To.Type = obj.TYPE_MEM
p.To.Reg = REG_BX
p.To.Offset = 0 // Panic.argp
p = obj.Appendp(ctxt, p)
p.As = ANOP
p.As = obj.ANOP
p1.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.
// This slows down function calls but can help avoid
// false positives in garbage collection.
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type = D_SP
p.To.Type = D_DI
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SP
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_DI
p = obj.Appendp(ctxt, p)
p.As = AMOVL
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
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.As = AMOVL
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
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.As = AREP
@ -454,18 +404,18 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
}
for ; p != nil; p = p.Link {
a = int(p.From.Type)
if a == D_AUTO {
a = int(p.From.Name)
if a == obj.NAME_AUTO {
p.From.Offset += int64(deltasp)
}
if a == D_PARAM {
if a == obj.NAME_PARAM {
p.From.Offset += int64(deltasp) + 4
}
a = int(p.To.Type)
if a == D_AUTO {
a = int(p.To.Name)
if a == obj.NAME_AUTO {
p.To.Offset += int64(deltasp)
}
if a == D_PARAM {
if a == obj.NAME_PARAM {
p.To.Offset += int64(deltasp) + 4
}
@ -497,7 +447,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.Spadj = -2
continue
case ARET:
case obj.ARET:
break
}
@ -507,11 +457,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
if autoffset != 0 {
p.As = AADJSP
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-autoffset)
p.Spadj = -autoffset
p = obj.Appendp(ctxt, p)
p.As = ARET
p.As = obj.ARET
// If there are instructions following
// 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
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.
// Returns last new instruction.
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
var next *obj.Prog
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.To.Type = D_CX
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_CX
next = p.Link
progedit(ctxt, p)
@ -546,7 +497,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
p = p.Link
}
if p.From.Index == D_TLS {
if p.From.Index == REG_TLS {
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
// 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 {
var q *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.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.To.Type = D_SP
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_SP
p = obj.Appendp(ctxt, p)
p.As = AJCC
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p.To.Offset = 4
q1 = p
p = obj.Appendp(ctxt, p)
p.As = AINT
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = 3
p = obj.Appendp(ctxt, p)
p.As = ANOP
p.As = obj.ANOP
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.As = ACMPL
p.From.Type = D_SP
p.To.Type = D_INDIR + D_CX
p.From.Type = obj.TYPE_REG
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
if ctxt.Cursym.Cfunc != 0 {
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.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.To.Type = D_AX
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p)
p.As = ACMPL
p.From.Type = D_AX
p.To.Type = D_INDIR + D_CX
p.From.Type = obj.TYPE_REG
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
if ctxt.Cursym.Cfunc != 0 {
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
}
} else {
// Such a large stack we need to protect against wraparound
// if SP is close to zero.
// 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.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 = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 {
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.As = ACMPL
p.From.Type = D_SI
p.To.Type = D_CONST
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SI
p.To.Type = obj.TYPE_CONST
p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
p = obj.Appendp(ctxt, p)
p.As = AJEQ
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
q1 = p
p = obj.Appendp(ctxt, p)
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.To.Type = D_AX
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p)
p.As = ASUBL
p.From.Type = D_SI
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SI
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.As = ACMPL
p.From.Type = D_AX
p.To.Type = D_CONST
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_AX
p.To.Type = obj.TYPE_CONST
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.As = AJHI
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p.To.Offset = 4
q = p
p = obj.Appendp(ctxt, p)
p.As = ACALL
p.To.Type = D_BRANCH
p.As = obj.ACALL
p.To.Type = obj.TYPE_BRANCH
if ctxt.Cursym.Cfunc != 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else {
p.To.Sym = ctxt.Symmorestack[noctxt]
}
p = obj.Appendp(ctxt, p)
p.As = AJMP
p.To.Type = D_BRANCH
p.As = obj.AJMP
p.To.Type = obj.TYPE_BRANCH
p.Pcond = ctxt.Cursym.Text.Link
if q != nil {
@ -723,7 +687,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
ctxt.Cursym = s
firstp = ctxt.NewProg()
firstp = new(obj.Prog)
lastp = firstp
xfol(ctxt, s.Text, &lastp)
lastp.Link = nil
@ -732,11 +696,11 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
func nofollow(a int) int {
switch a {
case AJMP,
ARET,
case obj.AJMP,
obj.ARET,
AIRETL,
AIRETW,
AUNDEF:
obj.AUNDEF:
return 1
}
@ -808,9 +772,9 @@ loop:
if p == nil {
return
}
if p.As == AJMP {
if p.As == obj.AJMP {
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 */
p.Mark = 1
@ -829,7 +793,6 @@ loop:
i = 0
q = p
for ; i < 4; (func() { i++; q = q.Link })() {
if q == nil {
break
}
@ -837,7 +800,7 @@ loop:
break
}
a = int(q.As)
if a == ANOP {
if a == obj.ANOP {
i--
continue
}
@ -848,11 +811,11 @@ loop:
if q.Pcond == nil || q.Pcond.Mark != 0 {
continue
}
if a == ACALL || a == ALOOP {
if a == obj.ACALL || a == ALOOP {
continue
}
for {
if p.As == ANOP {
if p.As == obj.ANOP {
p = p.Link
continue
}
@ -879,10 +842,10 @@ loop:
/* */
}
}
q = ctxt.NewProg()
q.As = AJMP
q = new(obj.Prog)
q.As = obj.AJMP
q.Lineno = p.Lineno
q.To.Type = D_BRANCH
q.To.Type = obj.TYPE_BRANCH
q.To.Offset = p.Pc
q.Pcond = p
p = q
@ -897,10 +860,9 @@ loop:
/* continue loop with what comes after p */
if nofollow(a) != 0 {
return
}
if p.Pcond != nil && a != ACALL {
if p.Pcond != nil && a != obj.ACALL {
/*
* some kind of conditional branch.
* recurse to follow one path.
@ -908,14 +870,13 @@ loop:
*/
q = obj.Brchain(ctxt, p.Pcond)
if q != nil {
p.Pcond = q
}
q = obj.Brchain(ctxt, p.Link)
if q != nil {
p.Link = q
}
if p.From.Type == D_CONST {
if p.From.Type == obj.TYPE_CONST {
if p.From.Offset == 1 {
/*
* expect conditional jump to be taken.
@ -928,7 +889,6 @@ loop:
p.Pcond = q
}
} else {
q = p.Link
if q.Mark != 0 {
if a != ALOOP {
@ -957,40 +917,11 @@ var Link386 = obj.LinkArch{
Name: "386",
Thechar: '8',
Endian: obj.LittleEndian,
Addstacksplit: addstacksplit,
Preprocess: preprocess,
Assemble: span8,
Datasize: datasize,
Follow: follow,
Iscall: iscall,
Isdata: isdata,
Prg: prg,
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 {
cnt[i] = 1
} else {
cnt[i] = LOG * cnt[i-1]
}
dwn[i] = 1

View File

@ -33,22 +33,23 @@ package obj
import "encoding/binary"
type Addr struct {
Type int16
Reg int16
Index int16
Scale int8
Name int8
Offset int64
Sym *LSym
U struct {
Sval string
Dval float64
Branch *Prog
Argsize int32
Bits uint64
}
Sym *LSym
Gotype *LSym
Type int16
Index uint8
Scale int8
Reg int8
Name int8
Class int8
Etype uint8
Offset2 int32
Node interface{}
Width int64
}
@ -61,7 +62,7 @@ type Prog struct {
As int16
Scond uint8
From Addr
Reg uint8
Reg int16
From3 Addr
To Addr
Opt interface{}
@ -79,7 +80,6 @@ type Prog struct {
Printed uint8
Width int8
Mode int8
TEXTFLAG uint8
}
type LSym struct {
@ -149,7 +149,7 @@ type Auto struct {
Asym *LSym
Link *Auto
Aoffset int32
Type int16
Name int16
Gotype *LSym
}
@ -241,47 +241,17 @@ type Plist struct {
type LinkArch struct {
Pconv func(*Prog) string
ByteOrder binary.ByteOrder
Name string
Thechar int
Endian int32
ByteOrder binary.ByteOrder
Addstacksplit func(*Link, *LSym)
Preprocess func(*Link, *LSym)
Assemble func(*Link, *LSym)
Datasize func(*Prog) int
Follow func(*Link, *LSym)
Iscall func(*Prog) bool
Isdata func(*Prog) bool
Prg func() *Prog
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 {
@ -318,7 +288,156 @@ type Pciter struct {
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
@ -397,7 +516,7 @@ const (
RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1
)
// Auto.type
// Auto.name
const (
A_AUTO = 1 + iota
A_PARAM
@ -461,3 +580,17 @@ const (
// go.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
)
func linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string {
func Linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string {
var a [HISTSZ]struct {
incl *Hist
idel int32
@ -222,11 +222,9 @@ func Linklinehist(ctxt *Link, lineno int, f string, offset int) {
if offset != 0 {
fmt.Printf("%4d: %s (#line %d)\n", lineno, f, offset)
} else {
fmt.Printf("%4d: %s\n", lineno, f)
}
} else {
fmt.Printf("%4d: <pop>\n", lineno)
}
}
@ -297,7 +295,6 @@ func Linkprfile(ctxt *Link, line int) {
* start a new Prog list.
*/
func Linknewplist(ctxt *Link) *Plist {
var pl *Plist
pl = new(Plist)
@ -305,7 +302,6 @@ func Linknewplist(ctxt *Link) *Plist {
if ctxt.Plist == nil {
ctxt.Plist = pl
} else {
ctxt.Plast.Link = 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
// does not write out object files.
func Writeobjdirect(ctxt *Link, b *Biobuf) {
var flag int
var found int
var h *Hist
@ -44,16 +43,16 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
for pl = ctxt.Plist; pl != nil; pl = pl.Link {
for p = pl.Firstpc; p != nil; p = plink {
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
fmt.Printf("obj: %p %v\n", p, p)
fmt.Printf("obj: %v\n", p)
}
plink = p.Link
p.Link = nil
if int(p.As) == ctxt.Arch.AEND {
if p.As == AEND {
continue
}
if int(p.As) == ctxt.Arch.ATYPE {
if p.As == ATYPE {
// Assume each TYPE instruction describes
// a different local variable or parameter,
// so no dedup.
@ -66,20 +65,19 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
// If something else could use them, we could arrange to
// preserve them.
if curtext == nil {
continue
}
a = new(Auto)
a.Asym = p.From.Sym
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.Link = curtext.Autom
curtext.Autom = a
continue
}
if int(p.As) == ctxt.Arch.AGLOBL {
if p.As == AGLOBL {
s = p.From.Sym
tmp6 := s.Seenglobl
s.Seenglobl++
@ -93,7 +91,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
if data == nil {
data = s
} else {
edata.Next = s
}
s.Next = nil
@ -101,7 +98,7 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
if s.Type == 0 || s.Type == SXREF {
s.Type = SBSS
}
flag = ctxt.Arch.Textflag(p)
flag = int(p.From3.Offset)
if flag&DUPOK != 0 {
s.Dupok = 1
}
@ -114,12 +111,12 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
continue
}
if int(p.As) == ctxt.Arch.ADATA {
if p.As == ADATA {
savedata(ctxt, p.From.Sym, p, "<input>")
continue
}
if int(p.As) == ctxt.Arch.ATEXT {
if p.As == ATEXT {
s = p.From.Sym
if s == nil {
// func _() { }
@ -138,11 +135,10 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
if text == nil {
text = s
} else {
etext.Next = s
}
etext = s
flag = ctxt.Arch.Textflag(p)
flag = int(p.From3.Offset)
if flag&DUPOK != 0 {
s.Dupok = 1
}
@ -157,16 +153,16 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
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.
if curtext == nil { // func _() {}
continue
}
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")
}
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.
for s = text; s != nil; s = s.Next {
if !strings.HasPrefix(s.Name, "\"\".") {
continue
}
found = 0
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
break
}
@ -195,28 +190,21 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
if !(found != 0) {
p = Appendp(ctxt, s.Text)
p.As = int16(ctxt.Arch.AFUNCDATA)
p.From.Type = int16(ctxt.Arch.D_CONST)
p.As = AFUNCDATA
p.From.Type = TYPE_CONST
p.From.Offset = FUNCDATA_ArgsPointerMaps
if ctxt.Arch.Thechar == '6' || ctxt.Arch.Thechar == '8' {
p.To.Type = int16(ctxt.Arch.D_EXTERN)
} else {
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))
p.To.Type = TYPE_MEM
p.To.Name = NAME_EXTERN
p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version))
}
}
// Turn functions into machine code images.
for s = text; s != nil; s = s.Next {
mkfwd(s)
linkpatch(ctxt, s)
ctxt.Arch.Follow(ctxt, s)
ctxt.Arch.Addstacksplit(ctxt, s)
ctxt.Arch.Preprocess(ctxt, s)
ctxt.Arch.Assemble(ctxt, s)
linkpcln(ctxt, s)
}
@ -230,7 +218,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
// Emit autolib.
for h = ctxt.Hist; h != nil; h = h.Link {
if h.Offset < 0 {
wrstring(b, h.Name)
}
@ -239,7 +226,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
// Emit symbols.
for s = text; s != nil; s = s.Next {
writesym(ctxt, b, s)
}
for s = data; s != nil; s = s.Next {
@ -307,7 +293,6 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) {
if ' ' <= c && c <= 0x7e {
fmt.Fprintf(ctxt.Bso, "%c", c)
} else {
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' {
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 {
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 {
wrsym(b, a.Asym)
wrint(b, int64(a.Aoffset))
if int(a.Type) == ctxt.Arch.D_AUTO {
if a.Name == NAME_AUTO {
wrint(b, A_AUTO)
} else if int(a.Type) == ctxt.Arch.D_PARAM {
} else if a.Name == NAME_PARAM {
wrint(b, A_PARAM)
} else {
log.Fatalf("%s: invalid local variable type %d", s.Name, a.Type)
log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name)
}
wrsym(b, a.Gotype)
}

View File

@ -33,11 +33,10 @@ package obj
// Code and data passes.
func Brchain(ctxt *Link, p *Prog) *Prog {
var i int
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
}
p = p.Pcond
@ -52,7 +51,7 @@ func brloop(ctxt *Link, p *Prog) *Prog {
c = 0
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
}
c++
@ -64,6 +63,92 @@ func brloop(ctxt *Link, p *Prog) *Prog {
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) {
var c int32
var name string
@ -73,10 +158,14 @@ func linkpatch(ctxt *Link, sym *LSym) {
ctxt.Cursym = sym
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 {
ctxt.Arch.Progedit(ctxt, p)
}
if int(p.To.Type) != ctxt.Arch.D_BRANCH {
if p.To.Type != TYPE_BRANCH {
continue
}
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 {
q = q.Forwd
} else {
q = q.Link
}
}
@ -108,7 +196,7 @@ func linkpatch(ctxt *Link, sym *LSym) {
name = p.To.Sym.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
@ -120,7 +208,7 @@ func linkpatch(ctxt *Link, sym *LSym) {
if p.Pcond != nil {
p.Pcond = brloop(ctxt, p.Pcond)
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
}
}

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
// 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{}) {
var dbg int
var i int
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
// for a true instruction boundary in the program.
if p.Link != nil && p.Link.Pc == p.Pc {
val = valfunc(ctxt, func_, val, p, 1, arg)
if ctxt.Debugpcln != 0 {
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.
if ctxt.Debugpcln != 0 {
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 {
delta = 1 | ^(delta << 1)
} else {
delta <<= 1
}
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)
// takes care of the update.
func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
var i int32
var l int32
var f *LSym
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
}
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
// apply the change during phase == 1.
func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
if oldval == -1 { // starting
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,
// 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 {
if phase == 0 || int(p.As) != ctxt.Arch.APCDATA || p.From.Offset != int64(arg.(uint32)) {
if phase == 0 || p.As != APCDATA || p.From.Offset != int64(arg.(uint32)) {
return oldval
}
if int64(int32(p.To.Offset)) != p.To.Offset {
@ -243,10 +236,10 @@ func linkpcln(ctxt *Link, cursym *LSym) {
npcdata = 0
nfuncdata = 0
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)
}
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)
}
}
@ -265,21 +258,20 @@ func linkpcln(ctxt *Link, cursym *LSym) {
havepc := make([]uint32, (npcdata+31)/32)
havefunc := make([]uint32, (nfuncdata+31)/32)
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 {
ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset)
}
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)
}
}
// pcdata.
for i = 0; i < npcdata; i++ {
if (havepc[i/32]>>uint(i%32))&1 == 0 {
continue
}
@ -288,12 +280,11 @@ func linkpcln(ctxt *Link, cursym *LSym) {
// funcdata
if nfuncdata > 0 {
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)
pcln.Funcdataoff[i] = p.To.Offset
if int(p.To.Type) != ctxt.Arch.D_CONST {
if p.To.Type != TYPE_CONST {
// TODO: Dedup.
//funcdata_bytes += p->to.sym->size;
pcln.Funcdata[i] = p.To.Sym
@ -306,7 +297,6 @@ func linkpcln(ctxt *Link, cursym *LSym) {
// iteration over encoded pcdata tables.
func getvarint(pp *[]byte) uint32 {
var p []byte
var shift int
var v uint32

View File

@ -29,6 +29,8 @@
package ppc64
import "cmd/internal/obj"
// auto generated by go tool dist
/*
@ -41,30 +43,112 @@ const (
NFREG = 32
)
// avoid conflict with ucontext.h. sigh.
const (
REGZERO = 0
REGSP = 1
REGSB = 2
REGRET = 3
REG_R0 = 32 + iota
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_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
REGRT1 = 3
REGRT2 = 4
REGMIN = 7
REGENV = 11
REGTLS = 13
REGMAX = 27
REGEXT = 30
REGG = 30
REGTMP = 31
FREGRET = 0
FREGMIN = 17
FREGMAX = 26
FREGEXT = 26
FREGCVI = 27
FREGZERO = 28
FREGHALF = 29
FREGONE = 30
FREGTWO = 31
REGRT1 = REG_R3
REGRT2 = REG_R4
REGMIN = REG_R7
REGENV = REG_R11
REGTLS = REG_R13
REGMAX = REG_R27
REGEXT = REG_R30
REGG = REG_R30
REGTMP = REG_R31
FREGRET = REG_F0
FREGMIN = REG_F17
FREGMAX = REG_F26
FREGEXT = REG_F26
FREGCVI = REG_F27
FREGZERO = REG_F28
FREGHALF = REG_F29
FREGONE = REG_F30
FREGTWO = REG_F31
)
/*
@ -129,12 +213,12 @@ const (
C_ANY
C_GOK
C_ADDR
C_TEXTSIZE
C_NCLASS
)
const (
AXXX = iota
AADD
AADD = obj.A_ARCHSPECIFIC + iota
AADDCC
AADDV
AADDVCC
@ -163,11 +247,9 @@ const (
ABEQ
ABGE
ABGT
ABL
ABLE
ABLT
ABNE
ABR
ABVC
ABVS
ACMP
@ -349,19 +431,7 @@ const (
ATLBSYNC
ATW
ASYSCALL
ADATA
AGLOBL
AGOK
AHISTORY
ANAME
ANOP
ARETURN
ATEXT
AWORD
AEND
ADYNT
AINIT
ASIGNAME
ARFCI
AFRES
AFRESCC
@ -438,48 +508,8 @@ const (
AREMDUV
AREMDUVCC
AHRFID
AUNDEF
AUSEFIELD
ATYPE
AFUNCDATA
APCDATA
ACHECKNIL
AVARDEF
AVARKILL
ADUFFCOPY
ADUFFZERO
ALAST
)
/* type/name */
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
ABR = obj.AJMP
ABL = obj.ACALL
ARETURN = obj.ARET
)

View File

@ -1,12 +1,28 @@
package ppc64
/* and many supervisor level registers */
/*
* this is the ranlib header
*/
var Anames = []string{
"XXX ",
"CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"ADD ",
"ADDCC",
"ADDV",
@ -36,11 +52,9 @@ var Anames = []string{
"BEQ",
"BGE",
"BGT",
"BL",
"BLE",
"BLT",
"BNE",
"BR",
"BVC",
"BVS",
"CMP",
@ -222,19 +236,7 @@ var Anames = []string{
"TLBSYNC",
"TW",
"SYSCALL",
"DATA",
"GLOBL",
"GOK",
"HISTORY",
"NAME",
"NOP",
"RETURN",
"TEXT",
"WORD",
"END",
"DYNT",
"INIT",
"SIGNAME",
"RFCI",
"FRES",
"FRESCC",
@ -311,16 +313,6 @@ var Anames = []string{
"REMDUV",
"REMDUVCC",
"HRFID",
"UNDEF",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"LAST",
}
@ -359,31 +351,6 @@ var cnames9 = []string{
"ANY",
"GOK",
"ADDR",
"TEXTSIZE",
"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{
Optab{ATEXT, C_LEXT, C_NONE, C_NONE, C_LCON, 0, 0, 0},
Optab{ATEXT, C_LEXT, C_REG, C_NONE, C_LCON, 0, 0, 0},
Optab{ATEXT, C_LEXT, C_NONE, C_LCON, C_LCON, 0, 0, 0},
Optab{ATEXT, C_LEXT, C_REG, C_LCON, C_LCON, 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},
Optab{obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
Optab{obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
Optab{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
Optab{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
/* move register */
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},
@ -389,15 +385,15 @@ var optab = []Optab{
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_LCON, C_REG, 42, 4, 0},
Optab{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{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{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{ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
Optab{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0},
Optab{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
Optab{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
Optab{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
Optab{obj.ADUFFZERO, 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 {
@ -426,7 +422,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
return
}
ctxt.Cursym = cursym
ctxt.Autosize = int32(p.To.Offset&0xffffffff) + 8
ctxt.Autosize = int32(p.To.Offset + 8)
if oprange[AANDN].start == nil {
buildop(ctxt)
@ -441,7 +437,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
o = oplook(ctxt, p)
m = int(o.size)
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)
}
continue
@ -472,21 +468,20 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
// very large conditional branches
if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
otxt = p.Pcond.Pc - c
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
q = ctxt.NewProg()
q = new(obj.Prog)
q.Link = p.Link
p.Link = q
q.As = ABR
q.To.Type = D_BRANCH
q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Pcond
p.Pcond = q
q = ctxt.NewProg()
q = new(obj.Prog)
q.Link = p.Link
p.Link = q
q.As = ABR
q.To.Type = D_BRANCH
q.To.Type = obj.TYPE_BRANCH
q.Pcond = q.Link.Link
//addnop(p->link);
@ -497,7 +492,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
m = int(o.size)
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)
}
continue
@ -516,7 +511,6 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
* lay out the code, emitting code and data relocations.
*/
if ctxt.Tlsg == nil {
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
switch a.Type {
case D_NONE:
case obj.TYPE_NONE:
return C_NONE
case D_REG:
case obj.TYPE_REG:
if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
return C_REG
case D_FREG:
}
if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
return C_FREG
case D_CREG:
}
if REG_C0 <= a.Reg && a.Reg <= REG_C7 || a.Reg == REG_CR {
return C_CREG
case D_SPR:
if a.Offset == D_LR {
}
if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
switch a.Reg {
case REG_LR:
return C_LR
}
if a.Offset == D_XER {
case REG_XER:
return C_XER
}
if a.Offset == D_CTR {
case REG_CTR:
return C_CTR
}
return C_SPR
case D_DCR:
return C_SPR
}
case D_FPSCR:
if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
return C_SPR
}
if a.Reg == REG_FPSCR {
return C_FPSCR
case D_MSR:
}
if a.Reg == REG_MSR {
return C_MSR
}
return C_GOK
case D_OREG:
case obj.TYPE_MEM:
switch a.Name {
case D_EXTERN,
D_STATIC:
case obj.NAME_EXTERN,
obj.NAME_STATIC:
if a.Sym == nil {
break
}
@ -596,21 +596,21 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
}
return C_LEXT
case D_AUTO:
case obj.NAME_AUTO:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SAUTO
}
return C_LAUTO
case D_PARAM:
case obj.NAME_PARAM:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SAUTO
}
return C_LAUTO
case D_NONE:
case obj.TYPE_NONE:
ctxt.Instoffset = a.Offset
if ctxt.Instoffset == 0 {
return C_ZOREG
@ -623,18 +623,15 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
return C_GOK
case D_OPT:
ctxt.Instoffset = a.Offset & 31
if a.Name == D_NONE {
return C_SCON
}
return C_GOK
case obj.TYPE_TEXTSIZE:
return C_TEXTSIZE
case D_CONST:
case obj.TYPE_CONST,
obj.TYPE_ADDR:
switch a.Name {
case D_NONE:
case obj.TYPE_NONE:
ctxt.Instoffset = a.Offset
if a.Reg != NREG {
if a.Reg != 0 {
if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG {
return C_SACON
}
@ -646,8 +643,8 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
goto consize
case D_EXTERN,
D_STATIC:
case obj.NAME_EXTERN,
obj.NAME_STATIC:
s = a.Sym
if s == nil {
break
@ -662,14 +659,14 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
/* not sure why this barfs */
return C_LCON
case D_AUTO:
case obj.NAME_AUTO:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SACON
}
return C_LACON
case D_PARAM:
case obj.NAME_PARAM:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SACON
@ -710,7 +707,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
}
return C_DCON
case D_BRANCH:
case obj.TYPE_BRANCH:
return C_SBRA
}
@ -759,7 +756,7 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
a4--
a2 = C_NONE
if p.Reg != NREG {
if p.Reg != 0 {
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]))
for i = 0; i < n; i++ {
@ -1295,14 +1291,14 @@ func buildop(ctxt *obj.Link) {
ASLBMTE,
AWORD,
ADWORD,
ANOP,
ATEXT,
AUNDEF,
AUSEFIELD,
AFUNCDATA,
APCDATA,
ADUFFZERO,
ADUFFCOPY:
obj.ANOP,
obj.ATEXT,
obj.AUNDEF,
obj.AUSEFIELD,
obj.AFUNCDATA,
obj.APCDATA,
obj.ADUFFZERO,
obj.ADUFFCOPY:
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 */
func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
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.
func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
var rel *obj.Reloc
rel = obj.Addrel(ctxt.Cursym)
@ -1412,7 +1406,6 @@ func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
* 32-bit masks
*/
func getmask(m []byte, v uint32) int {
var i int
m[1] = 0
@ -1461,7 +1454,6 @@ func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) {
* 64-bit masks (rldic etc)
*/
func getmask64(m []byte, v uint64) int {
var i int
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);
switch o.type_ {
default:
ctxt.Diag("unknown type %d", o.type_)
prasm(p)
@ -1543,8 +1534,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
break
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)
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
//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 */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.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)
r = int(p.From.Reg)
if r == NREG {
if r == 0 {
r = int(o.param)
}
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
} else {
if int64(int16(d)) != d {
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)
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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 */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.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) */
r = int(p.To.Reg)
if r == NREG {
if r == 0 {
r = int(o.param)
}
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 {
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))
} else {
if int32(int16(v)) != v {
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) */
r = int(p.From.Reg)
if r == NREG {
if r == 0 {
r = int(o.param)
}
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 {
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))
} else {
if int32(int16(v)) != v {
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 */
r = int(p.From.Reg)
if r == NREG {
if r == 0 {
r = int(o.param)
}
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 {
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))
} else {
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)
@ -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 */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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) */
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)
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
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 {
o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
} else {
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 */
if p.As == AMOVBZ {
o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
} else if p.As == AMOVH {
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 {
o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
} else {
ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
}
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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 */
a = 0
if p.From.Type == D_CONST {
if p.From.Type == obj.TYPE_CONST {
a = int(regoff(ctxt, &p.From))
}
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = 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) */
if p.As == ABC || p.As == ABCL {
v = regoff(ctxt, &p.To) & 31
} else {
v = 20 /* unconditional */
}
r = int(p.Reg)
if r == NREG {
if 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)
if p.As == ABL || p.As == ABCL {
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) */
if p.As == ABC || p.As == ABCL {
v = regoff(ctxt, &p.From) & 31
} else {
v = 20 /* unconditional */
}
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = 0
}
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)
o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
} else {
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(int32(d))))
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(d))
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)
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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)
}
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 */
if p.To.Reg == REGTMP || p.Reg == REGTMP {
ctxt.Diag("cant synthesize large constant\n%v", p)
}
d = vregoff(ctxt, &p.From)
o1 = loadu32(REGTMP, d)
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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. */
if p.To.Reg == REGTMP || p.Reg == REGTMP {
ctxt.Diag("cant synthesize large constant\n%v", p)
}
d = vregoff(ctxt, &p.From)
o1 = loadu32(REGTMP, d)
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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
}
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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 */
if p.To.Reg == REGTMP {
ctxt.Diag("can't synthesize large constant\n%v", p)
}
v = regoff(ctxt, &p.From)
r = int(p.From.Reg)
if r == NREG {
if r == 0 {
r = int(o.param)
}
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 */
if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
ctxt.Diag("can't synthesize large constant\n%v", p)
}
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)
o2 = uint32(d)
} else {
o1 = uint32(d)
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 */
r = int(p.Reg)
if r == NREG {
if r == 0 {
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
@ -2108,7 +2080,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v = regoff(ctxt, &p.To)
r = int(p.To.Reg)
if r == NREG {
if r == 0 {
r = int(o.param)
}
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)
r = int(p.From.Reg)
if r == NREG {
if r == 0 {
r = int(o.param)
}
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)
r = int(p.From.Reg)
if r == NREG {
if r == 0 {
r = int(o.param)
}
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) */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = 0
}
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 */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = 0
}
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 */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = 0
}
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 */
r = int(p.From.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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 */
r = int(p.From.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
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
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
} else {
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg))
}
case 50: /* rem[u] r1[,r2],r3 */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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 */
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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*/
if oclass(&p.From) == C_REG {
if p.As == AMOVD {
o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
} else {
o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
}
} else {
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)
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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)
r = int(p.Reg)
if r == NREG {
if r == 0 {
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);
*/
if v < 0 {
v = 0
} else if v > 32 {
v = 32
@ -2289,7 +2256,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
mask[1] = 31
v = 32 - v
} else {
mask[0] = 0
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)
r = int(p.Reg)
if r == NREG {
if r == 0 {
r = int(p.To.Reg)
}
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)
r = int(p.Reg)
if r == NREG {
if r == 0 {
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 */
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
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
} else {
v = 255
}
o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
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)
}
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 */
if p.From.Type == D_REG {
if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
r = int(p.From.Reg)
v = int32(p.To.Offset)
if p.To.Type == D_DCR {
v = int32(p.To.Reg)
if REG_DCR0 <= v && v <= REG_DCR0+1023 {
o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
} else {
o1 = OPVCC(31, 467, 0, 0) /* mtspr */
}
} else {
r = int(p.To.Reg)
v = int32(p.From.Offset)
if p.From.Type == D_DCR {
v = int32(p.From.Reg)
if REG_DCR0 <= v && v <= REG_DCR0+1023 {
o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
} else {
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
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)
}
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 */
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) */
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
} else {
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
}
case 69: /* mtcrf CRM,rS */
if p.From3.Type != D_NONE {
if p.To.Reg != NREG {
if p.From3.Type != obj.TYPE_NONE {
if p.To.Reg != 0 {
ctxt.Diag("can't use both mask and CR(n)\n%v", p)
}
v = regoff(ctxt, &p.From3) & 0xff
} else {
if p.To.Reg == NREG {
if p.To.Reg == 0 {
v = 0xff /* CR */
} else {
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
case 70: /* [f]cmp r,r,cr*/
if p.Reg == NREG {
if p.Reg == 0 {
r = 0
} else {
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))
case 71: /* cmp[l] r,i,cr*/
if p.Reg == NREG {
if p.Reg == 0 {
r = 0
} else {
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
@ -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))
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)
}
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 */
if p.From.Type == D_CONST {
if p.From.Type == obj.TYPE_CONST {
if p.From.Offset > BIG || p.From.Offset < -BIG {
ctxt.Diag("illegal syscall, sysnum too large: %v", p)
}
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))
} else {
ctxt.Diag("illegal syscall: %v", p)
o1 = 0x7fe00008 // trap always
}
@ -3046,21 +2992,21 @@ func opirr(ctxt *obj.Link, a int) int32 {
return int32(OPVCC(12, 0, 0, 0))
case AADDCCC:
return int32(OPVCC(13, 0, 0, 0))
case AADD + AEND:
case AADD + ALAST:
return int32(OPVCC(15, 0, 0, 0)) /* ADDIS/CAU */
case AANDCC:
return int32(OPVCC(28, 0, 0, 0))
case AANDCC + AEND:
case AANDCC + ALAST:
return int32(OPVCC(29, 0, 0, 0)) /* ANDIS./ANDIU. */
case ABR:
return int32(OPVCC(18, 0, 0, 0))
case ABL:
return int32(OPVCC(18, 0, 0, 0) | 1)
case ADUFFZERO:
case obj.ADUFFZERO:
return int32(OPVCC(18, 0, 0, 0) | 1)
case ADUFFCOPY:
case obj.ADUFFCOPY:
return int32(OPVCC(18, 0, 0, 0) | 1)
case ABC:
return int32(OPVCC(16, 0, 0, 0))
@ -3100,7 +3046,7 @@ func opirr(ctxt *obj.Link, a int) int32 {
case AOR:
return int32(OPVCC(24, 0, 0, 0))
case AOR + AEND:
case AOR + ALAST:
return int32(OPVCC(25, 0, 0, 0)) /* ORIS/ORIU */
case ARLWMI:
@ -3152,7 +3098,7 @@ func opirr(ctxt *obj.Link, a int) int32 {
case AXOR:
return int32(OPVCC(26, 0, 0, 0)) /* XORIL */
case AXOR + AEND:
case AXOR + ALAST:
return int32(OPVCC(27, 0, 0, 0)) /* XORIU */
}
@ -3164,7 +3110,6 @@ func opirr(ctxt *obj.Link, a int) int32 {
* load o(a),d
*/
func opload(ctxt *obj.Link, a int) int32 {
switch a {
case AMOVD:
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
*/
func oploadx(ctxt *obj.Link, a int) int32 {
switch a {
case AMOVWZ:
return int32(OPVCC(31, 23, 0, 0)) /* lwzx */
@ -3274,7 +3218,6 @@ func oploadx(ctxt *obj.Link, a int) int32 {
* store s,o(d)
*/
func opstore(ctxt *obj.Link, a int) int32 {
switch a {
case AMOVB,
AMOVBZ:
@ -3325,7 +3268,6 @@ func opstore(ctxt *obj.Link, a int) int32 {
* indexed store s,a(b)
*/
func opstorex(ctxt *obj.Link, a int) int32 {
switch a {
case AMOVB,
AMOVBZ:

View File

@ -43,7 +43,6 @@ const (
// %A int Opcodes (instruction mnemonics)
//
// %D Addr* Addresses (instruction operands)
// Flags: "%lD": seperate the high and low words of a constant by "-"
//
// %P Prog* Instructions
//
@ -59,49 +58,34 @@ func Pconv(p *obj.Prog) string {
var fp string
var a int
var ch int
a = int(p.As)
if a == ADATA || a == AINIT || a == ADYNT {
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))
} else if a == ATEXT {
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, fmtLong, &p.To))
str = ""
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.From3.Offset, Dconv(p, 0, &p.To))
} else if a == obj.ATEXT || a == obj.AGLOBL {
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 {
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))
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 p.Mark&NOSCHED != 0 {
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))
} else if a != ATEXT && p.From.Type == D_OREG {
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))
} else if p.To.Type == D_OREG {
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)
} else if a != obj.ATEXT && p.From.Type == obj.TYPE_MEM {
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 == obj.TYPE_MEM {
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 {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From))
if p.Reg != NREG {
ch = 'R'
if p.From.Type == D_FREG {
ch = 'F'
if p.Reg != 0 {
str += fmt.Sprintf(",%v", Rconv(int(p.Reg)))
}
str += fmt.Sprintf(",%c%d", ch, p.Reg)
}
if p.From3.Type != D_NONE {
if p.From3.Type != obj.TYPE_NONE {
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.From3))
}
str += fmt.Sprintf(",%v", Dconv(p, 0, &p.To))
@ -122,7 +106,7 @@ func Aconv(a int) string {
var fp string
s = "???"
if a >= AXXX && a < ALAST {
if a >= obj.AXXX && a < ALAST {
s = Anames[a]
}
fp += s
@ -135,126 +119,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string {
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 {
default:
str = fmt.Sprintf("GOK-type(%d)", a.Type)
case D_NONE:
case obj.TYPE_NONE:
str = ""
if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg)
if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil {
str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
}
case D_CONST,
D_DCONST:
if a.Reg != NREG {
str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg)
case obj.TYPE_CONST,
obj.TYPE_ADDR:
if a.Reg != 0 {
str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else {
str = fmt.Sprintf("$%v", Mconv(a))
}
case D_OREG:
if a.Reg != NREG {
str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg)
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_MEM:
if a.Reg != 0 {
str = fmt.Sprintf("%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else {
str = fmt.Sprintf("%v", Mconv(a))
}
case D_REG:
str = fmt.Sprintf("R%d", a.Reg)
if a.Name != D_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg)
case obj.TYPE_REG:
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
if a.Name != obj.TYPE_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
}
case D_FREG:
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:
case obj.TYPE_BRANCH:
if p.Pcond != nil {
v = int32(p.Pcond.Pc)
//if(v >= INITTEXT)
// v -= INITTEXT-HEADR;
if a.Sym != nil {
str = fmt.Sprintf("%s+%.5x(BRANCH)", a.Sym.Name, uint32(v))
} else {
str = fmt.Sprintf("%.5x(BRANCH)", uint32(v))
}
} 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 {
str = fmt.Sprintf("%s+%d(APC)", a.Sym.Name, a.Offset)
} else {
str = fmt.Sprintf("%d(APC)", a.Offset)
}
//sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
case D_FCONST:
case obj.TYPE_FCONST:
str = fmt.Sprintf("$%.17g", a.U.Dval)
case D_SCONST:
case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
break
}
ret:
fp += str
return fp
}
@ -298,43 +207,38 @@ func Mconv(a *obj.Addr) string {
// goto out;
//}
switch a.Name {
default:
str = fmt.Sprintf("GOK-name(%d)", a.Name)
case D_NONE:
case obj.TYPE_NONE:
l = int32(a.Offset)
if int64(l) != a.Offset {
str = fmt.Sprintf("0x%x", uint64(a.Offset))
} else {
str = fmt.Sprintf("%d", a.Offset)
}
case D_EXTERN:
case obj.NAME_EXTERN:
if a.Offset != 0 {
str = fmt.Sprintf("%s+%d(SB)", s.Name, a.Offset)
} else {
str = fmt.Sprintf("%s(SB)", s.Name)
}
case D_STATIC:
case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", s.Name, a.Offset)
case D_AUTO:
case obj.NAME_AUTO:
if s == nil {
str = fmt.Sprintf("%d(SP)", -a.Offset)
} else {
str = fmt.Sprintf("%s-%d(SP)", s.Name, -a.Offset)
}
case D_PARAM:
case obj.NAME_PARAM:
if s == nil {
str = fmt.Sprintf("%d(FP)", a.Offset)
} else {
str = fmt.Sprintf("%s+%d(FP)", s.Name, a.Offset)
}
break
@ -346,16 +250,61 @@ func Mconv(a *obj.Addr) string {
}
func Rconv(r int) string {
var str string
var fp string
if r < NREG {
str = fmt.Sprintf("r%d", r)
} else {
str = fmt.Sprintf("f%d", r-NREG)
if r == 0 {
fp += "NONE"
return fp
}
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
}

View File

@ -36,50 +36,6 @@ import (
"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) {
var literal string
var s *obj.LSym
@ -87,25 +43,23 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p.From.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 {
case ABR,
ABL,
ARETURN,
ADUFFZERO,
ADUFFCOPY:
obj.ADUFFZERO,
obj.ADUFFCOPY:
if p.To.Sym != nil {
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
}
break
}
// Rewrite float constants to values stored in memory.
switch p.As {
case AFMOVS:
if p.From.Type == D_FCONST {
if p.From.Type == obj.TYPE_FCONST {
var i32 uint32
var f32 float32
f32 = float32(p.From.U.Dval)
@ -113,56 +67,54 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
literal = fmt.Sprintf("$f32.%08x", i32)
s = obj.Linklookup(ctxt, literal, 0)
s.Size = 4
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Name = D_EXTERN
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
case AFMOVD:
if p.From.Type == D_FCONST {
if p.From.Type == obj.TYPE_FCONST {
var i64 uint64
i64 = math.Float64bits(p.From.U.Dval)
literal = fmt.Sprintf("$f64.%016x", i64)
s = obj.Linklookup(ctxt, literal, 0)
s.Size = 8
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Name = D_EXTERN
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
// Put >32-bit constants in memory and load them
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))
s = obj.Linklookup(ctxt, literal, 0)
s.Size = 8
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
p.From.Name = D_EXTERN
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
}
// Rewrite SUB constants into ADD.
switch p.As {
case ASUBC:
if p.From.Type == D_CONST {
if p.From.Type == obj.TYPE_CONST {
p.From.Offset = -p.From.Offset
p.As = AADDC
}
case ASUBCCC:
if p.From.Type == D_CONST {
if p.From.Type == obj.TYPE_CONST {
p.From.Offset = -p.From.Offset
p.As = AADDCCC
}
case ASUB:
if p.From.Type == D_CONST {
if p.From.Type == obj.TYPE_CONST {
p.From.Offset = -p.From.Offset
p.As = AADD
}
@ -171,20 +123,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
}
}
func parsetextconst(arg int64, textstksiz *int64, textarg *int64) {
*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) {
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
var p *obj.Prog
var q *obj.Prog
var p1 *obj.Prog
@ -194,7 +133,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
var mov int
var aoffset int
var textstksiz int64
var textarg int64
var autosize int32
if ctxt.Symmorestack[0] == nil {
@ -210,9 +148,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
}
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)
/*
@ -222,7 +160,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
* expand BECOME pseudo
*/
if ctxt.Debugvlog != 0 {
fmt.Fprintf(ctxt.Bso, "%5.2f noops\n", obj.Cputime())
}
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 {
switch p.As {
/* too hard, just leave alone */
case ATEXT:
case obj.ATEXT:
q = p
p.Mark |= LABEL | LEAF | SYNC
@ -241,7 +178,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
case ANOR:
q = p
if p.To.Type == D_REG {
if p.To.Type == obj.TYPE_REG {
if p.To.Reg == REGZERO {
p.Mark |= LABEL | SYNC
}
@ -284,24 +221,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
AMOVWZ,
AMOVD:
q = p
switch p.From.Type {
case D_MSR,
D_SPR,
D_FPSCR,
D_CREG,
D_DCR:
if p.From.Reg >= REG_SPECIAL || p.To.Reg >= REG_SPECIAL {
p.Mark |= LABEL | SYNC
}
switch p.To.Type {
case D_MSR,
D_SPR,
D_FPSCR,
D_CREG,
D_DCR:
p.Mark |= LABEL | SYNC
}
continue
case AFABS,
@ -346,8 +268,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
case ABL,
ABCL,
ADUFFZERO,
ADUFFCOPY:
obj.ADUFFZERO,
obj.ADUFFCOPY:
cursym.Text.Mark &^= LEAF
fallthrough
@ -365,7 +287,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q = p
q1 = p.Pcond
if q1 != nil {
for q1.As == ANOP {
for q1.As == obj.ANOP {
q1 = q1.Link
p.Pcond = q1
}
@ -374,7 +296,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q1.Mark |= LABEL
}
} else {
p.Mark |= LABEL
}
q1 = p.Link
@ -396,7 +317,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
}
continue
case ANOP:
case obj.ANOP:
q1 = p.Link
q.Link = q1 /* q is non-nop */
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 {
o = int(p.As)
switch o {
case ATEXT:
case obj.ATEXT:
mov = AMOVD
aoffset = 0
autosize = int32(textstksiz + 8)
@ -421,10 +342,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
} else if autosize&4 != 0 {
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) {
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.Reg&obj.NEEDCTXT != 0))) // emit split check
if !(p.From3.Offset&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0))) // emit split check
}
q = p
@ -432,17 +353,15 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
if autosize != 0 {
/* use MOVDU to adjust R1 when saving R31, if autosize is small */
if !(cursym.Text.Mark&LEAF != 0) && autosize >= -BIG && autosize <= BIG {
mov = AMOVDU
aoffset = int(-autosize)
} else {
q = obj.Appendp(ctxt, p)
q.As = AADD
q.Lineno = p.Lineno
q.From.Type = D_CONST
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(-autosize)
q.To.Type = D_REG
q.To.Type = obj.TYPE_REG
q.To.Reg = REGSP
q.Spadj = +autosize
}
@ -463,24 +382,24 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q = obj.Appendp(ctxt, q)
q.As = AMOVD
q.Lineno = p.Lineno
q.From.Type = D_SPR
q.From.Offset = D_LR
q.To.Type = D_REG
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_LR
q.To.Type = obj.TYPE_REG
q.To.Reg = REGTMP
q = obj.Appendp(ctxt, q)
q.As = int16(mov)
q.Lineno = p.Lineno
q.From.Type = D_REG
q.From.Type = obj.TYPE_REG
q.From.Reg = REGTMP
q.To.Type = D_OREG
q.To.Type = obj.TYPE_MEM
q.To.Offset = int64(aoffset)
q.To.Reg = REGSP
if q.As == AMOVDU {
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
//
// MOVD g_panic(g), R3
@ -501,109 +420,109 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q = obj.Appendp(ctxt, q)
q.As = AMOVD
q.From.Type = D_OREG
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
q.To.Type = D_REG
q.To.Reg = 3
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q)
q.As = ACMP
q.From.Type = D_REG
q.From.Reg = 0
q.To.Type = D_REG
q.To.Reg = 3
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R0
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q)
q.As = ABEQ
q.To.Type = D_BRANCH
q.To.Type = obj.TYPE_BRANCH
p1 = q
q = obj.Appendp(ctxt, q)
q.As = AMOVD
q.From.Type = D_OREG
q.From.Reg = 3
q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R3
q.From.Offset = 0 // Panic.argp
q.To.Type = D_REG
q.To.Reg = 4
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R4
q = obj.Appendp(ctxt, q)
q.As = AADD
q.From.Type = D_CONST
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) + 8
q.Reg = REGSP
q.To.Type = D_REG
q.To.Reg = 5
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q)
q.As = ACMP
q.From.Type = D_REG
q.From.Reg = 4
q.To.Type = D_REG
q.To.Reg = 5
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R4
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q)
q.As = ABNE
q.To.Type = D_BRANCH
q.To.Type = obj.TYPE_BRANCH
p2 = q
q = obj.Appendp(ctxt, q)
q.As = AADD
q.From.Type = D_CONST
q.From.Type = obj.TYPE_CONST
q.From.Offset = 8
q.Reg = REGSP
q.To.Type = D_REG
q.To.Reg = 6
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R6
q = obj.Appendp(ctxt, q)
q.As = AMOVD
q.From.Type = D_REG
q.From.Reg = 6
q.To.Type = D_OREG
q.To.Reg = 3
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R6
q.To.Type = obj.TYPE_MEM
q.To.Reg = REG_R3
q.To.Offset = 0 // Panic.argp
q = obj.Appendp(ctxt, q)
q.As = ANOP
q.As = obj.ANOP
p1.Pcond = q
p2.Pcond = q
}
case ARETURN:
if p.From.Type == D_CONST {
if p.From.Type == obj.TYPE_CONST {
ctxt.Diag("using BECOME (%v) is not supported!", p)
break
}
if p.To.Sym != nil { // retjmp
p.As = ABR
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
break
}
if cursym.Text.Mark&LEAF != 0 {
if !(autosize != 0) {
p.As = ABR
p.From = zprg.From
p.To.Type = D_SPR
p.To.Offset = D_LR
p.From = obj.Zprog.From
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_LR
p.Mark |= BRANCH
break
}
p.As = AADD
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize)
p.To.Type = D_REG
p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP
p.Spadj = -autosize
q = ctxt.NewProg()
q = new(obj.Prog)
q.As = ABR
q.Lineno = p.Lineno
q.To.Type = D_SPR
q.To.Offset = D_LR
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_LR
q.Mark |= BRANCH
q.Spadj = +autosize
@ -613,19 +532,19 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
}
p.As = AMOVD
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Offset = 0
p.From.Reg = REGSP
p.To.Type = D_REG
p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP
q = ctxt.NewProg()
q = new(obj.Prog)
q.As = AMOVD
q.Lineno = p.Lineno
q.From.Type = D_REG
q.From.Type = obj.TYPE_REG
q.From.Reg = REGTMP
q.To.Type = D_SPR
q.To.Offset = D_LR
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_LR
q.Link = p.Link
p.Link = q
@ -633,14 +552,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
if false {
// Debug bad returns
q = ctxt.NewProg()
q = new(obj.Prog)
q.As = AMOVD
q.Lineno = p.Lineno
q.From.Type = D_OREG
q.From.Type = obj.TYPE_MEM
q.From.Offset = 0
q.From.Reg = REGTMP
q.To.Type = D_REG
q.To.Type = obj.TYPE_REG
q.To.Reg = REGTMP
q.Link = p.Link
@ -649,12 +568,12 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
}
if autosize != 0 {
q = ctxt.NewProg()
q = new(obj.Prog)
q.As = AADD
q.Lineno = p.Lineno
q.From.Type = D_CONST
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize)
q.To.Type = D_REG
q.To.Type = obj.TYPE_REG
q.To.Reg = REGSP
q.Spadj = -autosize
@ -662,11 +581,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
p.Link = q
}
q1 = ctxt.NewProg()
q1 = new(obj.Prog)
q1.As = ABR
q1.Lineno = p.Lineno
q1.To.Type = D_SPR
q1.To.Offset = D_LR
q1.To.Type = obj.TYPE_REG
q1.To.Reg = REG_LR
q1.Mark |= BRANCH
q1.Spadj = +autosize
@ -674,7 +593,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) {
q.Link = q1
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)
}
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 {
var q *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.As = AMOVD
p.From.Type = D_OREG
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
if ctxt.Cursym.Cfunc != 0 {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
}
p.To.Type = D_REG
p.To.Reg = 3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
q = nil
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.As = ACMPU
p.From.Type = D_REG
p.From.Reg = 3
p.To.Type = D_REG
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP
} else if framesize <= obj.StackBig {
// 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.As = AADD
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-framesize)
p.Reg = REGSP
p.To.Type = D_REG
p.To.Reg = 4
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p)
p.As = ACMPU
p.From.Type = D_REG
p.From.Reg = 3
p.To.Type = D_REG
p.To.Reg = 4
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
} else {
// Such a large stack we need to protect against wraparound.
// If SP is close to zero:
// 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.As = ACMP
p.From.Type = D_REG
p.From.Reg = 3
p.To.Type = D_CONST
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_CONST
p.To.Offset = obj.StackPreempt
p = obj.Appendp(ctxt, p)
q = p
p.As = ABEQ
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p = obj.Appendp(ctxt, p)
p.As = AADD
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard
p.Reg = REGSP
p.To.Type = D_REG
p.To.Reg = 4
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p)
p.As = ASUB
p.From.Type = D_REG
p.From.Reg = 3
p.To.Type = D_REG
p.To.Reg = 4
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p)
p.As = AMOVD
p.From.Type = D_CONST
p.From.Type = obj.TYPE_CONST
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 = obj.Appendp(ctxt, p)
p.As = ACMPU
p.From.Type = D_REG
p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP
p.To.Type = D_REG
p.To.Reg = 4
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
}
// q1: BLT done
@ -840,16 +757,16 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P
q1 = p
p.As = ABLT
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
// MOVD LR, R5
p = obj.Appendp(ctxt, p)
p.As = AMOVD
p.From.Type = D_SPR
p.From.Offset = D_LR
p.To.Type = D_REG
p.To.Reg = 5
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_LR
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R5
if q != nil {
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.As = ABL
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
if ctxt.Cursym.Cfunc != 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else {
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.As = ABR
p.To.Type = D_BRANCH
p.To.Type = obj.TYPE_BRANCH
p.Pcond = ctxt.Cursym.Text.Link
// placeholder for q1's jump target
p = obj.Appendp(ctxt, p)
p.As = ANOP // zero-width place holder
p.As = obj.ANOP // zero-width place holder
q1.Pcond = p
return p
@ -888,7 +804,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) {
ctxt.Cursym = s
firstp = ctxt.NewProg()
firstp = new(obj.Prog)
lastp = firstp
xfol(ctxt, s.Text, &lastp)
lastp.Link = nil
@ -966,7 +882,7 @@ loop:
}
b = 0 /* set */
a = int(q.As)
if a == ANOP {
if a == obj.ANOP {
i--
continue
}
@ -984,7 +900,7 @@ loop:
copy:
for {
r = ctxt.NewProg()
r = new(obj.Prog)
*r = *p
if !(r.Mark&FOLL != 0) {
fmt.Printf("cant happen 1\n")
@ -1016,10 +932,10 @@ loop:
}
a = ABR
q = ctxt.NewProg()
q = new(obj.Prog)
q.As = int16(a)
q.Lineno = p.Lineno
q.To.Type = D_BRANCH
q.To.Type = obj.TYPE_BRANCH
q.To.Offset = p.Pc
q.Pcond = p
p = q
@ -1052,54 +968,19 @@ loop:
goto loop
}
func prg() *obj.Prog {
p := zprg
return &p
}
var Linkppc64 = obj.LinkArch{
ByteOrder: binary.BigEndian,
Pconv: Pconv,
Name: "ppc64",
Thechar: '9',
Endian: obj.BigEndian,
Addstacksplit: addstacksplit,
Preprocess: preprocess,
Assemble: span9,
Datasize: datasize,
Follow: follow,
Iscall: iscall,
Isdata: isdata,
Prg: prg,
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{
@ -1108,41 +989,11 @@ var Linkppc64le = obj.LinkArch{
Name: "ppc64le",
Thechar: '9',
Endian: obj.LittleEndian,
Addstacksplit: addstacksplit,
Preprocess: preprocess,
Assemble: span9,
Datasize: datasize,
Follow: follow,
Iscall: iscall,
Isdata: isdata,
Prg: prg,
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
val int
}{
struct {
name string
val int
}{"android", Hlinux},
struct {
name string
val int
@ -70,6 +66,10 @@ var headers = []struct {
name string
val int
}{"linux", Hlinux},
struct {
name string
val int
}{"android", Hlinux}, // must be after "linux" entry or else headstr(Hlinux) == "android"
struct {
name string
val int
@ -129,6 +129,8 @@ func Linknew(arch *LinkArch) *Link {
var p string
var buf string
linksetexp()
ctxt = new(Link)
ctxt.Arch = arch
ctxt.Version = HistVersion
@ -151,7 +153,6 @@ func Linknew(arch *LinkArch) *Link {
// Record thread-local storage offset.
// TODO(rsc): Move tlsoffset back into the linker.
switch ctxt.Headtype {
default:
log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype))
@ -194,7 +195,6 @@ func Linknew(arch *LinkArch) *Link {
*/
case Hdarwin:
switch ctxt.Arch.Thechar {
default:
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.
if ctxt.Arch.Thechar == '5' {
p = Getgoarm()
if p != "" {
ctxt.Goarm = int32(Atoi(p))
} else {
ctxt.Goarm = 6
}
}
@ -281,6 +279,5 @@ func Linklookup(ctxt *Link, name string, v int) *LSym {
// read-only lookup
func linkrlookup(ctxt *Link, name string, v int) *LSym {
return _lookup(ctxt, name, v, 0)
}

View File

@ -25,10 +25,19 @@ func Cputime() float64 {
type Biobuf struct {
unget int
haveUnget bool
f *os.File
r *bufio.Reader
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 {
return &Biobuf{w: bufio.NewWriter(w)}
}
@ -75,6 +84,15 @@ func Bflush(b *Biobuf) error {
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 {
if x := os.Getenv(key); x != "" {
return x
@ -108,7 +126,7 @@ func Atoi(s string) int {
}
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 {
@ -119,7 +137,11 @@ func (p *Prog) String() string {
}
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
return p
}
func (ctxt *Link) Line(n int) string {
return Linklinefmt(ctxt, n, false, false)
}

View File

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

@ -5,6 +5,24 @@ package x86
*/
var Anames = []string{
"XXX ",
"CALL",
"CHECKNIL",
"DATA",
"DUFFCOPY",
"DUFFZERO",
"END",
"FUNCDATA",
"GLOBL",
"JMP",
"NOP",
"PCDATA",
"RET",
"TEXT",
"TYPE",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"AAA ",
"AAD",
"AAM",
@ -35,7 +53,6 @@ var Anames = []string{
"BTSL",
"BTSW",
"BYTE",
"CALL",
"CLC",
"CLD",
"CLI",
@ -49,7 +66,6 @@ var Anames = []string{
"CMPSW",
"DAA",
"DAS",
"DATA",
"DECB",
"DECL",
"DECQ",
@ -58,9 +74,6 @@ var Anames = []string{
"DIVL",
"DIVW",
"ENTER",
"GLOBL",
"GOK",
"HISTORY",
"HLT",
"IDIVB",
"IDIVL",
@ -93,7 +106,6 @@ var Anames = []string{
"JLS",
"JLT",
"JMI",
"JMP",
"JNE",
"JOC",
"JOS",
@ -136,11 +148,9 @@ var Anames = []string{
"MULB",
"MULL",
"MULW",
"NAME",
"NEGB",
"NEGL",
"NEGW",
"NOP",
"NOTB",
"NOTL",
"NOTW",
@ -174,7 +184,6 @@ var Anames = []string{
"RCRW",
"REP",
"REPN",
"RET",
"ROLB",
"ROLL",
"ROLW",
@ -231,7 +240,6 @@ var Anames = []string{
"TESTB",
"TESTL",
"TESTW",
"TEXT",
"VERR",
"VERW",
"WAIT",
@ -340,10 +348,6 @@ var Anames = []string{
"FXTRACT",
"FYL2X",
"FYL2XP1",
"END",
"DYNT_",
"INIT_",
"SIGNAME",
"CMPXCHGB",
"CMPXCHGL",
"CMPXCHGW",
@ -684,7 +688,6 @@ var Anames = []string{
"MOVQL",
"BSWAPL",
"BSWAPQ",
"UNDEF",
"AESENC",
"AESENCLAST",
"AESDEC",
@ -693,97 +696,5 @@ var Anames = []string{
"AESKEYGENASSIST",
"PSHUFD",
"PCLMULQDQ",
"USEFIELD",
"TYPE",
"FUNCDATA",
"PCDATA",
"CHECKNIL",
"VARDEF",
"VARKILL",
"DUFFCOPY",
"DUFFZERO",
"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)
//
// %D Addr* Addresses (instruction operands)
// Flags: "%lD": seperate the high and low words of a constant by "-"
//
// %P Prog* Instructions
//
@ -59,16 +58,16 @@ func Pconv(p *obj.Prog) string {
var fp string
switch p.As {
case 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))
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.From3.Offset, Dconv(p, 0, &p.To))
case ATEXT:
if p.From.Scale != 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))
case obj.ATEXT:
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.From3.Offset, Dconv(p, 0, &p.To))
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:
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 fp string
var i int
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 {
switch a.Type {
default:
if a.Offset != 0 {
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i))
} else {
str = fmt.Sprintf("type=%d", a.Type)
str = fmt.Sprintf("%v", Rconv(i))
}
case D_NONE:
case obj.TYPE_NONE:
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 {
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
} 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 {
str = fmt.Sprintf("%d", a.U.Branch.Pc)
} else {
str = fmt.Sprintf("%d(PC)", a.Offset)
}
case D_EXTERN:
case obj.TYPE_MEM:
switch a.Name {
default:
str = fmt.Sprintf("name=%d", a.Name)
case obj.NAME_NONE:
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 obj.NAME_EXTERN:
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
case D_STATIC:
case obj.NAME_STATIC:
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
case D_AUTO:
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 D_PARAM:
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)
}
case D_CONST:
str = fmt.Sprintf("$%d", a.Offset)
case D_FCONST:
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
case D_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case D_ADDR:
a.Type = int16(a.Index)
a.Index = D_NONE
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
a.Index = uint8(a.Type)
a.Type = D_ADDR
goto conv
break
}
brk:
if a.Index != D_NONE {
if a.Index != REG_NONE {
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
str += s
}
conv:
case obj.TYPE_CONST:
str = fmt.Sprintf("$%d", a.Offset)
// 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)
case obj.TYPE_SCONST:
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
case obj.TYPE_ADDR:
a.Type = obj.TYPE_MEM
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
a.Type = obj.TYPE_ADDR
break
}
fp += str
return fp
}
@ -305,17 +307,21 @@ var Register = []string{
"TR6",
"TR7",
"TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */
"MAXREG", /* [MAXREG] */
}
func Rconv(r int) string {
var str string
var fp string
if r >= D_AL && r <= D_NONE {
str = fmt.Sprintf("%s", Register[r-D_AL])
} else {
if r == REG_NONE {
fp += "NONE"
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)
}

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1930,11 +1930,13 @@ prefixof(Link *ctxt, Addr *a)
}
static int
oclass(Link *ctxt, Addr *a)
oclass(Link *ctxt, Prog *p, Addr *a)
{
vlong v;
int32 l;
USED(p);
// TODO(rsc): This special case is for SHRQ $3, AX:DX,
// which encodes as SHRQ $32(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;
if(p->ft == 0)
p->ft = oclass(ctxt, &p->from);
p->ft = oclass(ctxt, p, &p->from);
if(p->tt == 0)
p->tt = oclass(ctxt, &p->to);
p->tt = oclass(ctxt, p, &p->to);
ft = p->ft * Ymax;
tt = p->tt * Ymax;
@ -3291,7 +3293,7 @@ bad:
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;
mfound:

View File

@ -1485,10 +1485,12 @@ prefixof(Link *ctxt, Addr *a)
}
static int
oclass(Link *ctxt, Addr *a)
oclass(Link *ctxt, Prog *p, Addr *a)
{
int32 v;
USED(p);
// TODO(rsc): This special case is for SHRQ $3, AX:DX,
// which encodes as SHRQ $32(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;
if(p->ft == 0)
p->ft = oclass(ctxt, &p->from);
p->ft = oclass(ctxt, p, &p->from);
if(p->tt == 0)
p->tt = oclass(ctxt, &p->to);
p->tt = oclass(ctxt, p, &p->to);
ft = p->ft * Ymax;
tt = p->tt * Ymax;

View File

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