mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
[dev.cc] cmd/new5a etc, cmd/internal/asm: edit to produce working Go code
These assemblers produce byte-for-byte identical output to the ones written in C. They are primarily a proof that cmd/internal/obj can be used standalone to produce working object files. (The use via objwriter starts by deserializing an already-constructed internal representation, so objwriter does not exercise the code in cmd/internal/obj that creates such a representation from scratch.) Change-Id: I1793d8d010046cfb9d8b4d2d4469e7f47a3d3ac7 Reviewed-on: https://go-review.googlesource.com/3143 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
9e2f8fdb6f
commit
4ca2fc4d8b
4
.gitignore
vendored
4
.gitignore
vendored
@ -26,14 +26,12 @@ misc/cgo/life/run.out
|
||||
misc/cgo/stdio/run.out
|
||||
misc/cgo/testso/main
|
||||
misc/dashboard/builder/builder
|
||||
src/cmd/?a/y.output
|
||||
src/liblink/anames?.c
|
||||
src/cmd/cc/y.output
|
||||
src/cmd/*/y.output
|
||||
src/cmd/cgo/zdefaultcc.go
|
||||
src/cmd/dist/dist.dSYM
|
||||
src/cmd/gc/mkbuiltin1
|
||||
src/cmd/gc/opnames.h
|
||||
src/cmd/gc/y.output
|
||||
src/cmd/go/zdefaultcc.go
|
||||
src/cmd/internal/obj/zbootstrap.go
|
||||
src/go/doc/headscan
|
||||
|
@ -396,6 +396,10 @@ var goTools = map[string]targetDir{
|
||||
"cmd/cgo": toTool,
|
||||
"cmd/fix": toTool,
|
||||
"cmd/link": toTool,
|
||||
"cmd/new5a": toTool,
|
||||
"cmd/new6a": toTool,
|
||||
"cmd/new8a": toTool,
|
||||
"cmd/new9a": toTool,
|
||||
"cmd/nm": toTool,
|
||||
"cmd/objdump": toTool,
|
||||
"cmd/objwriter": toTool,
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,12 @@
|
||||
// Inferno utils/cc/macbody
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/cc/macbody
|
||||
// http://code.Google.Com/p/inferno-os/source/browse/utils/cc/macbody
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.Net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 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)
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.Net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
@ -30,6 +30,14 @@
|
||||
|
||||
package asm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/internal/obj"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
VARMAC = 0x80
|
||||
)
|
||||
@ -52,39 +60,32 @@ func getnsn() int32 {
|
||||
return n
|
||||
}
|
||||
|
||||
func getsym() *new5a.Sym {
|
||||
func getsym() *Sym {
|
||||
var c int
|
||||
var cp string
|
||||
|
||||
c = getnsc()
|
||||
if !(main.Isalpha(c) != 0) && c != '_' && c < 0x80 {
|
||||
if !isalpha(c) && c != '_' && c < 0x80 {
|
||||
unget(c)
|
||||
return nil
|
||||
}
|
||||
|
||||
for cp = new5a.Symb; ; {
|
||||
if cp <= new5a.Symb[new5a.NSYMB-4:] {
|
||||
cp[0] = byte(c)
|
||||
cp = cp[1:]
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
for {
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
if main.Isalnum(c) != 0 || c == '_' || c >= 0x80 {
|
||||
if isalnum(c) || c == '_' || c >= 0x80 {
|
||||
continue
|
||||
}
|
||||
unget(c)
|
||||
break
|
||||
}
|
||||
|
||||
cp = ""
|
||||
if cp > new5a.Symb[new5a.NSYMB-4:] {
|
||||
Yyerror("symbol too large: %s", new5a.Symb)
|
||||
}
|
||||
return lookup()
|
||||
last = buf.String()
|
||||
return Lookup(last)
|
||||
}
|
||||
|
||||
func getsymdots(dots *int) *new5a.Sym {
|
||||
func getsymdots(dots *int) *Sym {
|
||||
var c int
|
||||
var s *new5a.Sym
|
||||
var s *Sym
|
||||
|
||||
s = getsym()
|
||||
if s != nil {
|
||||
@ -101,7 +102,7 @@ func getsymdots(dots *int) *new5a.Sym {
|
||||
Yyerror("bad dots in macro")
|
||||
}
|
||||
*dots = 1
|
||||
return Slookup("__VA_ARGS__")
|
||||
return Lookup("__VA_ARGS__")
|
||||
}
|
||||
|
||||
func getcom() int {
|
||||
@ -150,35 +151,28 @@ func getcom() int {
|
||||
return c
|
||||
}
|
||||
|
||||
func Dodefine(cp string) {
|
||||
var s *new5a.Sym
|
||||
func dodefine(cp string) {
|
||||
var s *Sym
|
||||
var p string
|
||||
var l int32
|
||||
|
||||
Ensuresymb(int32(len(cp)))
|
||||
new5a.Symb = cp
|
||||
p = main.Strchr(new5a.Symb, '=')
|
||||
if p != "" {
|
||||
p = ""
|
||||
p = p[1:]
|
||||
s = lookup()
|
||||
l = int32(len(p)) + 2 /* +1 null, +1 nargs */
|
||||
s.Macro = Alloc(l).(string)
|
||||
s.Macro[1:] = p
|
||||
if i := strings.Index(cp, "="); i >= 0 {
|
||||
p = cp[i+1:]
|
||||
cp = cp[:i]
|
||||
s = Lookup(cp)
|
||||
s.Macro = &Macro{Text: p}
|
||||
} else {
|
||||
|
||||
s = lookup()
|
||||
s.Macro = "\0001" /* \000 is nargs */
|
||||
s = Lookup(cp)
|
||||
s.Macro = &Macro{Text: "1"}
|
||||
}
|
||||
|
||||
if new5a.Debug['m'] != 0 {
|
||||
fmt.Printf("#define (-D) %s %s\n", s.Name, s.Macro[1:])
|
||||
if debug['m'] != 0 {
|
||||
fmt.Printf("#define (-D) %s %s\n", s.Name, s.Macro.Text)
|
||||
}
|
||||
}
|
||||
|
||||
var mactab = []struct {
|
||||
macname string
|
||||
macf func()
|
||||
Macname string
|
||||
Macf func()
|
||||
}{
|
||||
{"ifdef", nil}, /* macif(0) */
|
||||
{"ifndef", nil}, /* macif(1) */
|
||||
@ -193,18 +187,17 @@ var mactab = []struct {
|
||||
|
||||
func domacro() {
|
||||
var i int
|
||||
var s *new5a.Sym
|
||||
var s *Sym
|
||||
|
||||
s = getsym()
|
||||
if s == nil {
|
||||
s = Slookup("endif")
|
||||
s = Lookup("endif")
|
||||
}
|
||||
for i = 0; mactab[i].macname != ""; i++ {
|
||||
if s.Name == mactab[i].macname {
|
||||
if mactab[i].macf != nil {
|
||||
(*mactab[i].macf)()
|
||||
for i = 0; i < len(mactab); i++ {
|
||||
if s.Name == mactab[i].Macname {
|
||||
if mactab[i].Macf != nil {
|
||||
mactab[i].Macf()
|
||||
} else {
|
||||
|
||||
macif(i)
|
||||
}
|
||||
return
|
||||
@ -216,7 +209,7 @@ func domacro() {
|
||||
}
|
||||
|
||||
func macund() {
|
||||
var s *new5a.Sym
|
||||
var s *Sym
|
||||
|
||||
s = getsym()
|
||||
macend()
|
||||
@ -225,7 +218,7 @@ func macund() {
|
||||
return
|
||||
}
|
||||
|
||||
s.Macro = ""
|
||||
s.Macro = nil
|
||||
}
|
||||
|
||||
const (
|
||||
@ -233,23 +226,21 @@ const (
|
||||
)
|
||||
|
||||
func macdef() {
|
||||
var s *new5a.Sym
|
||||
var a *new5a.Sym
|
||||
var s *Sym
|
||||
var a *Sym
|
||||
var args [NARG]string
|
||||
var np string
|
||||
var base string
|
||||
var n int
|
||||
var i int
|
||||
var c int
|
||||
var len int
|
||||
var dots int
|
||||
var ischr int
|
||||
var base bytes.Buffer
|
||||
|
||||
s = getsym()
|
||||
if s == nil {
|
||||
goto bad
|
||||
}
|
||||
if s.Macro != "" {
|
||||
if s.Macro != nil {
|
||||
Yyerror("macro redefined: %s", s.Name)
|
||||
}
|
||||
c = getc()
|
||||
@ -285,53 +276,41 @@ func macdef() {
|
||||
c = getc()
|
||||
}
|
||||
|
||||
if main.Isspace(c) != 0 {
|
||||
if isspace(c) {
|
||||
if c != '\n' {
|
||||
c = getnsc()
|
||||
}
|
||||
}
|
||||
base = new5a.Hunk
|
||||
len = 1
|
||||
ischr = 0
|
||||
for {
|
||||
if main.Isalpha(c) != 0 || c == '_' {
|
||||
np = new5a.Symb
|
||||
np[0] = byte(c)
|
||||
np = np[1:]
|
||||
if isalpha(c) || c == '_' {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
for main.Isalnum(c) != 0 || c == '_' {
|
||||
np[0] = byte(c)
|
||||
np = np[1:]
|
||||
for isalnum(c) || c == '_' {
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
}
|
||||
|
||||
np = ""
|
||||
symb := buf.String()
|
||||
for i = 0; i < n; i++ {
|
||||
if new5a.Symb == args[i] {
|
||||
if symb == args[i] {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i >= n {
|
||||
i = len(new5a.Symb)
|
||||
base = Allocn(base, int32(len), int32(i)).(string)
|
||||
main.Memmove(base[len:], new5a.Symb, i)
|
||||
len += i
|
||||
base.WriteString(symb)
|
||||
continue
|
||||
}
|
||||
|
||||
base = Allocn(base, int32(len), 2).(string)
|
||||
base[len] = '#'
|
||||
len++
|
||||
base[len] = byte('a' + i)
|
||||
len++
|
||||
base.WriteByte('#')
|
||||
base.WriteByte(byte('a' + i))
|
||||
continue
|
||||
}
|
||||
|
||||
if ischr != 0 {
|
||||
if c == '\\' {
|
||||
base = Allocn(base, int32(len), 1).(string)
|
||||
base[len] = byte(c)
|
||||
len++
|
||||
base.WriteByte(byte(c))
|
||||
c = getc()
|
||||
} else if c == ischr {
|
||||
ischr = 0
|
||||
@ -339,9 +318,7 @@ func macdef() {
|
||||
} else {
|
||||
|
||||
if c == '"' || c == '\'' {
|
||||
base = Allocn(base, int32(len), 1).(string)
|
||||
base[len] = byte(c)
|
||||
len++
|
||||
base.WriteByte(byte(c))
|
||||
ischr = c
|
||||
c = getc()
|
||||
continue
|
||||
@ -384,9 +361,7 @@ func macdef() {
|
||||
continue
|
||||
}
|
||||
|
||||
base = Allocn(base, int32(len), 1).(string)
|
||||
base[len] = '/'
|
||||
len++
|
||||
base.WriteByte('/')
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -404,9 +379,7 @@ func macdef() {
|
||||
}
|
||||
}
|
||||
|
||||
base = Allocn(base, int32(len), 1).(string)
|
||||
base[len] = '\\'
|
||||
len++
|
||||
base.WriteByte('\\')
|
||||
continue
|
||||
}
|
||||
|
||||
@ -415,25 +388,14 @@ func macdef() {
|
||||
}
|
||||
if c == '#' {
|
||||
if n > 0 {
|
||||
base = Allocn(base, int32(len), 1).(string)
|
||||
base[len] = byte(c)
|
||||
len++
|
||||
base.WriteByte(byte(c))
|
||||
}
|
||||
}
|
||||
|
||||
base = Allocn(base, int32(len), 1).(string)
|
||||
base[len] = byte(c)
|
||||
len++
|
||||
new5a.Fi.c--
|
||||
var tmp C.int
|
||||
if new5a.Fi.c < 0 {
|
||||
tmp = C.int(filbuf())
|
||||
} else {
|
||||
tmp = new5a.Fi.p[0] & 0xff
|
||||
}
|
||||
c = int(tmp)
|
||||
base.WriteByte(byte(c))
|
||||
c = GETC()
|
||||
if c == '\n' {
|
||||
new5a.Lineno++
|
||||
Lineno++
|
||||
}
|
||||
if c == -1 {
|
||||
Yyerror("eof in a macro: %s", s.Name)
|
||||
@ -441,22 +403,13 @@ func macdef() {
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
base = Allocn(base, int32(len), 1).(string)
|
||||
base[len] = 0
|
||||
len++
|
||||
if !(len&3 != 0 /*untyped*/) {
|
||||
break
|
||||
}
|
||||
s.Macro = &Macro{
|
||||
Text: base.String(),
|
||||
Narg: n + 1,
|
||||
Dots: dots != 0,
|
||||
}
|
||||
|
||||
base[0] = byte(n + 1)
|
||||
if dots != 0 {
|
||||
base[0] |= VARMAC
|
||||
}
|
||||
s.Macro = base
|
||||
if new5a.Debug['m'] != 0 {
|
||||
fmt.Printf("#define %s %s\n", s.Name, s.Macro[1:])
|
||||
if debug['m'] != 0 {
|
||||
fmt.Printf("#define %s %s\n", s.Name, s.Macro.Text)
|
||||
}
|
||||
return
|
||||
|
||||
@ -470,59 +423,40 @@ bad:
|
||||
macend()
|
||||
}
|
||||
|
||||
func macexpand(s *new5a.Sym, b string) {
|
||||
var buf string
|
||||
var n int
|
||||
func macexpand(s *Sym) []byte {
|
||||
var l int
|
||||
var c int
|
||||
var nargs int
|
||||
var arg [NARG]string
|
||||
var arg []string
|
||||
var out bytes.Buffer
|
||||
var buf bytes.Buffer
|
||||
var cp string
|
||||
var ob string
|
||||
var ecp string
|
||||
var dots int8
|
||||
|
||||
ob = b
|
||||
if s.Macro[0] == 0 {
|
||||
b = s.Macro[1:]
|
||||
if new5a.Debug['m'] != 0 {
|
||||
fmt.Printf("#expand %s %s\n", s.Name, ob)
|
||||
if s.Macro.Narg == 0 {
|
||||
if debug['m'] != 0 {
|
||||
fmt.Printf("#expand %s %s\n", s.Name, s.Macro.Text)
|
||||
}
|
||||
return
|
||||
return []byte(s.Macro.Text)
|
||||
}
|
||||
|
||||
nargs = int(int8(s.Macro[0]&^VARMAC)) - 1
|
||||
dots = int8(s.Macro[0] & VARMAC)
|
||||
nargs := s.Macro.Narg - 1
|
||||
dots := s.Macro.Dots
|
||||
|
||||
c = getnsc()
|
||||
if c != '(' {
|
||||
goto bad
|
||||
}
|
||||
n = 0
|
||||
c = getc()
|
||||
if c != ')' {
|
||||
unget(c)
|
||||
l = 0
|
||||
cp = buf
|
||||
ecp = cp[sizeof(buf)-4:]
|
||||
arg[n] = cp
|
||||
n++
|
||||
for {
|
||||
if cp >= ecp {
|
||||
goto toobig
|
||||
}
|
||||
c = getc()
|
||||
if c == '"' {
|
||||
for {
|
||||
if cp >= ecp {
|
||||
goto toobig
|
||||
}
|
||||
cp[0] = byte(c)
|
||||
cp = cp[1:]
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
if c == '\\' {
|
||||
cp[0] = byte(c)
|
||||
cp = cp[1:]
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
continue
|
||||
}
|
||||
@ -538,15 +472,10 @@ func macexpand(s *new5a.Sym, b string) {
|
||||
|
||||
if c == '\'' {
|
||||
for {
|
||||
if cp >= ecp {
|
||||
goto toobig
|
||||
}
|
||||
cp[0] = byte(c)
|
||||
cp = cp[1:]
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
if c == '\\' {
|
||||
cp[0] = byte(c)
|
||||
cp = cp[1:]
|
||||
buf.WriteByte(byte(c))
|
||||
c = getc()
|
||||
continue
|
||||
}
|
||||
@ -574,8 +503,7 @@ func macexpand(s *new5a.Sym, b string) {
|
||||
}
|
||||
}
|
||||
|
||||
cp[0] = ' '
|
||||
cp = cp[1:]
|
||||
buf.WriteByte(' ')
|
||||
continue
|
||||
|
||||
case '/':
|
||||
@ -594,23 +522,18 @@ func macexpand(s *new5a.Sym, b string) {
|
||||
|
||||
if l == 0 {
|
||||
if c == ',' {
|
||||
if n == nargs && dots != 0 {
|
||||
cp[0] = ','
|
||||
cp = cp[1:]
|
||||
if len(arg) == nargs-1 && dots {
|
||||
buf.WriteByte(',')
|
||||
continue
|
||||
}
|
||||
|
||||
cp = ""
|
||||
cp = cp[1:]
|
||||
arg[n] = cp
|
||||
n++
|
||||
if n > nargs {
|
||||
break
|
||||
}
|
||||
arg = append(arg, buf.String())
|
||||
buf.Reset()
|
||||
continue
|
||||
}
|
||||
|
||||
if c == ')' {
|
||||
arg = append(arg, buf.String())
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -618,8 +541,7 @@ func macexpand(s *new5a.Sym, b string) {
|
||||
if c == '\n' {
|
||||
c = ' '
|
||||
}
|
||||
cp[0] = byte(c)
|
||||
cp = cp[1:]
|
||||
buf.WriteByte(byte(c))
|
||||
if c == '(' {
|
||||
l++
|
||||
}
|
||||
@ -627,74 +549,60 @@ func macexpand(s *new5a.Sym, b string) {
|
||||
l--
|
||||
}
|
||||
}
|
||||
|
||||
cp = ""
|
||||
}
|
||||
|
||||
if n != nargs {
|
||||
if len(arg) != nargs {
|
||||
Yyerror("argument mismatch expanding: %s", s.Name)
|
||||
b = ""
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
cp = s.Macro[1:]
|
||||
for {
|
||||
c = int(cp[0])
|
||||
cp = cp[1:]
|
||||
cp = s.Macro.Text
|
||||
for i := 0; i < len(cp); i++ {
|
||||
c = int(cp[i])
|
||||
if c == '\n' {
|
||||
c = ' '
|
||||
}
|
||||
if c != '#' {
|
||||
b[0] = byte(c)
|
||||
b = b[1:]
|
||||
if c == 0 {
|
||||
break
|
||||
}
|
||||
out.WriteByte(byte(c))
|
||||
continue
|
||||
}
|
||||
|
||||
c = int(cp[0])
|
||||
cp = cp[1:]
|
||||
if c == 0 {
|
||||
i++
|
||||
if i >= len(cp) {
|
||||
goto bad
|
||||
}
|
||||
c = int(cp[i])
|
||||
if c == '#' {
|
||||
b[0] = byte(c)
|
||||
b = b[1:]
|
||||
out.WriteByte(byte(c))
|
||||
continue
|
||||
}
|
||||
|
||||
c -= 'a'
|
||||
if c < 0 || c >= n {
|
||||
if c < 0 || c >= len(arg) {
|
||||
continue
|
||||
}
|
||||
b = arg[c]
|
||||
b = b[len(arg[c]):]
|
||||
out.WriteString(arg[c])
|
||||
}
|
||||
|
||||
b = ""
|
||||
if new5a.Debug['m'] != 0 {
|
||||
fmt.Printf("#expand %s %s\n", s.Name, ob)
|
||||
if debug['m'] != 0 {
|
||||
fmt.Printf("#expand %s %s\n", s.Name, out.String())
|
||||
}
|
||||
return
|
||||
return out.Bytes()
|
||||
|
||||
bad:
|
||||
Yyerror("syntax in macro expansion: %s", s.Name)
|
||||
b = ""
|
||||
return
|
||||
|
||||
toobig:
|
||||
Yyerror("too much text in macro expansion: %s", s.Name)
|
||||
b = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func macinc() {
|
||||
var c0 int
|
||||
var c int
|
||||
var i int
|
||||
var f int
|
||||
var str string
|
||||
var buf bytes.Buffer
|
||||
var f *os.File
|
||||
var hp string
|
||||
var str string
|
||||
var symb string
|
||||
|
||||
c0 = getnsc()
|
||||
if c0 != '"' {
|
||||
@ -705,7 +613,7 @@ func macinc() {
|
||||
c0 = '>'
|
||||
}
|
||||
|
||||
for hp = str; ; {
|
||||
for {
|
||||
c = getc()
|
||||
if c == c0 {
|
||||
break
|
||||
@ -713,41 +621,36 @@ func macinc() {
|
||||
if c == '\n' {
|
||||
goto bad
|
||||
}
|
||||
hp[0] = byte(c)
|
||||
hp = hp[1:]
|
||||
buf.WriteByte(byte(c))
|
||||
}
|
||||
|
||||
hp = ""
|
||||
str = buf.String()
|
||||
|
||||
c = getcom()
|
||||
if c != '\n' {
|
||||
goto bad
|
||||
}
|
||||
|
||||
f = -1
|
||||
for i = 0; i < new5a.Ninclude; i++ {
|
||||
for i = 0; i < len(include); i++ {
|
||||
if i == 0 && c0 == '>' {
|
||||
continue
|
||||
}
|
||||
Ensuresymb(int32(len(new5a.Include[i])) + int32(len(str)) + 2)
|
||||
new5a.Symb = new5a.Include[i]
|
||||
new5a.Symb += "/"
|
||||
if new5a.Symb == "./" {
|
||||
new5a.Symb = ""
|
||||
symb = include[i]
|
||||
symb += "/"
|
||||
if symb == "./" {
|
||||
symb = ""
|
||||
}
|
||||
new5a.Symb += str
|
||||
f = main.Open(new5a.Symb, main.OREAD)
|
||||
if f >= 0 {
|
||||
symb += str
|
||||
var err error
|
||||
f, err = os.Open(symb)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if f < 0 {
|
||||
new5a.Symb = str
|
||||
if f == nil {
|
||||
symb = str
|
||||
}
|
||||
c = len(new5a.Symb) + 1
|
||||
hp = Alloc(int32(c)).(string)
|
||||
main.Memmove(hp, new5a.Symb, c)
|
||||
hp = symb
|
||||
newio()
|
||||
pushio()
|
||||
newfile(hp, f)
|
||||
@ -760,16 +663,16 @@ bad:
|
||||
}
|
||||
|
||||
func maclin() {
|
||||
var cp string
|
||||
var c int
|
||||
var n int32
|
||||
var buf bytes.Buffer
|
||||
var symb string
|
||||
|
||||
n = getnsn()
|
||||
c = getc()
|
||||
if n < 0 {
|
||||
goto bad
|
||||
}
|
||||
|
||||
for {
|
||||
if c == ' ' || c == '\t' {
|
||||
c = getc()
|
||||
@ -780,34 +683,29 @@ func maclin() {
|
||||
break
|
||||
}
|
||||
if c == '\n' {
|
||||
new5a.Symb = "<noname>"
|
||||
symb = "<noname>"
|
||||
goto nn
|
||||
}
|
||||
|
||||
goto bad
|
||||
}
|
||||
|
||||
cp = new5a.Symb
|
||||
for {
|
||||
c = getc()
|
||||
if c == '"' {
|
||||
break
|
||||
}
|
||||
cp[0] = byte(c)
|
||||
cp = cp[1:]
|
||||
buf.WriteByte(byte(c))
|
||||
}
|
||||
symb = buf.String()
|
||||
|
||||
cp = ""
|
||||
c = getcom()
|
||||
if c != '\n' {
|
||||
goto bad
|
||||
}
|
||||
|
||||
nn:
|
||||
c = len(new5a.Symb) + 1
|
||||
cp = Alloc(int32(c)).(string)
|
||||
main.Memmove(cp, new5a.Symb, c)
|
||||
obj.Linklinehist(new5a.Ctxt, int(new5a.Lineno), cp, int(n))
|
||||
obj.Linklinehist(Ctxt, int(Lineno), symb, int(n))
|
||||
return
|
||||
|
||||
bad:
|
||||
@ -820,7 +718,7 @@ func macif(f int) {
|
||||
var c int
|
||||
var l int
|
||||
var bol int
|
||||
var s *new5a.Sym
|
||||
var s *Sym
|
||||
|
||||
if f == 2 {
|
||||
goto skip
|
||||
@ -832,7 +730,7 @@ func macif(f int) {
|
||||
if getcom() != '\n' {
|
||||
goto bad
|
||||
}
|
||||
if (s.Macro != "")^f != 0 /*untyped*/ {
|
||||
if (s.Macro != nil) != (f != 0) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -842,7 +740,7 @@ skip:
|
||||
for {
|
||||
c = getc()
|
||||
if c != '#' {
|
||||
if !(main.Isspace(c) != 0) {
|
||||
if !isspace(c) {
|
||||
bol = 0
|
||||
}
|
||||
if c == '\n' {
|
||||
@ -885,10 +783,11 @@ bad:
|
||||
}
|
||||
|
||||
func macprag() {
|
||||
var s *new5a.Sym
|
||||
var s *Sym
|
||||
var c0 int
|
||||
var c int
|
||||
var hp string
|
||||
var buf bytes.Buffer
|
||||
var symb string
|
||||
|
||||
s = getsym()
|
||||
|
||||
@ -945,7 +844,7 @@ praglib:
|
||||
c0 = '>'
|
||||
}
|
||||
|
||||
for hp = new5a.Symb; ; {
|
||||
for {
|
||||
c = getc()
|
||||
if c == c0 {
|
||||
break
|
||||
@ -953,11 +852,10 @@ praglib:
|
||||
if c == '\n' {
|
||||
goto bad
|
||||
}
|
||||
hp[0] = byte(c)
|
||||
hp = hp[1:]
|
||||
buf.WriteByte(byte(c))
|
||||
}
|
||||
symb = buf.String()
|
||||
|
||||
hp = ""
|
||||
c = getcom()
|
||||
if c != '\n' {
|
||||
goto bad
|
||||
@ -966,12 +864,7 @@ praglib:
|
||||
/*
|
||||
* put pragma-line in as a funny history
|
||||
*/
|
||||
c = len(new5a.Symb) + 1
|
||||
|
||||
hp = Alloc(int32(c)).(string)
|
||||
main.Memmove(hp, new5a.Symb, c)
|
||||
|
||||
obj.Linklinehist(new5a.Ctxt, int(new5a.Lineno), hp, -1)
|
||||
obj.Linklinehist(Ctxt, int(Lineno), symb, -1)
|
||||
return
|
||||
|
||||
bad:
|
||||
|
@ -29,20 +29,23 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
%{
|
||||
#include <u.h>
|
||||
#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
|
||||
#include <libc.h>
|
||||
#include "a.h"
|
||||
#include "../../runtime/funcdata.h"
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
. "cmd/internal/obj/arm"
|
||||
)
|
||||
%}
|
||||
%union
|
||||
{
|
||||
Sym *sym;
|
||||
int32 lval;
|
||||
double dval;
|
||||
char sval[8];
|
||||
Addr addr;
|
||||
|
||||
%union {
|
||||
sym *asm.Sym
|
||||
lval int32
|
||||
dval float64
|
||||
sval string
|
||||
addr obj.Addr
|
||||
}
|
||||
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
@ -68,30 +71,32 @@
|
||||
prog:
|
||||
| prog
|
||||
{
|
||||
stmtline = lineno;
|
||||
stmtline = asm.Lineno;
|
||||
}
|
||||
line
|
||||
|
||||
line:
|
||||
LNAME ':'
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
if($1->type == LLAB && $1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->labelname);
|
||||
$1->type = LLAB;
|
||||
$1->value = pc;
|
||||
$1 = asm.LabelLookup($1);
|
||||
if $1.Type == LLAB && $1.Value != int64(asm.PC) {
|
||||
yyerror("redeclaration of %s", $1.Labelname)
|
||||
}
|
||||
$1.Type = LLAB;
|
||||
$1.Value = int64(asm.PC)
|
||||
}
|
||||
line
|
||||
| LNAME '=' expr ';'
|
||||
{
|
||||
$1->type = LVAR;
|
||||
$1->value = $3;
|
||||
$1.Type = LVAR;
|
||||
$1.Value = int64($3);
|
||||
}
|
||||
| LVAR '=' expr ';'
|
||||
{
|
||||
if($1->value != $3)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = $3;
|
||||
if $1.Value != int64($3) {
|
||||
yyerror("redeclaration of %s", $1.Name)
|
||||
}
|
||||
$1.Value = int64($3);
|
||||
}
|
||||
| ';'
|
||||
| inst ';'
|
||||
@ -171,20 +176,20 @@ inst:
|
||||
*/
|
||||
| LTYPE8 cond ioreg ',' '[' reglist ']'
|
||||
{
|
||||
Addr g;
|
||||
var g obj.Addr
|
||||
|
||||
g = nullgen;
|
||||
g.type = D_CONST;
|
||||
g.offset = $6;
|
||||
g.Type_ = D_CONST;
|
||||
g.Offset = int64($6);
|
||||
outcode($1, $2, &$3, NREG, &g);
|
||||
}
|
||||
| LTYPE8 cond '[' reglist ']' ',' ioreg
|
||||
{
|
||||
Addr g;
|
||||
var g obj.Addr
|
||||
|
||||
g = nullgen;
|
||||
g.type = D_CONST;
|
||||
g.offset = $4;
|
||||
g.Type_ = D_CONST;
|
||||
g.Offset = int64($4);
|
||||
outcode($1, $2, &g, NREG, &$7);
|
||||
}
|
||||
/*
|
||||
@ -192,15 +197,15 @@ inst:
|
||||
*/
|
||||
| LTYPE9 cond reg ',' ireg ',' reg
|
||||
{
|
||||
outcode($1, $2, &$5, $3.reg, &$7);
|
||||
outcode($1, $2, &$5, int32($3.Reg), &$7);
|
||||
}
|
||||
| LTYPE9 cond reg ',' ireg comma
|
||||
{
|
||||
outcode($1, $2, &$5, $3.reg, &$3);
|
||||
outcode($1, $2, &$5, int32($3.Reg), &$3);
|
||||
}
|
||||
| LTYPE9 cond comma ireg ',' reg
|
||||
{
|
||||
outcode($1, $2, &$4, $6.reg, &$6);
|
||||
outcode($1, $2, &$4, int32($6.Reg), &$6);
|
||||
}
|
||||
/*
|
||||
* RET
|
||||
@ -214,23 +219,23 @@ inst:
|
||||
*/
|
||||
| LTYPEB name ',' imm
|
||||
{
|
||||
settext($2.sym);
|
||||
$4.type = D_CONST2;
|
||||
$4.offset2 = ArgsSizeUnknown;
|
||||
asm.Settext($2.Sym);
|
||||
$4.Type_ = D_CONST2;
|
||||
$4.Offset2 = -obj.ArgsSizeUnknown;
|
||||
outcode($1, Always, &$2, 0, &$4);
|
||||
}
|
||||
| LTYPEB name ',' con ',' imm
|
||||
{
|
||||
settext($2.sym);
|
||||
$6.type = D_CONST2;
|
||||
$6.offset2 = ArgsSizeUnknown;
|
||||
asm.Settext($2.Sym);
|
||||
$6.Type_ = D_CONST2;
|
||||
$6.Offset2 = -obj.ArgsSizeUnknown;
|
||||
outcode($1, Always, &$2, $4, &$6);
|
||||
}
|
||||
| LTYPEB name ',' con ',' imm '-' con
|
||||
{
|
||||
settext($2.sym);
|
||||
$6.type = D_CONST2;
|
||||
$6.offset2 = $8;
|
||||
asm.Settext($2.Sym);
|
||||
$6.Type_ = D_CONST2;
|
||||
$6.Offset2 = $8;
|
||||
outcode($1, Always, &$2, $4, &$6);
|
||||
}
|
||||
/*
|
||||
@ -271,18 +276,18 @@ inst:
|
||||
}
|
||||
| LTYPEL cond freg ',' freg comma
|
||||
{
|
||||
outcode($1, $2, &$3, $5.reg, &nullgen);
|
||||
outcode($1, $2, &$3, int32($5.Reg), &nullgen);
|
||||
}
|
||||
/*
|
||||
* MCR MRC
|
||||
*/
|
||||
| LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
|
||||
{
|
||||
Addr g;
|
||||
var g obj.Addr
|
||||
|
||||
g = nullgen;
|
||||
g.type = D_CONST;
|
||||
g.offset =
|
||||
g.Type_ = D_CONST;
|
||||
g.Offset = int64(
|
||||
(0xe << 24) | /* opcode */
|
||||
($1 << 20) | /* MCR/MRC */
|
||||
($2 << 28) | /* scond */
|
||||
@ -292,7 +297,7 @@ inst:
|
||||
(($9 & 15) << 16) | /* Crn */
|
||||
(($11 & 15) << 0) | /* Crm */
|
||||
(($12 & 7) << 5) | /* coprocessor information */
|
||||
(1<<4); /* must be set */
|
||||
(1<<4)); /* must be set */
|
||||
outcode(AMRC, Always, &nullgen, NREG, &g);
|
||||
}
|
||||
/*
|
||||
@ -300,17 +305,17 @@ inst:
|
||||
*/
|
||||
| LTYPEM cond reg ',' reg ',' regreg
|
||||
{
|
||||
outcode($1, $2, &$3, $5.reg, &$7);
|
||||
outcode($1, $2, &$3, int32($5.Reg), &$7);
|
||||
}
|
||||
/*
|
||||
* MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4
|
||||
* MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff . r4
|
||||
* MULAW{T,B} r1,r2,r3,r4
|
||||
*/
|
||||
| LTYPEN cond reg ',' reg ',' reg ',' spreg
|
||||
{
|
||||
$7.type = D_REGREG2;
|
||||
$7.offset = $9;
|
||||
outcode($1, $2, &$3, $5.reg, &$7);
|
||||
$7.Type_ = D_REGREG2;
|
||||
$7.Offset = int64($9);
|
||||
outcode($1, $2, &$3, int32($5.Reg), &$7);
|
||||
}
|
||||
/*
|
||||
* PLD
|
||||
@ -324,8 +329,9 @@ inst:
|
||||
*/
|
||||
| LTYPEPC gen ',' gen
|
||||
{
|
||||
if($2.type != D_CONST || $4.type != D_CONST)
|
||||
yyerror("arguments to PCDATA must be integer constants");
|
||||
if $2.Type_ != D_CONST || $4.Type_ != D_CONST {
|
||||
yyerror("arguments to PCDATA must be integer constants")
|
||||
}
|
||||
outcode($1, Always, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
@ -333,10 +339,12 @@ inst:
|
||||
*/
|
||||
| LTYPEF gen ',' gen
|
||||
{
|
||||
if($2.type != D_CONST)
|
||||
yyerror("index for FUNCDATA must be integer constant");
|
||||
if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
|
||||
yyerror("value for FUNCDATA must be symbol reference");
|
||||
if $2.Type_ != D_CONST {
|
||||
yyerror("index for FUNCDATA must be integer constant")
|
||||
}
|
||||
if $4.Type_ != D_EXTERN && $4.Type_ != D_STATIC && $4.Type_ != D_OREG {
|
||||
yyerror("value for FUNCDATA must be symbol reference")
|
||||
}
|
||||
outcode($1, Always, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
@ -353,7 +361,7 @@ cond:
|
||||
}
|
||||
| cond LCOND
|
||||
{
|
||||
$$ = ($1 & ~C_SCOND) | $2;
|
||||
$$ = ($1 & ^ C_SCOND) | $2;
|
||||
}
|
||||
| cond LS
|
||||
{
|
||||
@ -367,40 +375,41 @@ rel:
|
||||
con '(' LPC ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1 + pc;
|
||||
$$.Type_ = D_BRANCH;
|
||||
$$.Offset = int64($1) + int64(asm.PC);
|
||||
}
|
||||
| LNAME offset
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
$1 = asm.LabelLookup($1);
|
||||
$$ = nullgen;
|
||||
if(pass == 2 && $1->type != LLAB)
|
||||
yyerror("undefined label: %s", $1->labelname);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1->value + $2;
|
||||
if asm.Pass == 2 && $1.Type != LLAB {
|
||||
yyerror("undefined label: %s", $1.Labelname)
|
||||
}
|
||||
$$.Type_ = D_BRANCH;
|
||||
$$.Offset = $1.Value + int64($2);
|
||||
}
|
||||
|
||||
ximm: '$' con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CONST;
|
||||
$$.offset = $2;
|
||||
$$.Type_ = D_CONST;
|
||||
$$.Offset = int64($2);
|
||||
}
|
||||
| '$' oreg
|
||||
{
|
||||
$$ = $2;
|
||||
$$.type = D_CONST;
|
||||
$$.Type_ = D_CONST;
|
||||
}
|
||||
| '$' '*' '$' oreg
|
||||
{
|
||||
$$ = $4;
|
||||
$$.type = D_OCONST;
|
||||
$$.Type_ = D_OCONST;
|
||||
}
|
||||
| '$' LSCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SCONST;
|
||||
memcpy($$.u.sval, $2, sizeof($$.u.sval));
|
||||
$$.Type_ = D_SCONST;
|
||||
$$.U.Sval = $2
|
||||
}
|
||||
| fcon
|
||||
|
||||
@ -408,33 +417,34 @@ fcon:
|
||||
'$' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = $2;
|
||||
$$.Type_ = D_FCONST;
|
||||
$$.U.Dval = $2;
|
||||
}
|
||||
| '$' '-' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = -$3;
|
||||
$$.Type_ = D_FCONST;
|
||||
$$.U.Dval = -$3;
|
||||
}
|
||||
|
||||
reglist:
|
||||
spreg
|
||||
{
|
||||
$$ = 1 << $1;
|
||||
$$ = 1 << uint($1);
|
||||
}
|
||||
| spreg '-' spreg
|
||||
{
|
||||
int i;
|
||||
$$=0;
|
||||
for(i=$1; i<=$3; i++)
|
||||
$$ |= 1<<i;
|
||||
for(i=$3; i<=$1; i++)
|
||||
$$ |= 1<<i;
|
||||
for i:=$1; i<=$3; i++ {
|
||||
$$ |= 1<<uint(i)
|
||||
}
|
||||
for i:=$3; i<=$1; i++ {
|
||||
$$ |= 1<<uint(i)
|
||||
}
|
||||
}
|
||||
| spreg comma reglist
|
||||
{
|
||||
$$ = (1<<$1) | $3;
|
||||
$$ = (1<<uint($1)) | $3;
|
||||
}
|
||||
|
||||
gen:
|
||||
@ -444,25 +454,25 @@ gen:
|
||||
| shift '(' spreg ')'
|
||||
{
|
||||
$$ = $1;
|
||||
$$.reg = $3;
|
||||
$$.Reg = int8($3);
|
||||
}
|
||||
| LPSR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_PSR;
|
||||
$$.reg = $1;
|
||||
$$.Type_ = D_PSR;
|
||||
$$.Reg = int8($1);
|
||||
}
|
||||
| LFCR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FPCR;
|
||||
$$.reg = $1;
|
||||
$$.Type_ = D_FPCR;
|
||||
$$.Reg = int8($1);
|
||||
}
|
||||
| con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = D_OREG;
|
||||
$$.Offset = int64($1);
|
||||
}
|
||||
| oreg
|
||||
| freg
|
||||
@ -472,7 +482,7 @@ nireg:
|
||||
| name
|
||||
{
|
||||
$$ = $1;
|
||||
if($1.name != D_EXTERN && $1.name != D_STATIC) {
|
||||
if($1.Name != D_EXTERN && $1.Name != D_STATIC) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,9 +490,9 @@ ireg:
|
||||
'(' spreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $2;
|
||||
$$.offset = 0;
|
||||
$$.Type_ = D_OREG;
|
||||
$$.Reg = int8($2);
|
||||
$$.Offset = 0;
|
||||
}
|
||||
|
||||
ioreg:
|
||||
@ -490,9 +500,9 @@ ioreg:
|
||||
| con '(' sreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $3;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = D_OREG;
|
||||
$$.Reg = int8($3);
|
||||
$$.Offset = int64($1);
|
||||
}
|
||||
|
||||
oreg:
|
||||
@ -500,8 +510,8 @@ oreg:
|
||||
| name '(' sreg ')'
|
||||
{
|
||||
$$ = $1;
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $3;
|
||||
$$.Type_ = D_OREG;
|
||||
$$.Reg = int8($3);
|
||||
}
|
||||
| ioreg
|
||||
|
||||
@ -513,64 +523,66 @@ imsr:
|
||||
imm: '$' con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CONST;
|
||||
$$.offset = $2;
|
||||
$$.Type_ = D_CONST;
|
||||
$$.Offset = int64($2);
|
||||
}
|
||||
|
||||
reg:
|
||||
spreg
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_REG;
|
||||
$$.reg = $1;
|
||||
$$.Type_ = D_REG;
|
||||
$$.Reg = int8($1);
|
||||
}
|
||||
|
||||
regreg:
|
||||
'(' spreg ',' spreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_REGREG;
|
||||
$$.reg = $2;
|
||||
$$.offset = $4;
|
||||
$$.Type_ = D_REGREG;
|
||||
$$.Reg = int8($2);
|
||||
$$.Offset = int64($4);
|
||||
}
|
||||
|
||||
shift:
|
||||
spreg '<' '<' rcon
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SHIFT;
|
||||
$$.offset = $1 | $4 | (0 << 5);
|
||||
$$.Type_ = D_SHIFT;
|
||||
$$.Offset = int64($1) | int64($4) | (0 << 5);
|
||||
}
|
||||
| spreg '>' '>' rcon
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SHIFT;
|
||||
$$.offset = $1 | $4 | (1 << 5);
|
||||
$$.Type_ = D_SHIFT;
|
||||
$$.Offset = int64($1) | int64($4) | (1 << 5);
|
||||
}
|
||||
| spreg '-' '>' rcon
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SHIFT;
|
||||
$$.offset = $1 | $4 | (2 << 5);
|
||||
$$.Type_ = D_SHIFT;
|
||||
$$.Offset = int64($1) | int64($4) | (2 << 5);
|
||||
}
|
||||
| spreg LAT '>' rcon
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SHIFT;
|
||||
$$.offset = $1 | $4 | (3 << 5);
|
||||
$$.Type_ = D_SHIFT;
|
||||
$$.Offset = int64($1) | int64($4) | (3 << 5);
|
||||
}
|
||||
|
||||
rcon:
|
||||
spreg
|
||||
{
|
||||
if($$ < 0 || $$ >= 16)
|
||||
print("register value out of range\n");
|
||||
if $$ < 0 || $$ >= 16 {
|
||||
print("register value out of range\n")
|
||||
}
|
||||
$$ = (($1&15) << 8) | (1 << 4);
|
||||
}
|
||||
| con
|
||||
{
|
||||
if($$ < 0 || $$ >= 32)
|
||||
print("shift value out of range\n");
|
||||
if $$ < 0 || $$ >= 32 {
|
||||
print("shift value out of range\n")
|
||||
}
|
||||
$$ = ($1&31) << 7;
|
||||
}
|
||||
|
||||
@ -582,8 +594,9 @@ sreg:
|
||||
}
|
||||
| LR '(' expr ')'
|
||||
{
|
||||
if($3 < 0 || $3 >= NREG)
|
||||
print("register value out of range\n");
|
||||
if $3 < 0 || $3 >= NREG {
|
||||
print("register value out of range\n")
|
||||
}
|
||||
$$ = $3;
|
||||
}
|
||||
|
||||
@ -598,8 +611,9 @@ creg:
|
||||
LCREG
|
||||
| LC '(' expr ')'
|
||||
{
|
||||
if($3 < 0 || $3 >= NREG)
|
||||
print("register value out of range\n");
|
||||
if $3 < 0 || $3 >= NREG {
|
||||
print("register value out of range\n")
|
||||
}
|
||||
$$ = $3;
|
||||
}
|
||||
|
||||
@ -611,40 +625,40 @@ freg:
|
||||
LFREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FREG;
|
||||
$$.reg = $1;
|
||||
$$.Type_ = D_FREG;
|
||||
$$.Reg = int8($1);
|
||||
}
|
||||
| LF '(' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FREG;
|
||||
$$.reg = $3;
|
||||
$$.Type_ = D_FREG;
|
||||
$$.Reg = int8($3);
|
||||
}
|
||||
|
||||
name:
|
||||
con '(' pointer ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.name = $3;
|
||||
$$.sym = nil;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = D_OREG;
|
||||
$$.Name = int8($3);
|
||||
$$.Sym = nil;
|
||||
$$.Offset = int64($1);
|
||||
}
|
||||
| LNAME offset '(' pointer ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.name = $4;
|
||||
$$.sym = linklookup(ctxt, $1->name, 0);
|
||||
$$.offset = $2;
|
||||
$$.Type_ = D_OREG;
|
||||
$$.Name = int8($4);
|
||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||
$$.Offset = int64($2);
|
||||
}
|
||||
| LNAME '<' '>' offset '(' LSB ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.name = D_STATIC;
|
||||
$$.sym = linklookup(ctxt, $1->name, 1);
|
||||
$$.offset = $4;
|
||||
$$.Type_ = D_OREG;
|
||||
$$.Name = D_STATIC;
|
||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
||||
$$.Offset = int64($4);
|
||||
}
|
||||
|
||||
offset:
|
||||
@ -669,7 +683,7 @@ con:
|
||||
LCONST
|
||||
| LVAR
|
||||
{
|
||||
$$ = $1->value;
|
||||
$$ = int32($1.Value);
|
||||
}
|
||||
| '-' con
|
||||
{
|
||||
@ -681,7 +695,7 @@ con:
|
||||
}
|
||||
| '~' con
|
||||
{
|
||||
$$ = ~$2;
|
||||
$$ = ^$2;
|
||||
}
|
||||
| '(' expr ')'
|
||||
{
|
||||
@ -721,11 +735,11 @@ expr:
|
||||
}
|
||||
| expr '<' '<' expr
|
||||
{
|
||||
$$ = $1 << $4;
|
||||
$$ = $1 << uint($4);
|
||||
}
|
||||
| expr '>' '>' expr
|
||||
{
|
||||
$$ = $1 >> $4;
|
||||
$$ = $1 >> uint($4);
|
||||
}
|
||||
| expr '&' expr
|
||||
{
|
||||
|
@ -28,162 +28,66 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//go:generate go tool yacc a.y
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
Plan9 = 1 << 0
|
||||
Unix = 1 << 1
|
||||
Windows = 1 << 2
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/arm"
|
||||
)
|
||||
|
||||
func systemtype(sys int) int {
|
||||
return sys & Windows
|
||||
var (
|
||||
yyerror = asm.Yyerror
|
||||
nullgen obj.Addr
|
||||
stmtline int32
|
||||
)
|
||||
|
||||
return sys & Plan9
|
||||
}
|
||||
const Always = 14
|
||||
|
||||
func Lconv(fp *obj.Fmt) int {
|
||||
return obj.Linklinefmt(Ctxt, fp)
|
||||
}
|
||||
|
||||
func dodef(p string) {
|
||||
if nDlist%8 == 0 {
|
||||
Dlist = asm.Allocn(Dlist, nDlist*sizeof(string), 8*sizeof(string)).(*string)
|
||||
}
|
||||
Dlist[nDlist] = p
|
||||
nDlist++
|
||||
}
|
||||
|
||||
func usage() {
|
||||
fmt.Printf("usage: %ca [options] file.c...\n", Thechar)
|
||||
main.Flagprint(1)
|
||||
asm.Errorexit()
|
||||
}
|
||||
|
||||
func main(argc int, argv [XXX]string) {
|
||||
var p string
|
||||
|
||||
Thechar = '5'
|
||||
thestring = "arm"
|
||||
|
||||
Ctxt = obj.Linknew(&arm.Linkarm)
|
||||
Ctxt.Diag = asm.Yyerror
|
||||
Ctxt.Bso = &Bstdout
|
||||
Ctxt.Enforce_data_order = 1
|
||||
obj.Binit(&Bstdout, 1, main.OWRITE)
|
||||
arm.Listinit5()
|
||||
obj.Fmtinstall('L', Lconv)
|
||||
|
||||
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
|
||||
// but not other values.
|
||||
p = Getgoarch()
|
||||
|
||||
if !strings.HasPrefix(p, thestring) {
|
||||
log.Fatalf("cannot use %cc with GOARCH=%s", Thechar, p)
|
||||
}
|
||||
|
||||
asm.Ensuresymb(NSYMB)
|
||||
Debug = [256]int{}
|
||||
func main() {
|
||||
cinit()
|
||||
Outfile = ""
|
||||
asm.Setinclude(".")
|
||||
|
||||
main.Flagfn1("D", "name[=value]: add #define", dodef)
|
||||
main.Flagfn1("I", "dir: add dir to include path", asm.Setinclude)
|
||||
main.Flagcount("S", "print assembly and machine code", &Debug['S'])
|
||||
main.Flagcount("m", "debug preprocessor macros", &Debug['m'])
|
||||
main.Flagstr("o", "file: set output file", &Outfile)
|
||||
main.Flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &Ctxt.Trimpath)
|
||||
asm.LSCONST = LSCONST
|
||||
asm.LCONST = LCONST
|
||||
asm.LFCONST = LFCONST
|
||||
asm.LNAME = LNAME
|
||||
asm.LVAR = LVAR
|
||||
asm.LLAB = LLAB
|
||||
|
||||
main.Flagparse(&argc, (**string)(&argv), usage)
|
||||
Ctxt.Debugasm = int32(Debug['S'])
|
||||
asm.Lexinit = lexinit
|
||||
asm.Cclean = cclean
|
||||
asm.Yyparse = yyparse
|
||||
|
||||
if argc < 1 {
|
||||
usage()
|
||||
}
|
||||
if argc > 1 {
|
||||
fmt.Printf("can't assemble multiple files\n")
|
||||
asm.Errorexit()
|
||||
}
|
||||
asm.Thechar = '5'
|
||||
asm.Thestring = "arm"
|
||||
asm.Thelinkarch = &arm.Linkarm
|
||||
|
||||
if assemble(argv[0]) != 0 {
|
||||
asm.Errorexit()
|
||||
}
|
||||
obj.Bflush(&Bstdout)
|
||||
if Nerrors > 0 {
|
||||
asm.Errorexit()
|
||||
}
|
||||
main.Exits("")
|
||||
asm.Main()
|
||||
}
|
||||
|
||||
func assemble(file string) int {
|
||||
var ofile string
|
||||
var p string
|
||||
var i int
|
||||
var of int
|
||||
type yy struct{}
|
||||
|
||||
ofile = asm.Alloc(int32(len(file)) + 3).(string) // +3 for .x\0 (x=thechar)
|
||||
ofile = file
|
||||
p = main.Utfrrune(ofile, '/')
|
||||
if p != "" {
|
||||
Include[0] = ofile
|
||||
p = ""
|
||||
p = p[1:]
|
||||
} else {
|
||||
|
||||
p = ofile
|
||||
}
|
||||
if Outfile == "" {
|
||||
Outfile = p
|
||||
if Outfile != "" {
|
||||
p = main.Utfrrune(Outfile, '.')
|
||||
if p != "" {
|
||||
if p[1] == 's' && p[2] == 0 {
|
||||
p = ""
|
||||
}
|
||||
}
|
||||
p = main.Utfrune(Outfile, 0)
|
||||
p[0] = '.'
|
||||
p[1] = byte(Thechar)
|
||||
p[2] = 0
|
||||
} else {
|
||||
|
||||
Outfile = "/dev/null"
|
||||
}
|
||||
}
|
||||
|
||||
of = main.Create(Outfile, main.OWRITE, 0664)
|
||||
if of < 0 {
|
||||
asm.Yyerror("%ca: cannot create %s", Thechar, Outfile)
|
||||
asm.Errorexit()
|
||||
}
|
||||
|
||||
obj.Binit(&obuf, of, main.OWRITE)
|
||||
fmt.Fprintf(&obuf, "go object %s %s %s\n", main.Getgoos(), main.Getgoarch(), main.Getgoversion())
|
||||
fmt.Fprintf(&obuf, "!\n")
|
||||
|
||||
for pass = 1; pass <= 2; pass++ {
|
||||
asm.Pinit(file)
|
||||
for i = 0; i < nDlist; i++ {
|
||||
asm.Dodefine(Dlist[i])
|
||||
}
|
||||
yyparse()
|
||||
cclean()
|
||||
if Nerrors != 0 {
|
||||
return Nerrors
|
||||
}
|
||||
}
|
||||
|
||||
obj.Writeobj(Ctxt, &obuf)
|
||||
obj.Bflush(&obuf)
|
||||
return 0
|
||||
func (yy) Lex(v *yySymType) int {
|
||||
var av asm.Yylval
|
||||
tok := asm.Yylex(&av)
|
||||
v.sym = av.Sym
|
||||
v.lval = int32(av.Lval)
|
||||
v.sval = av.Sval
|
||||
v.dval = av.Dval
|
||||
return tok
|
||||
}
|
||||
|
||||
var itab = []struct {
|
||||
name string
|
||||
type_ uint16
|
||||
value uint16
|
||||
}{
|
||||
func (yy) Error(msg string) {
|
||||
asm.Yyerror("%s", msg)
|
||||
}
|
||||
|
||||
func yyparse() {
|
||||
yyParse(yy{})
|
||||
}
|
||||
|
||||
var lexinit = []asm.Lextab{
|
||||
{"SP", LSP, arm.D_AUTO},
|
||||
{"SB", LSB, arm.D_EXTERN},
|
||||
{"FP", LFP, arm.D_PARAM},
|
||||
@ -394,39 +298,17 @@ var itab = []struct {
|
||||
}
|
||||
|
||||
func cinit() {
|
||||
var s *Sym
|
||||
var i int
|
||||
|
||||
Nullgen.Type_ = arm.D_NONE
|
||||
Nullgen.Name = arm.D_NONE
|
||||
Nullgen.Reg = arm.NREG
|
||||
|
||||
Nerrors = 0
|
||||
Iostack = nil
|
||||
Iofree = nil
|
||||
Peekc = IGN
|
||||
nhunk = 0
|
||||
for i = 0; i < NHASH; i++ {
|
||||
Hash[i] = nil
|
||||
}
|
||||
for i = 0; itab[i].name != ""; i++ {
|
||||
s = asm.Slookup(itab[i].name)
|
||||
s.Type_ = itab[i].type_
|
||||
s.Value = int32(itab[i].value)
|
||||
}
|
||||
nullgen.Type_ = arm.D_NONE
|
||||
nullgen.Name = arm.D_NONE
|
||||
nullgen.Reg = arm.NREG
|
||||
}
|
||||
|
||||
func Syminit(s *Sym) {
|
||||
s.Type_ = LNAME
|
||||
s.Value = 0
|
||||
}
|
||||
|
||||
func isreg(g *obj.Addr) int {
|
||||
return 1
|
||||
func isreg(g *obj.Addr) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func cclean() {
|
||||
outcode(arm.AEND, Always, &Nullgen, arm.NREG, &Nullgen)
|
||||
outcode(arm.AEND, Always, &nullgen, arm.NREG, &nullgen)
|
||||
}
|
||||
|
||||
var bcode = []int{
|
||||
@ -450,42 +332,41 @@ var bcode = []int{
|
||||
|
||||
var lastpc *obj.Prog
|
||||
|
||||
func outcode(a int, scond int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
|
||||
func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
|
||||
var p *obj.Prog
|
||||
var pl *obj.Plist
|
||||
|
||||
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
|
||||
if a == arm.AB {
|
||||
|
||||
a = bcode[scond&0xf]
|
||||
scond = scond&^0xf | Always
|
||||
a = int32(bcode[scond&0xf])
|
||||
scond = (scond &^ 0xf) | Always
|
||||
}
|
||||
|
||||
if pass == 1 {
|
||||
if asm.Pass == 1 {
|
||||
goto out
|
||||
}
|
||||
|
||||
p = new(obj.Prog)
|
||||
*p = obj.Prog{}
|
||||
p.Ctxt = asm.Ctxt
|
||||
p.As = int16(a)
|
||||
p.Lineno = stmtline
|
||||
p.Scond = uint8(scond)
|
||||
p.From = *g1
|
||||
p.Reg = uint8(reg)
|
||||
p.To = *g2
|
||||
p.Pc = int64(Pc)
|
||||
p.Pc = int64(asm.PC)
|
||||
|
||||
if lastpc == nil {
|
||||
pl = obj.Linknewplist(Ctxt)
|
||||
pl = obj.Linknewplist(asm.Ctxt)
|
||||
pl.Firstpc = p
|
||||
} else {
|
||||
|
||||
lastpc.Link = p
|
||||
}
|
||||
lastpc = p
|
||||
|
||||
out:
|
||||
if a != arm.AGLOBL && a != arm.ADATA {
|
||||
Pc++
|
||||
asm.PC++
|
||||
}
|
||||
}
|
||||
|
1315
src/cmd/new5a/y.go
Normal file
1315
src/cmd/new5a/y.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,20 +29,24 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
%{
|
||||
#include <u.h>
|
||||
#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
|
||||
#include <libc.h>
|
||||
#include "a.h"
|
||||
#include "../../runtime/funcdata.h"
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/x86"
|
||||
)
|
||||
%}
|
||||
%union {
|
||||
Sym *sym;
|
||||
vlong lval;
|
||||
double dval;
|
||||
char sval[8];
|
||||
Addr addr;
|
||||
Addr2 addr2;
|
||||
|
||||
%union {
|
||||
sym *asm.Sym
|
||||
lval int64
|
||||
dval float64
|
||||
sval string
|
||||
addr obj.Addr
|
||||
addr2 Addr2
|
||||
}
|
||||
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
@ -66,18 +70,19 @@
|
||||
prog:
|
||||
| prog
|
||||
{
|
||||
stmtline = lineno;
|
||||
stmtline = asm.Lineno;
|
||||
}
|
||||
line
|
||||
|
||||
line:
|
||||
LNAME ':'
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
if($1->type == LLAB && $1->value != pc)
|
||||
yyerror("redeclaration of %s (%s)", $1->labelname, $1->name);
|
||||
$1->type = LLAB;
|
||||
$1->value = pc;
|
||||
$1 = asm.LabelLookup($1);
|
||||
if $1.Type == LLAB && $1.Value != int64(asm.PC) {
|
||||
yyerror("redeclaration of %s (%s)", $1.Labelname, $1.Name);
|
||||
}
|
||||
$1.Type = LLAB;
|
||||
$1.Value = int64(asm.PC)
|
||||
}
|
||||
line
|
||||
| ';'
|
||||
@ -87,34 +92,35 @@ line:
|
||||
inst:
|
||||
LNAME '=' expr
|
||||
{
|
||||
$1->type = LVAR;
|
||||
$1->value = $3;
|
||||
$1.Type = LVAR;
|
||||
$1.Value = $3;
|
||||
}
|
||||
| LVAR '=' expr
|
||||
{
|
||||
if($1->value != $3)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = $3;
|
||||
if $1.Value != $3 {
|
||||
yyerror("redeclaration of %s", $1.Name);
|
||||
}
|
||||
$1.Value = $3;
|
||||
}
|
||||
| LTYPE0 nonnon { outcode($1, &$2); }
|
||||
| LTYPE1 nonrem { outcode($1, &$2); }
|
||||
| LTYPE2 rimnon { outcode($1, &$2); }
|
||||
| LTYPE3 rimrem { outcode($1, &$2); }
|
||||
| LTYPE4 remrim { outcode($1, &$2); }
|
||||
| LTYPER nonrel { outcode($1, &$2); }
|
||||
| LTYPED spec1 { outcode($1, &$2); }
|
||||
| LTYPET spec2 { outcode($1, &$2); }
|
||||
| LTYPEC spec3 { outcode($1, &$2); }
|
||||
| LTYPEN spec4 { outcode($1, &$2); }
|
||||
| LTYPES spec5 { outcode($1, &$2); }
|
||||
| LTYPEM spec6 { outcode($1, &$2); }
|
||||
| LTYPEI spec7 { outcode($1, &$2); }
|
||||
| LTYPEXC spec8 { outcode($1, &$2); }
|
||||
| LTYPEX spec9 { outcode($1, &$2); }
|
||||
| LTYPERT spec10 { outcode($1, &$2); }
|
||||
| LTYPEG spec11 { outcode($1, &$2); }
|
||||
| LTYPEPC spec12 { outcode($1, &$2); }
|
||||
| LTYPEF spec13 { outcode($1, &$2); }
|
||||
| LTYPE0 nonnon { outcode(int($1), &$2); }
|
||||
| LTYPE1 nonrem { outcode(int($1), &$2); }
|
||||
| LTYPE2 rimnon { outcode(int($1), &$2); }
|
||||
| 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); }
|
||||
| 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); }
|
||||
| LTYPEXC spec8 { outcode(int($1), &$2); }
|
||||
| LTYPEX spec9 { outcode(int($1), &$2); }
|
||||
| LTYPERT spec10 { outcode(int($1), &$2); }
|
||||
| LTYPEG spec11 { outcode(int($1), &$2); }
|
||||
| LTYPEPC spec12 { outcode(int($1), &$2); }
|
||||
| LTYPEF spec13 { outcode(int($1), &$2); }
|
||||
|
||||
nonnon:
|
||||
{
|
||||
@ -186,22 +192,22 @@ spec1: /* DATA */
|
||||
nam '/' con ',' imm
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.from.scale = $3;
|
||||
$$.from.Scale = int8($3);
|
||||
$$.to = $5;
|
||||
}
|
||||
|
||||
spec2: /* TEXT */
|
||||
mem ',' imm2
|
||||
{
|
||||
settext($1.sym);
|
||||
asm.Settext($1.Sym);
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
}
|
||||
| mem ',' con ',' imm2
|
||||
{
|
||||
settext($1.sym);
|
||||
asm.Settext($1.Sym);
|
||||
$$.from = $1;
|
||||
$$.from.scale = $3;
|
||||
$$.from.Scale = int8($3);
|
||||
$$.to = $5;
|
||||
}
|
||||
|
||||
@ -231,9 +237,10 @@ spec5: /* SHL/SHR */
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
if($$.from.index != D_NONE)
|
||||
if $$.from.Index != x86.D_NONE {
|
||||
yyerror("dp shift with lhs index");
|
||||
$$.from.index = $5;
|
||||
}
|
||||
$$.from.Index = uint8($5);
|
||||
}
|
||||
|
||||
spec6: /* MOVW/MOVL */
|
||||
@ -246,9 +253,10 @@ spec6: /* MOVW/MOVL */
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
if($$.to.index != D_NONE)
|
||||
if $$.to.Index != x86.D_NONE {
|
||||
yyerror("dp move with lhs index");
|
||||
$$.to.index = $5;
|
||||
}
|
||||
$$.to.Index = uint8($5);
|
||||
}
|
||||
|
||||
spec7:
|
||||
@ -273,7 +281,7 @@ spec8: /* CMPPS/CMPPD */
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
$$.to.offset = $5;
|
||||
$$.to.Offset = $5;
|
||||
}
|
||||
|
||||
spec9: /* shufl */
|
||||
@ -281,9 +289,10 @@ spec9: /* shufl */
|
||||
{
|
||||
$$.from = $3;
|
||||
$$.to = $5;
|
||||
if($1.type != D_CONST)
|
||||
if $1.Type_ != x86.D_CONST {
|
||||
yyerror("illegal constant");
|
||||
$$.to.offset = $1.offset;
|
||||
}
|
||||
$$.to.Offset = $1.Offset;
|
||||
}
|
||||
|
||||
spec10: /* RET/RETF */
|
||||
@ -306,15 +315,16 @@ spec11: /* GLOBL */
|
||||
| mem ',' con ',' imm
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.from.scale = $3;
|
||||
$$.from.Scale = int8($3);
|
||||
$$.to = $5;
|
||||
}
|
||||
|
||||
spec12: /* PCDATA */
|
||||
spec12: /* asm.PCDATA */
|
||||
rim ',' rim
|
||||
{
|
||||
if($1.type != D_CONST || $3.type != D_CONST)
|
||||
yyerror("arguments to PCDATA must be integer constants");
|
||||
if $1.Type_ != x86.D_CONST || $3.Type_ != x86.D_CONST {
|
||||
yyerror("arguments to asm.PCDATA must be integer constants");
|
||||
}
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
}
|
||||
@ -322,10 +332,12 @@ spec12: /* PCDATA */
|
||||
spec13: /* FUNCDATA */
|
||||
rim ',' rim
|
||||
{
|
||||
if($1.type != D_CONST)
|
||||
if $1.Type_ != x86.D_CONST {
|
||||
yyerror("index for FUNCDATA must be integer constant");
|
||||
if($3.type != D_EXTERN && $3.type != D_STATIC)
|
||||
}
|
||||
if $3.Type_ != x86.D_EXTERN && $3.Type_ != x86.D_STATIC {
|
||||
yyerror("value for FUNCDATA must be symbol reference");
|
||||
}
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
}
|
||||
@ -356,110 +368,111 @@ rel:
|
||||
con '(' LPC ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1 + pc;
|
||||
$$.Type_ = x86.D_BRANCH;
|
||||
$$.Offset = $1 + int64(asm.PC);
|
||||
}
|
||||
| LNAME offset
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
$1 = asm.LabelLookup($1);
|
||||
$$ = nullgen;
|
||||
if(pass == 2 && $1->type != LLAB)
|
||||
yyerror("undefined label: %s", $1->labelname);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1->value + $2;
|
||||
if asm.Pass == 2 && $1.Type != LLAB {
|
||||
yyerror("undefined label: %s", $1.Labelname);
|
||||
}
|
||||
$$.Type_ = x86.D_BRANCH;
|
||||
$$.Offset = $1.Value + $2;
|
||||
}
|
||||
|
||||
reg:
|
||||
LBREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LFREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LLREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LMREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LSP
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SP;
|
||||
$$.Type_ = x86.D_SP;
|
||||
}
|
||||
| LSREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LXREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
imm2:
|
||||
'$' con2
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CONST;
|
||||
$$.offset = $2;
|
||||
$$.Type_ = x86.D_CONST;
|
||||
$$.Offset = $2;
|
||||
}
|
||||
|
||||
imm:
|
||||
'$' con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CONST;
|
||||
$$.offset = $2;
|
||||
$$.Type_ = x86.D_CONST;
|
||||
$$.Offset = $2;
|
||||
}
|
||||
| '$' nam
|
||||
{
|
||||
$$ = $2;
|
||||
$$.index = $2.type;
|
||||
$$.type = D_ADDR;
|
||||
$$.Index = uint8($2.Type_);
|
||||
$$.Type_ = x86.D_ADDR;
|
||||
/*
|
||||
if($2.type == D_AUTO || $2.type == D_PARAM)
|
||||
if($2.Type_ == x86.D_AUTO || $2.Type_ == x86.D_PARAM)
|
||||
yyerror("constant cannot be automatic: %s",
|
||||
$2.sym->name);
|
||||
$2.sym.Name);
|
||||
*/
|
||||
}
|
||||
| '$' LSCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SCONST;
|
||||
memcpy($$.u.sval, $2, sizeof($$.u.sval));
|
||||
$$.Type_ = x86.D_SCONST;
|
||||
$$.U.Sval = ($2+"\x00\x00\x00\x00\x00\x00\x00\x00")[:8]
|
||||
}
|
||||
| '$' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = $2;
|
||||
$$.Type_ = x86.D_FCONST;
|
||||
$$.U.Dval = $2;
|
||||
}
|
||||
| '$' '(' LFCONST ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = $3;
|
||||
$$.Type_ = x86.D_FCONST;
|
||||
$$.U.Dval = $3;
|
||||
}
|
||||
| '$' '(' '-' LFCONST ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = -$4;
|
||||
$$.Type_ = x86.D_FCONST;
|
||||
$$.U.Dval = -$4;
|
||||
}
|
||||
| '$' '-' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = -$3;
|
||||
$$.Type_ = x86.D_FCONST;
|
||||
$$.U.Dval = -$3;
|
||||
}
|
||||
|
||||
mem:
|
||||
@ -470,79 +483,79 @@ omem:
|
||||
con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_NONE;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = x86.D_INDIR+x86.D_NONE;
|
||||
$$.Offset = $1;
|
||||
}
|
||||
| con '(' LLREG ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$3;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = int16(x86.D_INDIR+$3);
|
||||
$$.Offset = $1;
|
||||
}
|
||||
| con '(' LSP ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_SP;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = int16(x86.D_INDIR+x86.D_SP);
|
||||
$$.Offset = $1;
|
||||
}
|
||||
| con '(' LSREG ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$3;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = int16(x86.D_INDIR+$3);
|
||||
$$.Offset = $1;
|
||||
}
|
||||
| con '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_NONE;
|
||||
$$.offset = $1;
|
||||
$$.index = $3;
|
||||
$$.scale = $5;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = int16(x86.D_INDIR+x86.D_NONE);
|
||||
$$.Offset = $1;
|
||||
$$.Index = uint8($3);
|
||||
$$.Scale = int8($5);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
| con '(' LLREG ')' '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$3;
|
||||
$$.offset = $1;
|
||||
$$.index = $6;
|
||||
$$.scale = $8;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = int16(x86.D_INDIR+$3);
|
||||
$$.Offset = $1;
|
||||
$$.Index = uint8($6);
|
||||
$$.Scale = int8($8);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
| con '(' LLREG ')' '(' LSREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$3;
|
||||
$$.offset = $1;
|
||||
$$.index = $6;
|
||||
$$.scale = $8;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = int16(x86.D_INDIR+$3);
|
||||
$$.Offset = $1;
|
||||
$$.Index = uint8($6);
|
||||
$$.Scale = int8($8);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
| '(' LLREG ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$2;
|
||||
$$.Type_ = int16(x86.D_INDIR+$2);
|
||||
}
|
||||
| '(' LSP ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_SP;
|
||||
$$.Type_ = int16(x86.D_INDIR+x86.D_SP);
|
||||
}
|
||||
| '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_NONE;
|
||||
$$.index = $2;
|
||||
$$.scale = $4;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = int16(x86.D_INDIR+x86.D_NONE);
|
||||
$$.Index = uint8($2);
|
||||
$$.Scale = int8($4);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
| '(' LLREG ')' '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$2;
|
||||
$$.index = $5;
|
||||
$$.scale = $7;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = int16(x86.D_INDIR+$2);
|
||||
$$.Index = uint8($5);
|
||||
$$.Scale = int8($7);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
|
||||
nmem:
|
||||
@ -553,25 +566,25 @@ nmem:
|
||||
| nam '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = $1;
|
||||
$$.index = $3;
|
||||
$$.scale = $5;
|
||||
checkscale($$.scale);
|
||||
$$.Index = uint8($3);
|
||||
$$.Scale = int8($5);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
|
||||
nam:
|
||||
LNAME offset '(' pointer ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $4;
|
||||
$$.sym = linklookup(ctxt, $1->name, 0);
|
||||
$$.offset = $2;
|
||||
$$.Type_ = int16($4);
|
||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||
$$.Offset = $2;
|
||||
}
|
||||
| LNAME '<' '>' offset '(' LSB ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_STATIC;
|
||||
$$.sym = linklookup(ctxt, $1->name, 1);
|
||||
$$.offset = $4;
|
||||
$$.Type_ = x86.D_STATIC;
|
||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
||||
$$.Offset = $4;
|
||||
}
|
||||
|
||||
offset:
|
||||
@ -591,7 +604,7 @@ pointer:
|
||||
LSB
|
||||
| LSP
|
||||
{
|
||||
$$ = D_AUTO;
|
||||
$$ = x86.D_AUTO;
|
||||
}
|
||||
| LFP
|
||||
|
||||
@ -599,7 +612,7 @@ con:
|
||||
LCONST
|
||||
| LVAR
|
||||
{
|
||||
$$ = $1->value;
|
||||
$$ = $1.Value;
|
||||
}
|
||||
| '-' con
|
||||
{
|
||||
@ -611,7 +624,7 @@ con:
|
||||
}
|
||||
| '~' con
|
||||
{
|
||||
$$ = ~$2;
|
||||
$$ = ^$2;
|
||||
}
|
||||
| '(' expr ')'
|
||||
{
|
||||
@ -621,23 +634,19 @@ con:
|
||||
con2:
|
||||
LCONST
|
||||
{
|
||||
$$ = ($1 & 0xffffffffLL) +
|
||||
((vlong)ArgsSizeUnknown << 32);
|
||||
$$ = int64(uint64($1 & 0xffffffff) + (obj.ArgsSizeUnknown<<32))
|
||||
}
|
||||
| '-' LCONST
|
||||
{
|
||||
$$ = (-$2 & 0xffffffffLL) +
|
||||
((vlong)ArgsSizeUnknown << 32);
|
||||
$$ = int64(uint64(-$2 & 0xffffffff) + (obj.ArgsSizeUnknown<<32))
|
||||
}
|
||||
| LCONST '-' LCONST
|
||||
{
|
||||
$$ = ($1 & 0xffffffffLL) +
|
||||
(($3 & 0xffffLL) << 32);
|
||||
$$ = ($1 & 0xffffffff) + (($3 & 0xffff) << 32);
|
||||
}
|
||||
| '-' LCONST '-' LCONST
|
||||
{
|
||||
$$ = (-$2 & 0xffffffffLL) +
|
||||
(($4 & 0xffffLL) << 32);
|
||||
$$ = (-$2 & 0xffffffff) + (($4 & 0xffff) << 32);
|
||||
}
|
||||
|
||||
expr:
|
||||
@ -664,11 +673,11 @@ expr:
|
||||
}
|
||||
| expr '<' '<' expr
|
||||
{
|
||||
$$ = $1 << $4;
|
||||
$$ = $1 << uint($4);
|
||||
}
|
||||
| expr '>' '>' expr
|
||||
{
|
||||
$$ = $1 >> $4;
|
||||
$$ = $1 >> uint($4);
|
||||
}
|
||||
| expr '&' expr
|
||||
{
|
||||
|
@ -28,171 +28,67 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//go:generate go tool yacc a.y
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
Plan9 = 1 << 0
|
||||
Unix = 1 << 1
|
||||
Windows = 1 << 2
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/x86"
|
||||
)
|
||||
|
||||
func systemtype(sys int) int {
|
||||
return sys & Windows
|
||||
var (
|
||||
yyerror = asm.Yyerror
|
||||
nullgen obj.Addr
|
||||
stmtline int32
|
||||
)
|
||||
|
||||
return sys & Plan9
|
||||
}
|
||||
|
||||
func pathchar() int {
|
||||
return '/'
|
||||
}
|
||||
|
||||
func Lconv(fp *obj.Fmt) int {
|
||||
return obj.Linklinefmt(ctxt, fp)
|
||||
}
|
||||
|
||||
func dodef(p string) {
|
||||
if nDlist%8 == 0 {
|
||||
Dlist = allocn(Dlist, nDlist*sizeof(string), 8*sizeof(string)).(*string)
|
||||
}
|
||||
Dlist[nDlist] = p
|
||||
nDlist++
|
||||
}
|
||||
|
||||
var thelinkarch *obj.LinkArch = &x86.Linkamd64
|
||||
|
||||
func usage() {
|
||||
fmt.Printf("usage: %ca [options] file.c...\n", thechar)
|
||||
main.Flagprint(1)
|
||||
errorexit()
|
||||
}
|
||||
|
||||
func main(argc int, argv [XXX]string) {
|
||||
var p string
|
||||
|
||||
thechar = '6'
|
||||
thestring = "amd64"
|
||||
|
||||
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
|
||||
// but not other values.
|
||||
p = Getgoarch()
|
||||
|
||||
if !strings.HasPrefix(p, thestring) {
|
||||
log.Fatalf("cannot use %cc with GOARCH=%s", thechar, p)
|
||||
}
|
||||
if p == "amd64p32" {
|
||||
thelinkarch = &x86.Linkamd64p32
|
||||
}
|
||||
|
||||
ctxt = obj.Linknew(thelinkarch)
|
||||
ctxt.Diag = yyerror
|
||||
ctxt.Bso = &bstdout
|
||||
ctxt.Enforce_data_order = 1
|
||||
obj.Binit(&bstdout, 1, main.OWRITE)
|
||||
x86.Listinit6()
|
||||
obj.Fmtinstall('L', Lconv)
|
||||
|
||||
ensuresymb(NSYMB)
|
||||
debug = [256]int{}
|
||||
func main() {
|
||||
cinit()
|
||||
outfile = ""
|
||||
setinclude(".")
|
||||
|
||||
main.Flagfn1("D", "name[=value]: add #define", dodef)
|
||||
main.Flagfn1("I", "dir: add dir to include path", setinclude)
|
||||
main.Flagcount("S", "print assembly and machine code", &debug['S'])
|
||||
main.Flagcount("m", "debug preprocessor macros", &debug['m'])
|
||||
main.Flagstr("o", "file: set output file", &outfile)
|
||||
main.Flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt.Trimpath)
|
||||
asm.LSCONST = LSCONST
|
||||
asm.LCONST = LCONST
|
||||
asm.LFCONST = LFCONST
|
||||
asm.LNAME = LNAME
|
||||
asm.LVAR = LVAR
|
||||
asm.LLAB = LLAB
|
||||
|
||||
main.Flagparse(&argc, (**string)(&argv), usage)
|
||||
ctxt.Debugasm = int32(debug['S'])
|
||||
|
||||
if argc < 1 {
|
||||
usage()
|
||||
}
|
||||
if argc > 1 {
|
||||
fmt.Printf("can't assemble multiple files\n")
|
||||
errorexit()
|
||||
asm.Thechar = '6'
|
||||
asm.Thestring = "amd64"
|
||||
asm.Thelinkarch = &x86.Linkamd64
|
||||
asm.Arches = map[string]*obj.LinkArch{
|
||||
"amd64p32": &x86.Linkamd64p32,
|
||||
}
|
||||
|
||||
if assemble(argv[0]) != 0 {
|
||||
errorexit()
|
||||
}
|
||||
obj.Bflush(&bstdout)
|
||||
if nerrors > 0 {
|
||||
errorexit()
|
||||
}
|
||||
main.Exits("")
|
||||
asm.Lexinit = lexinit
|
||||
asm.Cclean = cclean
|
||||
asm.Yyparse = yyparse
|
||||
|
||||
asm.Main()
|
||||
}
|
||||
|
||||
func assemble(file string) int {
|
||||
var ofile string
|
||||
var p string
|
||||
var i int
|
||||
var of int
|
||||
type yy struct{}
|
||||
|
||||
ofile = alloc(int32(len(file)) + 3).(string) // +3 for .x\0 (x=thechar)
|
||||
ofile = file
|
||||
p = main.Utfrrune(ofile, uint(pathchar()))
|
||||
if p != "" {
|
||||
include[0] = ofile
|
||||
p = ""
|
||||
p = p[1:]
|
||||
} else {
|
||||
|
||||
p = ofile
|
||||
}
|
||||
if outfile == "" {
|
||||
outfile = p
|
||||
if outfile != "" {
|
||||
p = main.Utfrrune(outfile, '.')
|
||||
if p != "" {
|
||||
if p[1] == 's' && p[2] == 0 {
|
||||
p = ""
|
||||
}
|
||||
}
|
||||
p = main.Utfrune(outfile, 0)
|
||||
p[0] = '.'
|
||||
p[1] = byte(thechar)
|
||||
p[2] = 0
|
||||
} else {
|
||||
|
||||
outfile = "/dev/null"
|
||||
}
|
||||
}
|
||||
|
||||
of = main.Create(outfile, main.OWRITE, 0664)
|
||||
if of < 0 {
|
||||
yyerror("%ca: cannot create %s", thechar, outfile)
|
||||
errorexit()
|
||||
}
|
||||
|
||||
obj.Binit(&obuf, of, main.OWRITE)
|
||||
fmt.Fprintf(&obuf, "go object %s %s %s\n", main.Getgoos(), main.Getgoarch(), main.Getgoversion())
|
||||
fmt.Fprintf(&obuf, "!\n")
|
||||
|
||||
for pass = 1; pass <= 2; pass++ {
|
||||
pinit(file)
|
||||
for i = 0; i < nDlist; i++ {
|
||||
dodefine(Dlist[i])
|
||||
}
|
||||
yyparse()
|
||||
cclean()
|
||||
if nerrors != 0 {
|
||||
return nerrors
|
||||
}
|
||||
}
|
||||
|
||||
obj.Writeobj(ctxt, &obuf)
|
||||
obj.Bflush(&obuf)
|
||||
return 0
|
||||
func (yy) Lex(v *yySymType) int {
|
||||
var av asm.Yylval
|
||||
tok := asm.Yylex(&av)
|
||||
v.sym = av.Sym
|
||||
v.lval = av.Lval
|
||||
v.sval = av.Sval
|
||||
v.dval = av.Dval
|
||||
return tok
|
||||
}
|
||||
|
||||
var itab = []struct {
|
||||
name string
|
||||
type_ uint16
|
||||
value uint16
|
||||
}{
|
||||
func (yy) Error(msg string) {
|
||||
asm.Yyerror("%s", msg)
|
||||
}
|
||||
|
||||
func yyparse() {
|
||||
yyParse(yy{})
|
||||
}
|
||||
|
||||
var lexinit = []asm.Lextab{
|
||||
{"SP", LSP, x86.D_AUTO},
|
||||
{"SB", LSB, x86.D_EXTERN},
|
||||
{"FP", LFP, x86.D_PARAM},
|
||||
@ -1019,31 +915,11 @@ var itab = []struct {
|
||||
}
|
||||
|
||||
func cinit() {
|
||||
var s *Sym
|
||||
var i int
|
||||
|
||||
nullgen.Type_ = x86.D_NONE
|
||||
nullgen.Index = x86.D_NONE
|
||||
|
||||
nerrors = 0
|
||||
iostack = nil
|
||||
iofree = nil
|
||||
peekc = IGN
|
||||
nhunk = 0
|
||||
for i = 0; i < NHASH; i++ {
|
||||
hash[i] = nil
|
||||
}
|
||||
for i = 0; itab[i].name != ""; i++ {
|
||||
s = slookup(itab[i].name)
|
||||
if s.type_ != LNAME {
|
||||
yyerror("double initialization %s", itab[i].name)
|
||||
}
|
||||
s.type_ = itab[i].type_
|
||||
s.value = int64(itab[i].value)
|
||||
}
|
||||
}
|
||||
|
||||
func checkscale(scale int) {
|
||||
func checkscale(scale int8) {
|
||||
switch scale {
|
||||
case 1,
|
||||
2,
|
||||
@ -1055,11 +931,6 @@ func checkscale(scale int) {
|
||||
yyerror("scale must be 1248: %d", scale)
|
||||
}
|
||||
|
||||
func syminit(s *Sym) {
|
||||
s.type_ = LNAME
|
||||
s.value = 0
|
||||
}
|
||||
|
||||
func cclean() {
|
||||
var g2 Addr2
|
||||
|
||||
@ -1070,24 +941,30 @@ func cclean() {
|
||||
|
||||
var lastpc *obj.Prog
|
||||
|
||||
type Addr2 struct {
|
||||
from obj.Addr
|
||||
to obj.Addr
|
||||
}
|
||||
|
||||
func outcode(a int, g2 *Addr2) {
|
||||
var p *obj.Prog
|
||||
var pl *obj.Plist
|
||||
|
||||
if pass == 1 {
|
||||
if asm.Pass == 1 {
|
||||
goto out
|
||||
}
|
||||
|
||||
p = new(obj.Prog)
|
||||
*p = obj.Prog{}
|
||||
p.Ctxt = asm.Ctxt
|
||||
p.As = int16(a)
|
||||
p.Lineno = stmtline
|
||||
p.From = g2.from
|
||||
p.To = g2.to
|
||||
p.Pc = int64(pc)
|
||||
p.Pc = int64(asm.PC)
|
||||
|
||||
if lastpc == nil {
|
||||
pl = obj.Linknewplist(ctxt)
|
||||
pl = obj.Linknewplist(asm.Ctxt)
|
||||
pl.Firstpc = p
|
||||
} else {
|
||||
|
||||
@ -1097,6 +974,6 @@ func outcode(a int, g2 *Addr2) {
|
||||
|
||||
out:
|
||||
if a != x86.AGLOBL && a != x86.ADATA {
|
||||
pc++
|
||||
asm.PC++
|
||||
}
|
||||
}
|
||||
|
1313
src/cmd/new6a/y.go
Normal file
1313
src/cmd/new6a/y.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,24 +29,28 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
%{
|
||||
#include <u.h>
|
||||
#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
|
||||
#include <libc.h>
|
||||
#include "a.h"
|
||||
#include "../../runtime/funcdata.h"
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
. "cmd/internal/obj/i386"
|
||||
)
|
||||
%}
|
||||
%union {
|
||||
Sym *sym;
|
||||
int32 lval;
|
||||
struct {
|
||||
int32 v1;
|
||||
int32 v2;
|
||||
} con2;
|
||||
double dval;
|
||||
char sval[8];
|
||||
Addr addr;
|
||||
Addr2 addr2;
|
||||
|
||||
%union {
|
||||
sym *asm.Sym
|
||||
lval int64
|
||||
con2 struct {
|
||||
v1 int32
|
||||
v2 int32
|
||||
}
|
||||
dval float64
|
||||
sval string
|
||||
addr obj.Addr
|
||||
addr2 Addr2
|
||||
}
|
||||
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
@ -69,18 +73,19 @@
|
||||
prog:
|
||||
| prog
|
||||
{
|
||||
stmtline = lineno;
|
||||
stmtline = asm.Lineno;
|
||||
}
|
||||
line
|
||||
|
||||
line:
|
||||
LNAME ':'
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
if($1->type == LLAB && $1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->labelname);
|
||||
$1->type = LLAB;
|
||||
$1->value = pc;
|
||||
$1 = asm.LabelLookup($1);
|
||||
if $1.Type == LLAB && $1.Value != int64(asm.PC) {
|
||||
yyerror("redeclaration of %s", $1.Labelname)
|
||||
}
|
||||
$1.Type = LLAB;
|
||||
$1.Value = int64(asm.PC)
|
||||
}
|
||||
line
|
||||
| ';'
|
||||
@ -90,33 +95,34 @@ line:
|
||||
inst:
|
||||
LNAME '=' expr
|
||||
{
|
||||
$1->type = LVAR;
|
||||
$1->value = $3;
|
||||
$1.Type = LVAR;
|
||||
$1.Value = $3;
|
||||
}
|
||||
| LVAR '=' expr
|
||||
{
|
||||
if($1->value != $3)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = $3;
|
||||
if $1.Value != int64($3) {
|
||||
yyerror("redeclaration of %s", $1.Name);
|
||||
}
|
||||
$1.Value = $3;
|
||||
}
|
||||
| LTYPE0 nonnon { outcode($1, &$2); }
|
||||
| LTYPE1 nonrem { outcode($1, &$2); }
|
||||
| LTYPE2 rimnon { outcode($1, &$2); }
|
||||
| LTYPE3 rimrem { outcode($1, &$2); }
|
||||
| LTYPE4 remrim { outcode($1, &$2); }
|
||||
| LTYPER nonrel { outcode($1, &$2); }
|
||||
| LTYPED spec1 { outcode($1, &$2); }
|
||||
| LTYPET spec2 { outcode($1, &$2); }
|
||||
| LTYPEC spec3 { outcode($1, &$2); }
|
||||
| LTYPEN spec4 { outcode($1, &$2); }
|
||||
| LTYPES spec5 { outcode($1, &$2); }
|
||||
| LTYPEM spec6 { outcode($1, &$2); }
|
||||
| LTYPEI spec7 { outcode($1, &$2); }
|
||||
| LTYPEG spec8 { outcode($1, &$2); }
|
||||
| LTYPEXC spec9 { outcode($1, &$2); }
|
||||
| LTYPEX spec10 { outcode($1, &$2); }
|
||||
| LTYPEPC spec11 { outcode($1, &$2); }
|
||||
| LTYPEF spec12 { outcode($1, &$2); }
|
||||
| LTYPE0 nonnon { outcode(int($1), &$2); }
|
||||
| LTYPE1 nonrem { outcode(int($1), &$2); }
|
||||
| LTYPE2 rimnon { outcode(int($1), &$2); }
|
||||
| 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); }
|
||||
| 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); }
|
||||
| LTYPEXC spec9 { outcode(int($1), &$2); }
|
||||
| LTYPEX spec10 { outcode(int($1), &$2); }
|
||||
| LTYPEPC spec11 { outcode(int($1), &$2); }
|
||||
| LTYPEF spec12 { outcode(int($1), &$2); }
|
||||
|
||||
nonnon:
|
||||
{
|
||||
@ -188,22 +194,22 @@ spec1: /* DATA */
|
||||
nam '/' con ',' imm
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.from.scale = $3;
|
||||
$$.from.Scale = int8($3);
|
||||
$$.to = $5;
|
||||
}
|
||||
|
||||
spec2: /* TEXT */
|
||||
mem ',' imm2
|
||||
{
|
||||
settext($1.sym);
|
||||
asm.Settext($1.Sym);
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
}
|
||||
| mem ',' con ',' imm2
|
||||
{
|
||||
settext($1.sym);
|
||||
asm.Settext($1.Sym);
|
||||
$$.from = $1;
|
||||
$$.from.scale = $3;
|
||||
$$.from.Scale = int8($3);
|
||||
$$.to = $5;
|
||||
}
|
||||
|
||||
@ -222,8 +228,8 @@ spec3: /* JMP/CALL */
|
||||
{
|
||||
$$.from = nullgen;
|
||||
$$.to = $2;
|
||||
$$.to.index = $2.type;
|
||||
$$.to.type = D_INDIR+D_ADDR;
|
||||
$$.to.Index = uint8($2.Type_)
|
||||
$$.to.Type_ = D_INDIR+D_ADDR;
|
||||
}
|
||||
|
||||
spec4: /* NOP */
|
||||
@ -240,9 +246,10 @@ spec5: /* SHL/SHR */
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
if($$.from.index != D_NONE)
|
||||
if $$.from.Index != D_NONE {
|
||||
yyerror("dp shift with lhs index");
|
||||
$$.from.index = $5;
|
||||
}
|
||||
$$.from.Index = uint8($5);
|
||||
}
|
||||
|
||||
spec6: /* MOVW/MOVL */
|
||||
@ -255,9 +262,10 @@ spec6: /* MOVW/MOVL */
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
if($$.to.index != D_NONE)
|
||||
if $$.to.Index != D_NONE {
|
||||
yyerror("dp move with lhs index");
|
||||
$$.to.index = $5;
|
||||
}
|
||||
$$.to.Index = uint8($5);
|
||||
}
|
||||
|
||||
spec7:
|
||||
@ -286,7 +294,7 @@ spec8: /* GLOBL */
|
||||
| mem ',' con ',' imm
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.from.scale = $3;
|
||||
$$.from.Scale = int8($3);
|
||||
$$.to = $5;
|
||||
}
|
||||
|
||||
@ -295,7 +303,7 @@ spec9: /* CMPPS/CMPPD */
|
||||
{
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
$$.to.offset = $5;
|
||||
$$.to.Offset = $5;
|
||||
}
|
||||
|
||||
spec10: /* PINSRD */
|
||||
@ -303,16 +311,18 @@ spec10: /* PINSRD */
|
||||
{
|
||||
$$.from = $3;
|
||||
$$.to = $5;
|
||||
if($1.type != D_CONST)
|
||||
yyerror("illegal constant");
|
||||
$$.to.offset = $1.offset;
|
||||
if $1.Type_ != D_CONST {
|
||||
yyerror("illegal constant")
|
||||
}
|
||||
$$.to.Offset = $1.Offset;
|
||||
}
|
||||
|
||||
spec11: /* PCDATA */
|
||||
rim ',' rim
|
||||
{
|
||||
if($1.type != D_CONST || $3.type != D_CONST)
|
||||
if $1.Type_ != D_CONST || $3.Type_ != D_CONST {
|
||||
yyerror("arguments to PCDATA must be integer constants");
|
||||
}
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
}
|
||||
@ -320,10 +330,12 @@ spec11: /* PCDATA */
|
||||
spec12: /* FUNCDATA */
|
||||
rim ',' rim
|
||||
{
|
||||
if($1.type != D_CONST)
|
||||
if $1.Type_ != D_CONST {
|
||||
yyerror("index for FUNCDATA must be integer constant");
|
||||
if($3.type != D_EXTERN && $3.type != D_STATIC)
|
||||
}
|
||||
if $3.Type_ != D_EXTERN && $3.Type_ != D_STATIC {
|
||||
yyerror("value for FUNCDATA must be symbol reference");
|
||||
}
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
}
|
||||
@ -355,129 +367,130 @@ rel:
|
||||
con '(' LPC ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1 + pc;
|
||||
$$.Type_ = D_BRANCH;
|
||||
$$.Offset = $1 + int64(asm.PC);
|
||||
}
|
||||
| LNAME offset
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
$1 = asm.LabelLookup($1);
|
||||
$$ = nullgen;
|
||||
if(pass == 2 && $1->type != LLAB)
|
||||
yyerror("undefined label: %s", $1->labelname);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1->value + $2;
|
||||
if asm.Pass == 2 && $1.Type != LLAB {
|
||||
yyerror("undefined label: %s", $1.Labelname);
|
||||
}
|
||||
$$.Type_ = D_BRANCH;
|
||||
$$.Offset = $1.Value + $2;
|
||||
}
|
||||
|
||||
reg:
|
||||
LBREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LFREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LLREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LXREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
| LSP
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SP;
|
||||
$$.Type_ = D_SP;
|
||||
}
|
||||
| LSREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.Type_ = int16($1);
|
||||
}
|
||||
|
||||
imm:
|
||||
'$' con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CONST;
|
||||
$$.offset = $2;
|
||||
$$.Type_ = D_CONST;
|
||||
$$.Offset = $2;
|
||||
}
|
||||
| '$' nam
|
||||
{
|
||||
$$ = $2;
|
||||
$$.index = $2.type;
|
||||
$$.type = D_ADDR;
|
||||
$$.Index = uint8($2.Type_);
|
||||
$$.Type_ = D_ADDR;
|
||||
/*
|
||||
if($2.type == D_AUTO || $2.type == D_PARAM)
|
||||
if($2.Type_ == D_AUTO || $2.Type_ == D_PARAM)
|
||||
yyerror("constant cannot be automatic: %s",
|
||||
$2.sym->name);
|
||||
$2.Sym.name);
|
||||
*/
|
||||
}
|
||||
| '$' LSCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SCONST;
|
||||
memcpy($$.u.sval, $2, sizeof($$.u.sval));
|
||||
$$.Type_ = D_SCONST;
|
||||
$$.U.Sval = $2
|
||||
}
|
||||
| '$' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = $2;
|
||||
$$.Type_ = D_FCONST;
|
||||
$$.U.Dval = $2;
|
||||
}
|
||||
| '$' '(' LFCONST ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = $3;
|
||||
$$.Type_ = D_FCONST;
|
||||
$$.U.Dval = $3;
|
||||
}
|
||||
| '$' '(' '-' LFCONST ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = -$4;
|
||||
$$.Type_ = D_FCONST;
|
||||
$$.U.Dval = -$4;
|
||||
}
|
||||
| '$' '-' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = -$3;
|
||||
$$.Type_ = D_FCONST;
|
||||
$$.U.Dval = -$3;
|
||||
}
|
||||
|
||||
imm2:
|
||||
'$' con2
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CONST2;
|
||||
$$.offset = $2.v1;
|
||||
$$.offset2 = $2.v2;
|
||||
$$.Type_ = D_CONST2;
|
||||
$$.Offset = int64($2.v1);
|
||||
$$.Offset2 = int32($2.v2);
|
||||
}
|
||||
|
||||
con2:
|
||||
LCONST
|
||||
{
|
||||
$$.v1 = $1;
|
||||
$$.v2 = ArgsSizeUnknown;
|
||||
$$.v1 = int32($1);
|
||||
$$.v2 = -obj.ArgsSizeUnknown
|
||||
}
|
||||
| '-' LCONST
|
||||
{
|
||||
$$.v1 = -$2;
|
||||
$$.v2 = ArgsSizeUnknown;
|
||||
$$.v1 = int32(-$2);
|
||||
$$.v2 = -obj.ArgsSizeUnknown;
|
||||
}
|
||||
| LCONST '-' LCONST
|
||||
{
|
||||
$$.v1 = $1;
|
||||
$$.v2 = $3;
|
||||
$$.v1 = int32($1);
|
||||
$$.v2 = int32($3);
|
||||
}
|
||||
| '-' LCONST '-' LCONST
|
||||
{
|
||||
$$.v1 = -$2;
|
||||
$$.v2 = $4;
|
||||
$$.v1 = int32(-$2);
|
||||
$$.v2 = int32($4);
|
||||
}
|
||||
|
||||
mem:
|
||||
@ -488,79 +501,79 @@ omem:
|
||||
con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_NONE;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = D_INDIR+D_NONE;
|
||||
$$.Offset = $1;
|
||||
}
|
||||
| con '(' LLREG ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$3;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = int16(D_INDIR+$3);
|
||||
$$.Offset = $1;
|
||||
}
|
||||
| con '(' LSP ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_SP;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = D_INDIR+D_SP;
|
||||
$$.Offset = $1;
|
||||
}
|
||||
| con '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_NONE;
|
||||
$$.offset = $1;
|
||||
$$.index = $3;
|
||||
$$.scale = $5;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = D_INDIR+D_NONE;
|
||||
$$.Offset = $1;
|
||||
$$.Index = uint8($3);
|
||||
$$.Scale = int8($5);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
| con '(' LLREG ')' '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$3;
|
||||
$$.offset = $1;
|
||||
$$.index = $6;
|
||||
$$.scale = $8;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = int16(D_INDIR+$3);
|
||||
$$.Offset = $1;
|
||||
$$.Index = uint8($6);
|
||||
$$.Scale = int8($8);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
| con '(' LLREG ')' '(' LSREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$3;
|
||||
$$.offset = $1;
|
||||
$$.index = $6;
|
||||
$$.scale = $8;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = int16(D_INDIR+$3);
|
||||
$$.Offset = $1;
|
||||
$$.Index = uint8($6);
|
||||
$$.Scale = int8($8);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
| '(' LLREG ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$2;
|
||||
$$.Type_ = int16(D_INDIR+$2);
|
||||
}
|
||||
| '(' LSP ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_SP;
|
||||
$$.Type_ = D_INDIR+D_SP;
|
||||
}
|
||||
| con '(' LSREG ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$3;
|
||||
$$.offset = $1;
|
||||
$$.Type_ = int16(D_INDIR+$3);
|
||||
$$.Offset = $1;
|
||||
}
|
||||
| '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+D_NONE;
|
||||
$$.index = $2;
|
||||
$$.scale = $4;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = D_INDIR+D_NONE;
|
||||
$$.Index = uint8($2);
|
||||
$$.Scale = int8($4);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
| '(' LLREG ')' '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_INDIR+$2;
|
||||
$$.index = $5;
|
||||
$$.scale = $7;
|
||||
checkscale($$.scale);
|
||||
$$.Type_ = int16(D_INDIR+$2);
|
||||
$$.Index = uint8($5);
|
||||
$$.Scale = int8($7);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
|
||||
nmem:
|
||||
@ -571,25 +584,25 @@ nmem:
|
||||
| nam '(' LLREG '*' con ')'
|
||||
{
|
||||
$$ = $1;
|
||||
$$.index = $3;
|
||||
$$.scale = $5;
|
||||
checkscale($$.scale);
|
||||
$$.Index = uint8($3);
|
||||
$$.Scale = int8($5);
|
||||
checkscale($$.Scale);
|
||||
}
|
||||
|
||||
nam:
|
||||
LNAME offset '(' pointer ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $4;
|
||||
$$.sym = linklookup(ctxt, $1->name, 0);
|
||||
$$.offset = $2;
|
||||
$$.Type_ = int16($4);
|
||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||
$$.Offset = $2;
|
||||
}
|
||||
| LNAME '<' '>' offset '(' LSB ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_STATIC;
|
||||
$$.sym = linklookup(ctxt, $1->name, 1);
|
||||
$$.offset = $4;
|
||||
$$.Type_ = D_STATIC;
|
||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
||||
$$.Offset = $4;
|
||||
}
|
||||
|
||||
offset:
|
||||
@ -617,7 +630,7 @@ con:
|
||||
LCONST
|
||||
| LVAR
|
||||
{
|
||||
$$ = $1->value;
|
||||
$$ = $1.Value;
|
||||
}
|
||||
| '-' con
|
||||
{
|
||||
@ -629,7 +642,7 @@ con:
|
||||
}
|
||||
| '~' con
|
||||
{
|
||||
$$ = ~$2;
|
||||
$$ = ^$2;
|
||||
}
|
||||
| '(' expr ')'
|
||||
{
|
||||
@ -660,11 +673,11 @@ expr:
|
||||
}
|
||||
| expr '<' '<' expr
|
||||
{
|
||||
$$ = $1 << $4;
|
||||
$$ = $1 << uint($4);
|
||||
}
|
||||
| expr '>' '>' expr
|
||||
{
|
||||
$$ = $1 >> $4;
|
||||
$$ = $1 >> uint($4);
|
||||
}
|
||||
| expr '&' expr
|
||||
{
|
||||
|
@ -28,166 +28,64 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//go:generate go tool yacc a.y
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
Plan9 = 1 << 0
|
||||
Unix = 1 << 1
|
||||
Windows = 1 << 2
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/i386"
|
||||
)
|
||||
|
||||
func systemtype(sys int) int {
|
||||
return sys & Windows
|
||||
var (
|
||||
yyerror = asm.Yyerror
|
||||
nullgen obj.Addr
|
||||
stmtline int32
|
||||
)
|
||||
|
||||
return sys & Plan9
|
||||
}
|
||||
|
||||
func pathchar() int {
|
||||
return '/'
|
||||
}
|
||||
|
||||
func Lconv(fp *obj.Fmt) int {
|
||||
return obj.Linklinefmt(ctxt, fp)
|
||||
}
|
||||
|
||||
func dodef(p string) {
|
||||
if nDlist%8 == 0 {
|
||||
Dlist = allocn(Dlist, nDlist*sizeof(string), 8*sizeof(string)).(*string)
|
||||
}
|
||||
Dlist[nDlist] = p
|
||||
nDlist++
|
||||
}
|
||||
|
||||
func usage() {
|
||||
fmt.Printf("usage: %ca [options] file.c...\n", thechar)
|
||||
main.Flagprint(1)
|
||||
errorexit()
|
||||
}
|
||||
|
||||
func main(argc int, argv [XXX]string) {
|
||||
var p string
|
||||
|
||||
thechar = '8'
|
||||
thestring = "386"
|
||||
|
||||
ctxt = obj.Linknew(&i386.Link386)
|
||||
ctxt.Diag = yyerror
|
||||
ctxt.Bso = &bstdout
|
||||
ctxt.Enforce_data_order = 1
|
||||
obj.Binit(&bstdout, 1, main.OWRITE)
|
||||
i386.Listinit8()
|
||||
obj.Fmtinstall('L', Lconv)
|
||||
|
||||
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
|
||||
// but not other values.
|
||||
p = Getgoarch()
|
||||
|
||||
if !strings.HasPrefix(p, thestring) {
|
||||
log.Fatalf("cannot use %cc with GOARCH=%s", thechar, p)
|
||||
}
|
||||
|
||||
ensuresymb(NSYMB)
|
||||
debug = [256]int{}
|
||||
func main() {
|
||||
cinit()
|
||||
outfile = ""
|
||||
setinclude(".")
|
||||
|
||||
main.Flagfn1("D", "name[=value]: add #define", dodef)
|
||||
main.Flagfn1("I", "dir: add dir to include path", setinclude)
|
||||
main.Flagcount("S", "print assembly and machine code", &debug['S'])
|
||||
main.Flagcount("m", "debug preprocessor macros", &debug['m'])
|
||||
main.Flagstr("o", "file: set output file", &outfile)
|
||||
main.Flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt.Trimpath)
|
||||
asm.LSCONST = LSCONST
|
||||
asm.LCONST = LCONST
|
||||
asm.LFCONST = LFCONST
|
||||
asm.LNAME = LNAME
|
||||
asm.LVAR = LVAR
|
||||
asm.LLAB = LLAB
|
||||
|
||||
main.Flagparse(&argc, (**string)(&argv), usage)
|
||||
ctxt.Debugasm = int32(debug['S'])
|
||||
asm.Lexinit = lexinit
|
||||
asm.Cclean = cclean
|
||||
asm.Yyparse = yyparse
|
||||
|
||||
if argc < 1 {
|
||||
usage()
|
||||
}
|
||||
if argc > 1 {
|
||||
fmt.Printf("can't assemble multiple files\n")
|
||||
errorexit()
|
||||
}
|
||||
asm.Thechar = '8'
|
||||
asm.Thestring = "386"
|
||||
asm.Thelinkarch = &i386.Link386
|
||||
|
||||
if assemble(argv[0]) != 0 {
|
||||
errorexit()
|
||||
}
|
||||
obj.Bflush(&bstdout)
|
||||
if nerrors > 0 {
|
||||
errorexit()
|
||||
}
|
||||
main.Exits("")
|
||||
asm.Main()
|
||||
}
|
||||
|
||||
func assemble(file string) int {
|
||||
var ofile string
|
||||
var p string
|
||||
var i int
|
||||
var of int
|
||||
type yy struct{}
|
||||
|
||||
ofile = alloc(int32(len(file)) + 3).(string) // +3 for .x\0 (x=thechar)
|
||||
ofile = file
|
||||
p = main.Utfrrune(ofile, uint(pathchar()))
|
||||
if p != "" {
|
||||
include[0] = ofile
|
||||
p = ""
|
||||
p = p[1:]
|
||||
} else {
|
||||
|
||||
p = ofile
|
||||
}
|
||||
if outfile == "" {
|
||||
outfile = p
|
||||
if outfile != "" {
|
||||
p = main.Utfrrune(outfile, '.')
|
||||
if p != "" {
|
||||
if p[1] == 's' && p[2] == 0 {
|
||||
p = ""
|
||||
}
|
||||
}
|
||||
p = main.Utfrune(outfile, 0)
|
||||
p[0] = '.'
|
||||
p[1] = byte(thechar)
|
||||
p[2] = 0
|
||||
} else {
|
||||
|
||||
outfile = "/dev/null"
|
||||
}
|
||||
}
|
||||
|
||||
of = main.Create(outfile, main.OWRITE, 0664)
|
||||
if of < 0 {
|
||||
yyerror("%ca: cannot create %s", thechar, outfile)
|
||||
errorexit()
|
||||
}
|
||||
|
||||
obj.Binit(&obuf, of, main.OWRITE)
|
||||
fmt.Fprintf(&obuf, "go object %s %s %s\n", main.Getgoos(), main.Getgoarch(), main.Getgoversion())
|
||||
fmt.Fprintf(&obuf, "!\n")
|
||||
|
||||
for pass = 1; pass <= 2; pass++ {
|
||||
pinit(file)
|
||||
for i = 0; i < nDlist; i++ {
|
||||
dodefine(Dlist[i])
|
||||
}
|
||||
yyparse()
|
||||
cclean()
|
||||
if nerrors != 0 {
|
||||
return nerrors
|
||||
}
|
||||
}
|
||||
|
||||
obj.Writeobj(ctxt, &obuf)
|
||||
obj.Bflush(&obuf)
|
||||
return 0
|
||||
func (yy) Lex(v *yySymType) int {
|
||||
var av asm.Yylval
|
||||
tok := asm.Yylex(&av)
|
||||
v.sym = av.Sym
|
||||
v.lval = av.Lval
|
||||
v.sval = av.Sval
|
||||
v.dval = av.Dval
|
||||
return tok
|
||||
}
|
||||
|
||||
var itab = []struct {
|
||||
name string
|
||||
type_ uint16
|
||||
value uint16
|
||||
}{
|
||||
func (yy) Error(msg string) {
|
||||
asm.Yyerror("%s", msg)
|
||||
}
|
||||
|
||||
func yyparse() {
|
||||
yyParse(yy{})
|
||||
}
|
||||
|
||||
var lexinit = []asm.Lextab{
|
||||
{"SP", LSP, i386.D_AUTO},
|
||||
{"SB", LSB, i386.D_EXTERN},
|
||||
{"FP", LFP, i386.D_PARAM},
|
||||
@ -804,31 +702,11 @@ var itab = []struct {
|
||||
}
|
||||
|
||||
func cinit() {
|
||||
var s *Sym
|
||||
var i int
|
||||
|
||||
nullgen.Type_ = i386.D_NONE
|
||||
nullgen.Index = i386.D_NONE
|
||||
|
||||
nerrors = 0
|
||||
iostack = nil
|
||||
iofree = nil
|
||||
peekc = IGN
|
||||
nhunk = 0
|
||||
for i = 0; i < NHASH; i++ {
|
||||
hash[i] = nil
|
||||
}
|
||||
for i = 0; itab[i].name != ""; i++ {
|
||||
s = slookup(itab[i].name)
|
||||
if s.type_ != LNAME {
|
||||
yyerror("double initialization %s", itab[i].name)
|
||||
}
|
||||
s.type_ = itab[i].type_
|
||||
s.value = int32(itab[i].value)
|
||||
}
|
||||
}
|
||||
|
||||
func checkscale(scale int) {
|
||||
func checkscale(scale int8) {
|
||||
switch scale {
|
||||
case 1,
|
||||
2,
|
||||
@ -840,9 +718,9 @@ func checkscale(scale int) {
|
||||
yyerror("scale must be 1248: %d", scale)
|
||||
}
|
||||
|
||||
func syminit(s *Sym) {
|
||||
s.type_ = LNAME
|
||||
s.value = 0
|
||||
func syminit(s *asm.Sym) {
|
||||
s.Type = LNAME
|
||||
s.Value = 0
|
||||
}
|
||||
|
||||
func cclean() {
|
||||
@ -855,24 +733,30 @@ func cclean() {
|
||||
|
||||
var lastpc *obj.Prog
|
||||
|
||||
type Addr2 struct {
|
||||
from obj.Addr
|
||||
to obj.Addr
|
||||
}
|
||||
|
||||
func outcode(a int, g2 *Addr2) {
|
||||
var p *obj.Prog
|
||||
var pl *obj.Plist
|
||||
|
||||
if pass == 1 {
|
||||
if asm.Pass == 1 {
|
||||
goto out
|
||||
}
|
||||
|
||||
p = new(obj.Prog)
|
||||
*p = obj.Prog{}
|
||||
p.Ctxt = asm.Ctxt
|
||||
p.As = int16(a)
|
||||
p.Lineno = stmtline
|
||||
p.From = g2.from
|
||||
p.To = g2.to
|
||||
p.Pc = int64(pc)
|
||||
p.Pc = int64(asm.PC)
|
||||
|
||||
if lastpc == nil {
|
||||
pl = obj.Linknewplist(ctxt)
|
||||
pl = obj.Linknewplist(asm.Ctxt)
|
||||
pl.Firstpc = p
|
||||
} else {
|
||||
|
||||
@ -882,6 +766,6 @@ func outcode(a int, g2 *Addr2) {
|
||||
|
||||
out:
|
||||
if a != i386.AGLOBL && a != i386.ADATA {
|
||||
pc++
|
||||
asm.PC++
|
||||
}
|
||||
}
|
||||
|
1306
src/cmd/new8a/y.go
Normal file
1306
src/cmd/new8a/y.go
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -27,172 +27,67 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//go:generate go tool yacc a.y
|
||||
|
||||
package main
|
||||
|
||||
const (
|
||||
Plan9 = 1 << 0
|
||||
Unix = 1 << 1
|
||||
Windows = 1 << 2
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/ppc64"
|
||||
)
|
||||
|
||||
func systemtype(sys int) int {
|
||||
return sys & Windows
|
||||
var (
|
||||
yyerror = asm.Yyerror
|
||||
nullgen obj.Addr
|
||||
)
|
||||
|
||||
return sys & Plan9
|
||||
}
|
||||
|
||||
func pathchar() int {
|
||||
return '/'
|
||||
}
|
||||
|
||||
func Lconv(fp *obj.Fmt) int {
|
||||
return obj.Linklinefmt(ctxt, fp)
|
||||
}
|
||||
|
||||
func dodef(p string) {
|
||||
if nDlist%8 == 0 {
|
||||
Dlist = allocn(Dlist, nDlist*sizeof(string), 8*sizeof(string)).(*string)
|
||||
}
|
||||
Dlist[nDlist] = p
|
||||
nDlist++
|
||||
}
|
||||
|
||||
var thelinkarch *obj.LinkArch = &ppc64.Linkppc64
|
||||
|
||||
func usage() {
|
||||
fmt.Printf("usage: %ca [options] file.c...\n", thechar)
|
||||
main.Flagprint(1)
|
||||
errorexit()
|
||||
}
|
||||
|
||||
func main(argc int, argv [XXX]string) {
|
||||
var p string
|
||||
|
||||
thechar = '9'
|
||||
thestring = "ppc64"
|
||||
|
||||
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
|
||||
// but not other values.
|
||||
p = Getgoarch()
|
||||
|
||||
if !strings.HasPrefix(p, thestring) {
|
||||
log.Fatalf("cannot use %cc with GOARCH=%s", thechar, p)
|
||||
}
|
||||
if p == "ppc64le" {
|
||||
thelinkarch = &ppc64.Linkppc64le
|
||||
}
|
||||
|
||||
ctxt = obj.Linknew(thelinkarch)
|
||||
ctxt.Diag = yyerror
|
||||
ctxt.Bso = &bstdout
|
||||
ctxt.Enforce_data_order = 1
|
||||
obj.Binit(&bstdout, 1, main.OWRITE)
|
||||
ppc64.Listinit9()
|
||||
obj.Fmtinstall('L', Lconv)
|
||||
|
||||
ensuresymb(NSYMB)
|
||||
debug = [256]int{}
|
||||
func main() {
|
||||
cinit()
|
||||
outfile = ""
|
||||
setinclude(".")
|
||||
|
||||
main.Flagfn1("D", "name[=value]: add #define", dodef)
|
||||
main.Flagfn1("I", "dir: add dir to include path", setinclude)
|
||||
main.Flagcount("S", "print assembly and machine code", &debug['S'])
|
||||
main.Flagcount("m", "debug preprocessor macros", &debug['m'])
|
||||
main.Flagstr("o", "file: set output file", &outfile)
|
||||
main.Flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt.Trimpath)
|
||||
asm.LSCONST = LSCONST
|
||||
asm.LCONST = LCONST
|
||||
asm.LFCONST = LFCONST
|
||||
asm.LNAME = LNAME
|
||||
asm.LVAR = LVAR
|
||||
asm.LLAB = LLAB
|
||||
|
||||
main.Flagparse(&argc, (**string)(&argv), usage)
|
||||
ctxt.Debugasm = int32(debug['S'])
|
||||
asm.Lexinit = lexinit
|
||||
asm.Cclean = cclean
|
||||
asm.Yyparse = yyparse
|
||||
|
||||
if argc < 1 {
|
||||
usage()
|
||||
}
|
||||
if argc > 1 {
|
||||
fmt.Printf("can't assemble multiple files\n")
|
||||
errorexit()
|
||||
asm.Thechar = '9'
|
||||
asm.Thestring = "ppc64"
|
||||
asm.Thelinkarch = &ppc64.Linkppc64
|
||||
asm.Arches = map[string]*obj.LinkArch{
|
||||
"ppc64le": &ppc64.Linkppc64le,
|
||||
}
|
||||
|
||||
if assemble(argv[0]) != 0 {
|
||||
errorexit()
|
||||
}
|
||||
obj.Bflush(&bstdout)
|
||||
if nerrors > 0 {
|
||||
errorexit()
|
||||
}
|
||||
main.Exits("")
|
||||
asm.Main()
|
||||
}
|
||||
|
||||
func assemble(file string) int {
|
||||
var ofile string
|
||||
var p string
|
||||
var i int
|
||||
var of int
|
||||
type yy struct{}
|
||||
|
||||
ofile = alloc(int32(len(file)) + 3).(string) // +3 for .x\0 (x=thechar)
|
||||
ofile = file
|
||||
p = main.Utfrrune(ofile, uint(pathchar()))
|
||||
if p != "" {
|
||||
include[0] = ofile
|
||||
p = ""
|
||||
p = p[1:]
|
||||
} else {
|
||||
|
||||
p = ofile
|
||||
}
|
||||
if outfile == "" {
|
||||
outfile = p
|
||||
if outfile != "" {
|
||||
p = main.Utfrrune(outfile, '.')
|
||||
if p != "" {
|
||||
if p[1] == 's' && p[2] == 0 {
|
||||
p = ""
|
||||
}
|
||||
}
|
||||
p = main.Utfrune(outfile, 0)
|
||||
p[0] = '.'
|
||||
p[1] = byte(thechar)
|
||||
p[2] = 0
|
||||
} else {
|
||||
|
||||
outfile = "/dev/null"
|
||||
}
|
||||
}
|
||||
|
||||
of = main.Create(outfile, main.OWRITE, 0664)
|
||||
if of < 0 {
|
||||
yyerror("%ca: cannot create %s", thechar, outfile)
|
||||
errorexit()
|
||||
}
|
||||
|
||||
obj.Binit(&obuf, of, main.OWRITE)
|
||||
fmt.Fprintf(&obuf, "go object %s %s %s\n", main.Getgoos(), main.Getgoarch(), main.Getgoversion())
|
||||
fmt.Fprintf(&obuf, "!\n")
|
||||
|
||||
for pass = 1; pass <= 2; pass++ {
|
||||
nosched = 0
|
||||
pinit(file)
|
||||
for i = 0; i < nDlist; i++ {
|
||||
dodefine(Dlist[i])
|
||||
}
|
||||
yyparse()
|
||||
cclean()
|
||||
if nerrors != 0 {
|
||||
return nerrors
|
||||
}
|
||||
}
|
||||
|
||||
obj.Writeobj(ctxt, &obuf)
|
||||
obj.Bflush(&obuf)
|
||||
return 0
|
||||
func (yy) Lex(v *yySymType) int {
|
||||
var av asm.Yylval
|
||||
tok := asm.Yylex(&av)
|
||||
v.sym = av.Sym
|
||||
v.lval = av.Lval
|
||||
v.sval = av.Sval
|
||||
v.dval = av.Dval
|
||||
return tok
|
||||
}
|
||||
|
||||
var itab = []struct {
|
||||
name string
|
||||
type_ uint16
|
||||
value uint16
|
||||
}{
|
||||
func (yy) Error(msg string) {
|
||||
asm.Yyerror("%s", msg)
|
||||
}
|
||||
|
||||
func yyparse() {
|
||||
nosched = 0
|
||||
yyParse(yy{})
|
||||
}
|
||||
|
||||
var lexinit = []asm.Lextab{
|
||||
{"SP", LSP, ppc64.D_AUTO},
|
||||
{"SB", LSB, ppc64.D_EXTERN},
|
||||
{"FP", LFP, ppc64.D_PARAM},
|
||||
@ -549,7 +444,6 @@ var itab = []struct {
|
||||
{"ECIWX", LXLD, ppc64.AECIWX},
|
||||
{"ECOWX", LXST, ppc64.AECOWX},
|
||||
{"LWAR", LXLD, ppc64.ALWAR},
|
||||
{"LWAR", LXLD, ppc64.ALWAR},
|
||||
{"STWCCC", LXST, ppc64.ASTWCCC},
|
||||
{"EIEIO", LRETRN, ppc64.AEIEIO},
|
||||
{"TLBIE", LNOP, ppc64.ATLBIE},
|
||||
@ -571,33 +465,10 @@ var itab = []struct {
|
||||
}
|
||||
|
||||
func cinit() {
|
||||
var s *Sym
|
||||
var i int
|
||||
|
||||
nullgen.Type_ = ppc64.D_NONE
|
||||
nullgen.Name = ppc64.D_NONE
|
||||
nullgen.Reg = ppc64.NREG
|
||||
nullgen.Scale = ppc64.NREG // replaced Gen.xreg with Prog.scale
|
||||
|
||||
nerrors = 0
|
||||
|
||||
iostack = nil
|
||||
iofree = nil
|
||||
peekc = IGN
|
||||
nhunk = 0
|
||||
for i = 0; i < NHASH; i++ {
|
||||
hash[i] = nil
|
||||
}
|
||||
for i = 0; itab[i].name != ""; i++ {
|
||||
s = slookup(itab[i].name)
|
||||
s.type_ = itab[i].type_
|
||||
s.value = int64(itab[i].value)
|
||||
}
|
||||
}
|
||||
|
||||
func syminit(s *Sym) {
|
||||
s.type_ = LNAME
|
||||
s.value = 0
|
||||
}
|
||||
|
||||
func cclean() {
|
||||
@ -605,12 +476,13 @@ func cclean() {
|
||||
}
|
||||
|
||||
var lastpc *obj.Prog
|
||||
var nosched int
|
||||
|
||||
func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
|
||||
var p *obj.Prog
|
||||
var pl *obj.Plist
|
||||
|
||||
if pass == 1 {
|
||||
if asm.Pass == 1 {
|
||||
goto out
|
||||
}
|
||||
|
||||
@ -626,43 +498,42 @@ func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
|
||||
reg = int(g2.Scale)
|
||||
}
|
||||
|
||||
p = ctxt.Arch.Prg()
|
||||
p = asm.Ctxt.Arch.Prg()
|
||||
p.As = int16(a)
|
||||
p.Lineno = lineno
|
||||
p.Lineno = asm.Lineno
|
||||
if nosched != 0 {
|
||||
p.Mark |= ppc64.NOSCHED
|
||||
}
|
||||
p.From = *g1
|
||||
p.Reg = uint8(reg)
|
||||
p.To = *g2
|
||||
p.Pc = int64(pc)
|
||||
p.Pc = int64(asm.PC)
|
||||
|
||||
if lastpc == nil {
|
||||
pl = obj.Linknewplist(ctxt)
|
||||
pl = obj.Linknewplist(asm.Ctxt)
|
||||
pl.Firstpc = p
|
||||
} else {
|
||||
|
||||
lastpc.Link = p
|
||||
}
|
||||
lastpc = p
|
||||
|
||||
out:
|
||||
if a != ppc64.AGLOBL && a != ppc64.ADATA {
|
||||
pc++
|
||||
asm.PC++
|
||||
}
|
||||
}
|
||||
|
||||
func outgcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr, g3 *obj.Addr) {
|
||||
func outgcode(a int, g1 *obj.Addr, reg int, g2, g3 *obj.Addr) {
|
||||
var p *obj.Prog
|
||||
var pl *obj.Plist
|
||||
|
||||
if pass == 1 {
|
||||
if asm.Pass == 1 {
|
||||
goto out
|
||||
}
|
||||
|
||||
p = ctxt.Arch.Prg()
|
||||
p = asm.Ctxt.Arch.Prg()
|
||||
p.As = int16(a)
|
||||
p.Lineno = lineno
|
||||
p.Lineno = asm.Lineno
|
||||
if nosched != 0 {
|
||||
p.Mark |= ppc64.NOSCHED
|
||||
}
|
||||
@ -670,19 +541,18 @@ func outgcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr, g3 *obj.Addr) {
|
||||
p.Reg = uint8(reg)
|
||||
p.From3 = *g2
|
||||
p.To = *g3
|
||||
p.Pc = int64(pc)
|
||||
p.Pc = int64(asm.PC)
|
||||
|
||||
if lastpc == nil {
|
||||
pl = obj.Linknewplist(ctxt)
|
||||
pl = obj.Linknewplist(asm.Ctxt)
|
||||
pl.Firstpc = p
|
||||
} else {
|
||||
|
||||
lastpc.Link = p
|
||||
}
|
||||
lastpc = p
|
||||
|
||||
out:
|
||||
if a != ppc64.AGLOBL && a != ppc64.ADATA {
|
||||
pc++
|
||||
asm.PC++
|
||||
}
|
||||
}
|
||||
|
1694
src/cmd/new9a/y.go
Normal file
1694
src/cmd/new9a/y.go
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user