mirror of
https://github.com/golang/go.git
synced 2025-05-18 05:44:35 +00:00
[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:
parent
8db173b85e
commit
1fc330d8fe
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -1,8 +1,26 @@
|
||||
package arm
|
||||
|
||||
var Anames = []string{
|
||||
"XXX",
|
||||
"AND",
|
||||
"XXX ",
|
||||
"CALL",
|
||||
"CHECKNIL",
|
||||
"DATA",
|
||||
"DUFFCOPY",
|
||||
"DUFFZERO",
|
||||
"END",
|
||||
"FUNCDATA",
|
||||
"GLOBL",
|
||||
"JMP",
|
||||
"NOP",
|
||||
"PCDATA",
|
||||
"RET",
|
||||
"TEXT",
|
||||
"TYPE",
|
||||
"UNDEF",
|
||||
"USEFIELD",
|
||||
"VARDEF",
|
||||
"VARKILL",
|
||||
"AND ",
|
||||
"EOR",
|
||||
"SUB",
|
||||
"RSB",
|
||||
@ -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
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
@ -1127,46 +1075,16 @@ loop:
|
||||
}
|
||||
|
||||
var Linkarm = obj.LinkArch{
|
||||
ByteOrder: binary.LittleEndian,
|
||||
Pconv: Pconv,
|
||||
Name: "arm",
|
||||
Thechar: '5',
|
||||
Endian: obj.LittleEndian,
|
||||
Addstacksplit: addstacksplit,
|
||||
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,
|
||||
ByteOrder: binary.LittleEndian,
|
||||
Pconv: Pconv,
|
||||
Name: "arm",
|
||||
Thechar: '5',
|
||||
Endian: obj.LittleEndian,
|
||||
Preprocess: preprocess,
|
||||
Assemble: span5,
|
||||
Follow: follow,
|
||||
Progedit: progedit,
|
||||
Minlc: 4,
|
||||
Ptrsize: 4,
|
||||
Regsize: 4,
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -4,8 +4,26 @@ package i386
|
||||
* this is the ranlib header
|
||||
*/
|
||||
var Anames = []string{
|
||||
"XXX",
|
||||
"AAA",
|
||||
"XXX ",
|
||||
"CALL",
|
||||
"CHECKNIL",
|
||||
"DATA",
|
||||
"DUFFCOPY",
|
||||
"DUFFZERO",
|
||||
"END",
|
||||
"FUNCDATA",
|
||||
"GLOBL",
|
||||
"JMP",
|
||||
"NOP",
|
||||
"PCDATA",
|
||||
"RET",
|
||||
"TEXT",
|
||||
"TYPE",
|
||||
"UNDEF",
|
||||
"USEFIELD",
|
||||
"VARDEF",
|
||||
"VARKILL",
|
||||
"AAA ",
|
||||
"AAD",
|
||||
"AAM",
|
||||
"AAS",
|
||||
@ -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
@ -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:
|
||||
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
|
||||
case obj.TYPE_MEM:
|
||||
switch a.Name {
|
||||
default:
|
||||
str = fmt.Sprintf("name=%d", a.Name)
|
||||
|
||||
case D_STATIC:
|
||||
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
|
||||
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 D_AUTO:
|
||||
if a.Sym != nil {
|
||||
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
|
||||
} else {
|
||||
case obj.NAME_EXTERN:
|
||||
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
|
||||
|
||||
str = fmt.Sprintf("%d(SP)", a.Offset)
|
||||
case obj.NAME_STATIC:
|
||||
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
|
||||
|
||||
case obj.NAME_AUTO:
|
||||
if a.Sym != nil {
|
||||
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
|
||||
} else {
|
||||
str = fmt.Sprintf("%d(SP)", a.Offset)
|
||||
}
|
||||
|
||||
case obj.NAME_PARAM:
|
||||
if a.Sym != nil {
|
||||
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
|
||||
} else {
|
||||
str = fmt.Sprintf("%d(FP)", a.Offset)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case D_PARAM:
|
||||
if a.Sym != nil {
|
||||
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
|
||||
} else {
|
||||
|
||||
str = fmt.Sprintf("%d(FP)", a.Offset)
|
||||
if a.Index != REG_NONE {
|
||||
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||
str += s
|
||||
}
|
||||
|
||||
case D_CONST:
|
||||
case obj.TYPE_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)
|
||||
// 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 D_FCONST:
|
||||
case obj.TYPE_TEXTSIZE:
|
||||
if a.U.Argsize == obj.ArgsSizeUnknown {
|
||||
str = fmt.Sprintf("$%d", a.Offset)
|
||||
} else {
|
||||
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
|
||||
}
|
||||
|
||||
case obj.TYPE_FCONST:
|
||||
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
|
||||
|
||||
case D_SCONST:
|
||||
case obj.TYPE_SCONST:
|
||||
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
||||
|
||||
case D_ADDR:
|
||||
a.Type = int16(a.Index)
|
||||
a.Index = D_NONE
|
||||
case obj.TYPE_ADDR:
|
||||
a.Type = obj.TYPE_MEM
|
||||
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
|
||||
a.Index = uint8(a.Type)
|
||||
a.Type = D_ADDR
|
||||
goto conv
|
||||
a.Type = obj.TYPE_ADDR
|
||||
break
|
||||
}
|
||||
|
||||
brk:
|
||||
if a.Index != D_NONE {
|
||||
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||
str += s
|
||||
}
|
||||
|
||||
conv:
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -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,59 +91,52 @@ 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 {
|
||||
p.As = AXORPS
|
||||
p.From.Type = p.To.Type
|
||||
p.From.Index = p.To.Index
|
||||
break
|
||||
}
|
||||
if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 {
|
||||
p.As = AXORPS
|
||||
p.From = p.To
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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,23 +172,20 @@ 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 {
|
||||
p.As = AXORPS
|
||||
p.From.Type = p.To.Type
|
||||
p.From.Index = p.To.Index
|
||||
break
|
||||
}
|
||||
if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 {
|
||||
p.As = AXORPS
|
||||
p.From = p.To
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
@ -952,45 +912,16 @@ loop:
|
||||
}
|
||||
|
||||
var Link386 = obj.LinkArch{
|
||||
ByteOrder: binary.LittleEndian,
|
||||
Pconv: Pconv,
|
||||
Name: "386",
|
||||
Thechar: '8',
|
||||
Endian: obj.LittleEndian,
|
||||
Addstacksplit: addstacksplit,
|
||||
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,
|
||||
ByteOrder: binary.LittleEndian,
|
||||
Pconv: Pconv,
|
||||
Name: "386",
|
||||
Thechar: '8',
|
||||
Endian: obj.LittleEndian,
|
||||
Preprocess: preprocess,
|
||||
Assemble: span8,
|
||||
Follow: follow,
|
||||
Progedit: progedit,
|
||||
Minlc: 1,
|
||||
Ptrsize: 4,
|
||||
Regsize: 4,
|
||||
}
|
||||
|
@ -116,7 +116,6 @@ func mkfwd(sym *LSym) {
|
||||
if i == 0 {
|
||||
cnt[i] = 1
|
||||
} else {
|
||||
|
||||
cnt[i] = LOG * cnt[i-1]
|
||||
}
|
||||
dwn[i] = 1
|
||||
|
@ -33,24 +33,25 @@ 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
|
||||
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
|
||||
Gotype *LSym
|
||||
Class int8
|
||||
Etype uint8
|
||||
Node interface{}
|
||||
Width int64
|
||||
}
|
||||
|
||||
type Prog struct {
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -240,48 +240,18 @@ type Plist struct {
|
||||
}
|
||||
|
||||
type LinkArch struct {
|
||||
Pconv func(*Prog) string
|
||||
Name string
|
||||
Thechar int
|
||||
Endian int32
|
||||
ByteOrder binary.ByteOrder
|
||||
Addstacksplit 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
|
||||
Pconv func(*Prog) string
|
||||
ByteOrder binary.ByteOrder
|
||||
Name string
|
||||
Thechar int
|
||||
Endian int32
|
||||
Preprocess func(*Link, *LSym)
|
||||
Assemble func(*Link, *LSym)
|
||||
Follow func(*Link, *LSym)
|
||||
Progedit func(*Link, *Prog)
|
||||
Minlc int
|
||||
Ptrsize int
|
||||
Regsize 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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -1,13 +1,29 @@
|
||||
package ppc64
|
||||
|
||||
/* and many supervisor level registers */
|
||||
|
||||
/*
|
||||
* this is the ranlib header
|
||||
*/
|
||||
var Anames = []string{
|
||||
"XXX",
|
||||
"ADD",
|
||||
"XXX ",
|
||||
"CALL",
|
||||
"CHECKNIL",
|
||||
"DATA",
|
||||
"DUFFCOPY",
|
||||
"DUFFZERO",
|
||||
"END",
|
||||
"FUNCDATA",
|
||||
"GLOBL",
|
||||
"JMP",
|
||||
"NOP",
|
||||
"PCDATA",
|
||||
"RET",
|
||||
"TEXT",
|
||||
"TYPE",
|
||||
"UNDEF",
|
||||
"USEFIELD",
|
||||
"VARDEF",
|
||||
"VARKILL",
|
||||
"ADD ",
|
||||
"ADDCC",
|
||||
"ADDV",
|
||||
"ADDVCC",
|
||||
@ -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",
|
||||
}
|
||||
|
@ -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:
|
||||
return C_REG
|
||||
|
||||
case D_FREG:
|
||||
return C_FREG
|
||||
|
||||
case D_CREG:
|
||||
return C_CREG
|
||||
|
||||
case D_SPR:
|
||||
if a.Offset == D_LR {
|
||||
return C_LR
|
||||
case obj.TYPE_REG:
|
||||
if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
|
||||
return C_REG
|
||||
}
|
||||
if a.Offset == D_XER {
|
||||
return C_XER
|
||||
if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
|
||||
return C_FREG
|
||||
}
|
||||
if a.Offset == D_CTR {
|
||||
return C_CTR
|
||||
if REG_C0 <= a.Reg && a.Reg <= REG_C7 || a.Reg == REG_CR {
|
||||
return C_CREG
|
||||
}
|
||||
return C_SPR
|
||||
if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
|
||||
switch a.Reg {
|
||||
case REG_LR:
|
||||
return C_LR
|
||||
|
||||
case D_DCR:
|
||||
return C_SPR
|
||||
case REG_XER:
|
||||
return C_XER
|
||||
|
||||
case D_FPSCR:
|
||||
return C_FPSCR
|
||||
case REG_CTR:
|
||||
return C_CTR
|
||||
}
|
||||
|
||||
case D_MSR:
|
||||
return C_MSR
|
||||
return C_SPR
|
||||
}
|
||||
|
||||
case D_OREG:
|
||||
if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
|
||||
return C_SPR
|
||||
}
|
||||
if a.Reg == REG_FPSCR {
|
||||
return C_FPSCR
|
||||
}
|
||||
if a.Reg == REG_MSR {
|
||||
return C_MSR
|
||||
}
|
||||
return C_GOK
|
||||
|
||||
case obj.TYPE_MEM:
|
||||
switch a.Name {
|
||||
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:
|
||||
|
@ -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'
|
||||
}
|
||||
str += fmt.Sprintf(",%c%d", ch, p.Reg)
|
||||
if p.Reg != 0 {
|
||||
str += fmt.Sprintf(",%v", Rconv(int(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
|
||||
}
|
||||
|
||||
|
@ -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,97 +968,32 @@ 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,
|
||||
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,
|
||||
ByteOrder: binary.BigEndian,
|
||||
Pconv: Pconv,
|
||||
Name: "ppc64",
|
||||
Thechar: '9',
|
||||
Endian: obj.BigEndian,
|
||||
Preprocess: preprocess,
|
||||
Assemble: span9,
|
||||
Follow: follow,
|
||||
Progedit: progedit,
|
||||
Minlc: 4,
|
||||
Ptrsize: 8,
|
||||
Regsize: 8,
|
||||
}
|
||||
|
||||
var Linkppc64le = obj.LinkArch{
|
||||
ByteOrder: binary.LittleEndian,
|
||||
Pconv: Pconv,
|
||||
Name: "ppc64le",
|
||||
Thechar: '9',
|
||||
Endian: obj.LittleEndian,
|
||||
Addstacksplit: addstacksplit,
|
||||
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,
|
||||
ByteOrder: binary.LittleEndian,
|
||||
Pconv: Pconv,
|
||||
Name: "ppc64le",
|
||||
Thechar: '9',
|
||||
Endian: obj.LittleEndian,
|
||||
Preprocess: preprocess,
|
||||
Assemble: span9,
|
||||
Follow: follow,
|
||||
Progedit: progedit,
|
||||
Minlc: 4,
|
||||
Ptrsize: 8,
|
||||
Regsize: 8,
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -4,8 +4,26 @@ package x86
|
||||
* this is the ranlib header
|
||||
*/
|
||||
var Anames = []string{
|
||||
"XXX",
|
||||
"AAA",
|
||||
"XXX ",
|
||||
"CALL",
|
||||
"CHECKNIL",
|
||||
"DATA",
|
||||
"DUFFCOPY",
|
||||
"DUFFZERO",
|
||||
"END",
|
||||
"FUNCDATA",
|
||||
"GLOBL",
|
||||
"JMP",
|
||||
"NOP",
|
||||
"PCDATA",
|
||||
"RET",
|
||||
"TEXT",
|
||||
"TYPE",
|
||||
"UNDEF",
|
||||
"USEFIELD",
|
||||
"VARDEF",
|
||||
"VARKILL",
|
||||
"AAA ",
|
||||
"AAD",
|
||||
"AAM",
|
||||
"AAS",
|
||||
@ -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
@ -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:
|
||||
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
|
||||
case obj.TYPE_MEM:
|
||||
switch a.Name {
|
||||
default:
|
||||
str = fmt.Sprintf("name=%d", a.Name)
|
||||
|
||||
case D_STATIC:
|
||||
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
|
||||
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 D_AUTO:
|
||||
if a.Sym != nil {
|
||||
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
|
||||
} else {
|
||||
case obj.NAME_EXTERN:
|
||||
str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset)
|
||||
|
||||
str = fmt.Sprintf("%d(SP)", a.Offset)
|
||||
case obj.NAME_STATIC:
|
||||
str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset)
|
||||
|
||||
case obj.NAME_AUTO:
|
||||
if a.Sym != nil {
|
||||
str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset)
|
||||
} else {
|
||||
str = fmt.Sprintf("%d(SP)", a.Offset)
|
||||
}
|
||||
|
||||
case obj.NAME_PARAM:
|
||||
if a.Sym != nil {
|
||||
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
|
||||
} else {
|
||||
str = fmt.Sprintf("%d(FP)", a.Offset)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case D_PARAM:
|
||||
if a.Sym != nil {
|
||||
str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset)
|
||||
} else {
|
||||
|
||||
str = fmt.Sprintf("%d(FP)", a.Offset)
|
||||
if a.Index != REG_NONE {
|
||||
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||
str += s
|
||||
}
|
||||
|
||||
case D_CONST:
|
||||
case obj.TYPE_CONST:
|
||||
str = fmt.Sprintf("$%d", a.Offset)
|
||||
|
||||
case D_FCONST:
|
||||
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
|
||||
// SHRQ $32(DX*0), AX
|
||||
// Remove.
|
||||
if a.Index != REG_NONE {
|
||||
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||
str += s
|
||||
}
|
||||
|
||||
case obj.TYPE_TEXTSIZE:
|
||||
if a.U.Argsize == obj.ArgsSizeUnknown {
|
||||
str = fmt.Sprintf("$%d", a.Offset)
|
||||
} else {
|
||||
str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize)
|
||||
}
|
||||
|
||||
case obj.TYPE_FCONST:
|
||||
str = fmt.Sprintf("$(%.17g)", a.U.Dval)
|
||||
|
||||
case D_SCONST:
|
||||
case obj.TYPE_SCONST:
|
||||
str = fmt.Sprintf("$\"%q\"", a.U.Sval)
|
||||
|
||||
case D_ADDR:
|
||||
a.Type = int16(a.Index)
|
||||
a.Index = D_NONE
|
||||
case obj.TYPE_ADDR:
|
||||
a.Type = obj.TYPE_MEM
|
||||
str = fmt.Sprintf("$%v", Dconv(p, 0, a))
|
||||
a.Index = uint8(a.Type)
|
||||
a.Type = D_ADDR
|
||||
goto conv
|
||||
a.Type = obj.TYPE_ADDR
|
||||
break
|
||||
}
|
||||
|
||||
brk:
|
||||
if a.Index != D_NONE {
|
||||
s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||
str += s
|
||||
}
|
||||
|
||||
conv:
|
||||
fp += str
|
||||
return fp
|
||||
}
|
||||
@ -304,18 +306,22 @@ var Register = []string{
|
||||
"TR5",
|
||||
"TR6",
|
||||
"TR7",
|
||||
"TLS", /* [D_TLS] */
|
||||
"NONE", /* [D_NONE] */
|
||||
"TLS", /* [D_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])
|
||||
} 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
@ -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);
|
||||
}
|
||||
|
@ -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++
|
||||
}
|
||||
}
|
||||
|
1121
src/cmd/new5a/y.go
1121
src/cmd/new5a/y.go
File diff suppressed because it is too large
Load Diff
@ -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:
|
||||
|
@ -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
@ -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,28 +190,48 @@ 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
|
||||
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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++
|
||||
}
|
||||
}
|
||||
|
1245
src/cmd/new9a/y.go
1245
src/cmd/new9a/y.go
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user