[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:
Russ Cox 2015-01-21 12:01:38 -05:00
parent 9e2f8fdb6f
commit 4ca2fc4d8b
17 changed files with 7310 additions and 3087 deletions

4
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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
{

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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
{

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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
{

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff