// 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
-
- 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)
- }
+var (
+ yyerror = asm.Yyerror
+ nullgen obj.Addr
+ stmtline int32
+)
- 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
-
- 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()
- }
+type yy struct{}
- 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")
+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
+}
- for pass = 1; pass <= 2; pass++ {
- pinit(file)
- for i = 0; i < nDlist; i++ {
- dodefine(Dlist[i])
- }
- yyparse()
- cclean()
- if nerrors != 0 {
- return nerrors
- }
- }
+func (yy) Error(msg string) {
+ asm.Yyerror("%s", msg)
+}
- obj.Writeobj(ctxt, &obuf)
- obj.Bflush(&obuf)
- return 0
+func yyparse() {
+ yyParse(yy{})
}
-var itab = []struct {
- name string
- type_ uint16
- value uint16
-}{
+var lexinit = []asm.Lextab{
{"SP", LSP, i386.D_AUTO},
{"SB", LSB, i386.D_EXTERN},
{"FP", LFP, i386.D_PARAM},
}
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,
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() {
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 {
out:
if a != i386.AGLOBL && a != i386.ADATA {
- pc++
+ asm.PC++
}
}