]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.cc] cmd/new5a etc, cmd/internal/asm: initial C → Go conversion
authorRuss Cox <rsc@golang.org>
Wed, 21 Jan 2015 16:36:15 +0000 (11:36 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 21 Jan 2015 19:42:48 +0000 (19:42 +0000)
This is the raw output of c2go. It needs fixes to make it compile.
Rather than make c2go do a 100% conversion (like we're doing for
liblink and the Go compilers), since this is so trivial I'm going to
make the remaining changes by hand in a followup CL.
This CL makes the next CL's diffs useful.

Also copy unmodified .y files (5a/a.y → new5a/a.y and so on)

The converted 6a/lex.c has been written to new6a/lex.go
but also to internal/asm/asm.go, because I'm going to factor
out some common code rather than convert it four times.

Change-Id: I01d5dfd6a9be3ef6191581560bdddd0ac0e8bc58
Reviewed-on: https://go-review.googlesource.com/3142
Reviewed-by: Rob Pike <r@golang.org>
src/cmd/internal/asm/asm.go [new file with mode: 0644]
src/cmd/internal/asm/lexbody.go [new file with mode: 0644]
src/cmd/internal/asm/macbody.go [new file with mode: 0644]
src/cmd/new5a/a.y [new file with mode: 0644]
src/cmd/new5a/lex.go [new file with mode: 0644]
src/cmd/new6a/a.y [new file with mode: 0644]
src/cmd/new6a/lex.go [new file with mode: 0644]
src/cmd/new8a/a.y [new file with mode: 0644]
src/cmd/new8a/lex.go [new file with mode: 0644]
src/cmd/new9a/a.y [new file with mode: 0644]
src/cmd/new9a/lex.go [new file with mode: 0644]

diff --git a/src/cmd/internal/asm/asm.go b/src/cmd/internal/asm/asm.go
new file mode 100644 (file)
index 0000000..264c119
--- /dev/null
@@ -0,0 +1,1102 @@
+// Inferno utils/6a/lex.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6a/lex.c
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package main
+
+const (
+       Plan9   = 1 << 0
+       Unix    = 1 << 1
+       Windows = 1 << 2
+)
+
+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++
+}
+
+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{}
+       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)
+
+       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()
+       }
+
+       if assemble(argv[0]) != 0 {
+               errorexit()
+       }
+       obj.Bflush(&bstdout)
+       if nerrors > 0 {
+               errorexit()
+       }
+       main.Exits("")
+}
+
+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()
+       }
+
+       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
+}
+
+var itab = []struct {
+       name  string
+       type_ uint16
+       value uint16
+}{
+       {"SP", LSP, x86.D_AUTO},
+       {"SB", LSB, x86.D_EXTERN},
+       {"FP", LFP, x86.D_PARAM},
+       {"PC", LPC, x86.D_BRANCH},
+       {"AL", LBREG, x86.D_AL},
+       {"CL", LBREG, x86.D_CL},
+       {"DL", LBREG, x86.D_DL},
+       {"BL", LBREG, x86.D_BL},
+       /*      "SPB",          LBREG,  D_SPB,  */
+       {"SIB", LBREG, x86.D_SIB},
+       {"DIB", LBREG, x86.D_DIB},
+       {"BPB", LBREG, x86.D_BPB},
+       {"R8B", LBREG, x86.D_R8B},
+       {"R9B", LBREG, x86.D_R9B},
+       {"R10B", LBREG, x86.D_R10B},
+       {"R11B", LBREG, x86.D_R11B},
+       {"R12B", LBREG, x86.D_R12B},
+       {"R13B", LBREG, x86.D_R13B},
+       {"R14B", LBREG, x86.D_R14B},
+       {"R15B", LBREG, x86.D_R15B},
+       {"AH", LBREG, x86.D_AH},
+       {"CH", LBREG, x86.D_CH},
+       {"DH", LBREG, x86.D_DH},
+       {"BH", LBREG, x86.D_BH},
+       {"AX", LLREG, x86.D_AX},
+       {"CX", LLREG, x86.D_CX},
+       {"DX", LLREG, x86.D_DX},
+       {"BX", LLREG, x86.D_BX},
+
+       /*      "SP",           LLREG,  D_SP,   */
+       {"BP", LLREG, x86.D_BP},
+       {"SI", LLREG, x86.D_SI},
+       {"DI", LLREG, x86.D_DI},
+       {"R8", LLREG, x86.D_R8},
+       {"R9", LLREG, x86.D_R9},
+       {"R10", LLREG, x86.D_R10},
+       {"R11", LLREG, x86.D_R11},
+       {"R12", LLREG, x86.D_R12},
+       {"R13", LLREG, x86.D_R13},
+       {"R14", LLREG, x86.D_R14},
+       {"R15", LLREG, x86.D_R15},
+       {"RARG", LLREG, x86.REGARG},
+       {"F0", LFREG, x86.D_F0 + 0},
+       {"F1", LFREG, x86.D_F0 + 1},
+       {"F2", LFREG, x86.D_F0 + 2},
+       {"F3", LFREG, x86.D_F0 + 3},
+       {"F4", LFREG, x86.D_F0 + 4},
+       {"F5", LFREG, x86.D_F0 + 5},
+       {"F6", LFREG, x86.D_F0 + 6},
+       {"F7", LFREG, x86.D_F0 + 7},
+       {"M0", LMREG, x86.D_M0 + 0},
+       {"M1", LMREG, x86.D_M0 + 1},
+       {"M2", LMREG, x86.D_M0 + 2},
+       {"M3", LMREG, x86.D_M0 + 3},
+       {"M4", LMREG, x86.D_M0 + 4},
+       {"M5", LMREG, x86.D_M0 + 5},
+       {"M6", LMREG, x86.D_M0 + 6},
+       {"M7", LMREG, x86.D_M0 + 7},
+       {"X0", LXREG, x86.D_X0 + 0},
+       {"X1", LXREG, x86.D_X0 + 1},
+       {"X2", LXREG, x86.D_X0 + 2},
+       {"X3", LXREG, x86.D_X0 + 3},
+       {"X4", LXREG, x86.D_X0 + 4},
+       {"X5", LXREG, x86.D_X0 + 5},
+       {"X6", LXREG, x86.D_X0 + 6},
+       {"X7", LXREG, x86.D_X0 + 7},
+       {"X8", LXREG, x86.D_X0 + 8},
+       {"X9", LXREG, x86.D_X0 + 9},
+       {"X10", LXREG, x86.D_X0 + 10},
+       {"X11", LXREG, x86.D_X0 + 11},
+       {"X12", LXREG, x86.D_X0 + 12},
+       {"X13", LXREG, x86.D_X0 + 13},
+       {"X14", LXREG, x86.D_X0 + 14},
+       {"X15", LXREG, x86.D_X0 + 15},
+       {"CS", LSREG, x86.D_CS},
+       {"SS", LSREG, x86.D_SS},
+       {"DS", LSREG, x86.D_DS},
+       {"ES", LSREG, x86.D_ES},
+       {"FS", LSREG, x86.D_FS},
+       {"GS", LSREG, x86.D_GS},
+       {"GDTR", LBREG, x86.D_GDTR},
+       {"IDTR", LBREG, x86.D_IDTR},
+       {"LDTR", LBREG, x86.D_LDTR},
+       {"MSW", LBREG, x86.D_MSW},
+       {"TASK", LBREG, x86.D_TASK},
+       {"CR0", LBREG, x86.D_CR + 0},
+       {"CR1", LBREG, x86.D_CR + 1},
+       {"CR2", LBREG, x86.D_CR + 2},
+       {"CR3", LBREG, x86.D_CR + 3},
+       {"CR4", LBREG, x86.D_CR + 4},
+       {"CR5", LBREG, x86.D_CR + 5},
+       {"CR6", LBREG, x86.D_CR + 6},
+       {"CR7", LBREG, x86.D_CR + 7},
+       {"CR8", LBREG, x86.D_CR + 8},
+       {"CR9", LBREG, x86.D_CR + 9},
+       {"CR10", LBREG, x86.D_CR + 10},
+       {"CR11", LBREG, x86.D_CR + 11},
+       {"CR12", LBREG, x86.D_CR + 12},
+       {"CR13", LBREG, x86.D_CR + 13},
+       {"CR14", LBREG, x86.D_CR + 14},
+       {"CR15", LBREG, x86.D_CR + 15},
+       {"DR0", LBREG, x86.D_DR + 0},
+       {"DR1", LBREG, x86.D_DR + 1},
+       {"DR2", LBREG, x86.D_DR + 2},
+       {"DR3", LBREG, x86.D_DR + 3},
+       {"DR4", LBREG, x86.D_DR + 4},
+       {"DR5", LBREG, x86.D_DR + 5},
+       {"DR6", LBREG, x86.D_DR + 6},
+       {"DR7", LBREG, x86.D_DR + 7},
+       {"TR0", LBREG, x86.D_TR + 0},
+       {"TR1", LBREG, x86.D_TR + 1},
+       {"TR2", LBREG, x86.D_TR + 2},
+       {"TR3", LBREG, x86.D_TR + 3},
+       {"TR4", LBREG, x86.D_TR + 4},
+       {"TR5", LBREG, x86.D_TR + 5},
+       {"TR6", LBREG, x86.D_TR + 6},
+       {"TR7", LBREG, x86.D_TR + 7},
+       {"TLS", LSREG, x86.D_TLS},
+       {"AAA", LTYPE0, x86.AAAA},
+       {"AAD", LTYPE0, x86.AAAD},
+       {"AAM", LTYPE0, x86.AAAM},
+       {"AAS", LTYPE0, x86.AAAS},
+       {"ADCB", LTYPE3, x86.AADCB},
+       {"ADCL", LTYPE3, x86.AADCL},
+       {"ADCQ", LTYPE3, x86.AADCQ},
+       {"ADCW", LTYPE3, x86.AADCW},
+       {"ADDB", LTYPE3, x86.AADDB},
+       {"ADDL", LTYPE3, x86.AADDL},
+       {"ADDQ", LTYPE3, x86.AADDQ},
+       {"ADDW", LTYPE3, x86.AADDW},
+       {"ADJSP", LTYPE2, x86.AADJSP},
+       {"ANDB", LTYPE3, x86.AANDB},
+       {"ANDL", LTYPE3, x86.AANDL},
+       {"ANDQ", LTYPE3, x86.AANDQ},
+       {"ANDW", LTYPE3, x86.AANDW},
+       {"ARPL", LTYPE3, x86.AARPL},
+       {"BOUNDL", LTYPE3, x86.ABOUNDL},
+       {"BOUNDW", LTYPE3, x86.ABOUNDW},
+       {"BSFL", LTYPE3, x86.ABSFL},
+       {"BSFQ", LTYPE3, x86.ABSFQ},
+       {"BSFW", LTYPE3, x86.ABSFW},
+       {"BSRL", LTYPE3, x86.ABSRL},
+       {"BSRQ", LTYPE3, x86.ABSRQ},
+       {"BSRW", LTYPE3, x86.ABSRW},
+       {"BSWAPL", LTYPE1, x86.ABSWAPL},
+       {"BSWAPQ", LTYPE1, x86.ABSWAPQ},
+       {"BTCL", LTYPE3, x86.ABTCL},
+       {"BTCQ", LTYPE3, x86.ABTCQ},
+       {"BTCW", LTYPE3, x86.ABTCW},
+       {"BTL", LTYPE3, x86.ABTL},
+       {"BTQ", LTYPE3, x86.ABTQ},
+       {"BTRL", LTYPE3, x86.ABTRL},
+       {"BTRQ", LTYPE3, x86.ABTRQ},
+       {"BTRW", LTYPE3, x86.ABTRW},
+       {"BTSL", LTYPE3, x86.ABTSL},
+       {"BTSQ", LTYPE3, x86.ABTSQ},
+       {"BTSW", LTYPE3, x86.ABTSW},
+       {"BTW", LTYPE3, x86.ABTW},
+       {"BYTE", LTYPE2, x86.ABYTE},
+       {"CALL", LTYPEC, x86.ACALL},
+       {"CLC", LTYPE0, x86.ACLC},
+       {"CLD", LTYPE0, x86.ACLD},
+       {"CLI", LTYPE0, x86.ACLI},
+       {"CLTS", LTYPE0, x86.ACLTS},
+       {"CMC", LTYPE0, x86.ACMC},
+       {"CMPB", LTYPE4, x86.ACMPB},
+       {"CMPL", LTYPE4, x86.ACMPL},
+       {"CMPQ", LTYPE4, x86.ACMPQ},
+       {"CMPW", LTYPE4, x86.ACMPW},
+       {"CMPSB", LTYPE0, x86.ACMPSB},
+       {"CMPSL", LTYPE0, x86.ACMPSL},
+       {"CMPSQ", LTYPE0, x86.ACMPSQ},
+       {"CMPSW", LTYPE0, x86.ACMPSW},
+       {"CMPXCHG8B", LTYPE1, x86.ACMPXCHG8B},
+       {"CMPXCHGB", LTYPE3, x86.ACMPXCHGB}, /* LTYPE3? */
+       {"CMPXCHGL", LTYPE3, x86.ACMPXCHGL},
+       {"CMPXCHGQ", LTYPE3, x86.ACMPXCHGQ},
+       {"CMPXCHGW", LTYPE3, x86.ACMPXCHGW},
+       {"CPUID", LTYPE0, x86.ACPUID},
+       {"DAA", LTYPE0, x86.ADAA},
+       {"DAS", LTYPE0, x86.ADAS},
+       {"DATA", LTYPED, x86.ADATA},
+       {"DECB", LTYPE1, x86.ADECB},
+       {"DECL", LTYPE1, x86.ADECL},
+       {"DECQ", LTYPE1, x86.ADECQ},
+       {"DECW", LTYPE1, x86.ADECW},
+       {"DIVB", LTYPE2, x86.ADIVB},
+       {"DIVL", LTYPE2, x86.ADIVL},
+       {"DIVQ", LTYPE2, x86.ADIVQ},
+       {"DIVW", LTYPE2, x86.ADIVW},
+       {"EMMS", LTYPE0, x86.AEMMS},
+       {"END", LTYPE0, x86.AEND},
+       {"ENTER", LTYPE2, x86.AENTER},
+       {"GLOBL", LTYPEG, x86.AGLOBL},
+       {"HLT", LTYPE0, x86.AHLT},
+       {"IDIVB", LTYPE2, x86.AIDIVB},
+       {"IDIVL", LTYPE2, x86.AIDIVL},
+       {"IDIVQ", LTYPE2, x86.AIDIVQ},
+       {"IDIVW", LTYPE2, x86.AIDIVW},
+       {"IMULB", LTYPEI, x86.AIMULB},
+       {"IMULL", LTYPEI, x86.AIMULL},
+       {"IMULQ", LTYPEI, x86.AIMULQ},
+       {"IMUL3Q", LTYPEX, x86.AIMUL3Q},
+       {"IMULW", LTYPEI, x86.AIMULW},
+       {"INB", LTYPE0, x86.AINB},
+       {"INL", LTYPE0, x86.AINL},
+       {"INW", LTYPE0, x86.AINW},
+       {"INCB", LTYPE1, x86.AINCB},
+       {"INCL", LTYPE1, x86.AINCL},
+       {"INCQ", LTYPE1, x86.AINCQ},
+       {"INCW", LTYPE1, x86.AINCW},
+       {"INSB", LTYPE0, x86.AINSB},
+       {"INSL", LTYPE0, x86.AINSL},
+       {"INSW", LTYPE0, x86.AINSW},
+       {"INT", LTYPE2, x86.AINT},
+       {"INTO", LTYPE0, x86.AINTO},
+       {"INVD", LTYPE0, x86.AINVD},
+       {"INVLPG", LTYPE2, x86.AINVLPG},
+       {"IRETL", LTYPE0, x86.AIRETL},
+       {"IRETQ", LTYPE0, x86.AIRETQ},
+       {"IRETW", LTYPE0, x86.AIRETW},
+       {"JOS", LTYPER, x86.AJOS},  /* overflow set (OF = 1) */
+       {"JO", LTYPER, x86.AJOS},   /* alternate */
+       {"JOC", LTYPER, x86.AJOC},  /* overflow clear (OF = 0) */
+       {"JNO", LTYPER, x86.AJOC},  /* alternate */
+       {"JCS", LTYPER, x86.AJCS},  /* carry set (CF = 1) */
+       {"JB", LTYPER, x86.AJCS},   /* alternate */
+       {"JC", LTYPER, x86.AJCS},   /* alternate */
+       {"JNAE", LTYPER, x86.AJCS}, /* alternate */
+       {"JLO", LTYPER, x86.AJCS},  /* alternate */
+       {"JCC", LTYPER, x86.AJCC},  /* carry clear (CF = 0) */
+       {"JAE", LTYPER, x86.AJCC},  /* alternate */
+       {"JNB", LTYPER, x86.AJCC},  /* alternate */
+       {"JNC", LTYPER, x86.AJCC},  /* alternate */
+       {"JHS", LTYPER, x86.AJCC},  /* alternate */
+       {"JEQ", LTYPER, x86.AJEQ},  /* equal (ZF = 1) */
+       {"JE", LTYPER, x86.AJEQ},   /* alternate */
+       {"JZ", LTYPER, x86.AJEQ},   /* alternate */
+       {"JNE", LTYPER, x86.AJNE},  /* not equal (ZF = 0) */
+       {"JNZ", LTYPER, x86.AJNE},  /* alternate */
+       {"JLS", LTYPER, x86.AJLS},  /* lower or same (unsigned) (CF = 1 || ZF = 1) */
+       {"JBE", LTYPER, x86.AJLS},  /* alternate */
+       {"JNA", LTYPER, x86.AJLS},  /* alternate */
+       {"JHI", LTYPER, x86.AJHI},  /* higher (unsigned) (CF = 0 && ZF = 0) */
+       {"JA", LTYPER, x86.AJHI},   /* alternate */
+       {"JNBE", LTYPER, x86.AJHI}, /* alternate */
+       {"JMI", LTYPER, x86.AJMI},  /* negative (minus) (SF = 1) */
+       {"JS", LTYPER, x86.AJMI},   /* alternate */
+       {"JPL", LTYPER, x86.AJPL},  /* non-negative (plus) (SF = 0) */
+       {"JNS", LTYPER, x86.AJPL},  /* alternate */
+       {"JPS", LTYPER, x86.AJPS},  /* parity set (PF = 1) */
+       {"JP", LTYPER, x86.AJPS},   /* alternate */
+       {"JPE", LTYPER, x86.AJPS},  /* alternate */
+       {"JPC", LTYPER, x86.AJPC},  /* parity clear (PF = 0) */
+       {"JNP", LTYPER, x86.AJPC},  /* alternate */
+       {"JPO", LTYPER, x86.AJPC},  /* alternate */
+       {"JLT", LTYPER, x86.AJLT},  /* less than (signed) (SF != OF) */
+       {"JL", LTYPER, x86.AJLT},   /* alternate */
+       {"JNGE", LTYPER, x86.AJLT}, /* alternate */
+       {"JGE", LTYPER, x86.AJGE},  /* greater than or equal (signed) (SF = OF) */
+       {"JNL", LTYPER, x86.AJGE},  /* alternate */
+       {"JLE", LTYPER, x86.AJLE},  /* less than or equal (signed) (ZF = 1 || SF != OF) */
+       {"JNG", LTYPER, x86.AJLE},  /* alternate */
+       {"JGT", LTYPER, x86.AJGT},  /* greater than (signed) (ZF = 0 && SF = OF) */
+       {"JG", LTYPER, x86.AJGT},   /* alternate */
+       {"JNLE", LTYPER, x86.AJGT}, /* alternate */
+       {"JCXZL", LTYPER, x86.AJCXZL},
+       {"JCXZQ", LTYPER, x86.AJCXZQ},
+       {"JMP", LTYPEC, x86.AJMP},
+       {"LAHF", LTYPE0, x86.ALAHF},
+       {"LARL", LTYPE3, x86.ALARL},
+       {"LARW", LTYPE3, x86.ALARW},
+       {"LEAL", LTYPE3, x86.ALEAL},
+       {"LEAQ", LTYPE3, x86.ALEAQ},
+       {"LEAW", LTYPE3, x86.ALEAW},
+       {"LEAVEL", LTYPE0, x86.ALEAVEL},
+       {"LEAVEQ", LTYPE0, x86.ALEAVEQ},
+       {"LEAVEW", LTYPE0, x86.ALEAVEW},
+       {"LFENCE", LTYPE0, x86.ALFENCE},
+       {"LOCK", LTYPE0, x86.ALOCK},
+       {"LODSB", LTYPE0, x86.ALODSB},
+       {"LODSL", LTYPE0, x86.ALODSL},
+       {"LODSQ", LTYPE0, x86.ALODSQ},
+       {"LODSW", LTYPE0, x86.ALODSW},
+       {"LONG", LTYPE2, x86.ALONG},
+       {"LOOP", LTYPER, x86.ALOOP},
+       {"LOOPEQ", LTYPER, x86.ALOOPEQ},
+       {"LOOPNE", LTYPER, x86.ALOOPNE},
+       {"LSLL", LTYPE3, x86.ALSLL},
+       {"LSLW", LTYPE3, x86.ALSLW},
+       {"MFENCE", LTYPE0, x86.AMFENCE},
+       {"MODE", LTYPE2, x86.AMODE},
+       {"MOVB", LTYPE3, x86.AMOVB},
+       {"MOVL", LTYPEM, x86.AMOVL},
+       {"MOVQ", LTYPEM, x86.AMOVQ},
+       {"MOVW", LTYPEM, x86.AMOVW},
+       {"MOVBLSX", LTYPE3, x86.AMOVBLSX},
+       {"MOVBLZX", LTYPE3, x86.AMOVBLZX},
+       {"MOVBQSX", LTYPE3, x86.AMOVBQSX},
+       {"MOVBQZX", LTYPE3, x86.AMOVBQZX},
+       {"MOVBWSX", LTYPE3, x86.AMOVBWSX},
+       {"MOVBWZX", LTYPE3, x86.AMOVBWZX},
+       {"MOVLQSX", LTYPE3, x86.AMOVLQSX},
+       {"MOVLQZX", LTYPE3, x86.AMOVLQZX},
+       {"MOVNTIL", LTYPE3, x86.AMOVNTIL},
+       {"MOVNTIQ", LTYPE3, x86.AMOVNTIQ},
+       {"MOVQL", LTYPE3, x86.AMOVQL},
+       {"MOVWLSX", LTYPE3, x86.AMOVWLSX},
+       {"MOVWLZX", LTYPE3, x86.AMOVWLZX},
+       {"MOVWQSX", LTYPE3, x86.AMOVWQSX},
+       {"MOVWQZX", LTYPE3, x86.AMOVWQZX},
+       {"MOVSB", LTYPE0, x86.AMOVSB},
+       {"MOVSL", LTYPE0, x86.AMOVSL},
+       {"MOVSQ", LTYPE0, x86.AMOVSQ},
+       {"MOVSW", LTYPE0, x86.AMOVSW},
+       {"MULB", LTYPE2, x86.AMULB},
+       {"MULL", LTYPE2, x86.AMULL},
+       {"MULQ", LTYPE2, x86.AMULQ},
+       {"MULW", LTYPE2, x86.AMULW},
+       {"NEGB", LTYPE1, x86.ANEGB},
+       {"NEGL", LTYPE1, x86.ANEGL},
+       {"NEGQ", LTYPE1, x86.ANEGQ},
+       {"NEGW", LTYPE1, x86.ANEGW},
+       {"NOP", LTYPEN, x86.ANOP},
+       {"NOTB", LTYPE1, x86.ANOTB},
+       {"NOTL", LTYPE1, x86.ANOTL},
+       {"NOTQ", LTYPE1, x86.ANOTQ},
+       {"NOTW", LTYPE1, x86.ANOTW},
+       {"ORB", LTYPE3, x86.AORB},
+       {"ORL", LTYPE3, x86.AORL},
+       {"ORQ", LTYPE3, x86.AORQ},
+       {"ORW", LTYPE3, x86.AORW},
+       {"OUTB", LTYPE0, x86.AOUTB},
+       {"OUTL", LTYPE0, x86.AOUTL},
+       {"OUTW", LTYPE0, x86.AOUTW},
+       {"OUTSB", LTYPE0, x86.AOUTSB},
+       {"OUTSL", LTYPE0, x86.AOUTSL},
+       {"OUTSW", LTYPE0, x86.AOUTSW},
+       {"PAUSE", LTYPEN, x86.APAUSE},
+       {"POPAL", LTYPE0, x86.APOPAL},
+       {"POPAW", LTYPE0, x86.APOPAW},
+       {"POPFL", LTYPE0, x86.APOPFL},
+       {"POPFQ", LTYPE0, x86.APOPFQ},
+       {"POPFW", LTYPE0, x86.APOPFW},
+       {"POPL", LTYPE1, x86.APOPL},
+       {"POPQ", LTYPE1, x86.APOPQ},
+       {"POPW", LTYPE1, x86.APOPW},
+       {"PUSHAL", LTYPE0, x86.APUSHAL},
+       {"PUSHAW", LTYPE0, x86.APUSHAW},
+       {"PUSHFL", LTYPE0, x86.APUSHFL},
+       {"PUSHFQ", LTYPE0, x86.APUSHFQ},
+       {"PUSHFW", LTYPE0, x86.APUSHFW},
+       {"PUSHL", LTYPE2, x86.APUSHL},
+       {"PUSHQ", LTYPE2, x86.APUSHQ},
+       {"PUSHW", LTYPE2, x86.APUSHW},
+       {"RCLB", LTYPE3, x86.ARCLB},
+       {"RCLL", LTYPE3, x86.ARCLL},
+       {"RCLQ", LTYPE3, x86.ARCLQ},
+       {"RCLW", LTYPE3, x86.ARCLW},
+       {"RCRB", LTYPE3, x86.ARCRB},
+       {"RCRL", LTYPE3, x86.ARCRL},
+       {"RCRQ", LTYPE3, x86.ARCRQ},
+       {"RCRW", LTYPE3, x86.ARCRW},
+       {"RDMSR", LTYPE0, x86.ARDMSR},
+       {"RDPMC", LTYPE0, x86.ARDPMC},
+       {"RDTSC", LTYPE0, x86.ARDTSC},
+       {"REP", LTYPE0, x86.AREP},
+       {"REPN", LTYPE0, x86.AREPN},
+       {"RET", LTYPE0, x86.ARET},
+       {"RETFL", LTYPERT, x86.ARETFL},
+       {"RETFW", LTYPERT, x86.ARETFW},
+       {"RETFQ", LTYPERT, x86.ARETFQ},
+       {"ROLB", LTYPE3, x86.AROLB},
+       {"ROLL", LTYPE3, x86.AROLL},
+       {"ROLQ", LTYPE3, x86.AROLQ},
+       {"ROLW", LTYPE3, x86.AROLW},
+       {"RORB", LTYPE3, x86.ARORB},
+       {"RORL", LTYPE3, x86.ARORL},
+       {"RORQ", LTYPE3, x86.ARORQ},
+       {"RORW", LTYPE3, x86.ARORW},
+       {"RSM", LTYPE0, x86.ARSM},
+       {"SAHF", LTYPE0, x86.ASAHF},
+       {"SALB", LTYPE3, x86.ASALB},
+       {"SALL", LTYPE3, x86.ASALL},
+       {"SALQ", LTYPE3, x86.ASALQ},
+       {"SALW", LTYPE3, x86.ASALW},
+       {"SARB", LTYPE3, x86.ASARB},
+       {"SARL", LTYPE3, x86.ASARL},
+       {"SARQ", LTYPE3, x86.ASARQ},
+       {"SARW", LTYPE3, x86.ASARW},
+       {"SBBB", LTYPE3, x86.ASBBB},
+       {"SBBL", LTYPE3, x86.ASBBL},
+       {"SBBQ", LTYPE3, x86.ASBBQ},
+       {"SBBW", LTYPE3, x86.ASBBW},
+       {"SCASB", LTYPE0, x86.ASCASB},
+       {"SCASL", LTYPE0, x86.ASCASL},
+       {"SCASQ", LTYPE0, x86.ASCASQ},
+       {"SCASW", LTYPE0, x86.ASCASW},
+       {"SETCC", LTYPE1, x86.ASETCC}, /* see JCC etc above for condition codes */
+       {"SETCS", LTYPE1, x86.ASETCS},
+       {"SETEQ", LTYPE1, x86.ASETEQ},
+       {"SETGE", LTYPE1, x86.ASETGE},
+       {"SETGT", LTYPE1, x86.ASETGT},
+       {"SETHI", LTYPE1, x86.ASETHI},
+       {"SETLE", LTYPE1, x86.ASETLE},
+       {"SETLS", LTYPE1, x86.ASETLS},
+       {"SETLT", LTYPE1, x86.ASETLT},
+       {"SETMI", LTYPE1, x86.ASETMI},
+       {"SETNE", LTYPE1, x86.ASETNE},
+       {"SETOC", LTYPE1, x86.ASETOC},
+       {"SETOS", LTYPE1, x86.ASETOS},
+       {"SETPC", LTYPE1, x86.ASETPC},
+       {"SETPL", LTYPE1, x86.ASETPL},
+       {"SETPS", LTYPE1, x86.ASETPS},
+       {"SFENCE", LTYPE0, x86.ASFENCE},
+       {"CDQ", LTYPE0, x86.ACDQ},
+       {"CWD", LTYPE0, x86.ACWD},
+       {"CQO", LTYPE0, x86.ACQO},
+       {"SHLB", LTYPE3, x86.ASHLB},
+       {"SHLL", LTYPES, x86.ASHLL},
+       {"SHLQ", LTYPES, x86.ASHLQ},
+       {"SHLW", LTYPES, x86.ASHLW},
+       {"SHRB", LTYPE3, x86.ASHRB},
+       {"SHRL", LTYPES, x86.ASHRL},
+       {"SHRQ", LTYPES, x86.ASHRQ},
+       {"SHRW", LTYPES, x86.ASHRW},
+       {"STC", LTYPE0, x86.ASTC},
+       {"STD", LTYPE0, x86.ASTD},
+       {"STI", LTYPE0, x86.ASTI},
+       {"STOSB", LTYPE0, x86.ASTOSB},
+       {"STOSL", LTYPE0, x86.ASTOSL},
+       {"STOSQ", LTYPE0, x86.ASTOSQ},
+       {"STOSW", LTYPE0, x86.ASTOSW},
+       {"SUBB", LTYPE3, x86.ASUBB},
+       {"SUBL", LTYPE3, x86.ASUBL},
+       {"SUBQ", LTYPE3, x86.ASUBQ},
+       {"SUBW", LTYPE3, x86.ASUBW},
+       {"SYSCALL", LTYPE0, x86.ASYSCALL},
+       {"SYSRET", LTYPE0, x86.ASYSRET},
+       {"SWAPGS", LTYPE0, x86.ASWAPGS},
+       {"TESTB", LTYPE3, x86.ATESTB},
+       {"TESTL", LTYPE3, x86.ATESTL},
+       {"TESTQ", LTYPE3, x86.ATESTQ},
+       {"TESTW", LTYPE3, x86.ATESTW},
+       {"TEXT", LTYPET, x86.ATEXT},
+       {"VERR", LTYPE2, x86.AVERR},
+       {"VERW", LTYPE2, x86.AVERW},
+       {"QUAD", LTYPE2, x86.AQUAD},
+       {"WAIT", LTYPE0, x86.AWAIT},
+       {"WBINVD", LTYPE0, x86.AWBINVD},
+       {"WRMSR", LTYPE0, x86.AWRMSR},
+       {"WORD", LTYPE2, x86.AWORD},
+       {"XADDB", LTYPE3, x86.AXADDB},
+       {"XADDL", LTYPE3, x86.AXADDL},
+       {"XADDQ", LTYPE3, x86.AXADDQ},
+       {"XADDW", LTYPE3, x86.AXADDW},
+       {"XCHGB", LTYPE3, x86.AXCHGB},
+       {"XCHGL", LTYPE3, x86.AXCHGL},
+       {"XCHGQ", LTYPE3, x86.AXCHGQ},
+       {"XCHGW", LTYPE3, x86.AXCHGW},
+       {"XLAT", LTYPE2, x86.AXLAT},
+       {"XORB", LTYPE3, x86.AXORB},
+       {"XORL", LTYPE3, x86.AXORL},
+       {"XORQ", LTYPE3, x86.AXORQ},
+       {"XORW", LTYPE3, x86.AXORW},
+       {"CMOVLCC", LTYPE3, x86.ACMOVLCC},
+       {"CMOVLCS", LTYPE3, x86.ACMOVLCS},
+       {"CMOVLEQ", LTYPE3, x86.ACMOVLEQ},
+       {"CMOVLGE", LTYPE3, x86.ACMOVLGE},
+       {"CMOVLGT", LTYPE3, x86.ACMOVLGT},
+       {"CMOVLHI", LTYPE3, x86.ACMOVLHI},
+       {"CMOVLLE", LTYPE3, x86.ACMOVLLE},
+       {"CMOVLLS", LTYPE3, x86.ACMOVLLS},
+       {"CMOVLLT", LTYPE3, x86.ACMOVLLT},
+       {"CMOVLMI", LTYPE3, x86.ACMOVLMI},
+       {"CMOVLNE", LTYPE3, x86.ACMOVLNE},
+       {"CMOVLOC", LTYPE3, x86.ACMOVLOC},
+       {"CMOVLOS", LTYPE3, x86.ACMOVLOS},
+       {"CMOVLPC", LTYPE3, x86.ACMOVLPC},
+       {"CMOVLPL", LTYPE3, x86.ACMOVLPL},
+       {"CMOVLPS", LTYPE3, x86.ACMOVLPS},
+       {"CMOVQCC", LTYPE3, x86.ACMOVQCC},
+       {"CMOVQCS", LTYPE3, x86.ACMOVQCS},
+       {"CMOVQEQ", LTYPE3, x86.ACMOVQEQ},
+       {"CMOVQGE", LTYPE3, x86.ACMOVQGE},
+       {"CMOVQGT", LTYPE3, x86.ACMOVQGT},
+       {"CMOVQHI", LTYPE3, x86.ACMOVQHI},
+       {"CMOVQLE", LTYPE3, x86.ACMOVQLE},
+       {"CMOVQLS", LTYPE3, x86.ACMOVQLS},
+       {"CMOVQLT", LTYPE3, x86.ACMOVQLT},
+       {"CMOVQMI", LTYPE3, x86.ACMOVQMI},
+       {"CMOVQNE", LTYPE3, x86.ACMOVQNE},
+       {"CMOVQOC", LTYPE3, x86.ACMOVQOC},
+       {"CMOVQOS", LTYPE3, x86.ACMOVQOS},
+       {"CMOVQPC", LTYPE3, x86.ACMOVQPC},
+       {"CMOVQPL", LTYPE3, x86.ACMOVQPL},
+       {"CMOVQPS", LTYPE3, x86.ACMOVQPS},
+       {"CMOVWCC", LTYPE3, x86.ACMOVWCC},
+       {"CMOVWCS", LTYPE3, x86.ACMOVWCS},
+       {"CMOVWEQ", LTYPE3, x86.ACMOVWEQ},
+       {"CMOVWGE", LTYPE3, x86.ACMOVWGE},
+       {"CMOVWGT", LTYPE3, x86.ACMOVWGT},
+       {"CMOVWHI", LTYPE3, x86.ACMOVWHI},
+       {"CMOVWLE", LTYPE3, x86.ACMOVWLE},
+       {"CMOVWLS", LTYPE3, x86.ACMOVWLS},
+       {"CMOVWLT", LTYPE3, x86.ACMOVWLT},
+       {"CMOVWMI", LTYPE3, x86.ACMOVWMI},
+       {"CMOVWNE", LTYPE3, x86.ACMOVWNE},
+       {"CMOVWOC", LTYPE3, x86.ACMOVWOC},
+       {"CMOVWOS", LTYPE3, x86.ACMOVWOS},
+       {"CMOVWPC", LTYPE3, x86.ACMOVWPC},
+       {"CMOVWPL", LTYPE3, x86.ACMOVWPL},
+       {"CMOVWPS", LTYPE3, x86.ACMOVWPS},
+       {"FMOVB", LTYPE3, x86.AFMOVB},
+       {"FMOVBP", LTYPE3, x86.AFMOVBP},
+       {"FMOVD", LTYPE3, x86.AFMOVD},
+       {"FMOVDP", LTYPE3, x86.AFMOVDP},
+       {"FMOVF", LTYPE3, x86.AFMOVF},
+       {"FMOVFP", LTYPE3, x86.AFMOVFP},
+       {"FMOVL", LTYPE3, x86.AFMOVL},
+       {"FMOVLP", LTYPE3, x86.AFMOVLP},
+       {"FMOVV", LTYPE3, x86.AFMOVV},
+       {"FMOVVP", LTYPE3, x86.AFMOVVP},
+       {"FMOVW", LTYPE3, x86.AFMOVW},
+       {"FMOVWP", LTYPE3, x86.AFMOVWP},
+       {"FMOVX", LTYPE3, x86.AFMOVX},
+       {"FMOVXP", LTYPE3, x86.AFMOVXP},
+       {"FCOMB", LTYPE3, x86.AFCOMB},
+       {"FCOMBP", LTYPE3, x86.AFCOMBP},
+       {"FCOMD", LTYPE3, x86.AFCOMD},
+       {"FCOMDP", LTYPE3, x86.AFCOMDP},
+       {"FCOMDPP", LTYPE3, x86.AFCOMDPP},
+       {"FCOMF", LTYPE3, x86.AFCOMF},
+       {"FCOMFP", LTYPE3, x86.AFCOMFP},
+       {"FCOML", LTYPE3, x86.AFCOML},
+       {"FCOMLP", LTYPE3, x86.AFCOMLP},
+       {"FCOMW", LTYPE3, x86.AFCOMW},
+       {"FCOMWP", LTYPE3, x86.AFCOMWP},
+       {"FUCOM", LTYPE3, x86.AFUCOM},
+       {"FUCOMP", LTYPE3, x86.AFUCOMP},
+       {"FUCOMPP", LTYPE3, x86.AFUCOMPP},
+       {"FADDW", LTYPE3, x86.AFADDW},
+       {"FADDL", LTYPE3, x86.AFADDL},
+       {"FADDF", LTYPE3, x86.AFADDF},
+       {"FADDD", LTYPE3, x86.AFADDD},
+       {"FADDDP", LTYPE3, x86.AFADDDP},
+       {"FSUBDP", LTYPE3, x86.AFSUBDP},
+       {"FSUBW", LTYPE3, x86.AFSUBW},
+       {"FSUBL", LTYPE3, x86.AFSUBL},
+       {"FSUBF", LTYPE3, x86.AFSUBF},
+       {"FSUBD", LTYPE3, x86.AFSUBD},
+       {"FSUBRDP", LTYPE3, x86.AFSUBRDP},
+       {"FSUBRW", LTYPE3, x86.AFSUBRW},
+       {"FSUBRL", LTYPE3, x86.AFSUBRL},
+       {"FSUBRF", LTYPE3, x86.AFSUBRF},
+       {"FSUBRD", LTYPE3, x86.AFSUBRD},
+       {"FMULDP", LTYPE3, x86.AFMULDP},
+       {"FMULW", LTYPE3, x86.AFMULW},
+       {"FMULL", LTYPE3, x86.AFMULL},
+       {"FMULF", LTYPE3, x86.AFMULF},
+       {"FMULD", LTYPE3, x86.AFMULD},
+       {"FDIVDP", LTYPE3, x86.AFDIVDP},
+       {"FDIVW", LTYPE3, x86.AFDIVW},
+       {"FDIVL", LTYPE3, x86.AFDIVL},
+       {"FDIVF", LTYPE3, x86.AFDIVF},
+       {"FDIVD", LTYPE3, x86.AFDIVD},
+       {"FDIVRDP", LTYPE3, x86.AFDIVRDP},
+       {"FDIVRW", LTYPE3, x86.AFDIVRW},
+       {"FDIVRL", LTYPE3, x86.AFDIVRL},
+       {"FDIVRF", LTYPE3, x86.AFDIVRF},
+       {"FDIVRD", LTYPE3, x86.AFDIVRD},
+       {"FXCHD", LTYPE3, x86.AFXCHD},
+       {"FFREE", LTYPE1, x86.AFFREE},
+       {"FLDCW", LTYPE2, x86.AFLDCW},
+       {"FLDENV", LTYPE1, x86.AFLDENV},
+       {"FRSTOR", LTYPE2, x86.AFRSTOR},
+       {"FSAVE", LTYPE1, x86.AFSAVE},
+       {"FSTCW", LTYPE1, x86.AFSTCW},
+       {"FSTENV", LTYPE1, x86.AFSTENV},
+       {"FSTSW", LTYPE1, x86.AFSTSW},
+       {"F2XM1", LTYPE0, x86.AF2XM1},
+       {"FABS", LTYPE0, x86.AFABS},
+       {"FCHS", LTYPE0, x86.AFCHS},
+       {"FCLEX", LTYPE0, x86.AFCLEX},
+       {"FCOS", LTYPE0, x86.AFCOS},
+       {"FDECSTP", LTYPE0, x86.AFDECSTP},
+       {"FINCSTP", LTYPE0, x86.AFINCSTP},
+       {"FINIT", LTYPE0, x86.AFINIT},
+       {"FLD1", LTYPE0, x86.AFLD1},
+       {"FLDL2E", LTYPE0, x86.AFLDL2E},
+       {"FLDL2T", LTYPE0, x86.AFLDL2T},
+       {"FLDLG2", LTYPE0, x86.AFLDLG2},
+       {"FLDLN2", LTYPE0, x86.AFLDLN2},
+       {"FLDPI", LTYPE0, x86.AFLDPI},
+       {"FLDZ", LTYPE0, x86.AFLDZ},
+       {"FNOP", LTYPE0, x86.AFNOP},
+       {"FPATAN", LTYPE0, x86.AFPATAN},
+       {"FPREM", LTYPE0, x86.AFPREM},
+       {"FPREM1", LTYPE0, x86.AFPREM1},
+       {"FPTAN", LTYPE0, x86.AFPTAN},
+       {"FRNDINT", LTYPE0, x86.AFRNDINT},
+       {"FSCALE", LTYPE0, x86.AFSCALE},
+       {"FSIN", LTYPE0, x86.AFSIN},
+       {"FSINCOS", LTYPE0, x86.AFSINCOS},
+       {"FSQRT", LTYPE0, x86.AFSQRT},
+       {"FTST", LTYPE0, x86.AFTST},
+       {"FXAM", LTYPE0, x86.AFXAM},
+       {"FXTRACT", LTYPE0, x86.AFXTRACT},
+       {"FYL2X", LTYPE0, x86.AFYL2X},
+       {"FYL2XP1", LTYPE0, x86.AFYL2XP1},
+       {"ADDPD", LTYPE3, x86.AADDPD},
+       {"ADDPS", LTYPE3, x86.AADDPS},
+       {"ADDSD", LTYPE3, x86.AADDSD},
+       {"ADDSS", LTYPE3, x86.AADDSS},
+       {"ANDNPD", LTYPE3, x86.AANDNPD},
+       {"ANDNPS", LTYPE3, x86.AANDNPS},
+       {"ANDPD", LTYPE3, x86.AANDPD},
+       {"ANDPS", LTYPE3, x86.AANDPS},
+       {"CMPPD", LTYPEXC, x86.ACMPPD},
+       {"CMPPS", LTYPEXC, x86.ACMPPS},
+       {"CMPSD", LTYPEXC, x86.ACMPSD},
+       {"CMPSS", LTYPEXC, x86.ACMPSS},
+       {"COMISD", LTYPE3, x86.ACOMISD},
+       {"COMISS", LTYPE3, x86.ACOMISS},
+       {"CVTPL2PD", LTYPE3, x86.ACVTPL2PD},
+       {"CVTPL2PS", LTYPE3, x86.ACVTPL2PS},
+       {"CVTPD2PL", LTYPE3, x86.ACVTPD2PL},
+       {"CVTPD2PS", LTYPE3, x86.ACVTPD2PS},
+       {"CVTPS2PL", LTYPE3, x86.ACVTPS2PL},
+       {"PF2IW", LTYPE3, x86.APF2IW},
+       {"PF2IL", LTYPE3, x86.APF2IL},
+       {"PF2ID", LTYPE3, x86.APF2IL}, /* syn */
+       {"PI2FL", LTYPE3, x86.API2FL},
+       {"PI2FD", LTYPE3, x86.API2FL}, /* syn */
+       {"PI2FW", LTYPE3, x86.API2FW},
+       {"CVTPS2PD", LTYPE3, x86.ACVTPS2PD},
+       {"CVTSD2SL", LTYPE3, x86.ACVTSD2SL},
+       {"CVTSD2SQ", LTYPE3, x86.ACVTSD2SQ},
+       {"CVTSD2SS", LTYPE3, x86.ACVTSD2SS},
+       {"CVTSL2SD", LTYPE3, x86.ACVTSL2SD},
+       {"CVTSQ2SD", LTYPE3, x86.ACVTSQ2SD},
+       {"CVTSL2SS", LTYPE3, x86.ACVTSL2SS},
+       {"CVTSQ2SS", LTYPE3, x86.ACVTSQ2SS},
+       {"CVTSS2SD", LTYPE3, x86.ACVTSS2SD},
+       {"CVTSS2SL", LTYPE3, x86.ACVTSS2SL},
+       {"CVTSS2SQ", LTYPE3, x86.ACVTSS2SQ},
+       {"CVTTPD2PL", LTYPE3, x86.ACVTTPD2PL},
+       {"CVTTPS2PL", LTYPE3, x86.ACVTTPS2PL},
+       {"CVTTSD2SL", LTYPE3, x86.ACVTTSD2SL},
+       {"CVTTSD2SQ", LTYPE3, x86.ACVTTSD2SQ},
+       {"CVTTSS2SL", LTYPE3, x86.ACVTTSS2SL},
+       {"CVTTSS2SQ", LTYPE3, x86.ACVTTSS2SQ},
+       {"DIVPD", LTYPE3, x86.ADIVPD},
+       {"DIVPS", LTYPE3, x86.ADIVPS},
+       {"DIVSD", LTYPE3, x86.ADIVSD},
+       {"DIVSS", LTYPE3, x86.ADIVSS},
+       {"FXRSTOR", LTYPE2, x86.AFXRSTOR},
+       {"FXRSTOR64", LTYPE2, x86.AFXRSTOR64},
+       {"FXSAVE", LTYPE1, x86.AFXSAVE},
+       {"FXSAVE64", LTYPE1, x86.AFXSAVE64},
+       {"LDMXCSR", LTYPE2, x86.ALDMXCSR},
+       {"MASKMOVOU", LTYPE3, x86.AMASKMOVOU},
+       {"MASKMOVDQU", LTYPE3, x86.AMASKMOVOU}, /* syn */
+       {"MASKMOVQ", LTYPE3, x86.AMASKMOVQ},
+       {"MAXPD", LTYPE3, x86.AMAXPD},
+       {"MAXPS", LTYPE3, x86.AMAXPS},
+       {"MAXSD", LTYPE3, x86.AMAXSD},
+       {"MAXSS", LTYPE3, x86.AMAXSS},
+       {"MINPD", LTYPE3, x86.AMINPD},
+       {"MINPS", LTYPE3, x86.AMINPS},
+       {"MINSD", LTYPE3, x86.AMINSD},
+       {"MINSS", LTYPE3, x86.AMINSS},
+       {"MOVAPD", LTYPE3, x86.AMOVAPD},
+       {"MOVAPS", LTYPE3, x86.AMOVAPS},
+       {"MOVD", LTYPE3, x86.AMOVQ},    /* syn */
+       {"MOVDQ2Q", LTYPE3, x86.AMOVQ}, /* syn */
+       {"MOVO", LTYPE3, x86.AMOVO},
+       {"MOVOA", LTYPE3, x86.AMOVO}, /* syn */
+       {"MOVOU", LTYPE3, x86.AMOVOU},
+       {"MOVHLPS", LTYPE3, x86.AMOVHLPS},
+       {"MOVHPD", LTYPE3, x86.AMOVHPD},
+       {"MOVHPS", LTYPE3, x86.AMOVHPS},
+       {"MOVLHPS", LTYPE3, x86.AMOVLHPS},
+       {"MOVLPD", LTYPE3, x86.AMOVLPD},
+       {"MOVLPS", LTYPE3, x86.AMOVLPS},
+       {"MOVMSKPD", LTYPE3, x86.AMOVMSKPD},
+       {"MOVMSKPS", LTYPE3, x86.AMOVMSKPS},
+       {"MOVNTO", LTYPE3, x86.AMOVNTO},
+       {"MOVNTDQ", LTYPE3, x86.AMOVNTO}, /* syn */
+       {"MOVNTPD", LTYPE3, x86.AMOVNTPD},
+       {"MOVNTPS", LTYPE3, x86.AMOVNTPS},
+       {"MOVNTQ", LTYPE3, x86.AMOVNTQ},
+       {"MOVQOZX", LTYPE3, x86.AMOVQOZX},
+       {"MOVSD", LTYPE3, x86.AMOVSD},
+       {"MOVSS", LTYPE3, x86.AMOVSS},
+       {"MOVUPD", LTYPE3, x86.AMOVUPD},
+       {"MOVUPS", LTYPE3, x86.AMOVUPS},
+       {"MULPD", LTYPE3, x86.AMULPD},
+       {"MULPS", LTYPE3, x86.AMULPS},
+       {"MULSD", LTYPE3, x86.AMULSD},
+       {"MULSS", LTYPE3, x86.AMULSS},
+       {"ORPD", LTYPE3, x86.AORPD},
+       {"ORPS", LTYPE3, x86.AORPS},
+       {"PACKSSLW", LTYPE3, x86.APACKSSLW},
+       {"PACKSSWB", LTYPE3, x86.APACKSSWB},
+       {"PACKUSWB", LTYPE3, x86.APACKUSWB},
+       {"PADDB", LTYPE3, x86.APADDB},
+       {"PADDL", LTYPE3, x86.APADDL},
+       {"PADDQ", LTYPE3, x86.APADDQ},
+       {"PADDSB", LTYPE3, x86.APADDSB},
+       {"PADDSW", LTYPE3, x86.APADDSW},
+       {"PADDUSB", LTYPE3, x86.APADDUSB},
+       {"PADDUSW", LTYPE3, x86.APADDUSW},
+       {"PADDW", LTYPE3, x86.APADDW},
+       {"PAND", LTYPE3, x86.APAND},
+       {"PANDB", LTYPE3, x86.APANDB},
+       {"PANDL", LTYPE3, x86.APANDL},
+       {"PANDSB", LTYPE3, x86.APANDSB},
+       {"PANDSW", LTYPE3, x86.APANDSW},
+       {"PANDUSB", LTYPE3, x86.APANDUSB},
+       {"PANDUSW", LTYPE3, x86.APANDUSW},
+       {"PANDW", LTYPE3, x86.APANDW},
+       {"PANDN", LTYPE3, x86.APANDN},
+       {"PAVGB", LTYPE3, x86.APAVGB},
+       {"PAVGW", LTYPE3, x86.APAVGW},
+       {"PCMPEQB", LTYPE3, x86.APCMPEQB},
+       {"PCMPEQL", LTYPE3, x86.APCMPEQL},
+       {"PCMPEQW", LTYPE3, x86.APCMPEQW},
+       {"PCMPGTB", LTYPE3, x86.APCMPGTB},
+       {"PCMPGTL", LTYPE3, x86.APCMPGTL},
+       {"PCMPGTW", LTYPE3, x86.APCMPGTW},
+       {"PEXTRW", LTYPEX, x86.APEXTRW},
+       {"PINSRW", LTYPEX, x86.APINSRW},
+       {"PINSRD", LTYPEX, x86.APINSRD},
+       {"PINSRQ", LTYPEX, x86.APINSRQ},
+       {"PMADDWL", LTYPE3, x86.APMADDWL},
+       {"PMAXSW", LTYPE3, x86.APMAXSW},
+       {"PMAXUB", LTYPE3, x86.APMAXUB},
+       {"PMINSW", LTYPE3, x86.APMINSW},
+       {"PMINUB", LTYPE3, x86.APMINUB},
+       {"PMOVMSKB", LTYPE3, x86.APMOVMSKB},
+       {"PMULHRW", LTYPE3, x86.APMULHRW},
+       {"PMULHUW", LTYPE3, x86.APMULHUW},
+       {"PMULHW", LTYPE3, x86.APMULHW},
+       {"PMULLW", LTYPE3, x86.APMULLW},
+       {"PMULULQ", LTYPE3, x86.APMULULQ},
+       {"POR", LTYPE3, x86.APOR},
+       {"PSADBW", LTYPE3, x86.APSADBW},
+       {"PSHUFHW", LTYPEX, x86.APSHUFHW},
+       {"PSHUFL", LTYPEX, x86.APSHUFL},
+       {"PSHUFLW", LTYPEX, x86.APSHUFLW},
+       {"PSHUFW", LTYPEX, x86.APSHUFW},
+       {"PSHUFB", LTYPEM, x86.APSHUFB},
+       {"PSLLO", LTYPE3, x86.APSLLO},
+       {"PSLLDQ", LTYPE3, x86.APSLLO}, /* syn */
+       {"PSLLL", LTYPE3, x86.APSLLL},
+       {"PSLLQ", LTYPE3, x86.APSLLQ},
+       {"PSLLW", LTYPE3, x86.APSLLW},
+       {"PSRAL", LTYPE3, x86.APSRAL},
+       {"PSRAW", LTYPE3, x86.APSRAW},
+       {"PSRLO", LTYPE3, x86.APSRLO},
+       {"PSRLDQ", LTYPE3, x86.APSRLO}, /* syn */
+       {"PSRLL", LTYPE3, x86.APSRLL},
+       {"PSRLQ", LTYPE3, x86.APSRLQ},
+       {"PSRLW", LTYPE3, x86.APSRLW},
+       {"PSUBB", LTYPE3, x86.APSUBB},
+       {"PSUBL", LTYPE3, x86.APSUBL},
+       {"PSUBQ", LTYPE3, x86.APSUBQ},
+       {"PSUBSB", LTYPE3, x86.APSUBSB},
+       {"PSUBSW", LTYPE3, x86.APSUBSW},
+       {"PSUBUSB", LTYPE3, x86.APSUBUSB},
+       {"PSUBUSW", LTYPE3, x86.APSUBUSW},
+       {"PSUBW", LTYPE3, x86.APSUBW},
+       {"PUNPCKHBW", LTYPE3, x86.APUNPCKHBW},
+       {"PUNPCKHLQ", LTYPE3, x86.APUNPCKHLQ},
+       {"PUNPCKHQDQ", LTYPE3, x86.APUNPCKHQDQ},
+       {"PUNPCKHWL", LTYPE3, x86.APUNPCKHWL},
+       {"PUNPCKLBW", LTYPE3, x86.APUNPCKLBW},
+       {"PUNPCKLLQ", LTYPE3, x86.APUNPCKLLQ},
+       {"PUNPCKLQDQ", LTYPE3, x86.APUNPCKLQDQ},
+       {"PUNPCKLWL", LTYPE3, x86.APUNPCKLWL},
+       {"PXOR", LTYPE3, x86.APXOR},
+       {"RCPPS", LTYPE3, x86.ARCPPS},
+       {"RCPSS", LTYPE3, x86.ARCPSS},
+       {"RSQRTPS", LTYPE3, x86.ARSQRTPS},
+       {"RSQRTSS", LTYPE3, x86.ARSQRTSS},
+       {"SHUFPD", LTYPEX, x86.ASHUFPD},
+       {"SHUFPS", LTYPEX, x86.ASHUFPS},
+       {"SQRTPD", LTYPE3, x86.ASQRTPD},
+       {"SQRTPS", LTYPE3, x86.ASQRTPS},
+       {"SQRTSD", LTYPE3, x86.ASQRTSD},
+       {"SQRTSS", LTYPE3, x86.ASQRTSS},
+       {"STMXCSR", LTYPE1, x86.ASTMXCSR},
+       {"SUBPD", LTYPE3, x86.ASUBPD},
+       {"SUBPS", LTYPE3, x86.ASUBPS},
+       {"SUBSD", LTYPE3, x86.ASUBSD},
+       {"SUBSS", LTYPE3, x86.ASUBSS},
+       {"UCOMISD", LTYPE3, x86.AUCOMISD},
+       {"UCOMISS", LTYPE3, x86.AUCOMISS},
+       {"UNPCKHPD", LTYPE3, x86.AUNPCKHPD},
+       {"UNPCKHPS", LTYPE3, x86.AUNPCKHPS},
+       {"UNPCKLPD", LTYPE3, x86.AUNPCKLPD},
+       {"UNPCKLPS", LTYPE3, x86.AUNPCKLPS},
+       {"XORPD", LTYPE3, x86.AXORPD},
+       {"XORPS", LTYPE3, x86.AXORPS},
+       {"CRC32B", LTYPE4, x86.ACRC32B},
+       {"CRC32Q", LTYPE4, x86.ACRC32Q},
+       {"PREFETCHT0", LTYPE2, x86.APREFETCHT0},
+       {"PREFETCHT1", LTYPE2, x86.APREFETCHT1},
+       {"PREFETCHT2", LTYPE2, x86.APREFETCHT2},
+       {"PREFETCHNTA", LTYPE2, x86.APREFETCHNTA},
+       {"UNDEF", LTYPE0, x86.AUNDEF},
+       {"AESENC", LTYPE3, x86.AAESENC},
+       {"AESENCLAST", LTYPE3, x86.AAESENCLAST},
+       {"AESDEC", LTYPE3, x86.AAESDEC},
+       {"AESDECLAST", LTYPE3, x86.AAESDECLAST},
+       {"AESIMC", LTYPE3, x86.AAESIMC},
+       {"AESKEYGENASSIST", LTYPEX, x86.AAESKEYGENASSIST},
+       {"PSHUFD", LTYPEX, x86.APSHUFD},
+       {"USEFIELD", LTYPEN, x86.AUSEFIELD},
+       {"PCLMULQDQ", LTYPEX, x86.APCLMULQDQ},
+       {"PCDATA", LTYPEPC, x86.APCDATA},
+       {"FUNCDATA", LTYPEF, x86.AFUNCDATA},
+}
+
+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) {
+       switch scale {
+       case 1,
+               2,
+               4,
+               8:
+               return
+       }
+
+       yyerror("scale must be 1248: %d", scale)
+}
+
+func syminit(s *Sym) {
+       s.type_ = LNAME
+       s.value = 0
+}
+
+func cclean() {
+       var g2 Addr2
+
+       g2.from = nullgen
+       g2.to = nullgen
+       outcode(x86.AEND, &g2)
+}
+
+var lastpc *obj.Prog
+
+func outcode(a int, g2 *Addr2) {
+       var p *obj.Prog
+       var pl *obj.Plist
+
+       if pass == 1 {
+               goto out
+       }
+
+       p = new(obj.Prog)
+       *p = obj.Prog{}
+       p.As = int16(a)
+       p.Lineno = stmtline
+       p.From = g2.from
+       p.To = g2.to
+       p.Pc = int64(pc)
+
+       if lastpc == nil {
+               pl = obj.Linknewplist(ctxt)
+               pl.Firstpc = p
+       } else {
+
+               lastpc.Link = p
+       }
+       lastpc = p
+
+out:
+       if a != x86.AGLOBL && a != x86.ADATA {
+               pc++
+       }
+}
diff --git a/src/cmd/internal/asm/lexbody.go b/src/cmd/internal/asm/lexbody.go
new file mode 100644 (file)
index 0000000..d835e7b
--- /dev/null
@@ -0,0 +1,804 @@
+// Inferno utils/cc/lexbody
+// http://code.google.com/p/inferno-os/source/browse/utils/cc/lexbody
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package asm
+
+/*
+ * common code for all the assemblers
+ */
+func pragpack() {
+
+       for getnsc() != '\n' {
+
+       }
+}
+
+func pragvararg() {
+       for getnsc() != '\n' {
+
+       }
+}
+
+func pragcgo(name string) {
+       for getnsc() != '\n' {
+
+       }
+}
+
+func pragfpround() {
+       for getnsc() != '\n' {
+
+       }
+}
+
+func pragtextflag() {
+       for getnsc() != '\n' {
+
+       }
+}
+
+func pragdataflag() {
+       for getnsc() != '\n' {
+
+       }
+}
+
+func pragprofile() {
+       for getnsc() != '\n' {
+
+       }
+}
+
+func pragincomplete() {
+       for getnsc() != '\n' {
+
+       }
+}
+
+func Alloc(n int32) interface{} {
+       var p interface{}
+
+       p = make([]byte, n)
+       if p == nil {
+               fmt.Printf("alloc out of mem\n")
+               main.Exits("alloc: out of mem")
+       }
+
+       main.Memset(p, 0, n)
+       return p
+}
+
+func Allocn(p interface{}, n int32, d int32) interface{} {
+       if p == nil {
+               return Alloc(n + d)
+       }
+       p = main.Realloc(p, int(n+d))
+       if p == nil {
+               fmt.Printf("allocn out of mem\n")
+               main.Exits("allocn: out of mem")
+       }
+
+       if d > 0 {
+               main.Memset(p.(string)[n:], 0, d)
+       }
+       return p
+}
+
+func Ensuresymb(n int32) {
+       if new5a.Symb == nil {
+               new5a.Symb = Alloc(new5a.NSYMB + 1).(string)
+               new5a.Nsymb = new5a.NSYMB
+       }
+
+       if n > new5a.Nsymb {
+               new5a.Symb = Allocn(new5a.Symb, new5a.Nsymb, n+1-new5a.Nsymb).(string)
+               new5a.Nsymb = n
+       }
+}
+
+func Setinclude(p string) {
+       var i int
+
+       if p == "" {
+               return
+       }
+       for i = 1; i < new5a.Ninclude; i++ {
+               if p == new5a.Include[i] {
+                       return
+               }
+       }
+
+       if new5a.Ninclude%8 == 0 {
+               new5a.Include = Allocn(new5a.Include, new5a.Ninclude*sizeof(string), 8*sizeof(string)).(*string)
+       }
+       new5a.Include[new5a.Ninclude] = p
+       new5a.Ninclude++
+}
+
+func Errorexit() {
+       obj.Bflush(&new5a.Bstdout)
+       if new5a.Outfile != "" {
+               main.Remove(new5a.Outfile)
+       }
+       main.Exits("error")
+}
+
+func pushio() {
+       var i *new5a.Io
+
+       i = new5a.Iostack
+       if i == nil {
+               Yyerror("botch in pushio")
+               Errorexit()
+       }
+
+       i.P = new5a.Fi.p
+       i.C = int16(new5a.Fi.c)
+}
+
+func newio() {
+       var i *new5a.Io
+       var pushdepth int = 0
+
+       i = new5a.Iofree
+       if i == nil {
+               pushdepth++
+               if pushdepth > 1000 {
+                       Yyerror("macro/io expansion too deep")
+                       Errorexit()
+               }
+
+               i = Alloc(sizeof(*i)).(*new5a.Io)
+       } else {
+
+               new5a.Iofree = i.Link
+       }
+       i.C = 0
+       i.F = -1
+       new5a.Ionext = i
+}
+
+func newfile(s string, f int) {
+       var i *new5a.Io
+
+       i = new5a.Ionext
+       i.Link = new5a.Iostack
+       new5a.Iostack = i
+       i.F = int16(f)
+       if f < 0 {
+               i.F = int16(main.Open(s, 0))
+       }
+       if i.F < 0 {
+               Yyerror("%ca: %r: %s", new5a.Thechar, s)
+               Errorexit()
+       }
+
+       new5a.Fi.c = 0
+       obj.Linklinehist(new5a.Ctxt, int(new5a.Lineno), s, 0)
+}
+
+func Slookup(s string) *new5a.Sym {
+       Ensuresymb(int32(len(s)))
+       new5a.Symb = s
+       return lookup()
+}
+
+var thetext *obj.LSym
+
+func settext(s *obj.LSym) {
+       thetext = s
+}
+
+func labellookup(s *new5a.Sym) *new5a.Sym {
+       var p string
+       var lab *new5a.Sym
+
+       if thetext == nil {
+               s.Labelname = s.Name
+               return s
+       }
+
+       p = string(fmt.Sprintf("%s.%s", thetext.Name, s.Name))
+       lab = Slookup(p)
+
+       lab.Labelname = s.Name
+       return lab
+}
+
+func lookup() *new5a.Sym {
+       var s *new5a.Sym
+       var h uint32
+       var p string
+       var c int
+       var l int
+       var r string
+       var w string
+
+       if uint8(new5a.Symb[0]) == 0xc2 && uint8(new5a.Symb[1]) == 0xb7 {
+               // turn leading · into ""·
+               h = uint32(len(new5a.Symb))
+
+               Ensuresymb(int32(h + 2))
+               main.Memmove(new5a.Symb[2:], new5a.Symb, h+1)
+               new5a.Symb[0] = '"'
+               new5a.Symb[1] = '"'
+       }
+
+       w = new5a.Symb
+       for r = w; r[0] != 0; r = r[1:] {
+               // turn · (U+00B7) into .
+               // turn ∕ (U+2215) into /
+               if uint8(r[0]) == 0xc2 && uint8((r[1:])[0]) == 0xb7 {
+
+                       w[0] = '.'
+                       w = w[1:]
+                       r = r[1:]
+               } else if uint8(r[0]) == 0xe2 && uint8((r[1:])[0]) == 0x88 && uint8((r[2:])[0]) == 0x95 {
+                       w[0] = '/'
+                       w = w[1:]
+                       r = r[1:]
+                       r = r[1:]
+               } else {
+
+                       w[0] = r[0]
+                       w = w[1:]
+               }
+       }
+
+       w[0] = '\x00'
+
+       h = 0
+       for p = new5a.Symb; ; p = p[1:] {
+               c = int(p[0])
+               if !(c != 0) {
+                       break
+               }
+               h = h + h + h + uint32(c)
+       }
+       l = (-cap(p) + cap(new5a.Symb)) + 1
+       h &= 0xffffff
+       h %= new5a.NHASH
+       c = int(new5a.Symb[0])
+       for s = new5a.Hash[h]; s != nil; s = s.Link {
+               if int(s.Name[0]) != c {
+                       continue
+               }
+               if s.Name == new5a.Symb {
+                       return s
+               }
+       }
+
+       s = Alloc(sizeof(*s)).(*new5a.Sym)
+       s.Name = Alloc(int32(l)).(string)
+       main.Memmove(s.Name, new5a.Symb, l)
+
+       s.Link = new5a.Hash[h]
+       new5a.Hash[h] = s
+       new5a.Syminit(s)
+       return s
+}
+
+func ISALPHA(c int) int {
+       if main.Isalpha(c) != 0 {
+               return 1
+       }
+       if c >= main.Runeself {
+               return 1
+       }
+       return 0
+}
+
+func yylex() int32 {
+       var c int
+       var c1 int
+       var cp string
+       var s *new5a.Sym
+
+       c = new5a.Peekc
+       if c != new5a.IGN {
+               new5a.Peekc = new5a.IGN
+               goto l1
+       }
+
+l0:
+       c = new5a.GETC()
+
+l1:
+       if c == new5a.EOF {
+               new5a.Peekc = new5a.EOF
+               return -1
+       }
+
+       if main.Isspace(c) != 0 {
+               if c == '\n' {
+                       new5a.Lineno++
+                       return ';'
+               }
+
+               goto l0
+       }
+
+       if ISALPHA(c) != 0 {
+               goto talph
+       }
+       if main.Isdigit(c) != 0 {
+               goto tnum
+       }
+       switch c {
+       case '\n':
+               new5a.Lineno++
+               return ';'
+
+       case '#':
+               domacro()
+               goto l0
+
+       case '.':
+               c = new5a.GETC()
+               if ISALPHA(c) != 0 {
+                       cp = new5a.Symb
+                       cp[0] = '.'
+                       cp = cp[1:]
+                       goto aloop
+               }
+
+               if main.Isdigit(c) != 0 {
+                       cp = new5a.Symb
+                       cp[0] = '.'
+                       cp = cp[1:]
+                       goto casedot
+               }
+
+               new5a.Peekc = c
+               return '.'
+
+       case '_',
+               '@':
+       talph:
+               cp = new5a.Symb
+
+       aloop:
+               cp[0] = byte(c)
+               cp = cp[1:]
+               c = new5a.GETC()
+               if ISALPHA(c) != 0 || main.Isdigit(c) != 0 || c == '_' || c == '$' {
+                       goto aloop
+               }
+               cp = ""
+               new5a.Peekc = c
+               s = lookup()
+               if s.Macro != "" {
+                       newio()
+                       cp = new5a.Ionext.B
+                       macexpand(s, cp)
+                       pushio()
+                       new5a.Ionext.Link = new5a.Iostack
+                       new5a.Iostack = new5a.Ionext
+                       new5a.Fi.p = cp
+                       new5a.Fi.c = len(cp)
+                       if new5a.Peekc != new5a.IGN {
+                               cp[new5a.Fi.c] = byte(new5a.Peekc)
+                               new5a.Fi.c++
+                               cp[new5a.Fi.c] = 0
+                               new5a.Peekc = new5a.IGN
+                       }
+
+                       goto l0
+               }
+
+               if s.Type_ == 0 {
+                       s.Type_ = new5a.LNAME
+               }
+               if s.Type_ == new5a.LNAME || s.Type_ == new5a.LVAR || s.Type_ == new5a.LLAB {
+                       new5a.Yylval.sym = s
+                       return int32(s.Type_)
+               }
+
+               new5a.Yylval.lval = s.Value
+               return int32(s.Type_)
+
+       tnum:
+               cp = new5a.Symb
+               if c != '0' {
+                       goto dc
+               }
+               cp[0] = byte(c)
+               cp = cp[1:]
+               c = new5a.GETC()
+               c1 = 3
+               if c == 'x' || c == 'X' {
+                       c1 = 4
+                       c = new5a.GETC()
+               } else if c < '0' || c > '7' {
+                       goto dc
+               }
+               new5a.Yylval.lval = 0
+               for {
+                       if c >= '0' && c <= '9' {
+                               if c > '7' && c1 == 3 {
+                                       break
+                               }
+                               new5a.Yylval.lval = int32(uint64(new5a.Yylval.lval) << uint(c1))
+                               new5a.Yylval.lval += int32(c) - '0'
+                               c = new5a.GETC()
+                               continue
+                       }
+
+                       if c1 == 3 {
+                               break
+                       }
+                       if c >= 'A' && c <= 'F' {
+                               c += 'a' - 'A'
+                       }
+                       if c >= 'a' && c <= 'f' {
+                               new5a.Yylval.lval = int32(uint64(new5a.Yylval.lval) << uint(c1))
+                               new5a.Yylval.lval += int32(c) - 'a' + 10
+                               c = new5a.GETC()
+                               continue
+                       }
+
+                       break
+               }
+
+               goto ncu
+
+       dc:
+               for {
+                       if !(main.Isdigit(c) != 0) {
+                               break
+                       }
+                       cp[0] = byte(c)
+                       cp = cp[1:]
+                       c = new5a.GETC()
+               }
+
+               if c == '.' {
+                       goto casedot
+               }
+               if c == 'e' || c == 'E' {
+                       goto casee
+               }
+               cp = ""
+               if sizeof(new5a.Yylval.lval) == sizeof(int64) {
+                       new5a.Yylval.lval = int32(main.Strtoll(new5a.Symb, nil, 10))
+               } else {
+
+                       new5a.Yylval.lval = int32(main.Strtol(new5a.Symb, nil, 10))
+               }
+
+       ncu:
+               for c == 'U' || c == 'u' || c == 'l' || c == 'L' {
+                       c = new5a.GETC()
+               }
+               new5a.Peekc = c
+               return new5a.LCONST
+
+       casedot:
+               for {
+                       cp[0] = byte(c)
+                       cp = cp[1:]
+                       c = new5a.GETC()
+                       if !(main.Isdigit(c) != 0) {
+                               break
+                       }
+               }
+
+               if c == 'e' || c == 'E' {
+                       goto casee
+               }
+               goto caseout
+
+       casee:
+               cp[0] = 'e'
+               cp = cp[1:]
+               c = new5a.GETC()
+               if c == '+' || c == '-' {
+                       cp[0] = byte(c)
+                       cp = cp[1:]
+                       c = new5a.GETC()
+               }
+
+               for main.Isdigit(c) != 0 {
+                       cp[0] = byte(c)
+                       cp = cp[1:]
+                       c = new5a.GETC()
+               }
+
+       caseout:
+               cp = ""
+               new5a.Peekc = c
+               if new5a.FPCHIP != 0 /*TypeKind(100016)*/ {
+                       new5a.Yylval.dval = main.Atof(new5a.Symb)
+                       return new5a.LFCONST
+               }
+
+               Yyerror("assembler cannot interpret fp constants")
+               new5a.Yylval.lval = 1
+               return new5a.LCONST
+
+       case '"':
+               main.Memmove(new5a.Yylval.sval, new5a.Nullgen.U.Sval, sizeof(new5a.Yylval.sval))
+               cp = new5a.Yylval.sval
+               c1 = 0
+               for {
+                       c = escchar('"')
+                       if c == new5a.EOF {
+                               break
+                       }
+                       if c1 < sizeof(new5a.Yylval.sval) {
+                               cp[0] = byte(c)
+                               cp = cp[1:]
+                       }
+                       c1++
+               }
+
+               if c1 > sizeof(new5a.Yylval.sval) {
+                       Yyerror("string constant too long")
+               }
+               return new5a.LSCONST
+
+       case '\'':
+               c = escchar('\'')
+               if c == new5a.EOF {
+                       c = '\''
+               }
+               if escchar('\'') != new5a.EOF {
+                       Yyerror("missing '")
+               }
+               new5a.Yylval.lval = int32(c)
+               return new5a.LCONST
+
+       case '/':
+               c1 = new5a.GETC()
+               if c1 == '/' {
+                       for {
+                               c = new5a.GETC()
+                               if c == '\n' {
+                                       goto l1
+                               }
+                               if c == new5a.EOF {
+                                       Yyerror("eof in comment")
+                                       Errorexit()
+                               }
+                       }
+               }
+
+               if c1 == '*' {
+                       for {
+                               c = new5a.GETC()
+                               for c == '*' {
+                                       c = new5a.GETC()
+                                       if c == '/' {
+                                               goto l0
+                                       }
+                               }
+
+                               if c == new5a.EOF {
+                                       Yyerror("eof in comment")
+                                       Errorexit()
+                               }
+
+                               if c == '\n' {
+                                       new5a.Lineno++
+                               }
+                       }
+               }
+
+       default:
+               return int32(c)
+       }
+
+       new5a.Peekc = c1
+       return int32(c)
+}
+
+func getc() int {
+       var c int
+
+       c = new5a.Peekc
+       if c != new5a.IGN {
+               new5a.Peekc = new5a.IGN
+               return c
+       }
+
+       c = new5a.GETC()
+       if c == '\n' {
+               new5a.Lineno++
+       }
+       if c == new5a.EOF {
+               Yyerror("End of file")
+               Errorexit()
+       }
+
+       return c
+}
+
+func getnsc() int {
+       var c int
+
+       for {
+               c = getc()
+               if !(main.Isspace(c) != 0) || c == '\n' {
+                       return c
+               }
+       }
+}
+
+func unget(c int) {
+       new5a.Peekc = c
+       if c == '\n' {
+               new5a.Lineno--
+       }
+}
+
+func escchar(e int) int {
+       var c int
+       var l int
+
+loop:
+       c = getc()
+       if c == '\n' {
+               Yyerror("newline in string")
+               return new5a.EOF
+       }
+
+       if c != '\\' {
+               if c == e {
+                       return new5a.EOF
+               }
+               return c
+       }
+
+       c = getc()
+       if c >= '0' && c <= '7' {
+               l = c - '0'
+               c = getc()
+               if c >= '0' && c <= '7' {
+                       l = l*8 + c - '0'
+                       c = getc()
+                       if c >= '0' && c <= '7' {
+                               l = l*8 + c - '0'
+                               return l
+                       }
+               }
+
+               new5a.Peekc = c
+               return l
+       }
+
+       switch c {
+       case '\n':
+               goto loop
+       case 'n':
+               return '\n'
+       case 't':
+               return '\t'
+       case 'b':
+               return '\b'
+       case 'r':
+               return '\r'
+       case 'f':
+               return '\f'
+       case 'a':
+               return 0x07
+       case 'v':
+               return 0x0b
+       case 'z':
+               return 0x00
+       }
+
+       return c
+}
+
+func Pinit(f string) {
+       var i int
+       var s *new5a.Sym
+
+       new5a.Lineno = 1
+       newio()
+       newfile(f, -1)
+       new5a.Pc = 0
+       new5a.Peekc = new5a.IGN
+       new5a.Sym = 1
+       for i = 0; i < new5a.NHASH; i++ {
+               for s = new5a.Hash[i]; s != nil; s = s.Link {
+                       s.Macro = ""
+               }
+       }
+}
+
+func filbuf() int {
+       var i *new5a.Io
+
+loop:
+       i = new5a.Iostack
+       if i == nil {
+               return new5a.EOF
+       }
+       if i.F < 0 {
+               goto pop
+       }
+       new5a.Fi.c = main.Read(int(i.F), i.B, new5a.BUFSIZ) - 1
+       if new5a.Fi.c < 0 {
+               main.Close(int(i.F))
+               obj.Linklinehist(new5a.Ctxt, int(new5a.Lineno), "", 0)
+               goto pop
+       }
+
+       new5a.Fi.p = i.B[1:]
+       return int(i.B[0]) & 0xff
+
+pop:
+       new5a.Iostack = i.Link
+       i.Link = new5a.Iofree
+       new5a.Iofree = i
+       i = new5a.Iostack
+       if i == nil {
+               return new5a.EOF
+       }
+       new5a.Fi.p = i.P
+       new5a.Fi.c = int(i.C)
+       new5a.Fi.c--
+       if new5a.Fi.c < 0 {
+               goto loop
+       }
+       tmp8 := new5a.Fi.p
+       new5a.Fi.p = new5a.Fi.p[1:]
+       return int(tmp8[0]) & 0xff
+}
+
+func Yyerror(a string, args ...interface{}) {
+       var buf string
+       var arg []interface{}
+
+       /*
+        * hack to intercept message from yaccpar
+        */
+       if a == "syntax error" {
+
+               Yyerror("syntax error, last name: %s", new5a.Symb)
+               return
+       }
+
+       prfile(new5a.Lineno)
+       main.Va_start(arg, a)
+       obj.Vseprint(buf, buf[sizeof(buf):], a, arg)
+       main.Va_end(arg)
+       fmt.Printf("%s\n", buf)
+       new5a.Nerrors++
+       if new5a.Nerrors > 10 {
+               fmt.Printf("too many errors\n")
+               Errorexit()
+       }
+}
+
+func prfile(l int32) {
+       obj.Linkprfile(new5a.Ctxt, l)
+}
diff --git a/src/cmd/internal/asm/macbody.go b/src/cmd/internal/asm/macbody.go
new file mode 100644 (file)
index 0000000..d8ec242
--- /dev/null
@@ -0,0 +1,992 @@
+// Inferno 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 © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package asm
+
+const (
+       VARMAC = 0x80
+)
+
+func getnsn() int32 {
+       var n int32
+       var c int
+
+       c = getnsc()
+       if c < '0' || c > '9' {
+               return -1
+       }
+       n = 0
+       for c >= '0' && c <= '9' {
+               n = n*10 + int32(c) - '0'
+               c = getc()
+       }
+
+       unget(c)
+       return n
+}
+
+func getsym() *new5a.Sym {
+       var c int
+       var cp string
+
+       c = getnsc()
+       if !(main.Isalpha(c) != 0) && 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:]
+               }
+               c = getc()
+               if main.Isalnum(c) != 0 || c == '_' || c >= 0x80 {
+                       continue
+               }
+               unget(c)
+               break
+       }
+
+       cp = ""
+       if cp > new5a.Symb[new5a.NSYMB-4:] {
+               Yyerror("symbol too large: %s", new5a.Symb)
+       }
+       return lookup()
+}
+
+func getsymdots(dots *int) *new5a.Sym {
+       var c int
+       var s *new5a.Sym
+
+       s = getsym()
+       if s != nil {
+               return s
+       }
+
+       c = getnsc()
+       if c != '.' {
+               unget(c)
+               return nil
+       }
+
+       if getc() != '.' || getc() != '.' {
+               Yyerror("bad dots in macro")
+       }
+       *dots = 1
+       return Slookup("__VA_ARGS__")
+}
+
+func getcom() int {
+       var c int
+
+       for {
+               c = getnsc()
+               if c != '/' {
+                       break
+               }
+               c = getc()
+               if c == '/' {
+                       for c != '\n' {
+                               c = getc()
+                       }
+                       break
+               }
+
+               if c != '*' {
+                       break
+               }
+               c = getc()
+               for {
+                       if c == '*' {
+                               c = getc()
+                               if c != '/' {
+                                       continue
+                               }
+                               c = getc()
+                               break
+                       }
+
+                       if c == '\n' {
+                               Yyerror("comment across newline")
+                               break
+                       }
+
+                       c = getc()
+               }
+
+               if c == '\n' {
+                       break
+               }
+       }
+
+       return c
+}
+
+func Dodefine(cp string) {
+       var s *new5a.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
+       } else {
+
+               s = lookup()
+               s.Macro = "\0001" /* \000 is nargs */
+       }
+
+       if new5a.Debug['m'] != 0 {
+               fmt.Printf("#define (-D) %s %s\n", s.Name, s.Macro[1:])
+       }
+}
+
+var mactab = []struct {
+       macname string
+       macf    func()
+}{
+       {"ifdef", nil},  /* macif(0) */
+       {"ifndef", nil}, /* macif(1) */
+       {"else", nil},   /* macif(2) */
+       {"line", maclin},
+       {"define", macdef},
+       {"include", macinc},
+       {"undef", macund},
+       {"pragma", macprag},
+       {"endif", macend},
+}
+
+func domacro() {
+       var i int
+       var s *new5a.Sym
+
+       s = getsym()
+       if s == nil {
+               s = Slookup("endif")
+       }
+       for i = 0; mactab[i].macname != ""; i++ {
+               if s.Name == mactab[i].macname {
+                       if mactab[i].macf != nil {
+                               (*mactab[i].macf)()
+                       } else {
+
+                               macif(i)
+                       }
+                       return
+               }
+       }
+
+       Yyerror("unknown #: %s", s.Name)
+       macend()
+}
+
+func macund() {
+       var s *new5a.Sym
+
+       s = getsym()
+       macend()
+       if s == nil {
+               Yyerror("syntax in #undef")
+               return
+       }
+
+       s.Macro = ""
+}
+
+const (
+       NARG = 25
+)
+
+func macdef() {
+       var s *new5a.Sym
+       var a *new5a.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
+
+       s = getsym()
+       if s == nil {
+               goto bad
+       }
+       if s.Macro != "" {
+               Yyerror("macro redefined: %s", s.Name)
+       }
+       c = getc()
+       n = -1
+       dots = 0
+       if c == '(' {
+               n++
+               c = getnsc()
+               if c != ')' {
+                       unget(c)
+                       for {
+                               a = getsymdots(&dots)
+                               if a == nil {
+                                       goto bad
+                               }
+                               if n >= NARG {
+                                       Yyerror("too many arguments in #define: %s", s.Name)
+                                       goto bad
+                               }
+
+                               args[n] = a.Name
+                               n++
+                               c = getnsc()
+                               if c == ')' {
+                                       break
+                               }
+                               if c != ',' || dots != 0 {
+                                       goto bad
+                               }
+                       }
+               }
+
+               c = getc()
+       }
+
+       if main.Isspace(c) != 0 {
+               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:]
+                       c = getc()
+                       for main.Isalnum(c) != 0 || c == '_' {
+                               np[0] = byte(c)
+                               np = np[1:]
+                               c = getc()
+                       }
+
+                       np = ""
+                       for i = 0; i < n; i++ {
+                               if new5a.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
+                               continue
+                       }
+
+                       base = Allocn(base, int32(len), 2).(string)
+                       base[len] = '#'
+                       len++
+                       base[len] = byte('a' + i)
+                       len++
+                       continue
+               }
+
+               if ischr != 0 {
+                       if c == '\\' {
+                               base = Allocn(base, int32(len), 1).(string)
+                               base[len] = byte(c)
+                               len++
+                               c = getc()
+                       } else if c == ischr {
+                               ischr = 0
+                       }
+               } else {
+
+                       if c == '"' || c == '\'' {
+                               base = Allocn(base, int32(len), 1).(string)
+                               base[len] = byte(c)
+                               len++
+                               ischr = c
+                               c = getc()
+                               continue
+                       }
+
+                       if c == '/' {
+                               c = getc()
+                               if c == '/' {
+                                       c = getc()
+                                       for {
+                                               if c == '\n' {
+                                                       break
+                                               }
+                                               c = getc()
+                                       }
+
+                                       continue
+                               }
+
+                               if c == '*' {
+                                       c = getc()
+                                       for {
+                                               if c == '*' {
+                                                       c = getc()
+                                                       if c != '/' {
+                                                               continue
+                                                       }
+                                                       c = getc()
+                                                       break
+                                               }
+
+                                               if c == '\n' {
+                                                       Yyerror("comment and newline in define: %s", s.Name)
+                                                       break
+                                               }
+
+                                               c = getc()
+                                       }
+
+                                       continue
+                               }
+
+                               base = Allocn(base, int32(len), 1).(string)
+                               base[len] = '/'
+                               len++
+                               continue
+                       }
+               }
+
+               if c == '\\' {
+                       c = getc()
+                       if c == '\n' {
+                               c = getc()
+                               continue
+                       } else if c == '\r' {
+                               c = getc()
+                               if c == '\n' {
+                                       c = getc()
+                                       continue
+                               }
+                       }
+
+                       base = Allocn(base, int32(len), 1).(string)
+                       base[len] = '\\'
+                       len++
+                       continue
+               }
+
+               if c == '\n' {
+                       break
+               }
+               if c == '#' {
+                       if n > 0 {
+                               base = Allocn(base, int32(len), 1).(string)
+                               base[len] = byte(c)
+                               len++
+                       }
+               }
+
+               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)
+               if c == '\n' {
+                       new5a.Lineno++
+               }
+               if c == -1 {
+                       Yyerror("eof in a macro: %s", s.Name)
+                       break
+               }
+       }
+
+       for {
+               base = Allocn(base, int32(len), 1).(string)
+               base[len] = 0
+               len++
+               if !(len&3 != 0 /*untyped*/) {
+                       break
+               }
+       }
+
+       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:])
+       }
+       return
+
+bad:
+       if s == nil {
+               Yyerror("syntax in #define")
+       } else {
+
+               Yyerror("syntax in #define: %s", s.Name)
+       }
+       macend()
+}
+
+func macexpand(s *new5a.Sym, b string) {
+       var buf string
+       var n int
+       var l int
+       var c int
+       var nargs int
+       var arg [NARG]string
+       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)
+               }
+               return
+       }
+
+       nargs = int(int8(s.Macro[0]&^VARMAC)) - 1
+       dots = int8(s.Macro[0] & VARMAC)
+
+       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:]
+                                       c = getc()
+                                       if c == '\\' {
+                                               cp[0] = byte(c)
+                                               cp = cp[1:]
+                                               c = getc()
+                                               continue
+                                       }
+
+                                       if c == '\n' {
+                                               goto bad
+                                       }
+                                       if c == '"' {
+                                               break
+                                       }
+                               }
+                       }
+
+                       if c == '\'' {
+                               for {
+                                       if cp >= ecp {
+                                               goto toobig
+                                       }
+                                       cp[0] = byte(c)
+                                       cp = cp[1:]
+                                       c = getc()
+                                       if c == '\\' {
+                                               cp[0] = byte(c)
+                                               cp = cp[1:]
+                                               c = getc()
+                                               continue
+                                       }
+
+                                       if c == '\n' {
+                                               goto bad
+                                       }
+                                       if c == '\'' {
+                                               break
+                                       }
+                               }
+                       }
+
+                       if c == '/' {
+                               c = getc()
+                               switch c {
+                               case '*':
+                                       for {
+                                               c = getc()
+                                               if c == '*' {
+                                                       c = getc()
+                                                       if c == '/' {
+                                                               break
+                                                       }
+                                               }
+                                       }
+
+                                       cp[0] = ' '
+                                       cp = cp[1:]
+                                       continue
+
+                               case '/':
+                                       for {
+                                               c = getc()
+                                               if !(c != '\n') {
+                                                       break
+                                               }
+                                       }
+
+                               default:
+                                       unget(c)
+                                       c = '/'
+                               }
+                       }
+
+                       if l == 0 {
+                               if c == ',' {
+                                       if n == nargs && dots != 0 {
+                                               cp[0] = ','
+                                               cp = cp[1:]
+                                               continue
+                                       }
+
+                                       cp = ""
+                                       cp = cp[1:]
+                                       arg[n] = cp
+                                       n++
+                                       if n > nargs {
+                                               break
+                                       }
+                                       continue
+                               }
+
+                               if c == ')' {
+                                       break
+                               }
+                       }
+
+                       if c == '\n' {
+                               c = ' '
+                       }
+                       cp[0] = byte(c)
+                       cp = cp[1:]
+                       if c == '(' {
+                               l++
+                       }
+                       if c == ')' {
+                               l--
+                       }
+               }
+
+               cp = ""
+       }
+
+       if n != nargs {
+               Yyerror("argument mismatch expanding: %s", s.Name)
+               b = ""
+               return
+       }
+
+       cp = s.Macro[1:]
+       for {
+               c = int(cp[0])
+               cp = cp[1:]
+               if c == '\n' {
+                       c = ' '
+               }
+               if c != '#' {
+                       b[0] = byte(c)
+                       b = b[1:]
+                       if c == 0 {
+                               break
+                       }
+                       continue
+               }
+
+               c = int(cp[0])
+               cp = cp[1:]
+               if c == 0 {
+                       goto bad
+               }
+               if c == '#' {
+                       b[0] = byte(c)
+                       b = b[1:]
+                       continue
+               }
+
+               c -= 'a'
+               if c < 0 || c >= n {
+                       continue
+               }
+               b = arg[c]
+               b = b[len(arg[c]):]
+       }
+
+       b = ""
+       if new5a.Debug['m'] != 0 {
+               fmt.Printf("#expand %s %s\n", s.Name, ob)
+       }
+       return
+
+bad:
+       Yyerror("syntax in macro expansion: %s", s.Name)
+       b = ""
+       return
+
+toobig:
+       Yyerror("too much text in macro expansion: %s", s.Name)
+       b = ""
+}
+
+func macinc() {
+       var c0 int
+       var c int
+       var i int
+       var f int
+       var str string
+       var hp string
+
+       c0 = getnsc()
+       if c0 != '"' {
+               c = c0
+               if c0 != '<' {
+                       goto bad
+               }
+               c0 = '>'
+       }
+
+       for hp = str; ; {
+               c = getc()
+               if c == c0 {
+                       break
+               }
+               if c == '\n' {
+                       goto bad
+               }
+               hp[0] = byte(c)
+               hp = hp[1:]
+       }
+
+       hp = ""
+
+       c = getcom()
+       if c != '\n' {
+               goto bad
+       }
+
+       f = -1
+       for i = 0; i < new5a.Ninclude; 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 = ""
+               }
+               new5a.Symb += str
+               f = main.Open(new5a.Symb, main.OREAD)
+               if f >= 0 {
+                       break
+               }
+       }
+
+       if f < 0 {
+               new5a.Symb = str
+       }
+       c = len(new5a.Symb) + 1
+       hp = Alloc(int32(c)).(string)
+       main.Memmove(hp, new5a.Symb, c)
+       newio()
+       pushio()
+       newfile(hp, f)
+       return
+
+bad:
+       unget(c)
+       Yyerror("syntax in #include")
+       macend()
+}
+
+func maclin() {
+       var cp string
+       var c int
+       var n int32
+
+       n = getnsn()
+       c = getc()
+       if n < 0 {
+               goto bad
+       }
+
+       for {
+               if c == ' ' || c == '\t' {
+                       c = getc()
+                       continue
+               }
+
+               if c == '"' {
+                       break
+               }
+               if c == '\n' {
+                       new5a.Symb = "<noname>"
+                       goto nn
+               }
+
+               goto bad
+       }
+
+       cp = new5a.Symb
+       for {
+               c = getc()
+               if c == '"' {
+                       break
+               }
+               cp[0] = byte(c)
+               cp = cp[1:]
+       }
+
+       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))
+       return
+
+bad:
+       unget(c)
+       Yyerror("syntax in #line")
+       macend()
+}
+
+func macif(f int) {
+       var c int
+       var l int
+       var bol int
+       var s *new5a.Sym
+
+       if f == 2 {
+               goto skip
+       }
+       s = getsym()
+       if s == nil {
+               goto bad
+       }
+       if getcom() != '\n' {
+               goto bad
+       }
+       if (s.Macro != "")^f != 0 /*untyped*/ {
+               return
+       }
+
+skip:
+       bol = 1
+       l = 0
+       for {
+               c = getc()
+               if c != '#' {
+                       if !(main.Isspace(c) != 0) {
+                               bol = 0
+                       }
+                       if c == '\n' {
+                               bol = 1
+                       }
+                       continue
+               }
+
+               if !(bol != 0) {
+                       continue
+               }
+               s = getsym()
+               if s == nil {
+                       continue
+               }
+               if s.Name == "endif" {
+                       if l != 0 {
+                               l--
+                               continue
+                       }
+
+                       macend()
+                       return
+               }
+
+               if s.Name == "ifdef" || s.Name == "ifndef" {
+                       l++
+                       continue
+               }
+
+               if l == 0 && f != 2 && s.Name == "else" {
+                       macend()
+                       return
+               }
+       }
+
+bad:
+       Yyerror("syntax in #if(n)def")
+       macend()
+}
+
+func macprag() {
+       var s *new5a.Sym
+       var c0 int
+       var c int
+       var hp string
+
+       s = getsym()
+
+       if s != nil && s.Name == "lib" {
+               goto praglib
+       }
+       if s != nil && s.Name == "pack" {
+               pragpack()
+               return
+       }
+
+       if s != nil && s.Name == "fpround" {
+               pragfpround()
+               return
+       }
+
+       if s != nil && s.Name == "textflag" {
+               pragtextflag()
+               return
+       }
+
+       if s != nil && s.Name == "dataflag" {
+               pragdataflag()
+               return
+       }
+
+       if s != nil && s.Name == "varargck" {
+               pragvararg()
+               return
+       }
+
+       if s != nil && s.Name == "incomplete" {
+               pragincomplete()
+               return
+       }
+
+       if s != nil && (strings.HasPrefix(s.Name, "cgo_") || strings.HasPrefix(s.Name, "dyn")) {
+               pragcgo(s.Name)
+               return
+       }
+
+       for getnsc() != '\n' {
+
+       }
+       return
+
+praglib:
+       c0 = getnsc()
+       if c0 != '"' {
+               c = c0
+               if c0 != '<' {
+                       goto bad
+               }
+               c0 = '>'
+       }
+
+       for hp = new5a.Symb; ; {
+               c = getc()
+               if c == c0 {
+                       break
+               }
+               if c == '\n' {
+                       goto bad
+               }
+               hp[0] = byte(c)
+               hp = hp[1:]
+       }
+
+       hp = ""
+       c = getcom()
+       if c != '\n' {
+               goto bad
+       }
+
+       /*
+        * 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)
+       return
+
+bad:
+       unget(c)
+       Yyerror("syntax in #pragma lib")
+       macend()
+}
+
+func macend() {
+       var c int
+
+       for {
+               c = getnsc()
+               if c < 0 || c == '\n' {
+                       return
+               }
+       }
+}
diff --git a/src/cmd/new5a/a.y b/src/cmd/new5a/a.y
new file mode 100644 (file)
index 0000000..d365c75
--- /dev/null
@@ -0,0 +1,741 @@
+// Inferno utils/5a/a.y
+// http://code.google.com/p/inferno-os/source/browse/utils/5a/a.y
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// 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"
+%}
+%union
+{
+       Sym     *sym;
+       int32   lval;
+       double  dval;
+       char    sval[8];
+       Addr    addr;
+}
+%left  '|'
+%left  '^'
+%left  '&'
+%left  '<' '>'
+%left  '+' '-'
+%left  '*' '/' '%'
+%token <lval>  LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
+%token <lval>  LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
+%token <lval>  LTYPEB LTYPEC LTYPED LTYPEE
+%token <lval>  LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
+%token <lval>  LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
+%token <lval>  LCONST LSP LSB LFP LPC
+%token <lval>  LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
+%token <lval>  LCOND LS LAT
+%token <dval>  LFCONST
+%token <sval>  LSCONST
+%token <sym>   LNAME LLAB LVAR
+%type  <lval>  con expr oexpr pointer offset sreg spreg creg
+%type  <lval>  rcon cond reglist
+%type  <addr>  gen rel reg regreg freg shift fcon frcon
+%type  <addr>  imm ximm name oreg ireg nireg ioreg imsr
+%%
+prog:
+|      prog
+       {
+               stmtline = 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;
+       }
+       line
+|      LNAME '=' expr ';'
+       {
+               $1->type = LVAR;
+               $1->value = $3;
+       }
+|      LVAR '=' expr ';'
+       {
+               if($1->value != $3)
+                       yyerror("redeclaration of %s", $1->name);
+               $1->value = $3;
+       }
+|      ';'
+|      inst ';'
+|      error ';'
+
+inst:
+/*
+ * ADD
+ */
+       LTYPE1 cond imsr ',' spreg ',' reg
+       {
+               outcode($1, $2, &$3, $5, &$7);
+       }
+|      LTYPE1 cond imsr ',' spreg ','
+       {
+               outcode($1, $2, &$3, $5, &nullgen);
+       }
+|      LTYPE1 cond imsr ',' reg
+       {
+               outcode($1, $2, &$3, NREG, &$5);
+       }
+/*
+ * MVN
+ */
+|      LTYPE2 cond imsr ',' reg
+       {
+               outcode($1, $2, &$3, NREG, &$5);
+       }
+/*
+ * MOVW
+ */
+|      LTYPE3 cond gen ',' gen
+       {
+               outcode($1, $2, &$3, NREG, &$5);
+       }
+/*
+ * B/BL
+ */
+|      LTYPE4 cond comma rel
+       {
+               outcode($1, $2, &nullgen, NREG, &$4);
+       }
+|      LTYPE4 cond comma nireg
+       {
+               outcode($1, $2, &nullgen, NREG, &$4);
+       }
+/*
+ * BX
+ */
+|      LTYPEBX comma ireg
+       {
+               outcode($1, Always, &nullgen, NREG, &$3);
+       }
+/*
+ * BEQ
+ */
+|      LTYPE5 comma rel
+       {
+               outcode($1, Always, &nullgen, NREG, &$3);
+       }
+/*
+ * SWI
+ */
+|      LTYPE6 cond comma gen
+       {
+               outcode($1, $2, &nullgen, NREG, &$4);
+       }
+/*
+ * CMP
+ */
+|      LTYPE7 cond imsr ',' spreg comma
+       {
+               outcode($1, $2, &$3, $5, &nullgen);
+       }
+/*
+ * MOVM
+ */
+|      LTYPE8 cond ioreg ',' '[' reglist ']'
+       {
+               Addr g;
+
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = $6;
+               outcode($1, $2, &$3, NREG, &g);
+       }
+|      LTYPE8 cond '[' reglist ']' ',' ioreg
+       {
+               Addr g;
+
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = $4;
+               outcode($1, $2, &g, NREG, &$7);
+       }
+/*
+ * SWAP
+ */
+|      LTYPE9 cond reg ',' ireg ',' reg
+       {
+               outcode($1, $2, &$5, $3.reg, &$7);
+       }
+|      LTYPE9 cond reg ',' ireg comma
+       {
+               outcode($1, $2, &$5, $3.reg, &$3);
+       }
+|      LTYPE9 cond comma ireg ',' reg
+       {
+               outcode($1, $2, &$4, $6.reg, &$6);
+       }
+/*
+ * RET
+ */
+|      LTYPEA cond comma
+       {
+               outcode($1, $2, &nullgen, NREG, &nullgen);
+       }
+/*
+ * TEXT/GLOBL
+ */
+|      LTYPEB name ',' imm
+       {
+               settext($2.sym);
+               $4.type = D_CONST2;
+               $4.offset2 = ArgsSizeUnknown;
+               outcode($1, Always, &$2, 0, &$4);
+       }
+|      LTYPEB name ',' con ',' imm
+       {
+               settext($2.sym);
+               $6.type = D_CONST2;
+               $6.offset2 = ArgsSizeUnknown;
+               outcode($1, Always, &$2, $4, &$6);
+       }
+|      LTYPEB name ',' con ',' imm '-' con
+       {
+               settext($2.sym);
+               $6.type = D_CONST2;
+               $6.offset2 = $8;
+               outcode($1, Always, &$2, $4, &$6);
+       }
+/*
+ * DATA
+ */
+|      LTYPEC name '/' con ',' ximm
+       {
+               outcode($1, Always, &$2, $4, &$6);
+       }
+/*
+ * CASE
+ */
+|      LTYPED cond reg comma
+       {
+               outcode($1, $2, &$3, NREG, &nullgen);
+       }
+/*
+ * word
+ */
+|      LTYPEH comma ximm
+       {
+               outcode($1, Always, &nullgen, NREG, &$3);
+       }
+/*
+ * floating-point coprocessor
+ */
+|      LTYPEI cond freg ',' freg
+       {
+               outcode($1, $2, &$3, NREG, &$5);
+       }
+|      LTYPEK cond frcon ',' freg
+       {
+               outcode($1, $2, &$3, NREG, &$5);
+       }
+|      LTYPEK cond frcon ',' LFREG ',' freg
+       {
+               outcode($1, $2, &$3, $5, &$7);
+       }
+|      LTYPEL cond freg ',' freg comma
+       {
+               outcode($1, $2, &$3, $5.reg, &nullgen);
+       }
+/*
+ * MCR MRC
+ */
+|      LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
+       {
+               Addr g;
+
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset =
+                       (0xe << 24) |           /* opcode */
+                       ($1 << 20) |            /* MCR/MRC */
+                       ($2 << 28) |            /* scond */
+                       (($3 & 15) << 8) |      /* coprocessor number */
+                       (($5 & 7) << 21) |      /* coprocessor operation */
+                       (($7 & 15) << 12) |     /* arm register */
+                       (($9 & 15) << 16) |     /* Crn */
+                       (($11 & 15) << 0) |     /* Crm */
+                       (($12 & 7) << 5) |      /* coprocessor information */
+                       (1<<4);                 /* must be set */
+               outcode(AMRC, Always, &nullgen, NREG, &g);
+       }
+/*
+ * MULL r1,r2,(hi,lo)
+ */
+|      LTYPEM cond reg ',' reg ',' regreg
+       {
+               outcode($1, $2, &$3, $5.reg, &$7);
+       }
+/*
+ * 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);
+       }
+/*
+ * PLD
+ */
+|      LTYPEPLD oreg
+       {
+               outcode($1, Always, &$2, NREG, &nullgen);
+       }
+/*
+ * PCDATA
+ */
+|      LTYPEPC gen ',' gen
+       {
+               if($2.type != D_CONST || $4.type != D_CONST)
+                       yyerror("arguments to PCDATA must be integer constants");
+               outcode($1, Always, &$2, NREG, &$4);
+       }
+/*
+ * FUNCDATA
+ */
+|      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");
+               outcode($1, Always, &$2, NREG, &$4);
+       }
+/*
+ * END
+ */
+|      LTYPEE comma
+       {
+               outcode($1, Always, &nullgen, NREG, &nullgen);
+       }
+
+cond:
+       {
+               $$ = Always;
+       }
+|      cond LCOND
+       {
+               $$ = ($1 & ~C_SCOND) | $2;
+       }
+|      cond LS
+       {
+               $$ = $1 | $2;
+       }
+
+comma:
+|      ',' comma
+
+rel:
+       con '(' LPC ')'
+       {
+               $$ = nullgen;
+               $$.type = D_BRANCH;
+               $$.offset = $1 + pc;
+       }
+|      LNAME offset
+       {
+               $1 = labellookup($1);
+               $$ = nullgen;
+               if(pass == 2 && $1->type != LLAB)
+                       yyerror("undefined label: %s", $1->labelname);
+               $$.type = D_BRANCH;
+               $$.offset = $1->value + $2;
+       }
+
+ximm:  '$' con
+       {
+               $$ = nullgen;
+               $$.type = D_CONST;
+               $$.offset = $2;
+       }
+|      '$' oreg
+       {
+               $$ = $2;
+               $$.type = D_CONST;
+       }
+|      '$' '*' '$' oreg
+       {
+               $$ = $4;
+               $$.type = D_OCONST;
+       }
+|      '$' LSCONST
+       {
+               $$ = nullgen;
+               $$.type = D_SCONST;
+               memcpy($$.u.sval, $2, sizeof($$.u.sval));
+       }
+|      fcon
+
+fcon:
+       '$' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = $2;
+       }
+|      '$' '-' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = -$3;
+       }
+
+reglist:
+       spreg
+       {
+               $$ = 1 << $1;
+       }
+|      spreg '-' spreg
+       {
+               int i;
+               $$=0;
+               for(i=$1; i<=$3; i++)
+                       $$ |= 1<<i;
+               for(i=$3; i<=$1; i++)
+                       $$ |= 1<<i;
+       }
+|      spreg comma reglist
+       {
+               $$ = (1<<$1) | $3;
+       }
+
+gen:
+       reg
+|      ximm
+|      shift
+|      shift '(' spreg ')'
+       {
+               $$ = $1;
+               $$.reg = $3;
+       }
+|      LPSR
+       {
+               $$ = nullgen;
+               $$.type = D_PSR;
+               $$.reg = $1;
+       }
+|      LFCR
+       {
+               $$ = nullgen;
+               $$.type = D_FPCR;
+               $$.reg = $1;
+       }
+|      con
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.offset = $1;
+       }
+|      oreg
+|      freg
+
+nireg:
+       ireg
+|      name
+       {
+               $$ = $1;
+               if($1.name != D_EXTERN && $1.name != D_STATIC) {
+               }
+       }
+
+ireg:
+       '(' spreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.reg = $2;
+               $$.offset = 0;
+       }
+
+ioreg:
+       ireg
+|      con '(' sreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.reg = $3;
+               $$.offset = $1;
+       }
+
+oreg:
+       name
+|      name '(' sreg ')'
+       {
+               $$ = $1;
+               $$.type = D_OREG;
+               $$.reg = $3;
+       }
+|      ioreg
+
+imsr:
+       reg
+|      imm
+|      shift
+
+imm:   '$' con
+       {
+               $$ = nullgen;
+               $$.type = D_CONST;
+               $$.offset = $2;
+       }
+
+reg:
+       spreg
+       {
+               $$ = nullgen;
+               $$.type = D_REG;
+               $$.reg = $1;
+       }
+
+regreg:
+       '(' spreg ',' spreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_REGREG;
+               $$.reg = $2;
+               $$.offset = $4;
+       }
+
+shift:
+       spreg '<' '<' rcon
+       {
+               $$ = nullgen;
+               $$.type = D_SHIFT;
+               $$.offset = $1 | $4 | (0 << 5);
+       }
+|      spreg '>' '>' rcon
+       {
+               $$ = nullgen;
+               $$.type = D_SHIFT;
+               $$.offset = $1 | $4 | (1 << 5);
+       }
+|      spreg '-' '>' rcon
+       {
+               $$ = nullgen;
+               $$.type = D_SHIFT;
+               $$.offset = $1 | $4 | (2 << 5);
+       }
+|      spreg LAT '>' rcon
+       {
+               $$ = nullgen;
+               $$.type = D_SHIFT;
+               $$.offset = $1 | $4 | (3 << 5);
+       }
+
+rcon:
+       spreg
+       {
+               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");
+               $$ = ($1&31) << 7;
+       }
+
+sreg:
+       LREG
+|      LPC
+       {
+               $$ = REGPC;
+       }
+|      LR '(' expr ')'
+       {
+               if($3 < 0 || $3 >= NREG)
+                       print("register value out of range\n");
+               $$ = $3;
+       }
+
+spreg:
+       sreg
+|      LSP
+       {
+               $$ = REGSP;
+       }
+
+creg:
+       LCREG
+|      LC '(' expr ')'
+       {
+               if($3 < 0 || $3 >= NREG)
+                       print("register value out of range\n");
+               $$ = $3;
+       }
+
+frcon:
+       freg
+|      fcon
+
+freg:
+       LFREG
+       {
+               $$ = nullgen;
+               $$.type = D_FREG;
+               $$.reg = $1;
+       }
+|      LF '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FREG;
+               $$.reg = $3;
+       }
+
+name:
+       con '(' pointer ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = $3;
+               $$.sym = nil;
+               $$.offset = $1;
+       }
+|      LNAME offset '(' pointer ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = $4;
+               $$.sym = linklookup(ctxt, $1->name, 0);
+               $$.offset = $2;
+       }
+|      LNAME '<' '>' offset '(' LSB ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = D_STATIC;
+               $$.sym = linklookup(ctxt, $1->name, 1);
+               $$.offset = $4;
+       }
+
+offset:
+       {
+               $$ = 0;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+
+pointer:
+       LSB
+|      LSP
+|      LFP
+
+con:
+       LCONST
+|      LVAR
+       {
+               $$ = $1->value;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '~' con
+       {
+               $$ = ~$2;
+       }
+|      '(' expr ')'
+       {
+               $$ = $2;
+       }
+
+oexpr:
+       {
+               $$ = 0;
+       }
+|      ',' expr
+       {
+               $$ = $2;
+       }
+
+expr:
+       con
+|      expr '+' expr
+       {
+               $$ = $1 + $3;
+       }
+|      expr '-' expr
+       {
+               $$ = $1 - $3;
+       }
+|      expr '*' expr
+       {
+               $$ = $1 * $3;
+       }
+|      expr '/' expr
+       {
+               $$ = $1 / $3;
+       }
+|      expr '%' expr
+       {
+               $$ = $1 % $3;
+       }
+|      expr '<' '<' expr
+       {
+               $$ = $1 << $4;
+       }
+|      expr '>' '>' expr
+       {
+               $$ = $1 >> $4;
+       }
+|      expr '&' expr
+       {
+               $$ = $1 & $3;
+       }
+|      expr '^' expr
+       {
+               $$ = $1 ^ $3;
+       }
+|      expr '|' expr
+       {
+               $$ = $1 | $3;
+       }
diff --git a/src/cmd/new5a/lex.go b/src/cmd/new5a/lex.go
new file mode 100644 (file)
index 0000000..17255d0
--- /dev/null
@@ -0,0 +1,491 @@
+// Inferno utils/5a/lex.c
+// http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.c
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package main
+
+const (
+       Plan9   = 1 << 0
+       Unix    = 1 << 1
+       Windows = 1 << 2
+)
+
+func systemtype(sys int) int {
+       return sys & Windows
+
+       return sys & Plan9
+}
+
+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{}
+       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)
+
+       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")
+               asm.Errorexit()
+       }
+
+       if assemble(argv[0]) != 0 {
+               asm.Errorexit()
+       }
+       obj.Bflush(&Bstdout)
+       if Nerrors > 0 {
+               asm.Errorexit()
+       }
+       main.Exits("")
+}
+
+func assemble(file string) int {
+       var ofile string
+       var p string
+       var i int
+       var of int
+
+       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
+}
+
+var itab = []struct {
+       name  string
+       type_ uint16
+       value uint16
+}{
+       {"SP", LSP, arm.D_AUTO},
+       {"SB", LSB, arm.D_EXTERN},
+       {"FP", LFP, arm.D_PARAM},
+       {"PC", LPC, arm.D_BRANCH},
+       {"R", LR, 0},
+       {"R0", LREG, 0},
+       {"R1", LREG, 1},
+       {"R2", LREG, 2},
+       {"R3", LREG, 3},
+       {"R4", LREG, 4},
+       {"R5", LREG, 5},
+       {"R6", LREG, 6},
+       {"R7", LREG, 7},
+       {"R8", LREG, 8},
+       {"R9", LREG, 9},
+       {"g", LREG, 10}, // avoid unintentionally clobber g using R10
+       {"R11", LREG, 11},
+       {"R12", LREG, 12},
+       {"R13", LREG, 13},
+       {"R14", LREG, 14},
+       {"R15", LREG, 15},
+       {"F", LF, 0},
+       {"F0", LFREG, 0},
+       {"F1", LFREG, 1},
+       {"F2", LFREG, 2},
+       {"F3", LFREG, 3},
+       {"F4", LFREG, 4},
+       {"F5", LFREG, 5},
+       {"F6", LFREG, 6},
+       {"F7", LFREG, 7},
+       {"F8", LFREG, 8},
+       {"F9", LFREG, 9},
+       {"F10", LFREG, 10},
+       {"F11", LFREG, 11},
+       {"F12", LFREG, 12},
+       {"F13", LFREG, 13},
+       {"F14", LFREG, 14},
+       {"F15", LFREG, 15},
+       {"C", LC, 0},
+       {"C0", LCREG, 0},
+       {"C1", LCREG, 1},
+       {"C2", LCREG, 2},
+       {"C3", LCREG, 3},
+       {"C4", LCREG, 4},
+       {"C5", LCREG, 5},
+       {"C6", LCREG, 6},
+       {"C7", LCREG, 7},
+       {"C8", LCREG, 8},
+       {"C9", LCREG, 9},
+       {"C10", LCREG, 10},
+       {"C11", LCREG, 11},
+       {"C12", LCREG, 12},
+       {"C13", LCREG, 13},
+       {"C14", LCREG, 14},
+       {"C15", LCREG, 15},
+       {"CPSR", LPSR, 0},
+       {"SPSR", LPSR, 1},
+       {"FPSR", LFCR, 0},
+       {"FPCR", LFCR, 1},
+       {".EQ", LCOND, 0},
+       {".NE", LCOND, 1},
+       {".CS", LCOND, 2},
+       {".HS", LCOND, 2},
+       {".CC", LCOND, 3},
+       {".LO", LCOND, 3},
+       {".MI", LCOND, 4},
+       {".PL", LCOND, 5},
+       {".VS", LCOND, 6},
+       {".VC", LCOND, 7},
+       {".HI", LCOND, 8},
+       {".LS", LCOND, 9},
+       {".GE", LCOND, 10},
+       {".LT", LCOND, 11},
+       {".GT", LCOND, 12},
+       {".LE", LCOND, 13},
+       {".AL", LCOND, Always},
+       {".U", LS, arm.C_UBIT},
+       {".S", LS, arm.C_SBIT},
+       {".W", LS, arm.C_WBIT},
+       {".P", LS, arm.C_PBIT},
+       {".PW", LS, arm.C_WBIT | arm.C_PBIT},
+       {".WP", LS, arm.C_WBIT | arm.C_PBIT},
+       {".F", LS, arm.C_FBIT},
+       {".IBW", LS, arm.C_WBIT | arm.C_PBIT | arm.C_UBIT},
+       {".IAW", LS, arm.C_WBIT | arm.C_UBIT},
+       {".DBW", LS, arm.C_WBIT | arm.C_PBIT},
+       {".DAW", LS, arm.C_WBIT},
+       {".IB", LS, arm.C_PBIT | arm.C_UBIT},
+       {".IA", LS, arm.C_UBIT},
+       {".DB", LS, arm.C_PBIT},
+       {".DA", LS, 0},
+       {"@", LAT, 0},
+       {"AND", LTYPE1, arm.AAND},
+       {"EOR", LTYPE1, arm.AEOR},
+       {"SUB", LTYPE1, arm.ASUB},
+       {"RSB", LTYPE1, arm.ARSB},
+       {"ADD", LTYPE1, arm.AADD},
+       {"ADC", LTYPE1, arm.AADC},
+       {"SBC", LTYPE1, arm.ASBC},
+       {"RSC", LTYPE1, arm.ARSC},
+       {"ORR", LTYPE1, arm.AORR},
+       {"BIC", LTYPE1, arm.ABIC},
+       {"SLL", LTYPE1, arm.ASLL},
+       {"SRL", LTYPE1, arm.ASRL},
+       {"SRA", LTYPE1, arm.ASRA},
+       {"MUL", LTYPE1, arm.AMUL},
+       {"MULA", LTYPEN, arm.AMULA},
+       {"DIV", LTYPE1, arm.ADIV},
+       {"MOD", LTYPE1, arm.AMOD},
+       {"MULL", LTYPEM, arm.AMULL},
+       {"MULAL", LTYPEM, arm.AMULAL},
+       {"MULLU", LTYPEM, arm.AMULLU},
+       {"MULALU", LTYPEM, arm.AMULALU},
+       {"MVN", LTYPE2, arm.AMVN}, /* op2 ignored */
+       {"MOVB", LTYPE3, arm.AMOVB},
+       {"MOVBU", LTYPE3, arm.AMOVBU},
+       {"MOVH", LTYPE3, arm.AMOVH},
+       {"MOVHU", LTYPE3, arm.AMOVHU},
+       {"MOVW", LTYPE3, arm.AMOVW},
+       {"MOVD", LTYPE3, arm.AMOVD},
+       {"MOVDF", LTYPE3, arm.AMOVDF},
+       {"MOVDW", LTYPE3, arm.AMOVDW},
+       {"MOVF", LTYPE3, arm.AMOVF},
+       {"MOVFD", LTYPE3, arm.AMOVFD},
+       {"MOVFW", LTYPE3, arm.AMOVFW},
+       {"MOVWD", LTYPE3, arm.AMOVWD},
+       {"MOVWF", LTYPE3, arm.AMOVWF},
+       {"LDREX", LTYPE3, arm.ALDREX},
+       {"LDREXD", LTYPE3, arm.ALDREXD},
+       {"STREX", LTYPE9, arm.ASTREX},
+       {"STREXD", LTYPE9, arm.ASTREXD},
+
+       /*
+               {"NEGF",                LTYPEI, ANEGF},
+               {"NEGD",                LTYPEI, ANEGD},
+               {"SQTF",                LTYPEI, ASQTF},
+               {"SQTD",                LTYPEI, ASQTD},
+               {"RNDF",                LTYPEI, ARNDF},
+               {"RNDD",                LTYPEI, ARNDD},
+               {"URDF",                LTYPEI, AURDF},
+               {"URDD",                LTYPEI, AURDD},
+               {"NRMF",                LTYPEI, ANRMF},
+               {"NRMD",                LTYPEI, ANRMD},
+       */
+       {"ABSF", LTYPEI, arm.AABSF},
+       {"ABSD", LTYPEI, arm.AABSD},
+       {"SQRTF", LTYPEI, arm.ASQRTF},
+       {"SQRTD", LTYPEI, arm.ASQRTD},
+       {"CMPF", LTYPEL, arm.ACMPF},
+       {"CMPD", LTYPEL, arm.ACMPD},
+       {"ADDF", LTYPEK, arm.AADDF},
+       {"ADDD", LTYPEK, arm.AADDD},
+       {"SUBF", LTYPEK, arm.ASUBF},
+       {"SUBD", LTYPEK, arm.ASUBD},
+       {"MULF", LTYPEK, arm.AMULF},
+       {"MULD", LTYPEK, arm.AMULD},
+       {"DIVF", LTYPEK, arm.ADIVF},
+       {"DIVD", LTYPEK, arm.ADIVD},
+       {"B", LTYPE4, arm.AB},
+       {"BL", LTYPE4, arm.ABL},
+       {"BX", LTYPEBX, arm.ABX},
+       {"BEQ", LTYPE5, arm.ABEQ},
+       {"BNE", LTYPE5, arm.ABNE},
+       {"BCS", LTYPE5, arm.ABCS},
+       {"BHS", LTYPE5, arm.ABHS},
+       {"BCC", LTYPE5, arm.ABCC},
+       {"BLO", LTYPE5, arm.ABLO},
+       {"BMI", LTYPE5, arm.ABMI},
+       {"BPL", LTYPE5, arm.ABPL},
+       {"BVS", LTYPE5, arm.ABVS},
+       {"BVC", LTYPE5, arm.ABVC},
+       {"BHI", LTYPE5, arm.ABHI},
+       {"BLS", LTYPE5, arm.ABLS},
+       {"BGE", LTYPE5, arm.ABGE},
+       {"BLT", LTYPE5, arm.ABLT},
+       {"BGT", LTYPE5, arm.ABGT},
+       {"BLE", LTYPE5, arm.ABLE},
+       {"BCASE", LTYPE5, arm.ABCASE},
+       {"SWI", LTYPE6, arm.ASWI},
+       {"CMP", LTYPE7, arm.ACMP},
+       {"TST", LTYPE7, arm.ATST},
+       {"TEQ", LTYPE7, arm.ATEQ},
+       {"CMN", LTYPE7, arm.ACMN},
+       {"MOVM", LTYPE8, arm.AMOVM},
+       {"SWPBU", LTYPE9, arm.ASWPBU},
+       {"SWPW", LTYPE9, arm.ASWPW},
+       {"RET", LTYPEA, arm.ARET},
+       {"RFE", LTYPEA, arm.ARFE},
+       {"TEXT", LTYPEB, arm.ATEXT},
+       {"GLOBL", LTYPEB, arm.AGLOBL},
+       {"DATA", LTYPEC, arm.ADATA},
+       {"CASE", LTYPED, arm.ACASE},
+       {"END", LTYPEE, arm.AEND},
+       {"WORD", LTYPEH, arm.AWORD},
+       {"NOP", LTYPEI, arm.ANOP},
+       {"MCR", LTYPEJ, 0},
+       {"MRC", LTYPEJ, 1},
+       {"PLD", LTYPEPLD, arm.APLD},
+       {"UNDEF", LTYPEE, arm.AUNDEF},
+       {"CLZ", LTYPE2, arm.ACLZ},
+       {"MULWT", LTYPE1, arm.AMULWT},
+       {"MULWB", LTYPE1, arm.AMULWB},
+       {"MULAWT", LTYPEN, arm.AMULAWT},
+       {"MULAWB", LTYPEN, arm.AMULAWB},
+       {"USEFIELD", LTYPEN, arm.AUSEFIELD},
+       {"PCDATA", LTYPEPC, arm.APCDATA},
+       {"FUNCDATA", LTYPEF, arm.AFUNCDATA},
+}
+
+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)
+       }
+}
+
+func Syminit(s *Sym) {
+       s.Type_ = LNAME
+       s.Value = 0
+}
+
+func isreg(g *obj.Addr) int {
+       return 1
+}
+
+func cclean() {
+       outcode(arm.AEND, Always, &Nullgen, arm.NREG, &Nullgen)
+}
+
+var bcode = []int{
+       arm.ABEQ,
+       arm.ABNE,
+       arm.ABCS,
+       arm.ABCC,
+       arm.ABMI,
+       arm.ABPL,
+       arm.ABVS,
+       arm.ABVC,
+       arm.ABHI,
+       arm.ABLS,
+       arm.ABGE,
+       arm.ABLT,
+       arm.ABGT,
+       arm.ABLE,
+       arm.AB,
+       arm.ANOP,
+}
+
+var lastpc *obj.Prog
+
+func outcode(a int, scond int, g1 *obj.Addr, reg int, 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
+       }
+
+       if pass == 1 {
+               goto out
+       }
+
+       p = new(obj.Prog)
+       *p = obj.Prog{}
+       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)
+
+       if lastpc == nil {
+               pl = obj.Linknewplist(Ctxt)
+               pl.Firstpc = p
+       } else {
+
+               lastpc.Link = p
+       }
+       lastpc = p
+
+out:
+       if a != arm.AGLOBL && a != arm.ADATA {
+               Pc++
+       }
+}
diff --git a/src/cmd/new6a/a.y b/src/cmd/new6a/a.y
new file mode 100644 (file)
index 0000000..29011c7
--- /dev/null
@@ -0,0 +1,684 @@
+// Inferno utils/6a/a.y
+// http://code.google.com/p/inferno-os/source/browse/utils/6a/a.y
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// 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"
+%}
+%union {
+       Sym     *sym;
+       vlong   lval;
+       double  dval;
+       char    sval[8];
+       Addr    addr;
+       Addr2   addr2;
+}
+%left  '|'
+%left  '^'
+%left  '&'
+%left  '<' '>'
+%left  '+' '-'
+%left  '*' '/' '%'
+%token <lval>  LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
+%token <lval>  LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG LTYPEPC
+%token <lval>  LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT LTYPEF
+%token <lval>  LCONST LFP LPC LSB
+%token <lval>  LBREG LLREG LSREG LFREG LMREG LXREG
+%token <dval>  LFCONST
+%token <sval>  LSCONST LSP
+%token <sym>   LNAME LLAB LVAR
+%type  <lval>  con con2 expr pointer offset
+%type  <addr>  mem imm imm2 reg nam rel rem rim rom omem nmem
+%type  <addr2> nonnon nonrel nonrem rimnon rimrem remrim
+%type  <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
+%type  <addr2> spec10 spec11 spec12 spec13
+%%
+prog:
+|      prog 
+       {
+               stmtline = 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;
+       }
+       line
+|      ';'
+|      inst ';'
+|      error ';'
+
+inst:
+       LNAME '=' expr
+       {
+               $1->type = LVAR;
+               $1->value = $3;
+       }
+|      LVAR '=' expr
+       {
+               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); }
+
+nonnon:
+       {
+               $$.from = nullgen;
+               $$.to = nullgen;
+       }
+|      ','
+       {
+               $$.from = nullgen;
+               $$.to = nullgen;
+       }
+
+rimrem:
+       rim ',' rem
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+remrim:
+       rem ',' rim
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+rimnon:
+       rim ','
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+|      rim
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+
+nonrem:
+       ',' rem
+       {
+               $$.from = nullgen;
+               $$.to = $2;
+       }
+|      rem
+       {
+               $$.from = nullgen;
+               $$.to = $1;
+       }
+
+nonrel:
+       ',' rel
+       {
+               $$.from = nullgen;
+               $$.to = $2;
+       }
+|      rel
+       {
+               $$.from = nullgen;
+               $$.to = $1;
+       }
+|      imm ',' rel
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+spec1: /* DATA */
+       nam '/' con ',' imm
+       {
+               $$.from = $1;
+               $$.from.scale = $3;
+               $$.to = $5;
+       }
+
+spec2: /* TEXT */
+       mem ',' imm2
+       {
+               settext($1.sym);
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      mem ',' con ',' imm2
+       {
+               settext($1.sym);
+               $$.from = $1;
+               $$.from.scale = $3;
+               $$.to = $5;
+       }
+
+spec3: /* JMP/CALL */
+       ',' rom
+       {
+               $$.from = nullgen;
+               $$.to = $2;
+       }
+|      rom
+       {
+               $$.from = nullgen;
+               $$.to = $1;
+       }
+
+spec4: /* NOP */
+       nonnon
+|      nonrem
+
+spec5: /* SHL/SHR */
+       rim ',' rem
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      rim ',' rem ':' LLREG
+       {
+               $$.from = $1;
+               $$.to = $3;
+               if($$.from.index != D_NONE)
+                       yyerror("dp shift with lhs index");
+               $$.from.index = $5;
+       }
+
+spec6: /* MOVW/MOVL */
+       rim ',' rem
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      rim ',' rem ':' LSREG
+       {
+               $$.from = $1;
+               $$.to = $3;
+               if($$.to.index != D_NONE)
+                       yyerror("dp move with lhs index");
+               $$.to.index = $5;
+       }
+
+spec7:
+       rim ','
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+|      rim
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+|      rim ',' rem
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+spec8: /* CMPPS/CMPPD */
+       reg ',' rem ',' con
+       {
+               $$.from = $1;
+               $$.to = $3;
+               $$.to.offset = $5;
+       }
+
+spec9: /* shufl */
+       imm ',' rem ',' reg
+       {
+               $$.from = $3;
+               $$.to = $5;
+               if($1.type != D_CONST)
+                       yyerror("illegal constant");
+               $$.to.offset = $1.offset;
+       }
+
+spec10:        /* RET/RETF */
+       {
+               $$.from = nullgen;
+               $$.to = nullgen;
+       }
+|      imm
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+
+spec11:        /* GLOBL */
+       mem ',' imm
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      mem ',' con ',' imm
+       {
+               $$.from = $1;
+               $$.from.scale = $3;
+               $$.to = $5;
+       }
+
+spec12:        /* PCDATA */
+       rim ',' rim
+       {
+               if($1.type != D_CONST || $3.type != D_CONST)
+                       yyerror("arguments to PCDATA must be integer constants");
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+spec13:        /* FUNCDATA */
+       rim ',' rim
+       {
+               if($1.type != D_CONST)
+                       yyerror("index for FUNCDATA must be integer constant");
+               if($3.type != D_EXTERN && $3.type != D_STATIC)
+                       yyerror("value for FUNCDATA must be symbol reference");
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+rem:
+       reg
+|      mem
+
+rom:
+       rel
+|      nmem
+|      '*' reg
+       {
+               $$ = $2;
+       }
+|      '*' omem
+       {
+               $$ = $2;
+       }
+|      reg
+|      omem
+
+rim:
+       rem
+|      imm
+
+rel:
+       con '(' LPC ')'
+       {
+               $$ = nullgen;
+               $$.type = D_BRANCH;
+               $$.offset = $1 + pc;
+       }
+|      LNAME offset
+       {
+               $1 = labellookup($1);
+               $$ = nullgen;
+               if(pass == 2 && $1->type != LLAB)
+                       yyerror("undefined label: %s", $1->labelname);
+               $$.type = D_BRANCH;
+               $$.offset = $1->value + $2;
+       }
+
+reg:
+       LBREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LFREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LLREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LMREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LSP
+       {
+               $$ = nullgen;
+               $$.type = D_SP;
+       }
+|      LSREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LXREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+imm2:
+       '$' con2
+       {
+               $$ = nullgen;
+               $$.type = D_CONST;
+               $$.offset = $2;
+       }
+
+imm:
+       '$' con
+       {
+               $$ = nullgen;
+               $$.type = D_CONST;
+               $$.offset = $2;
+       }
+|      '$' nam
+       {
+               $$ = $2;
+               $$.index = $2.type;
+               $$.type = D_ADDR;
+               /*
+               if($2.type == D_AUTO || $2.type == D_PARAM)
+                       yyerror("constant cannot be automatic: %s",
+                               $2.sym->name);
+                */
+       }
+|      '$' LSCONST
+       {
+               $$ = nullgen;
+               $$.type = D_SCONST;
+               memcpy($$.u.sval, $2, sizeof($$.u.sval));
+       }
+|      '$' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = $2;
+       }
+|      '$' '(' LFCONST ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = $3;
+       }
+|      '$' '(' '-' LFCONST ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = -$4;
+       }
+|      '$' '-' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = -$3;
+       }
+
+mem:
+       omem
+|      nmem
+
+omem:
+       con
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_NONE;
+               $$.offset = $1;
+       }
+|      con '(' LLREG ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+       }
+|      con '(' LSP ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_SP;
+               $$.offset = $1;
+       }
+|      con '(' LSREG ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+       }
+|      con '(' LLREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_NONE;
+               $$.offset = $1;
+               $$.index = $3;
+               $$.scale = $5;
+               checkscale($$.scale);
+       }
+|      con '(' LLREG ')' '(' LLREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+               $$.index = $6;
+               $$.scale = $8;
+               checkscale($$.scale);
+       }
+|      con '(' LLREG ')' '(' LSREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+               $$.index = $6;
+               $$.scale = $8;
+               checkscale($$.scale);
+       }
+|      '(' LLREG ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$2;
+       }
+|      '(' LSP ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_SP;
+       }
+|      '(' LLREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_NONE;
+               $$.index = $2;
+               $$.scale = $4;
+               checkscale($$.scale);
+       }
+|      '(' LLREG ')' '(' LLREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$2;
+               $$.index = $5;
+               $$.scale = $7;
+               checkscale($$.scale);
+       }
+
+nmem:
+       nam
+       {
+               $$ = $1;
+       }
+|      nam '(' LLREG '*' con ')'
+       {
+               $$ = $1;
+               $$.index = $3;
+               $$.scale = $5;
+               checkscale($$.scale);
+       }
+
+nam:
+       LNAME offset '(' pointer ')'
+       {
+               $$ = nullgen;
+               $$.type = $4;
+               $$.sym = linklookup(ctxt, $1->name, 0);
+               $$.offset = $2;
+       }
+|      LNAME '<' '>' offset '(' LSB ')'
+       {
+               $$ = nullgen;
+               $$.type = D_STATIC;
+               $$.sym = linklookup(ctxt, $1->name, 1);
+               $$.offset = $4;
+       }
+
+offset:
+       {
+               $$ = 0;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+
+pointer:
+       LSB
+|      LSP
+       {
+               $$ = D_AUTO;
+       }
+|      LFP
+
+con:
+       LCONST
+|      LVAR
+       {
+               $$ = $1->value;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '~' con
+       {
+               $$ = ~$2;
+       }
+|      '(' expr ')'
+       {
+               $$ = $2;
+       }
+
+con2:
+       LCONST
+       {
+               $$ = ($1 & 0xffffffffLL) +
+                       ((vlong)ArgsSizeUnknown << 32);
+       }
+|      '-' LCONST
+       {
+               $$ = (-$2 & 0xffffffffLL) +
+                       ((vlong)ArgsSizeUnknown << 32);
+       }
+|      LCONST '-' LCONST
+       {
+               $$ = ($1 & 0xffffffffLL) +
+                       (($3 & 0xffffLL) << 32);
+       }
+|      '-' LCONST '-' LCONST
+       {
+               $$ = (-$2 & 0xffffffffLL) +
+                       (($4 & 0xffffLL) << 32);
+       }
+
+expr:
+       con
+|      expr '+' expr
+       {
+               $$ = $1 + $3;
+       }
+|      expr '-' expr
+       {
+               $$ = $1 - $3;
+       }
+|      expr '*' expr
+       {
+               $$ = $1 * $3;
+       }
+|      expr '/' expr
+       {
+               $$ = $1 / $3;
+       }
+|      expr '%' expr
+       {
+               $$ = $1 % $3;
+       }
+|      expr '<' '<' expr
+       {
+               $$ = $1 << $4;
+       }
+|      expr '>' '>' expr
+       {
+               $$ = $1 >> $4;
+       }
+|      expr '&' expr
+       {
+               $$ = $1 & $3;
+       }
+|      expr '^' expr
+       {
+               $$ = $1 ^ $3;
+       }
+|      expr '|' expr
+       {
+               $$ = $1 | $3;
+       }
diff --git a/src/cmd/new6a/lex.go b/src/cmd/new6a/lex.go
new file mode 100644 (file)
index 0000000..264c119
--- /dev/null
@@ -0,0 +1,1102 @@
+// Inferno utils/6a/lex.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6a/lex.c
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package main
+
+const (
+       Plan9   = 1 << 0
+       Unix    = 1 << 1
+       Windows = 1 << 2
+)
+
+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++
+}
+
+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{}
+       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)
+
+       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()
+       }
+
+       if assemble(argv[0]) != 0 {
+               errorexit()
+       }
+       obj.Bflush(&bstdout)
+       if nerrors > 0 {
+               errorexit()
+       }
+       main.Exits("")
+}
+
+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()
+       }
+
+       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
+}
+
+var itab = []struct {
+       name  string
+       type_ uint16
+       value uint16
+}{
+       {"SP", LSP, x86.D_AUTO},
+       {"SB", LSB, x86.D_EXTERN},
+       {"FP", LFP, x86.D_PARAM},
+       {"PC", LPC, x86.D_BRANCH},
+       {"AL", LBREG, x86.D_AL},
+       {"CL", LBREG, x86.D_CL},
+       {"DL", LBREG, x86.D_DL},
+       {"BL", LBREG, x86.D_BL},
+       /*      "SPB",          LBREG,  D_SPB,  */
+       {"SIB", LBREG, x86.D_SIB},
+       {"DIB", LBREG, x86.D_DIB},
+       {"BPB", LBREG, x86.D_BPB},
+       {"R8B", LBREG, x86.D_R8B},
+       {"R9B", LBREG, x86.D_R9B},
+       {"R10B", LBREG, x86.D_R10B},
+       {"R11B", LBREG, x86.D_R11B},
+       {"R12B", LBREG, x86.D_R12B},
+       {"R13B", LBREG, x86.D_R13B},
+       {"R14B", LBREG, x86.D_R14B},
+       {"R15B", LBREG, x86.D_R15B},
+       {"AH", LBREG, x86.D_AH},
+       {"CH", LBREG, x86.D_CH},
+       {"DH", LBREG, x86.D_DH},
+       {"BH", LBREG, x86.D_BH},
+       {"AX", LLREG, x86.D_AX},
+       {"CX", LLREG, x86.D_CX},
+       {"DX", LLREG, x86.D_DX},
+       {"BX", LLREG, x86.D_BX},
+
+       /*      "SP",           LLREG,  D_SP,   */
+       {"BP", LLREG, x86.D_BP},
+       {"SI", LLREG, x86.D_SI},
+       {"DI", LLREG, x86.D_DI},
+       {"R8", LLREG, x86.D_R8},
+       {"R9", LLREG, x86.D_R9},
+       {"R10", LLREG, x86.D_R10},
+       {"R11", LLREG, x86.D_R11},
+       {"R12", LLREG, x86.D_R12},
+       {"R13", LLREG, x86.D_R13},
+       {"R14", LLREG, x86.D_R14},
+       {"R15", LLREG, x86.D_R15},
+       {"RARG", LLREG, x86.REGARG},
+       {"F0", LFREG, x86.D_F0 + 0},
+       {"F1", LFREG, x86.D_F0 + 1},
+       {"F2", LFREG, x86.D_F0 + 2},
+       {"F3", LFREG, x86.D_F0 + 3},
+       {"F4", LFREG, x86.D_F0 + 4},
+       {"F5", LFREG, x86.D_F0 + 5},
+       {"F6", LFREG, x86.D_F0 + 6},
+       {"F7", LFREG, x86.D_F0 + 7},
+       {"M0", LMREG, x86.D_M0 + 0},
+       {"M1", LMREG, x86.D_M0 + 1},
+       {"M2", LMREG, x86.D_M0 + 2},
+       {"M3", LMREG, x86.D_M0 + 3},
+       {"M4", LMREG, x86.D_M0 + 4},
+       {"M5", LMREG, x86.D_M0 + 5},
+       {"M6", LMREG, x86.D_M0 + 6},
+       {"M7", LMREG, x86.D_M0 + 7},
+       {"X0", LXREG, x86.D_X0 + 0},
+       {"X1", LXREG, x86.D_X0 + 1},
+       {"X2", LXREG, x86.D_X0 + 2},
+       {"X3", LXREG, x86.D_X0 + 3},
+       {"X4", LXREG, x86.D_X0 + 4},
+       {"X5", LXREG, x86.D_X0 + 5},
+       {"X6", LXREG, x86.D_X0 + 6},
+       {"X7", LXREG, x86.D_X0 + 7},
+       {"X8", LXREG, x86.D_X0 + 8},
+       {"X9", LXREG, x86.D_X0 + 9},
+       {"X10", LXREG, x86.D_X0 + 10},
+       {"X11", LXREG, x86.D_X0 + 11},
+       {"X12", LXREG, x86.D_X0 + 12},
+       {"X13", LXREG, x86.D_X0 + 13},
+       {"X14", LXREG, x86.D_X0 + 14},
+       {"X15", LXREG, x86.D_X0 + 15},
+       {"CS", LSREG, x86.D_CS},
+       {"SS", LSREG, x86.D_SS},
+       {"DS", LSREG, x86.D_DS},
+       {"ES", LSREG, x86.D_ES},
+       {"FS", LSREG, x86.D_FS},
+       {"GS", LSREG, x86.D_GS},
+       {"GDTR", LBREG, x86.D_GDTR},
+       {"IDTR", LBREG, x86.D_IDTR},
+       {"LDTR", LBREG, x86.D_LDTR},
+       {"MSW", LBREG, x86.D_MSW},
+       {"TASK", LBREG, x86.D_TASK},
+       {"CR0", LBREG, x86.D_CR + 0},
+       {"CR1", LBREG, x86.D_CR + 1},
+       {"CR2", LBREG, x86.D_CR + 2},
+       {"CR3", LBREG, x86.D_CR + 3},
+       {"CR4", LBREG, x86.D_CR + 4},
+       {"CR5", LBREG, x86.D_CR + 5},
+       {"CR6", LBREG, x86.D_CR + 6},
+       {"CR7", LBREG, x86.D_CR + 7},
+       {"CR8", LBREG, x86.D_CR + 8},
+       {"CR9", LBREG, x86.D_CR + 9},
+       {"CR10", LBREG, x86.D_CR + 10},
+       {"CR11", LBREG, x86.D_CR + 11},
+       {"CR12", LBREG, x86.D_CR + 12},
+       {"CR13", LBREG, x86.D_CR + 13},
+       {"CR14", LBREG, x86.D_CR + 14},
+       {"CR15", LBREG, x86.D_CR + 15},
+       {"DR0", LBREG, x86.D_DR + 0},
+       {"DR1", LBREG, x86.D_DR + 1},
+       {"DR2", LBREG, x86.D_DR + 2},
+       {"DR3", LBREG, x86.D_DR + 3},
+       {"DR4", LBREG, x86.D_DR + 4},
+       {"DR5", LBREG, x86.D_DR + 5},
+       {"DR6", LBREG, x86.D_DR + 6},
+       {"DR7", LBREG, x86.D_DR + 7},
+       {"TR0", LBREG, x86.D_TR + 0},
+       {"TR1", LBREG, x86.D_TR + 1},
+       {"TR2", LBREG, x86.D_TR + 2},
+       {"TR3", LBREG, x86.D_TR + 3},
+       {"TR4", LBREG, x86.D_TR + 4},
+       {"TR5", LBREG, x86.D_TR + 5},
+       {"TR6", LBREG, x86.D_TR + 6},
+       {"TR7", LBREG, x86.D_TR + 7},
+       {"TLS", LSREG, x86.D_TLS},
+       {"AAA", LTYPE0, x86.AAAA},
+       {"AAD", LTYPE0, x86.AAAD},
+       {"AAM", LTYPE0, x86.AAAM},
+       {"AAS", LTYPE0, x86.AAAS},
+       {"ADCB", LTYPE3, x86.AADCB},
+       {"ADCL", LTYPE3, x86.AADCL},
+       {"ADCQ", LTYPE3, x86.AADCQ},
+       {"ADCW", LTYPE3, x86.AADCW},
+       {"ADDB", LTYPE3, x86.AADDB},
+       {"ADDL", LTYPE3, x86.AADDL},
+       {"ADDQ", LTYPE3, x86.AADDQ},
+       {"ADDW", LTYPE3, x86.AADDW},
+       {"ADJSP", LTYPE2, x86.AADJSP},
+       {"ANDB", LTYPE3, x86.AANDB},
+       {"ANDL", LTYPE3, x86.AANDL},
+       {"ANDQ", LTYPE3, x86.AANDQ},
+       {"ANDW", LTYPE3, x86.AANDW},
+       {"ARPL", LTYPE3, x86.AARPL},
+       {"BOUNDL", LTYPE3, x86.ABOUNDL},
+       {"BOUNDW", LTYPE3, x86.ABOUNDW},
+       {"BSFL", LTYPE3, x86.ABSFL},
+       {"BSFQ", LTYPE3, x86.ABSFQ},
+       {"BSFW", LTYPE3, x86.ABSFW},
+       {"BSRL", LTYPE3, x86.ABSRL},
+       {"BSRQ", LTYPE3, x86.ABSRQ},
+       {"BSRW", LTYPE3, x86.ABSRW},
+       {"BSWAPL", LTYPE1, x86.ABSWAPL},
+       {"BSWAPQ", LTYPE1, x86.ABSWAPQ},
+       {"BTCL", LTYPE3, x86.ABTCL},
+       {"BTCQ", LTYPE3, x86.ABTCQ},
+       {"BTCW", LTYPE3, x86.ABTCW},
+       {"BTL", LTYPE3, x86.ABTL},
+       {"BTQ", LTYPE3, x86.ABTQ},
+       {"BTRL", LTYPE3, x86.ABTRL},
+       {"BTRQ", LTYPE3, x86.ABTRQ},
+       {"BTRW", LTYPE3, x86.ABTRW},
+       {"BTSL", LTYPE3, x86.ABTSL},
+       {"BTSQ", LTYPE3, x86.ABTSQ},
+       {"BTSW", LTYPE3, x86.ABTSW},
+       {"BTW", LTYPE3, x86.ABTW},
+       {"BYTE", LTYPE2, x86.ABYTE},
+       {"CALL", LTYPEC, x86.ACALL},
+       {"CLC", LTYPE0, x86.ACLC},
+       {"CLD", LTYPE0, x86.ACLD},
+       {"CLI", LTYPE0, x86.ACLI},
+       {"CLTS", LTYPE0, x86.ACLTS},
+       {"CMC", LTYPE0, x86.ACMC},
+       {"CMPB", LTYPE4, x86.ACMPB},
+       {"CMPL", LTYPE4, x86.ACMPL},
+       {"CMPQ", LTYPE4, x86.ACMPQ},
+       {"CMPW", LTYPE4, x86.ACMPW},
+       {"CMPSB", LTYPE0, x86.ACMPSB},
+       {"CMPSL", LTYPE0, x86.ACMPSL},
+       {"CMPSQ", LTYPE0, x86.ACMPSQ},
+       {"CMPSW", LTYPE0, x86.ACMPSW},
+       {"CMPXCHG8B", LTYPE1, x86.ACMPXCHG8B},
+       {"CMPXCHGB", LTYPE3, x86.ACMPXCHGB}, /* LTYPE3? */
+       {"CMPXCHGL", LTYPE3, x86.ACMPXCHGL},
+       {"CMPXCHGQ", LTYPE3, x86.ACMPXCHGQ},
+       {"CMPXCHGW", LTYPE3, x86.ACMPXCHGW},
+       {"CPUID", LTYPE0, x86.ACPUID},
+       {"DAA", LTYPE0, x86.ADAA},
+       {"DAS", LTYPE0, x86.ADAS},
+       {"DATA", LTYPED, x86.ADATA},
+       {"DECB", LTYPE1, x86.ADECB},
+       {"DECL", LTYPE1, x86.ADECL},
+       {"DECQ", LTYPE1, x86.ADECQ},
+       {"DECW", LTYPE1, x86.ADECW},
+       {"DIVB", LTYPE2, x86.ADIVB},
+       {"DIVL", LTYPE2, x86.ADIVL},
+       {"DIVQ", LTYPE2, x86.ADIVQ},
+       {"DIVW", LTYPE2, x86.ADIVW},
+       {"EMMS", LTYPE0, x86.AEMMS},
+       {"END", LTYPE0, x86.AEND},
+       {"ENTER", LTYPE2, x86.AENTER},
+       {"GLOBL", LTYPEG, x86.AGLOBL},
+       {"HLT", LTYPE0, x86.AHLT},
+       {"IDIVB", LTYPE2, x86.AIDIVB},
+       {"IDIVL", LTYPE2, x86.AIDIVL},
+       {"IDIVQ", LTYPE2, x86.AIDIVQ},
+       {"IDIVW", LTYPE2, x86.AIDIVW},
+       {"IMULB", LTYPEI, x86.AIMULB},
+       {"IMULL", LTYPEI, x86.AIMULL},
+       {"IMULQ", LTYPEI, x86.AIMULQ},
+       {"IMUL3Q", LTYPEX, x86.AIMUL3Q},
+       {"IMULW", LTYPEI, x86.AIMULW},
+       {"INB", LTYPE0, x86.AINB},
+       {"INL", LTYPE0, x86.AINL},
+       {"INW", LTYPE0, x86.AINW},
+       {"INCB", LTYPE1, x86.AINCB},
+       {"INCL", LTYPE1, x86.AINCL},
+       {"INCQ", LTYPE1, x86.AINCQ},
+       {"INCW", LTYPE1, x86.AINCW},
+       {"INSB", LTYPE0, x86.AINSB},
+       {"INSL", LTYPE0, x86.AINSL},
+       {"INSW", LTYPE0, x86.AINSW},
+       {"INT", LTYPE2, x86.AINT},
+       {"INTO", LTYPE0, x86.AINTO},
+       {"INVD", LTYPE0, x86.AINVD},
+       {"INVLPG", LTYPE2, x86.AINVLPG},
+       {"IRETL", LTYPE0, x86.AIRETL},
+       {"IRETQ", LTYPE0, x86.AIRETQ},
+       {"IRETW", LTYPE0, x86.AIRETW},
+       {"JOS", LTYPER, x86.AJOS},  /* overflow set (OF = 1) */
+       {"JO", LTYPER, x86.AJOS},   /* alternate */
+       {"JOC", LTYPER, x86.AJOC},  /* overflow clear (OF = 0) */
+       {"JNO", LTYPER, x86.AJOC},  /* alternate */
+       {"JCS", LTYPER, x86.AJCS},  /* carry set (CF = 1) */
+       {"JB", LTYPER, x86.AJCS},   /* alternate */
+       {"JC", LTYPER, x86.AJCS},   /* alternate */
+       {"JNAE", LTYPER, x86.AJCS}, /* alternate */
+       {"JLO", LTYPER, x86.AJCS},  /* alternate */
+       {"JCC", LTYPER, x86.AJCC},  /* carry clear (CF = 0) */
+       {"JAE", LTYPER, x86.AJCC},  /* alternate */
+       {"JNB", LTYPER, x86.AJCC},  /* alternate */
+       {"JNC", LTYPER, x86.AJCC},  /* alternate */
+       {"JHS", LTYPER, x86.AJCC},  /* alternate */
+       {"JEQ", LTYPER, x86.AJEQ},  /* equal (ZF = 1) */
+       {"JE", LTYPER, x86.AJEQ},   /* alternate */
+       {"JZ", LTYPER, x86.AJEQ},   /* alternate */
+       {"JNE", LTYPER, x86.AJNE},  /* not equal (ZF = 0) */
+       {"JNZ", LTYPER, x86.AJNE},  /* alternate */
+       {"JLS", LTYPER, x86.AJLS},  /* lower or same (unsigned) (CF = 1 || ZF = 1) */
+       {"JBE", LTYPER, x86.AJLS},  /* alternate */
+       {"JNA", LTYPER, x86.AJLS},  /* alternate */
+       {"JHI", LTYPER, x86.AJHI},  /* higher (unsigned) (CF = 0 && ZF = 0) */
+       {"JA", LTYPER, x86.AJHI},   /* alternate */
+       {"JNBE", LTYPER, x86.AJHI}, /* alternate */
+       {"JMI", LTYPER, x86.AJMI},  /* negative (minus) (SF = 1) */
+       {"JS", LTYPER, x86.AJMI},   /* alternate */
+       {"JPL", LTYPER, x86.AJPL},  /* non-negative (plus) (SF = 0) */
+       {"JNS", LTYPER, x86.AJPL},  /* alternate */
+       {"JPS", LTYPER, x86.AJPS},  /* parity set (PF = 1) */
+       {"JP", LTYPER, x86.AJPS},   /* alternate */
+       {"JPE", LTYPER, x86.AJPS},  /* alternate */
+       {"JPC", LTYPER, x86.AJPC},  /* parity clear (PF = 0) */
+       {"JNP", LTYPER, x86.AJPC},  /* alternate */
+       {"JPO", LTYPER, x86.AJPC},  /* alternate */
+       {"JLT", LTYPER, x86.AJLT},  /* less than (signed) (SF != OF) */
+       {"JL", LTYPER, x86.AJLT},   /* alternate */
+       {"JNGE", LTYPER, x86.AJLT}, /* alternate */
+       {"JGE", LTYPER, x86.AJGE},  /* greater than or equal (signed) (SF = OF) */
+       {"JNL", LTYPER, x86.AJGE},  /* alternate */
+       {"JLE", LTYPER, x86.AJLE},  /* less than or equal (signed) (ZF = 1 || SF != OF) */
+       {"JNG", LTYPER, x86.AJLE},  /* alternate */
+       {"JGT", LTYPER, x86.AJGT},  /* greater than (signed) (ZF = 0 && SF = OF) */
+       {"JG", LTYPER, x86.AJGT},   /* alternate */
+       {"JNLE", LTYPER, x86.AJGT}, /* alternate */
+       {"JCXZL", LTYPER, x86.AJCXZL},
+       {"JCXZQ", LTYPER, x86.AJCXZQ},
+       {"JMP", LTYPEC, x86.AJMP},
+       {"LAHF", LTYPE0, x86.ALAHF},
+       {"LARL", LTYPE3, x86.ALARL},
+       {"LARW", LTYPE3, x86.ALARW},
+       {"LEAL", LTYPE3, x86.ALEAL},
+       {"LEAQ", LTYPE3, x86.ALEAQ},
+       {"LEAW", LTYPE3, x86.ALEAW},
+       {"LEAVEL", LTYPE0, x86.ALEAVEL},
+       {"LEAVEQ", LTYPE0, x86.ALEAVEQ},
+       {"LEAVEW", LTYPE0, x86.ALEAVEW},
+       {"LFENCE", LTYPE0, x86.ALFENCE},
+       {"LOCK", LTYPE0, x86.ALOCK},
+       {"LODSB", LTYPE0, x86.ALODSB},
+       {"LODSL", LTYPE0, x86.ALODSL},
+       {"LODSQ", LTYPE0, x86.ALODSQ},
+       {"LODSW", LTYPE0, x86.ALODSW},
+       {"LONG", LTYPE2, x86.ALONG},
+       {"LOOP", LTYPER, x86.ALOOP},
+       {"LOOPEQ", LTYPER, x86.ALOOPEQ},
+       {"LOOPNE", LTYPER, x86.ALOOPNE},
+       {"LSLL", LTYPE3, x86.ALSLL},
+       {"LSLW", LTYPE3, x86.ALSLW},
+       {"MFENCE", LTYPE0, x86.AMFENCE},
+       {"MODE", LTYPE2, x86.AMODE},
+       {"MOVB", LTYPE3, x86.AMOVB},
+       {"MOVL", LTYPEM, x86.AMOVL},
+       {"MOVQ", LTYPEM, x86.AMOVQ},
+       {"MOVW", LTYPEM, x86.AMOVW},
+       {"MOVBLSX", LTYPE3, x86.AMOVBLSX},
+       {"MOVBLZX", LTYPE3, x86.AMOVBLZX},
+       {"MOVBQSX", LTYPE3, x86.AMOVBQSX},
+       {"MOVBQZX", LTYPE3, x86.AMOVBQZX},
+       {"MOVBWSX", LTYPE3, x86.AMOVBWSX},
+       {"MOVBWZX", LTYPE3, x86.AMOVBWZX},
+       {"MOVLQSX", LTYPE3, x86.AMOVLQSX},
+       {"MOVLQZX", LTYPE3, x86.AMOVLQZX},
+       {"MOVNTIL", LTYPE3, x86.AMOVNTIL},
+       {"MOVNTIQ", LTYPE3, x86.AMOVNTIQ},
+       {"MOVQL", LTYPE3, x86.AMOVQL},
+       {"MOVWLSX", LTYPE3, x86.AMOVWLSX},
+       {"MOVWLZX", LTYPE3, x86.AMOVWLZX},
+       {"MOVWQSX", LTYPE3, x86.AMOVWQSX},
+       {"MOVWQZX", LTYPE3, x86.AMOVWQZX},
+       {"MOVSB", LTYPE0, x86.AMOVSB},
+       {"MOVSL", LTYPE0, x86.AMOVSL},
+       {"MOVSQ", LTYPE0, x86.AMOVSQ},
+       {"MOVSW", LTYPE0, x86.AMOVSW},
+       {"MULB", LTYPE2, x86.AMULB},
+       {"MULL", LTYPE2, x86.AMULL},
+       {"MULQ", LTYPE2, x86.AMULQ},
+       {"MULW", LTYPE2, x86.AMULW},
+       {"NEGB", LTYPE1, x86.ANEGB},
+       {"NEGL", LTYPE1, x86.ANEGL},
+       {"NEGQ", LTYPE1, x86.ANEGQ},
+       {"NEGW", LTYPE1, x86.ANEGW},
+       {"NOP", LTYPEN, x86.ANOP},
+       {"NOTB", LTYPE1, x86.ANOTB},
+       {"NOTL", LTYPE1, x86.ANOTL},
+       {"NOTQ", LTYPE1, x86.ANOTQ},
+       {"NOTW", LTYPE1, x86.ANOTW},
+       {"ORB", LTYPE3, x86.AORB},
+       {"ORL", LTYPE3, x86.AORL},
+       {"ORQ", LTYPE3, x86.AORQ},
+       {"ORW", LTYPE3, x86.AORW},
+       {"OUTB", LTYPE0, x86.AOUTB},
+       {"OUTL", LTYPE0, x86.AOUTL},
+       {"OUTW", LTYPE0, x86.AOUTW},
+       {"OUTSB", LTYPE0, x86.AOUTSB},
+       {"OUTSL", LTYPE0, x86.AOUTSL},
+       {"OUTSW", LTYPE0, x86.AOUTSW},
+       {"PAUSE", LTYPEN, x86.APAUSE},
+       {"POPAL", LTYPE0, x86.APOPAL},
+       {"POPAW", LTYPE0, x86.APOPAW},
+       {"POPFL", LTYPE0, x86.APOPFL},
+       {"POPFQ", LTYPE0, x86.APOPFQ},
+       {"POPFW", LTYPE0, x86.APOPFW},
+       {"POPL", LTYPE1, x86.APOPL},
+       {"POPQ", LTYPE1, x86.APOPQ},
+       {"POPW", LTYPE1, x86.APOPW},
+       {"PUSHAL", LTYPE0, x86.APUSHAL},
+       {"PUSHAW", LTYPE0, x86.APUSHAW},
+       {"PUSHFL", LTYPE0, x86.APUSHFL},
+       {"PUSHFQ", LTYPE0, x86.APUSHFQ},
+       {"PUSHFW", LTYPE0, x86.APUSHFW},
+       {"PUSHL", LTYPE2, x86.APUSHL},
+       {"PUSHQ", LTYPE2, x86.APUSHQ},
+       {"PUSHW", LTYPE2, x86.APUSHW},
+       {"RCLB", LTYPE3, x86.ARCLB},
+       {"RCLL", LTYPE3, x86.ARCLL},
+       {"RCLQ", LTYPE3, x86.ARCLQ},
+       {"RCLW", LTYPE3, x86.ARCLW},
+       {"RCRB", LTYPE3, x86.ARCRB},
+       {"RCRL", LTYPE3, x86.ARCRL},
+       {"RCRQ", LTYPE3, x86.ARCRQ},
+       {"RCRW", LTYPE3, x86.ARCRW},
+       {"RDMSR", LTYPE0, x86.ARDMSR},
+       {"RDPMC", LTYPE0, x86.ARDPMC},
+       {"RDTSC", LTYPE0, x86.ARDTSC},
+       {"REP", LTYPE0, x86.AREP},
+       {"REPN", LTYPE0, x86.AREPN},
+       {"RET", LTYPE0, x86.ARET},
+       {"RETFL", LTYPERT, x86.ARETFL},
+       {"RETFW", LTYPERT, x86.ARETFW},
+       {"RETFQ", LTYPERT, x86.ARETFQ},
+       {"ROLB", LTYPE3, x86.AROLB},
+       {"ROLL", LTYPE3, x86.AROLL},
+       {"ROLQ", LTYPE3, x86.AROLQ},
+       {"ROLW", LTYPE3, x86.AROLW},
+       {"RORB", LTYPE3, x86.ARORB},
+       {"RORL", LTYPE3, x86.ARORL},
+       {"RORQ", LTYPE3, x86.ARORQ},
+       {"RORW", LTYPE3, x86.ARORW},
+       {"RSM", LTYPE0, x86.ARSM},
+       {"SAHF", LTYPE0, x86.ASAHF},
+       {"SALB", LTYPE3, x86.ASALB},
+       {"SALL", LTYPE3, x86.ASALL},
+       {"SALQ", LTYPE3, x86.ASALQ},
+       {"SALW", LTYPE3, x86.ASALW},
+       {"SARB", LTYPE3, x86.ASARB},
+       {"SARL", LTYPE3, x86.ASARL},
+       {"SARQ", LTYPE3, x86.ASARQ},
+       {"SARW", LTYPE3, x86.ASARW},
+       {"SBBB", LTYPE3, x86.ASBBB},
+       {"SBBL", LTYPE3, x86.ASBBL},
+       {"SBBQ", LTYPE3, x86.ASBBQ},
+       {"SBBW", LTYPE3, x86.ASBBW},
+       {"SCASB", LTYPE0, x86.ASCASB},
+       {"SCASL", LTYPE0, x86.ASCASL},
+       {"SCASQ", LTYPE0, x86.ASCASQ},
+       {"SCASW", LTYPE0, x86.ASCASW},
+       {"SETCC", LTYPE1, x86.ASETCC}, /* see JCC etc above for condition codes */
+       {"SETCS", LTYPE1, x86.ASETCS},
+       {"SETEQ", LTYPE1, x86.ASETEQ},
+       {"SETGE", LTYPE1, x86.ASETGE},
+       {"SETGT", LTYPE1, x86.ASETGT},
+       {"SETHI", LTYPE1, x86.ASETHI},
+       {"SETLE", LTYPE1, x86.ASETLE},
+       {"SETLS", LTYPE1, x86.ASETLS},
+       {"SETLT", LTYPE1, x86.ASETLT},
+       {"SETMI", LTYPE1, x86.ASETMI},
+       {"SETNE", LTYPE1, x86.ASETNE},
+       {"SETOC", LTYPE1, x86.ASETOC},
+       {"SETOS", LTYPE1, x86.ASETOS},
+       {"SETPC", LTYPE1, x86.ASETPC},
+       {"SETPL", LTYPE1, x86.ASETPL},
+       {"SETPS", LTYPE1, x86.ASETPS},
+       {"SFENCE", LTYPE0, x86.ASFENCE},
+       {"CDQ", LTYPE0, x86.ACDQ},
+       {"CWD", LTYPE0, x86.ACWD},
+       {"CQO", LTYPE0, x86.ACQO},
+       {"SHLB", LTYPE3, x86.ASHLB},
+       {"SHLL", LTYPES, x86.ASHLL},
+       {"SHLQ", LTYPES, x86.ASHLQ},
+       {"SHLW", LTYPES, x86.ASHLW},
+       {"SHRB", LTYPE3, x86.ASHRB},
+       {"SHRL", LTYPES, x86.ASHRL},
+       {"SHRQ", LTYPES, x86.ASHRQ},
+       {"SHRW", LTYPES, x86.ASHRW},
+       {"STC", LTYPE0, x86.ASTC},
+       {"STD", LTYPE0, x86.ASTD},
+       {"STI", LTYPE0, x86.ASTI},
+       {"STOSB", LTYPE0, x86.ASTOSB},
+       {"STOSL", LTYPE0, x86.ASTOSL},
+       {"STOSQ", LTYPE0, x86.ASTOSQ},
+       {"STOSW", LTYPE0, x86.ASTOSW},
+       {"SUBB", LTYPE3, x86.ASUBB},
+       {"SUBL", LTYPE3, x86.ASUBL},
+       {"SUBQ", LTYPE3, x86.ASUBQ},
+       {"SUBW", LTYPE3, x86.ASUBW},
+       {"SYSCALL", LTYPE0, x86.ASYSCALL},
+       {"SYSRET", LTYPE0, x86.ASYSRET},
+       {"SWAPGS", LTYPE0, x86.ASWAPGS},
+       {"TESTB", LTYPE3, x86.ATESTB},
+       {"TESTL", LTYPE3, x86.ATESTL},
+       {"TESTQ", LTYPE3, x86.ATESTQ},
+       {"TESTW", LTYPE3, x86.ATESTW},
+       {"TEXT", LTYPET, x86.ATEXT},
+       {"VERR", LTYPE2, x86.AVERR},
+       {"VERW", LTYPE2, x86.AVERW},
+       {"QUAD", LTYPE2, x86.AQUAD},
+       {"WAIT", LTYPE0, x86.AWAIT},
+       {"WBINVD", LTYPE0, x86.AWBINVD},
+       {"WRMSR", LTYPE0, x86.AWRMSR},
+       {"WORD", LTYPE2, x86.AWORD},
+       {"XADDB", LTYPE3, x86.AXADDB},
+       {"XADDL", LTYPE3, x86.AXADDL},
+       {"XADDQ", LTYPE3, x86.AXADDQ},
+       {"XADDW", LTYPE3, x86.AXADDW},
+       {"XCHGB", LTYPE3, x86.AXCHGB},
+       {"XCHGL", LTYPE3, x86.AXCHGL},
+       {"XCHGQ", LTYPE3, x86.AXCHGQ},
+       {"XCHGW", LTYPE3, x86.AXCHGW},
+       {"XLAT", LTYPE2, x86.AXLAT},
+       {"XORB", LTYPE3, x86.AXORB},
+       {"XORL", LTYPE3, x86.AXORL},
+       {"XORQ", LTYPE3, x86.AXORQ},
+       {"XORW", LTYPE3, x86.AXORW},
+       {"CMOVLCC", LTYPE3, x86.ACMOVLCC},
+       {"CMOVLCS", LTYPE3, x86.ACMOVLCS},
+       {"CMOVLEQ", LTYPE3, x86.ACMOVLEQ},
+       {"CMOVLGE", LTYPE3, x86.ACMOVLGE},
+       {"CMOVLGT", LTYPE3, x86.ACMOVLGT},
+       {"CMOVLHI", LTYPE3, x86.ACMOVLHI},
+       {"CMOVLLE", LTYPE3, x86.ACMOVLLE},
+       {"CMOVLLS", LTYPE3, x86.ACMOVLLS},
+       {"CMOVLLT", LTYPE3, x86.ACMOVLLT},
+       {"CMOVLMI", LTYPE3, x86.ACMOVLMI},
+       {"CMOVLNE", LTYPE3, x86.ACMOVLNE},
+       {"CMOVLOC", LTYPE3, x86.ACMOVLOC},
+       {"CMOVLOS", LTYPE3, x86.ACMOVLOS},
+       {"CMOVLPC", LTYPE3, x86.ACMOVLPC},
+       {"CMOVLPL", LTYPE3, x86.ACMOVLPL},
+       {"CMOVLPS", LTYPE3, x86.ACMOVLPS},
+       {"CMOVQCC", LTYPE3, x86.ACMOVQCC},
+       {"CMOVQCS", LTYPE3, x86.ACMOVQCS},
+       {"CMOVQEQ", LTYPE3, x86.ACMOVQEQ},
+       {"CMOVQGE", LTYPE3, x86.ACMOVQGE},
+       {"CMOVQGT", LTYPE3, x86.ACMOVQGT},
+       {"CMOVQHI", LTYPE3, x86.ACMOVQHI},
+       {"CMOVQLE", LTYPE3, x86.ACMOVQLE},
+       {"CMOVQLS", LTYPE3, x86.ACMOVQLS},
+       {"CMOVQLT", LTYPE3, x86.ACMOVQLT},
+       {"CMOVQMI", LTYPE3, x86.ACMOVQMI},
+       {"CMOVQNE", LTYPE3, x86.ACMOVQNE},
+       {"CMOVQOC", LTYPE3, x86.ACMOVQOC},
+       {"CMOVQOS", LTYPE3, x86.ACMOVQOS},
+       {"CMOVQPC", LTYPE3, x86.ACMOVQPC},
+       {"CMOVQPL", LTYPE3, x86.ACMOVQPL},
+       {"CMOVQPS", LTYPE3, x86.ACMOVQPS},
+       {"CMOVWCC", LTYPE3, x86.ACMOVWCC},
+       {"CMOVWCS", LTYPE3, x86.ACMOVWCS},
+       {"CMOVWEQ", LTYPE3, x86.ACMOVWEQ},
+       {"CMOVWGE", LTYPE3, x86.ACMOVWGE},
+       {"CMOVWGT", LTYPE3, x86.ACMOVWGT},
+       {"CMOVWHI", LTYPE3, x86.ACMOVWHI},
+       {"CMOVWLE", LTYPE3, x86.ACMOVWLE},
+       {"CMOVWLS", LTYPE3, x86.ACMOVWLS},
+       {"CMOVWLT", LTYPE3, x86.ACMOVWLT},
+       {"CMOVWMI", LTYPE3, x86.ACMOVWMI},
+       {"CMOVWNE", LTYPE3, x86.ACMOVWNE},
+       {"CMOVWOC", LTYPE3, x86.ACMOVWOC},
+       {"CMOVWOS", LTYPE3, x86.ACMOVWOS},
+       {"CMOVWPC", LTYPE3, x86.ACMOVWPC},
+       {"CMOVWPL", LTYPE3, x86.ACMOVWPL},
+       {"CMOVWPS", LTYPE3, x86.ACMOVWPS},
+       {"FMOVB", LTYPE3, x86.AFMOVB},
+       {"FMOVBP", LTYPE3, x86.AFMOVBP},
+       {"FMOVD", LTYPE3, x86.AFMOVD},
+       {"FMOVDP", LTYPE3, x86.AFMOVDP},
+       {"FMOVF", LTYPE3, x86.AFMOVF},
+       {"FMOVFP", LTYPE3, x86.AFMOVFP},
+       {"FMOVL", LTYPE3, x86.AFMOVL},
+       {"FMOVLP", LTYPE3, x86.AFMOVLP},
+       {"FMOVV", LTYPE3, x86.AFMOVV},
+       {"FMOVVP", LTYPE3, x86.AFMOVVP},
+       {"FMOVW", LTYPE3, x86.AFMOVW},
+       {"FMOVWP", LTYPE3, x86.AFMOVWP},
+       {"FMOVX", LTYPE3, x86.AFMOVX},
+       {"FMOVXP", LTYPE3, x86.AFMOVXP},
+       {"FCOMB", LTYPE3, x86.AFCOMB},
+       {"FCOMBP", LTYPE3, x86.AFCOMBP},
+       {"FCOMD", LTYPE3, x86.AFCOMD},
+       {"FCOMDP", LTYPE3, x86.AFCOMDP},
+       {"FCOMDPP", LTYPE3, x86.AFCOMDPP},
+       {"FCOMF", LTYPE3, x86.AFCOMF},
+       {"FCOMFP", LTYPE3, x86.AFCOMFP},
+       {"FCOML", LTYPE3, x86.AFCOML},
+       {"FCOMLP", LTYPE3, x86.AFCOMLP},
+       {"FCOMW", LTYPE3, x86.AFCOMW},
+       {"FCOMWP", LTYPE3, x86.AFCOMWP},
+       {"FUCOM", LTYPE3, x86.AFUCOM},
+       {"FUCOMP", LTYPE3, x86.AFUCOMP},
+       {"FUCOMPP", LTYPE3, x86.AFUCOMPP},
+       {"FADDW", LTYPE3, x86.AFADDW},
+       {"FADDL", LTYPE3, x86.AFADDL},
+       {"FADDF", LTYPE3, x86.AFADDF},
+       {"FADDD", LTYPE3, x86.AFADDD},
+       {"FADDDP", LTYPE3, x86.AFADDDP},
+       {"FSUBDP", LTYPE3, x86.AFSUBDP},
+       {"FSUBW", LTYPE3, x86.AFSUBW},
+       {"FSUBL", LTYPE3, x86.AFSUBL},
+       {"FSUBF", LTYPE3, x86.AFSUBF},
+       {"FSUBD", LTYPE3, x86.AFSUBD},
+       {"FSUBRDP", LTYPE3, x86.AFSUBRDP},
+       {"FSUBRW", LTYPE3, x86.AFSUBRW},
+       {"FSUBRL", LTYPE3, x86.AFSUBRL},
+       {"FSUBRF", LTYPE3, x86.AFSUBRF},
+       {"FSUBRD", LTYPE3, x86.AFSUBRD},
+       {"FMULDP", LTYPE3, x86.AFMULDP},
+       {"FMULW", LTYPE3, x86.AFMULW},
+       {"FMULL", LTYPE3, x86.AFMULL},
+       {"FMULF", LTYPE3, x86.AFMULF},
+       {"FMULD", LTYPE3, x86.AFMULD},
+       {"FDIVDP", LTYPE3, x86.AFDIVDP},
+       {"FDIVW", LTYPE3, x86.AFDIVW},
+       {"FDIVL", LTYPE3, x86.AFDIVL},
+       {"FDIVF", LTYPE3, x86.AFDIVF},
+       {"FDIVD", LTYPE3, x86.AFDIVD},
+       {"FDIVRDP", LTYPE3, x86.AFDIVRDP},
+       {"FDIVRW", LTYPE3, x86.AFDIVRW},
+       {"FDIVRL", LTYPE3, x86.AFDIVRL},
+       {"FDIVRF", LTYPE3, x86.AFDIVRF},
+       {"FDIVRD", LTYPE3, x86.AFDIVRD},
+       {"FXCHD", LTYPE3, x86.AFXCHD},
+       {"FFREE", LTYPE1, x86.AFFREE},
+       {"FLDCW", LTYPE2, x86.AFLDCW},
+       {"FLDENV", LTYPE1, x86.AFLDENV},
+       {"FRSTOR", LTYPE2, x86.AFRSTOR},
+       {"FSAVE", LTYPE1, x86.AFSAVE},
+       {"FSTCW", LTYPE1, x86.AFSTCW},
+       {"FSTENV", LTYPE1, x86.AFSTENV},
+       {"FSTSW", LTYPE1, x86.AFSTSW},
+       {"F2XM1", LTYPE0, x86.AF2XM1},
+       {"FABS", LTYPE0, x86.AFABS},
+       {"FCHS", LTYPE0, x86.AFCHS},
+       {"FCLEX", LTYPE0, x86.AFCLEX},
+       {"FCOS", LTYPE0, x86.AFCOS},
+       {"FDECSTP", LTYPE0, x86.AFDECSTP},
+       {"FINCSTP", LTYPE0, x86.AFINCSTP},
+       {"FINIT", LTYPE0, x86.AFINIT},
+       {"FLD1", LTYPE0, x86.AFLD1},
+       {"FLDL2E", LTYPE0, x86.AFLDL2E},
+       {"FLDL2T", LTYPE0, x86.AFLDL2T},
+       {"FLDLG2", LTYPE0, x86.AFLDLG2},
+       {"FLDLN2", LTYPE0, x86.AFLDLN2},
+       {"FLDPI", LTYPE0, x86.AFLDPI},
+       {"FLDZ", LTYPE0, x86.AFLDZ},
+       {"FNOP", LTYPE0, x86.AFNOP},
+       {"FPATAN", LTYPE0, x86.AFPATAN},
+       {"FPREM", LTYPE0, x86.AFPREM},
+       {"FPREM1", LTYPE0, x86.AFPREM1},
+       {"FPTAN", LTYPE0, x86.AFPTAN},
+       {"FRNDINT", LTYPE0, x86.AFRNDINT},
+       {"FSCALE", LTYPE0, x86.AFSCALE},
+       {"FSIN", LTYPE0, x86.AFSIN},
+       {"FSINCOS", LTYPE0, x86.AFSINCOS},
+       {"FSQRT", LTYPE0, x86.AFSQRT},
+       {"FTST", LTYPE0, x86.AFTST},
+       {"FXAM", LTYPE0, x86.AFXAM},
+       {"FXTRACT", LTYPE0, x86.AFXTRACT},
+       {"FYL2X", LTYPE0, x86.AFYL2X},
+       {"FYL2XP1", LTYPE0, x86.AFYL2XP1},
+       {"ADDPD", LTYPE3, x86.AADDPD},
+       {"ADDPS", LTYPE3, x86.AADDPS},
+       {"ADDSD", LTYPE3, x86.AADDSD},
+       {"ADDSS", LTYPE3, x86.AADDSS},
+       {"ANDNPD", LTYPE3, x86.AANDNPD},
+       {"ANDNPS", LTYPE3, x86.AANDNPS},
+       {"ANDPD", LTYPE3, x86.AANDPD},
+       {"ANDPS", LTYPE3, x86.AANDPS},
+       {"CMPPD", LTYPEXC, x86.ACMPPD},
+       {"CMPPS", LTYPEXC, x86.ACMPPS},
+       {"CMPSD", LTYPEXC, x86.ACMPSD},
+       {"CMPSS", LTYPEXC, x86.ACMPSS},
+       {"COMISD", LTYPE3, x86.ACOMISD},
+       {"COMISS", LTYPE3, x86.ACOMISS},
+       {"CVTPL2PD", LTYPE3, x86.ACVTPL2PD},
+       {"CVTPL2PS", LTYPE3, x86.ACVTPL2PS},
+       {"CVTPD2PL", LTYPE3, x86.ACVTPD2PL},
+       {"CVTPD2PS", LTYPE3, x86.ACVTPD2PS},
+       {"CVTPS2PL", LTYPE3, x86.ACVTPS2PL},
+       {"PF2IW", LTYPE3, x86.APF2IW},
+       {"PF2IL", LTYPE3, x86.APF2IL},
+       {"PF2ID", LTYPE3, x86.APF2IL}, /* syn */
+       {"PI2FL", LTYPE3, x86.API2FL},
+       {"PI2FD", LTYPE3, x86.API2FL}, /* syn */
+       {"PI2FW", LTYPE3, x86.API2FW},
+       {"CVTPS2PD", LTYPE3, x86.ACVTPS2PD},
+       {"CVTSD2SL", LTYPE3, x86.ACVTSD2SL},
+       {"CVTSD2SQ", LTYPE3, x86.ACVTSD2SQ},
+       {"CVTSD2SS", LTYPE3, x86.ACVTSD2SS},
+       {"CVTSL2SD", LTYPE3, x86.ACVTSL2SD},
+       {"CVTSQ2SD", LTYPE3, x86.ACVTSQ2SD},
+       {"CVTSL2SS", LTYPE3, x86.ACVTSL2SS},
+       {"CVTSQ2SS", LTYPE3, x86.ACVTSQ2SS},
+       {"CVTSS2SD", LTYPE3, x86.ACVTSS2SD},
+       {"CVTSS2SL", LTYPE3, x86.ACVTSS2SL},
+       {"CVTSS2SQ", LTYPE3, x86.ACVTSS2SQ},
+       {"CVTTPD2PL", LTYPE3, x86.ACVTTPD2PL},
+       {"CVTTPS2PL", LTYPE3, x86.ACVTTPS2PL},
+       {"CVTTSD2SL", LTYPE3, x86.ACVTTSD2SL},
+       {"CVTTSD2SQ", LTYPE3, x86.ACVTTSD2SQ},
+       {"CVTTSS2SL", LTYPE3, x86.ACVTTSS2SL},
+       {"CVTTSS2SQ", LTYPE3, x86.ACVTTSS2SQ},
+       {"DIVPD", LTYPE3, x86.ADIVPD},
+       {"DIVPS", LTYPE3, x86.ADIVPS},
+       {"DIVSD", LTYPE3, x86.ADIVSD},
+       {"DIVSS", LTYPE3, x86.ADIVSS},
+       {"FXRSTOR", LTYPE2, x86.AFXRSTOR},
+       {"FXRSTOR64", LTYPE2, x86.AFXRSTOR64},
+       {"FXSAVE", LTYPE1, x86.AFXSAVE},
+       {"FXSAVE64", LTYPE1, x86.AFXSAVE64},
+       {"LDMXCSR", LTYPE2, x86.ALDMXCSR},
+       {"MASKMOVOU", LTYPE3, x86.AMASKMOVOU},
+       {"MASKMOVDQU", LTYPE3, x86.AMASKMOVOU}, /* syn */
+       {"MASKMOVQ", LTYPE3, x86.AMASKMOVQ},
+       {"MAXPD", LTYPE3, x86.AMAXPD},
+       {"MAXPS", LTYPE3, x86.AMAXPS},
+       {"MAXSD", LTYPE3, x86.AMAXSD},
+       {"MAXSS", LTYPE3, x86.AMAXSS},
+       {"MINPD", LTYPE3, x86.AMINPD},
+       {"MINPS", LTYPE3, x86.AMINPS},
+       {"MINSD", LTYPE3, x86.AMINSD},
+       {"MINSS", LTYPE3, x86.AMINSS},
+       {"MOVAPD", LTYPE3, x86.AMOVAPD},
+       {"MOVAPS", LTYPE3, x86.AMOVAPS},
+       {"MOVD", LTYPE3, x86.AMOVQ},    /* syn */
+       {"MOVDQ2Q", LTYPE3, x86.AMOVQ}, /* syn */
+       {"MOVO", LTYPE3, x86.AMOVO},
+       {"MOVOA", LTYPE3, x86.AMOVO}, /* syn */
+       {"MOVOU", LTYPE3, x86.AMOVOU},
+       {"MOVHLPS", LTYPE3, x86.AMOVHLPS},
+       {"MOVHPD", LTYPE3, x86.AMOVHPD},
+       {"MOVHPS", LTYPE3, x86.AMOVHPS},
+       {"MOVLHPS", LTYPE3, x86.AMOVLHPS},
+       {"MOVLPD", LTYPE3, x86.AMOVLPD},
+       {"MOVLPS", LTYPE3, x86.AMOVLPS},
+       {"MOVMSKPD", LTYPE3, x86.AMOVMSKPD},
+       {"MOVMSKPS", LTYPE3, x86.AMOVMSKPS},
+       {"MOVNTO", LTYPE3, x86.AMOVNTO},
+       {"MOVNTDQ", LTYPE3, x86.AMOVNTO}, /* syn */
+       {"MOVNTPD", LTYPE3, x86.AMOVNTPD},
+       {"MOVNTPS", LTYPE3, x86.AMOVNTPS},
+       {"MOVNTQ", LTYPE3, x86.AMOVNTQ},
+       {"MOVQOZX", LTYPE3, x86.AMOVQOZX},
+       {"MOVSD", LTYPE3, x86.AMOVSD},
+       {"MOVSS", LTYPE3, x86.AMOVSS},
+       {"MOVUPD", LTYPE3, x86.AMOVUPD},
+       {"MOVUPS", LTYPE3, x86.AMOVUPS},
+       {"MULPD", LTYPE3, x86.AMULPD},
+       {"MULPS", LTYPE3, x86.AMULPS},
+       {"MULSD", LTYPE3, x86.AMULSD},
+       {"MULSS", LTYPE3, x86.AMULSS},
+       {"ORPD", LTYPE3, x86.AORPD},
+       {"ORPS", LTYPE3, x86.AORPS},
+       {"PACKSSLW", LTYPE3, x86.APACKSSLW},
+       {"PACKSSWB", LTYPE3, x86.APACKSSWB},
+       {"PACKUSWB", LTYPE3, x86.APACKUSWB},
+       {"PADDB", LTYPE3, x86.APADDB},
+       {"PADDL", LTYPE3, x86.APADDL},
+       {"PADDQ", LTYPE3, x86.APADDQ},
+       {"PADDSB", LTYPE3, x86.APADDSB},
+       {"PADDSW", LTYPE3, x86.APADDSW},
+       {"PADDUSB", LTYPE3, x86.APADDUSB},
+       {"PADDUSW", LTYPE3, x86.APADDUSW},
+       {"PADDW", LTYPE3, x86.APADDW},
+       {"PAND", LTYPE3, x86.APAND},
+       {"PANDB", LTYPE3, x86.APANDB},
+       {"PANDL", LTYPE3, x86.APANDL},
+       {"PANDSB", LTYPE3, x86.APANDSB},
+       {"PANDSW", LTYPE3, x86.APANDSW},
+       {"PANDUSB", LTYPE3, x86.APANDUSB},
+       {"PANDUSW", LTYPE3, x86.APANDUSW},
+       {"PANDW", LTYPE3, x86.APANDW},
+       {"PANDN", LTYPE3, x86.APANDN},
+       {"PAVGB", LTYPE3, x86.APAVGB},
+       {"PAVGW", LTYPE3, x86.APAVGW},
+       {"PCMPEQB", LTYPE3, x86.APCMPEQB},
+       {"PCMPEQL", LTYPE3, x86.APCMPEQL},
+       {"PCMPEQW", LTYPE3, x86.APCMPEQW},
+       {"PCMPGTB", LTYPE3, x86.APCMPGTB},
+       {"PCMPGTL", LTYPE3, x86.APCMPGTL},
+       {"PCMPGTW", LTYPE3, x86.APCMPGTW},
+       {"PEXTRW", LTYPEX, x86.APEXTRW},
+       {"PINSRW", LTYPEX, x86.APINSRW},
+       {"PINSRD", LTYPEX, x86.APINSRD},
+       {"PINSRQ", LTYPEX, x86.APINSRQ},
+       {"PMADDWL", LTYPE3, x86.APMADDWL},
+       {"PMAXSW", LTYPE3, x86.APMAXSW},
+       {"PMAXUB", LTYPE3, x86.APMAXUB},
+       {"PMINSW", LTYPE3, x86.APMINSW},
+       {"PMINUB", LTYPE3, x86.APMINUB},
+       {"PMOVMSKB", LTYPE3, x86.APMOVMSKB},
+       {"PMULHRW", LTYPE3, x86.APMULHRW},
+       {"PMULHUW", LTYPE3, x86.APMULHUW},
+       {"PMULHW", LTYPE3, x86.APMULHW},
+       {"PMULLW", LTYPE3, x86.APMULLW},
+       {"PMULULQ", LTYPE3, x86.APMULULQ},
+       {"POR", LTYPE3, x86.APOR},
+       {"PSADBW", LTYPE3, x86.APSADBW},
+       {"PSHUFHW", LTYPEX, x86.APSHUFHW},
+       {"PSHUFL", LTYPEX, x86.APSHUFL},
+       {"PSHUFLW", LTYPEX, x86.APSHUFLW},
+       {"PSHUFW", LTYPEX, x86.APSHUFW},
+       {"PSHUFB", LTYPEM, x86.APSHUFB},
+       {"PSLLO", LTYPE3, x86.APSLLO},
+       {"PSLLDQ", LTYPE3, x86.APSLLO}, /* syn */
+       {"PSLLL", LTYPE3, x86.APSLLL},
+       {"PSLLQ", LTYPE3, x86.APSLLQ},
+       {"PSLLW", LTYPE3, x86.APSLLW},
+       {"PSRAL", LTYPE3, x86.APSRAL},
+       {"PSRAW", LTYPE3, x86.APSRAW},
+       {"PSRLO", LTYPE3, x86.APSRLO},
+       {"PSRLDQ", LTYPE3, x86.APSRLO}, /* syn */
+       {"PSRLL", LTYPE3, x86.APSRLL},
+       {"PSRLQ", LTYPE3, x86.APSRLQ},
+       {"PSRLW", LTYPE3, x86.APSRLW},
+       {"PSUBB", LTYPE3, x86.APSUBB},
+       {"PSUBL", LTYPE3, x86.APSUBL},
+       {"PSUBQ", LTYPE3, x86.APSUBQ},
+       {"PSUBSB", LTYPE3, x86.APSUBSB},
+       {"PSUBSW", LTYPE3, x86.APSUBSW},
+       {"PSUBUSB", LTYPE3, x86.APSUBUSB},
+       {"PSUBUSW", LTYPE3, x86.APSUBUSW},
+       {"PSUBW", LTYPE3, x86.APSUBW},
+       {"PUNPCKHBW", LTYPE3, x86.APUNPCKHBW},
+       {"PUNPCKHLQ", LTYPE3, x86.APUNPCKHLQ},
+       {"PUNPCKHQDQ", LTYPE3, x86.APUNPCKHQDQ},
+       {"PUNPCKHWL", LTYPE3, x86.APUNPCKHWL},
+       {"PUNPCKLBW", LTYPE3, x86.APUNPCKLBW},
+       {"PUNPCKLLQ", LTYPE3, x86.APUNPCKLLQ},
+       {"PUNPCKLQDQ", LTYPE3, x86.APUNPCKLQDQ},
+       {"PUNPCKLWL", LTYPE3, x86.APUNPCKLWL},
+       {"PXOR", LTYPE3, x86.APXOR},
+       {"RCPPS", LTYPE3, x86.ARCPPS},
+       {"RCPSS", LTYPE3, x86.ARCPSS},
+       {"RSQRTPS", LTYPE3, x86.ARSQRTPS},
+       {"RSQRTSS", LTYPE3, x86.ARSQRTSS},
+       {"SHUFPD", LTYPEX, x86.ASHUFPD},
+       {"SHUFPS", LTYPEX, x86.ASHUFPS},
+       {"SQRTPD", LTYPE3, x86.ASQRTPD},
+       {"SQRTPS", LTYPE3, x86.ASQRTPS},
+       {"SQRTSD", LTYPE3, x86.ASQRTSD},
+       {"SQRTSS", LTYPE3, x86.ASQRTSS},
+       {"STMXCSR", LTYPE1, x86.ASTMXCSR},
+       {"SUBPD", LTYPE3, x86.ASUBPD},
+       {"SUBPS", LTYPE3, x86.ASUBPS},
+       {"SUBSD", LTYPE3, x86.ASUBSD},
+       {"SUBSS", LTYPE3, x86.ASUBSS},
+       {"UCOMISD", LTYPE3, x86.AUCOMISD},
+       {"UCOMISS", LTYPE3, x86.AUCOMISS},
+       {"UNPCKHPD", LTYPE3, x86.AUNPCKHPD},
+       {"UNPCKHPS", LTYPE3, x86.AUNPCKHPS},
+       {"UNPCKLPD", LTYPE3, x86.AUNPCKLPD},
+       {"UNPCKLPS", LTYPE3, x86.AUNPCKLPS},
+       {"XORPD", LTYPE3, x86.AXORPD},
+       {"XORPS", LTYPE3, x86.AXORPS},
+       {"CRC32B", LTYPE4, x86.ACRC32B},
+       {"CRC32Q", LTYPE4, x86.ACRC32Q},
+       {"PREFETCHT0", LTYPE2, x86.APREFETCHT0},
+       {"PREFETCHT1", LTYPE2, x86.APREFETCHT1},
+       {"PREFETCHT2", LTYPE2, x86.APREFETCHT2},
+       {"PREFETCHNTA", LTYPE2, x86.APREFETCHNTA},
+       {"UNDEF", LTYPE0, x86.AUNDEF},
+       {"AESENC", LTYPE3, x86.AAESENC},
+       {"AESENCLAST", LTYPE3, x86.AAESENCLAST},
+       {"AESDEC", LTYPE3, x86.AAESDEC},
+       {"AESDECLAST", LTYPE3, x86.AAESDECLAST},
+       {"AESIMC", LTYPE3, x86.AAESIMC},
+       {"AESKEYGENASSIST", LTYPEX, x86.AAESKEYGENASSIST},
+       {"PSHUFD", LTYPEX, x86.APSHUFD},
+       {"USEFIELD", LTYPEN, x86.AUSEFIELD},
+       {"PCLMULQDQ", LTYPEX, x86.APCLMULQDQ},
+       {"PCDATA", LTYPEPC, x86.APCDATA},
+       {"FUNCDATA", LTYPEF, x86.AFUNCDATA},
+}
+
+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) {
+       switch scale {
+       case 1,
+               2,
+               4,
+               8:
+               return
+       }
+
+       yyerror("scale must be 1248: %d", scale)
+}
+
+func syminit(s *Sym) {
+       s.type_ = LNAME
+       s.value = 0
+}
+
+func cclean() {
+       var g2 Addr2
+
+       g2.from = nullgen
+       g2.to = nullgen
+       outcode(x86.AEND, &g2)
+}
+
+var lastpc *obj.Prog
+
+func outcode(a int, g2 *Addr2) {
+       var p *obj.Prog
+       var pl *obj.Plist
+
+       if pass == 1 {
+               goto out
+       }
+
+       p = new(obj.Prog)
+       *p = obj.Prog{}
+       p.As = int16(a)
+       p.Lineno = stmtline
+       p.From = g2.from
+       p.To = g2.to
+       p.Pc = int64(pc)
+
+       if lastpc == nil {
+               pl = obj.Linknewplist(ctxt)
+               pl.Firstpc = p
+       } else {
+
+               lastpc.Link = p
+       }
+       lastpc = p
+
+out:
+       if a != x86.AGLOBL && a != x86.ADATA {
+               pc++
+       }
+}
diff --git a/src/cmd/new8a/a.y b/src/cmd/new8a/a.y
new file mode 100644 (file)
index 0000000..c810d38
--- /dev/null
@@ -0,0 +1,680 @@
+// Inferno utils/8a/a.y
+// http://code.google.com/p/inferno-os/source/browse/utils/8a/a.y
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// 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"
+%}
+%union {
+       Sym     *sym;
+       int32   lval;
+       struct {
+               int32 v1;
+               int32 v2;
+       } con2;
+       double  dval;
+       char    sval[8];
+       Addr    addr;
+       Addr2   addr2;
+}
+%left  '|'
+%left  '^'
+%left  '&'
+%left  '<' '>'
+%left  '+' '-'
+%left  '*' '/' '%'
+%token <lval>  LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
+%token <lval>  LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC
+%token <lval>  LTYPEX LTYPEPC LTYPEF LCONST LFP LPC LSB
+%token <lval>  LBREG LLREG LSREG LFREG LXREG
+%token <dval>  LFCONST
+%token <sval>  LSCONST LSP
+%token <sym>   LNAME LLAB LVAR
+%type  <lval>  con expr pointer offset
+%type  <con2>  con2
+%type  <addr>  mem imm imm2 reg nam rel rem rim rom omem nmem
+%type  <addr2> nonnon nonrel nonrem rimnon rimrem remrim
+%type  <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
+%%
+prog:
+|      prog
+       {
+               stmtline = 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;
+       }
+       line
+|      ';'
+|      inst ';'
+|      error ';'
+
+inst:
+       LNAME '=' expr
+       {
+               $1->type = LVAR;
+               $1->value = $3;
+       }
+|      LVAR '=' expr
+       {
+               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); }
+|      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); }
+
+nonnon:
+       {
+               $$.from = nullgen;
+               $$.to = nullgen;
+       }
+|      ','
+       {
+               $$.from = nullgen;
+               $$.to = nullgen;
+       }
+
+rimrem:
+       rim ',' rem
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+remrim:
+       rem ',' rim
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+rimnon:
+       rim ','
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+|      rim
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+
+nonrem:
+       ',' rem
+       {
+               $$.from = nullgen;
+               $$.to = $2;
+       }
+|      rem
+       {
+               $$.from = nullgen;
+               $$.to = $1;
+       }
+
+nonrel:
+       ',' rel
+       {
+               $$.from = nullgen;
+               $$.to = $2;
+       }
+|      rel
+       {
+               $$.from = nullgen;
+               $$.to = $1;
+       }
+|      imm ',' rel
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+spec1: /* DATA */
+       nam '/' con ',' imm
+       {
+               $$.from = $1;
+               $$.from.scale = $3;
+               $$.to = $5;
+       }
+
+spec2: /* TEXT */
+       mem ',' imm2
+       {
+               settext($1.sym);
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      mem ',' con ',' imm2
+       {
+               settext($1.sym);
+               $$.from = $1;
+               $$.from.scale = $3;
+               $$.to = $5;
+       }
+
+spec3: /* JMP/CALL */
+       ',' rom
+       {
+               $$.from = nullgen;
+               $$.to = $2;
+       }
+|      rom
+       {
+               $$.from = nullgen;
+               $$.to = $1;
+       }
+|      '*' nam
+       {
+               $$.from = nullgen;
+               $$.to = $2;
+               $$.to.index = $2.type;
+               $$.to.type = D_INDIR+D_ADDR;
+       }
+
+spec4: /* NOP */
+       nonnon
+|      nonrem
+
+spec5: /* SHL/SHR */
+       rim ',' rem
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      rim ',' rem ':' LLREG
+       {
+               $$.from = $1;
+               $$.to = $3;
+               if($$.from.index != D_NONE)
+                       yyerror("dp shift with lhs index");
+               $$.from.index = $5;
+       }
+
+spec6: /* MOVW/MOVL */
+       rim ',' rem
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      rim ',' rem ':' LSREG
+       {
+               $$.from = $1;
+               $$.to = $3;
+               if($$.to.index != D_NONE)
+                       yyerror("dp move with lhs index");
+               $$.to.index = $5;
+       }
+
+spec7:
+       rim ','
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+|      rim
+       {
+               $$.from = $1;
+               $$.to = nullgen;
+       }
+|      rim ',' rem
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+spec8: /* GLOBL */
+       mem ',' imm
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      mem ',' con ',' imm
+       {
+               $$.from = $1;
+               $$.from.scale = $3;
+               $$.to = $5;
+       }
+
+spec9: /* CMPPS/CMPPD */
+       reg ',' rem ',' con
+       {
+               $$.from = $1;
+               $$.to = $3;
+               $$.to.offset = $5;
+       }
+
+spec10:        /* PINSRD */
+       imm ',' rem ',' reg
+       {
+               $$.from = $3;
+               $$.to = $5;
+               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)
+                       yyerror("arguments to PCDATA must be integer constants");
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+spec12:        /* FUNCDATA */
+       rim ',' rim
+       {
+               if($1.type != D_CONST)
+                       yyerror("index for FUNCDATA must be integer constant");
+               if($3.type != D_EXTERN && $3.type != D_STATIC)
+                       yyerror("value for FUNCDATA must be symbol reference");
+               $$.from = $1;
+               $$.to = $3;
+       }
+
+rem:
+       reg
+|      mem
+
+rom:
+       rel
+|      nmem
+|      '*' reg
+       {
+               $$ = $2;
+       }
+|      '*' omem
+       {
+               $$ = $2;
+       }
+|      reg
+|      omem
+|      imm
+
+rim:
+       rem
+|      imm
+
+rel:
+       con '(' LPC ')'
+       {
+               $$ = nullgen;
+               $$.type = D_BRANCH;
+               $$.offset = $1 + pc;
+       }
+|      LNAME offset
+       {
+               $1 = labellookup($1);
+               $$ = nullgen;
+               if(pass == 2 && $1->type != LLAB)
+                       yyerror("undefined label: %s", $1->labelname);
+               $$.type = D_BRANCH;
+               $$.offset = $1->value + $2;
+       }
+
+reg:
+       LBREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LFREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LLREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LXREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+|      LSP
+       {
+               $$ = nullgen;
+               $$.type = D_SP;
+       }
+|      LSREG
+       {
+               $$ = nullgen;
+               $$.type = $1;
+       }
+
+imm:
+       '$' con
+       {
+               $$ = nullgen;
+               $$.type = D_CONST;
+               $$.offset = $2;
+       }
+|      '$' nam
+       {
+               $$ = $2;
+               $$.index = $2.type;
+               $$.type = D_ADDR;
+               /*
+               if($2.type == D_AUTO || $2.type == D_PARAM)
+                       yyerror("constant cannot be automatic: %s",
+                               $2.sym->name);
+                */
+       }
+|      '$' LSCONST
+       {
+               $$ = nullgen;
+               $$.type = D_SCONST;
+               memcpy($$.u.sval, $2, sizeof($$.u.sval));
+       }
+|      '$' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = $2;
+       }
+|      '$' '(' LFCONST ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = $3;
+       }
+|      '$' '(' '-' LFCONST ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = -$4;
+       }
+|      '$' '-' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = -$3;
+       }
+
+imm2:
+       '$' con2
+       {
+               $$ = nullgen;
+               $$.type = D_CONST2;
+               $$.offset = $2.v1;
+               $$.offset2 = $2.v2;
+       }
+
+con2:
+       LCONST
+       {
+               $$.v1 = $1;
+               $$.v2 = ArgsSizeUnknown;
+       }
+|      '-' LCONST
+       {
+               $$.v1 = -$2;
+               $$.v2 = ArgsSizeUnknown;
+       }
+|      LCONST '-' LCONST
+       {
+               $$.v1 = $1;
+               $$.v2 = $3;
+       }
+|      '-' LCONST '-' LCONST
+       {
+               $$.v1 = -$2;
+               $$.v2 = $4;
+       }
+
+mem:
+       omem
+|      nmem
+
+omem:
+       con
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_NONE;
+               $$.offset = $1;
+       }
+|      con '(' LLREG ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+       }
+|      con '(' LSP ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_SP;
+               $$.offset = $1;
+       }
+|      con '(' LLREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_NONE;
+               $$.offset = $1;
+               $$.index = $3;
+               $$.scale = $5;
+               checkscale($$.scale);
+       }
+|      con '(' LLREG ')' '(' LLREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+               $$.index = $6;
+               $$.scale = $8;
+               checkscale($$.scale);
+       }
+|      con '(' LLREG ')' '(' LSREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+               $$.index = $6;
+               $$.scale = $8;
+               checkscale($$.scale);
+       }
+|      '(' LLREG ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$2;
+       }
+|      '(' LSP ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_SP;
+       }
+|      con '(' LSREG ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+       }
+|      '(' LLREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+D_NONE;
+               $$.index = $2;
+               $$.scale = $4;
+               checkscale($$.scale);
+       }
+|      '(' LLREG ')' '(' LLREG '*' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$2;
+               $$.index = $5;
+               $$.scale = $7;
+               checkscale($$.scale);
+       }
+
+nmem:
+       nam
+       {
+               $$ = $1;
+       }
+|      nam '(' LLREG '*' con ')'
+       {
+               $$ = $1;
+               $$.index = $3;
+               $$.scale = $5;
+               checkscale($$.scale);
+       }
+
+nam:
+       LNAME offset '(' pointer ')'
+       {
+               $$ = nullgen;
+               $$.type = $4;
+               $$.sym = linklookup(ctxt, $1->name, 0);
+               $$.offset = $2;
+       }
+|      LNAME '<' '>' offset '(' LSB ')'
+       {
+               $$ = nullgen;
+               $$.type = D_STATIC;
+               $$.sym = linklookup(ctxt, $1->name, 1);
+               $$.offset = $4;
+       }
+
+offset:
+       {
+               $$ = 0;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+
+pointer:
+       LSB
+|      LSP
+       {
+               $$ = D_AUTO;
+       }
+|      LFP
+
+con:
+       LCONST
+|      LVAR
+       {
+               $$ = $1->value;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '~' con
+       {
+               $$ = ~$2;
+       }
+|      '(' expr ')'
+       {
+               $$ = $2;
+       }
+
+expr:
+       con
+|      expr '+' expr
+       {
+               $$ = $1 + $3;
+       }
+|      expr '-' expr
+       {
+               $$ = $1 - $3;
+       }
+|      expr '*' expr
+       {
+               $$ = $1 * $3;
+       }
+|      expr '/' expr
+       {
+               $$ = $1 / $3;
+       }
+|      expr '%' expr
+       {
+               $$ = $1 % $3;
+       }
+|      expr '<' '<' expr
+       {
+               $$ = $1 << $4;
+       }
+|      expr '>' '>' expr
+       {
+               $$ = $1 >> $4;
+       }
+|      expr '&' expr
+       {
+               $$ = $1 & $3;
+       }
+|      expr '^' expr
+       {
+               $$ = $1 ^ $3;
+       }
+|      expr '|' expr
+       {
+               $$ = $1 | $3;
+       }
diff --git a/src/cmd/new8a/lex.go b/src/cmd/new8a/lex.go
new file mode 100644 (file)
index 0000000..f9ea92a
--- /dev/null
@@ -0,0 +1,887 @@
+// Inferno utils/8a/lex.c
+// http://code.google.com/p/inferno-os/source/browse/utils/8a/lex.c
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package main
+
+const (
+       Plan9   = 1 << 0
+       Unix    = 1 << 1
+       Windows = 1 << 2
+)
+
+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)
+       }
+
+       ensuresymb(NSYMB)
+       debug = [256]int{}
+       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)
+
+       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()
+       }
+
+       if assemble(argv[0]) != 0 {
+               errorexit()
+       }
+       obj.Bflush(&bstdout)
+       if nerrors > 0 {
+               errorexit()
+       }
+       main.Exits("")
+}
+
+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()
+       }
+
+       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
+}
+
+var itab = []struct {
+       name  string
+       type_ uint16
+       value uint16
+}{
+       {"SP", LSP, i386.D_AUTO},
+       {"SB", LSB, i386.D_EXTERN},
+       {"FP", LFP, i386.D_PARAM},
+       {"PC", LPC, i386.D_BRANCH},
+       {"AL", LBREG, i386.D_AL},
+       {"CL", LBREG, i386.D_CL},
+       {"DL", LBREG, i386.D_DL},
+       {"BL", LBREG, i386.D_BL},
+       {"AH", LBREG, i386.D_AH},
+       {"CH", LBREG, i386.D_CH},
+       {"DH", LBREG, i386.D_DH},
+       {"BH", LBREG, i386.D_BH},
+       {"AX", LLREG, i386.D_AX},
+       {"CX", LLREG, i386.D_CX},
+       {"DX", LLREG, i386.D_DX},
+       {"BX", LLREG, i386.D_BX},
+       /*      "SP",           LLREG,  D_SP,   */
+       {"BP", LLREG, i386.D_BP},
+       {"SI", LLREG, i386.D_SI},
+       {"DI", LLREG, i386.D_DI},
+       {"F0", LFREG, i386.D_F0 + 0},
+       {"F1", LFREG, i386.D_F0 + 1},
+       {"F2", LFREG, i386.D_F0 + 2},
+       {"F3", LFREG, i386.D_F0 + 3},
+       {"F4", LFREG, i386.D_F0 + 4},
+       {"F5", LFREG, i386.D_F0 + 5},
+       {"F6", LFREG, i386.D_F0 + 6},
+       {"F7", LFREG, i386.D_F0 + 7},
+       {"X0", LXREG, i386.D_X0 + 0},
+       {"X1", LXREG, i386.D_X0 + 1},
+       {"X2", LXREG, i386.D_X0 + 2},
+       {"X3", LXREG, i386.D_X0 + 3},
+       {"X4", LXREG, i386.D_X0 + 4},
+       {"X5", LXREG, i386.D_X0 + 5},
+       {"X6", LXREG, i386.D_X0 + 6},
+       {"X7", LXREG, i386.D_X0 + 7},
+       {"CS", LSREG, i386.D_CS},
+       {"SS", LSREG, i386.D_SS},
+       {"DS", LSREG, i386.D_DS},
+       {"ES", LSREG, i386.D_ES},
+       {"FS", LSREG, i386.D_FS},
+       {"GS", LSREG, i386.D_GS},
+       {"TLS", LSREG, i386.D_TLS},
+       {"GDTR", LBREG, i386.D_GDTR},
+       {"IDTR", LBREG, i386.D_IDTR},
+       {"LDTR", LBREG, i386.D_LDTR},
+       {"MSW", LBREG, i386.D_MSW},
+       {"TASK", LBREG, i386.D_TASK},
+       {"CR0", LBREG, i386.D_CR + 0},
+       {"CR1", LBREG, i386.D_CR + 1},
+       {"CR2", LBREG, i386.D_CR + 2},
+       {"CR3", LBREG, i386.D_CR + 3},
+       {"CR4", LBREG, i386.D_CR + 4},
+       {"CR5", LBREG, i386.D_CR + 5},
+       {"CR6", LBREG, i386.D_CR + 6},
+       {"CR7", LBREG, i386.D_CR + 7},
+       {"DR0", LBREG, i386.D_DR + 0},
+       {"DR1", LBREG, i386.D_DR + 1},
+       {"DR2", LBREG, i386.D_DR + 2},
+       {"DR3", LBREG, i386.D_DR + 3},
+       {"DR4", LBREG, i386.D_DR + 4},
+       {"DR5", LBREG, i386.D_DR + 5},
+       {"DR6", LBREG, i386.D_DR + 6},
+       {"DR7", LBREG, i386.D_DR + 7},
+       {"TR0", LBREG, i386.D_TR + 0},
+       {"TR1", LBREG, i386.D_TR + 1},
+       {"TR2", LBREG, i386.D_TR + 2},
+       {"TR3", LBREG, i386.D_TR + 3},
+       {"TR4", LBREG, i386.D_TR + 4},
+       {"TR5", LBREG, i386.D_TR + 5},
+       {"TR6", LBREG, i386.D_TR + 6},
+       {"TR7", LBREG, i386.D_TR + 7},
+       {"AAA", LTYPE0, i386.AAAA},
+       {"AAD", LTYPE0, i386.AAAD},
+       {"AAM", LTYPE0, i386.AAAM},
+       {"AAS", LTYPE0, i386.AAAS},
+       {"ADCB", LTYPE3, i386.AADCB},
+       {"ADCL", LTYPE3, i386.AADCL},
+       {"ADCW", LTYPE3, i386.AADCW},
+       {"ADDB", LTYPE3, i386.AADDB},
+       {"ADDL", LTYPE3, i386.AADDL},
+       {"ADDW", LTYPE3, i386.AADDW},
+       {"ADJSP", LTYPE2, i386.AADJSP},
+       {"ANDB", LTYPE3, i386.AANDB},
+       {"ANDL", LTYPE3, i386.AANDL},
+       {"ANDW", LTYPE3, i386.AANDW},
+       {"ARPL", LTYPE3, i386.AARPL},
+       {"BOUNDL", LTYPE3, i386.ABOUNDL},
+       {"BOUNDW", LTYPE3, i386.ABOUNDW},
+       {"BSFL", LTYPE3, i386.ABSFL},
+       {"BSFW", LTYPE3, i386.ABSFW},
+       {"BSRL", LTYPE3, i386.ABSRL},
+       {"BSRW", LTYPE3, i386.ABSRW},
+       {"BSWAPL", LTYPE1, i386.ABSWAPL},
+       {"BTCL", LTYPE3, i386.ABTCL},
+       {"BTCW", LTYPE3, i386.ABTCW},
+       {"BTL", LTYPE3, i386.ABTL},
+       {"BTRL", LTYPE3, i386.ABTRL},
+       {"BTRW", LTYPE3, i386.ABTRW},
+       {"BTSL", LTYPE3, i386.ABTSL},
+       {"BTSW", LTYPE3, i386.ABTSW},
+       {"BTW", LTYPE3, i386.ABTW},
+       {"BYTE", LTYPE2, i386.ABYTE},
+       {"CALL", LTYPEC, i386.ACALL},
+       {"CLC", LTYPE0, i386.ACLC},
+       {"CLD", LTYPE0, i386.ACLD},
+       {"CLI", LTYPE0, i386.ACLI},
+       {"CLTS", LTYPE0, i386.ACLTS},
+       {"CMC", LTYPE0, i386.ACMC},
+       {"CMPB", LTYPE4, i386.ACMPB},
+       {"CMPL", LTYPE4, i386.ACMPL},
+       {"CMPW", LTYPE4, i386.ACMPW},
+       {"CMPSB", LTYPE0, i386.ACMPSB},
+       {"CMPSL", LTYPE0, i386.ACMPSL},
+       {"CMPSW", LTYPE0, i386.ACMPSW},
+       {"CMPXCHG8B", LTYPE1, i386.ACMPXCHG8B},
+       {"CMPXCHGB", LTYPE3, i386.ACMPXCHGB},
+       {"CMPXCHGL", LTYPE3, i386.ACMPXCHGL},
+       {"CMPXCHGW", LTYPE3, i386.ACMPXCHGW},
+       {"CPUID", LTYPE0, i386.ACPUID},
+       {"DAA", LTYPE0, i386.ADAA},
+       {"DAS", LTYPE0, i386.ADAS},
+       {"DATA", LTYPED, i386.ADATA},
+       {"DECB", LTYPE1, i386.ADECB},
+       {"DECL", LTYPE1, i386.ADECL},
+       {"DECW", LTYPE1, i386.ADECW},
+       {"DIVB", LTYPE2, i386.ADIVB},
+       {"DIVL", LTYPE2, i386.ADIVL},
+       {"DIVW", LTYPE2, i386.ADIVW},
+       {"END", LTYPE0, i386.AEND},
+       {"ENTER", LTYPE2, i386.AENTER},
+       {"GLOBL", LTYPEG, i386.AGLOBL},
+       {"HLT", LTYPE0, i386.AHLT},
+       {"IDIVB", LTYPE2, i386.AIDIVB},
+       {"IDIVL", LTYPE2, i386.AIDIVL},
+       {"IDIVW", LTYPE2, i386.AIDIVW},
+       {"IMULB", LTYPE2, i386.AIMULB},
+       {"IMULL", LTYPEI, i386.AIMULL},
+       {"IMULW", LTYPEI, i386.AIMULW},
+       {"INB", LTYPE0, i386.AINB},
+       {"INL", LTYPE0, i386.AINL},
+       {"INW", LTYPE0, i386.AINW},
+       {"INCB", LTYPE1, i386.AINCB},
+       {"INCL", LTYPE1, i386.AINCL},
+       {"INCW", LTYPE1, i386.AINCW},
+       {"INSB", LTYPE0, i386.AINSB},
+       {"INSL", LTYPE0, i386.AINSL},
+       {"INSW", LTYPE0, i386.AINSW},
+       {"INT", LTYPE2, i386.AINT},
+       {"INTO", LTYPE0, i386.AINTO},
+       {"IRETL", LTYPE0, i386.AIRETL},
+       {"IRETW", LTYPE0, i386.AIRETW},
+       {"JOS", LTYPER, i386.AJOS},  /* overflow set (OF = 1) */
+       {"JO", LTYPER, i386.AJOS},   /* alternate */
+       {"JOC", LTYPER, i386.AJOC},  /* overflow clear (OF = 0) */
+       {"JNO", LTYPER, i386.AJOC},  /* alternate */
+       {"JCS", LTYPER, i386.AJCS},  /* carry set (CF = 1) */
+       {"JB", LTYPER, i386.AJCS},   /* alternate */
+       {"JC", LTYPER, i386.AJCS},   /* alternate */
+       {"JNAE", LTYPER, i386.AJCS}, /* alternate */
+       {"JLO", LTYPER, i386.AJCS},  /* alternate */
+       {"JCC", LTYPER, i386.AJCC},  /* carry clear (CF = 0) */
+       {"JAE", LTYPER, i386.AJCC},  /* alternate */
+       {"JNB", LTYPER, i386.AJCC},  /* alternate */
+       {"JNC", LTYPER, i386.AJCC},  /* alternate */
+       {"JHS", LTYPER, i386.AJCC},  /* alternate */
+       {"JEQ", LTYPER, i386.AJEQ},  /* equal (ZF = 1) */
+       {"JE", LTYPER, i386.AJEQ},   /* alternate */
+       {"JZ", LTYPER, i386.AJEQ},   /* alternate */
+       {"JNE", LTYPER, i386.AJNE},  /* not equal (ZF = 0) */
+       {"JNZ", LTYPER, i386.AJNE},  /* alternate */
+       {"JLS", LTYPER, i386.AJLS},  /* lower or same (unsigned) (CF = 1 || ZF = 1) */
+       {"JBE", LTYPER, i386.AJLS},  /* alternate */
+       {"JNA", LTYPER, i386.AJLS},  /* alternate */
+       {"JHI", LTYPER, i386.AJHI},  /* higher (unsigned) (CF = 0 && ZF = 0) */
+       {"JA", LTYPER, i386.AJHI},   /* alternate */
+       {"JNBE", LTYPER, i386.AJHI}, /* alternate */
+       {"JMI", LTYPER, i386.AJMI},  /* negative (minus) (SF = 1) */
+       {"JS", LTYPER, i386.AJMI},   /* alternate */
+       {"JPL", LTYPER, i386.AJPL},  /* non-negative (plus) (SF = 0) */
+       {"JNS", LTYPER, i386.AJPL},  /* alternate */
+       {"JPS", LTYPER, i386.AJPS},  /* parity set (PF = 1) */
+       {"JP", LTYPER, i386.AJPS},   /* alternate */
+       {"JPE", LTYPER, i386.AJPS},  /* alternate */
+       {"JPC", LTYPER, i386.AJPC},  /* parity clear (PF = 0) */
+       {"JNP", LTYPER, i386.AJPC},  /* alternate */
+       {"JPO", LTYPER, i386.AJPC},  /* alternate */
+       {"JLT", LTYPER, i386.AJLT},  /* less than (signed) (SF != OF) */
+       {"JL", LTYPER, i386.AJLT},   /* alternate */
+       {"JNGE", LTYPER, i386.AJLT}, /* alternate */
+       {"JGE", LTYPER, i386.AJGE},  /* greater than or equal (signed) (SF = OF) */
+       {"JNL", LTYPER, i386.AJGE},  /* alternate */
+       {"JLE", LTYPER, i386.AJLE},  /* less than or equal (signed) (ZF = 1 || SF != OF) */
+       {"JNG", LTYPER, i386.AJLE},  /* alternate */
+       {"JGT", LTYPER, i386.AJGT},  /* greater than (signed) (ZF = 0 && SF = OF) */
+       {"JG", LTYPER, i386.AJGT},   /* alternate */
+       {"JNLE", LTYPER, i386.AJGT}, /* alternate */
+       {"JCXZL", LTYPER, i386.AJCXZL},
+       {"JCXZW", LTYPER, i386.AJCXZW},
+       {"JMP", LTYPEC, i386.AJMP},
+       {"LAHF", LTYPE0, i386.ALAHF},
+       {"LARL", LTYPE3, i386.ALARL},
+       {"LARW", LTYPE3, i386.ALARW},
+       {"LEAL", LTYPE3, i386.ALEAL},
+       {"LEAW", LTYPE3, i386.ALEAW},
+       {"LEAVEL", LTYPE0, i386.ALEAVEL},
+       {"LEAVEW", LTYPE0, i386.ALEAVEW},
+       {"LOCK", LTYPE0, i386.ALOCK},
+       {"LODSB", LTYPE0, i386.ALODSB},
+       {"LODSL", LTYPE0, i386.ALODSL},
+       {"LODSW", LTYPE0, i386.ALODSW},
+       {"LONG", LTYPE2, i386.ALONG},
+       {"LOOP", LTYPER, i386.ALOOP},
+       {"LOOPEQ", LTYPER, i386.ALOOPEQ},
+       {"LOOPNE", LTYPER, i386.ALOOPNE},
+       {"LSLL", LTYPE3, i386.ALSLL},
+       {"LSLW", LTYPE3, i386.ALSLW},
+       {"MOVB", LTYPE3, i386.AMOVB},
+       {"MOVL", LTYPEM, i386.AMOVL},
+       {"MOVW", LTYPEM, i386.AMOVW},
+       {"MOVQ", LTYPEM, i386.AMOVQ},
+       {"MOVBLSX", LTYPE3, i386.AMOVBLSX},
+       {"MOVBLZX", LTYPE3, i386.AMOVBLZX},
+       {"MOVBWSX", LTYPE3, i386.AMOVBWSX},
+       {"MOVBWZX", LTYPE3, i386.AMOVBWZX},
+       {"MOVWLSX", LTYPE3, i386.AMOVWLSX},
+       {"MOVWLZX", LTYPE3, i386.AMOVWLZX},
+       {"MOVSB", LTYPE0, i386.AMOVSB},
+       {"MOVSL", LTYPE0, i386.AMOVSL},
+       {"MOVSW", LTYPE0, i386.AMOVSW},
+       {"MULB", LTYPE2, i386.AMULB},
+       {"MULL", LTYPE2, i386.AMULL},
+       {"MULW", LTYPE2, i386.AMULW},
+       {"NEGB", LTYPE1, i386.ANEGB},
+       {"NEGL", LTYPE1, i386.ANEGL},
+       {"NEGW", LTYPE1, i386.ANEGW},
+       {"NOP", LTYPEN, i386.ANOP},
+       {"NOTB", LTYPE1, i386.ANOTB},
+       {"NOTL", LTYPE1, i386.ANOTL},
+       {"NOTW", LTYPE1, i386.ANOTW},
+       {"ORB", LTYPE3, i386.AORB},
+       {"ORL", LTYPE3, i386.AORL},
+       {"ORW", LTYPE3, i386.AORW},
+       {"OUTB", LTYPE0, i386.AOUTB},
+       {"OUTL", LTYPE0, i386.AOUTL},
+       {"OUTW", LTYPE0, i386.AOUTW},
+       {"OUTSB", LTYPE0, i386.AOUTSB},
+       {"OUTSL", LTYPE0, i386.AOUTSL},
+       {"OUTSW", LTYPE0, i386.AOUTSW},
+       {"PAUSE", LTYPEN, i386.APAUSE},
+       {"PINSRD", LTYPEX, i386.APINSRD},
+       {"POPAL", LTYPE0, i386.APOPAL},
+       {"POPAW", LTYPE0, i386.APOPAW},
+       {"POPFL", LTYPE0, i386.APOPFL},
+       {"POPFW", LTYPE0, i386.APOPFW},
+       {"POPL", LTYPE1, i386.APOPL},
+       {"POPW", LTYPE1, i386.APOPW},
+       {"PUSHAL", LTYPE0, i386.APUSHAL},
+       {"PUSHAW", LTYPE0, i386.APUSHAW},
+       {"PUSHFL", LTYPE0, i386.APUSHFL},
+       {"PUSHFW", LTYPE0, i386.APUSHFW},
+       {"PUSHL", LTYPE2, i386.APUSHL},
+       {"PUSHW", LTYPE2, i386.APUSHW},
+       {"RCLB", LTYPE3, i386.ARCLB},
+       {"RCLL", LTYPE3, i386.ARCLL},
+       {"RCLW", LTYPE3, i386.ARCLW},
+       {"RCRB", LTYPE3, i386.ARCRB},
+       {"RCRL", LTYPE3, i386.ARCRL},
+       {"RCRW", LTYPE3, i386.ARCRW},
+       {"RDTSC", LTYPE0, i386.ARDTSC},
+       {"REP", LTYPE0, i386.AREP},
+       {"REPN", LTYPE0, i386.AREPN},
+       {"RET", LTYPE0, i386.ARET},
+       {"ROLB", LTYPE3, i386.AROLB},
+       {"ROLL", LTYPE3, i386.AROLL},
+       {"ROLW", LTYPE3, i386.AROLW},
+       {"RORB", LTYPE3, i386.ARORB},
+       {"RORL", LTYPE3, i386.ARORL},
+       {"RORW", LTYPE3, i386.ARORW},
+       {"SAHF", LTYPE0, i386.ASAHF},
+       {"SALB", LTYPE3, i386.ASALB},
+       {"SALL", LTYPE3, i386.ASALL},
+       {"SALW", LTYPE3, i386.ASALW},
+       {"SARB", LTYPE3, i386.ASARB},
+       {"SARL", LTYPE3, i386.ASARL},
+       {"SARW", LTYPE3, i386.ASARW},
+       {"SBBB", LTYPE3, i386.ASBBB},
+       {"SBBL", LTYPE3, i386.ASBBL},
+       {"SBBW", LTYPE3, i386.ASBBW},
+       {"SCASB", LTYPE0, i386.ASCASB},
+       {"SCASL", LTYPE0, i386.ASCASL},
+       {"SCASW", LTYPE0, i386.ASCASW},
+       {"SETCC", LTYPE1, i386.ASETCC}, /* see JCC etc above for condition codes */
+       {"SETCS", LTYPE1, i386.ASETCS},
+       {"SETEQ", LTYPE1, i386.ASETEQ},
+       {"SETGE", LTYPE1, i386.ASETGE},
+       {"SETGT", LTYPE1, i386.ASETGT},
+       {"SETHI", LTYPE1, i386.ASETHI},
+       {"SETLE", LTYPE1, i386.ASETLE},
+       {"SETLS", LTYPE1, i386.ASETLS},
+       {"SETLT", LTYPE1, i386.ASETLT},
+       {"SETMI", LTYPE1, i386.ASETMI},
+       {"SETNE", LTYPE1, i386.ASETNE},
+       {"SETOC", LTYPE1, i386.ASETOC},
+       {"SETOS", LTYPE1, i386.ASETOS},
+       {"SETPC", LTYPE1, i386.ASETPC},
+       {"SETPL", LTYPE1, i386.ASETPL},
+       {"SETPS", LTYPE1, i386.ASETPS},
+       {"CDQ", LTYPE0, i386.ACDQ},
+       {"CWD", LTYPE0, i386.ACWD},
+       {"SHLB", LTYPE3, i386.ASHLB},
+       {"SHLL", LTYPES, i386.ASHLL},
+       {"SHLW", LTYPES, i386.ASHLW},
+       {"SHRB", LTYPE3, i386.ASHRB},
+       {"SHRL", LTYPES, i386.ASHRL},
+       {"SHRW", LTYPES, i386.ASHRW},
+       {"STC", LTYPE0, i386.ASTC},
+       {"STD", LTYPE0, i386.ASTD},
+       {"STI", LTYPE0, i386.ASTI},
+       {"STOSB", LTYPE0, i386.ASTOSB},
+       {"STOSL", LTYPE0, i386.ASTOSL},
+       {"STOSW", LTYPE0, i386.ASTOSW},
+       {"SUBB", LTYPE3, i386.ASUBB},
+       {"SUBL", LTYPE3, i386.ASUBL},
+       {"SUBW", LTYPE3, i386.ASUBW},
+       {"SYSCALL", LTYPE0, i386.ASYSCALL},
+       {"TESTB", LTYPE3, i386.ATESTB},
+       {"TESTL", LTYPE3, i386.ATESTL},
+       {"TESTW", LTYPE3, i386.ATESTW},
+       {"TEXT", LTYPET, i386.ATEXT},
+       {"VERR", LTYPE2, i386.AVERR},
+       {"VERW", LTYPE2, i386.AVERW},
+       {"WAIT", LTYPE0, i386.AWAIT},
+       {"WORD", LTYPE2, i386.AWORD},
+       {"XADDB", LTYPE3, i386.AXADDB},
+       {"XADDL", LTYPE3, i386.AXADDL},
+       {"XADDW", LTYPE3, i386.AXADDW},
+       {"XCHGB", LTYPE3, i386.AXCHGB},
+       {"XCHGL", LTYPE3, i386.AXCHGL},
+       {"XCHGW", LTYPE3, i386.AXCHGW},
+       {"XLAT", LTYPE2, i386.AXLAT},
+       {"XORB", LTYPE3, i386.AXORB},
+       {"XORL", LTYPE3, i386.AXORL},
+       {"XORW", LTYPE3, i386.AXORW},
+       {"CMOVLCC", LTYPE3, i386.ACMOVLCC},
+       {"CMOVLCS", LTYPE3, i386.ACMOVLCS},
+       {"CMOVLEQ", LTYPE3, i386.ACMOVLEQ},
+       {"CMOVLGE", LTYPE3, i386.ACMOVLGE},
+       {"CMOVLGT", LTYPE3, i386.ACMOVLGT},
+       {"CMOVLHI", LTYPE3, i386.ACMOVLHI},
+       {"CMOVLLE", LTYPE3, i386.ACMOVLLE},
+       {"CMOVLLS", LTYPE3, i386.ACMOVLLS},
+       {"CMOVLLT", LTYPE3, i386.ACMOVLLT},
+       {"CMOVLMI", LTYPE3, i386.ACMOVLMI},
+       {"CMOVLNE", LTYPE3, i386.ACMOVLNE},
+       {"CMOVLOC", LTYPE3, i386.ACMOVLOC},
+       {"CMOVLOS", LTYPE3, i386.ACMOVLOS},
+       {"CMOVLPC", LTYPE3, i386.ACMOVLPC},
+       {"CMOVLPL", LTYPE3, i386.ACMOVLPL},
+       {"CMOVLPS", LTYPE3, i386.ACMOVLPS},
+       {"CMOVWCC", LTYPE3, i386.ACMOVWCC},
+       {"CMOVWCS", LTYPE3, i386.ACMOVWCS},
+       {"CMOVWEQ", LTYPE3, i386.ACMOVWEQ},
+       {"CMOVWGE", LTYPE3, i386.ACMOVWGE},
+       {"CMOVWGT", LTYPE3, i386.ACMOVWGT},
+       {"CMOVWHI", LTYPE3, i386.ACMOVWHI},
+       {"CMOVWLE", LTYPE3, i386.ACMOVWLE},
+       {"CMOVWLS", LTYPE3, i386.ACMOVWLS},
+       {"CMOVWLT", LTYPE3, i386.ACMOVWLT},
+       {"CMOVWMI", LTYPE3, i386.ACMOVWMI},
+       {"CMOVWNE", LTYPE3, i386.ACMOVWNE},
+       {"CMOVWOC", LTYPE3, i386.ACMOVWOC},
+       {"CMOVWOS", LTYPE3, i386.ACMOVWOS},
+       {"CMOVWPC", LTYPE3, i386.ACMOVWPC},
+       {"CMOVWPL", LTYPE3, i386.ACMOVWPL},
+       {"CMOVWPS", LTYPE3, i386.ACMOVWPS},
+       {"FMOVB", LTYPE3, i386.AFMOVB},
+       {"FMOVBP", LTYPE3, i386.AFMOVBP},
+       {"FMOVD", LTYPE3, i386.AFMOVD},
+       {"FMOVDP", LTYPE3, i386.AFMOVDP},
+       {"FMOVF", LTYPE3, i386.AFMOVF},
+       {"FMOVFP", LTYPE3, i386.AFMOVFP},
+       {"FMOVL", LTYPE3, i386.AFMOVL},
+       {"FMOVLP", LTYPE3, i386.AFMOVLP},
+       {"FMOVV", LTYPE3, i386.AFMOVV},
+       {"FMOVVP", LTYPE3, i386.AFMOVVP},
+       {"FMOVW", LTYPE3, i386.AFMOVW},
+       {"FMOVWP", LTYPE3, i386.AFMOVWP},
+       {"FMOVX", LTYPE3, i386.AFMOVX},
+       {"FMOVXP", LTYPE3, i386.AFMOVXP},
+       {"FCMOVCC", LTYPE3, i386.AFCMOVCC},
+       {"FCMOVCS", LTYPE3, i386.AFCMOVCS},
+       {"FCMOVEQ", LTYPE3, i386.AFCMOVEQ},
+       {"FCMOVHI", LTYPE3, i386.AFCMOVHI},
+       {"FCMOVLS", LTYPE3, i386.AFCMOVLS},
+       {"FCMOVNE", LTYPE3, i386.AFCMOVNE},
+       {"FCMOVNU", LTYPE3, i386.AFCMOVNU},
+       {"FCMOVUN", LTYPE3, i386.AFCMOVUN},
+       {"FCOMB", LTYPE3, i386.AFCOMB},
+       {"FCOMBP", LTYPE3, i386.AFCOMBP},
+       {"FCOMD", LTYPE3, i386.AFCOMD},
+       {"FCOMDP", LTYPE3, i386.AFCOMDP},
+       {"FCOMDPP", LTYPE3, i386.AFCOMDPP},
+       {"FCOMF", LTYPE3, i386.AFCOMF},
+       {"FCOMFP", LTYPE3, i386.AFCOMFP},
+       {"FCOMI", LTYPE3, i386.AFCOMI},
+       {"FCOMIP", LTYPE3, i386.AFCOMIP},
+       {"FCOML", LTYPE3, i386.AFCOML},
+       {"FCOMLP", LTYPE3, i386.AFCOMLP},
+       {"FCOMW", LTYPE3, i386.AFCOMW},
+       {"FCOMWP", LTYPE3, i386.AFCOMWP},
+       {"FUCOM", LTYPE3, i386.AFUCOM},
+       {"FUCOMI", LTYPE3, i386.AFUCOMI},
+       {"FUCOMIP", LTYPE3, i386.AFUCOMIP},
+       {"FUCOMP", LTYPE3, i386.AFUCOMP},
+       {"FUCOMPP", LTYPE3, i386.AFUCOMPP},
+       {"FADDW", LTYPE3, i386.AFADDW},
+       {"FADDL", LTYPE3, i386.AFADDL},
+       {"FADDF", LTYPE3, i386.AFADDF},
+       {"FADDD", LTYPE3, i386.AFADDD},
+       {"FADDDP", LTYPE3, i386.AFADDDP},
+       {"FSUBDP", LTYPE3, i386.AFSUBDP},
+       {"FSUBW", LTYPE3, i386.AFSUBW},
+       {"FSUBL", LTYPE3, i386.AFSUBL},
+       {"FSUBF", LTYPE3, i386.AFSUBF},
+       {"FSUBD", LTYPE3, i386.AFSUBD},
+       {"FSUBRDP", LTYPE3, i386.AFSUBRDP},
+       {"FSUBRW", LTYPE3, i386.AFSUBRW},
+       {"FSUBRL", LTYPE3, i386.AFSUBRL},
+       {"FSUBRF", LTYPE3, i386.AFSUBRF},
+       {"FSUBRD", LTYPE3, i386.AFSUBRD},
+       {"FMULDP", LTYPE3, i386.AFMULDP},
+       {"FMULW", LTYPE3, i386.AFMULW},
+       {"FMULL", LTYPE3, i386.AFMULL},
+       {"FMULF", LTYPE3, i386.AFMULF},
+       {"FMULD", LTYPE3, i386.AFMULD},
+       {"FDIVDP", LTYPE3, i386.AFDIVDP},
+       {"FDIVW", LTYPE3, i386.AFDIVW},
+       {"FDIVL", LTYPE3, i386.AFDIVL},
+       {"FDIVF", LTYPE3, i386.AFDIVF},
+       {"FDIVD", LTYPE3, i386.AFDIVD},
+       {"FDIVRDP", LTYPE3, i386.AFDIVRDP},
+       {"FDIVRW", LTYPE3, i386.AFDIVRW},
+       {"FDIVRL", LTYPE3, i386.AFDIVRL},
+       {"FDIVRF", LTYPE3, i386.AFDIVRF},
+       {"FDIVRD", LTYPE3, i386.AFDIVRD},
+       {"FXCHD", LTYPE3, i386.AFXCHD},
+       {"FFREE", LTYPE1, i386.AFFREE},
+       {"FLDCW", LTYPE2, i386.AFLDCW},
+       {"FLDENV", LTYPE1, i386.AFLDENV},
+       {"FRSTOR", LTYPE2, i386.AFRSTOR},
+       {"FSAVE", LTYPE1, i386.AFSAVE},
+       {"FSTCW", LTYPE1, i386.AFSTCW},
+       {"FSTENV", LTYPE1, i386.AFSTENV},
+       {"FSTSW", LTYPE1, i386.AFSTSW},
+       {"F2XM1", LTYPE0, i386.AF2XM1},
+       {"FABS", LTYPE0, i386.AFABS},
+       {"FCHS", LTYPE0, i386.AFCHS},
+       {"FCLEX", LTYPE0, i386.AFCLEX},
+       {"FCOS", LTYPE0, i386.AFCOS},
+       {"FDECSTP", LTYPE0, i386.AFDECSTP},
+       {"FINCSTP", LTYPE0, i386.AFINCSTP},
+       {"FINIT", LTYPE0, i386.AFINIT},
+       {"FLD1", LTYPE0, i386.AFLD1},
+       {"FLDL2E", LTYPE0, i386.AFLDL2E},
+       {"FLDL2T", LTYPE0, i386.AFLDL2T},
+       {"FLDLG2", LTYPE0, i386.AFLDLG2},
+       {"FLDLN2", LTYPE0, i386.AFLDLN2},
+       {"FLDPI", LTYPE0, i386.AFLDPI},
+       {"FLDZ", LTYPE0, i386.AFLDZ},
+       {"FNOP", LTYPE0, i386.AFNOP},
+       {"FPATAN", LTYPE0, i386.AFPATAN},
+       {"FPREM", LTYPE0, i386.AFPREM},
+       {"FPREM1", LTYPE0, i386.AFPREM1},
+       {"FPTAN", LTYPE0, i386.AFPTAN},
+       {"FRNDINT", LTYPE0, i386.AFRNDINT},
+       {"FSCALE", LTYPE0, i386.AFSCALE},
+       {"FSIN", LTYPE0, i386.AFSIN},
+       {"FSINCOS", LTYPE0, i386.AFSINCOS},
+       {"FSQRT", LTYPE0, i386.AFSQRT},
+       {"FTST", LTYPE0, i386.AFTST},
+       {"FXAM", LTYPE0, i386.AFXAM},
+       {"FXTRACT", LTYPE0, i386.AFXTRACT},
+       {"FYL2X", LTYPE0, i386.AFYL2X},
+       {"FYL2XP1", LTYPE0, i386.AFYL2XP1},
+       {"LFENCE", LTYPE0, i386.ALFENCE},
+       {"MFENCE", LTYPE0, i386.AMFENCE},
+       {"SFENCE", LTYPE0, i386.ASFENCE},
+       {"EMMS", LTYPE0, i386.AEMMS},
+       {"PREFETCHT0", LTYPE2, i386.APREFETCHT0},
+       {"PREFETCHT1", LTYPE2, i386.APREFETCHT1},
+       {"PREFETCHT2", LTYPE2, i386.APREFETCHT2},
+       {"PREFETCHNTA", LTYPE2, i386.APREFETCHNTA},
+       {"UNDEF", LTYPE0, i386.AUNDEF},
+       {"ADDPD", LTYPE3, i386.AADDPD},
+       {"ADDPS", LTYPE3, i386.AADDPS},
+       {"ADDSD", LTYPE3, i386.AADDSD},
+       {"ADDSS", LTYPE3, i386.AADDSS},
+       {"AESENC", LTYPE3, i386.AAESENC},
+       {"ANDNPD", LTYPE3, i386.AANDNPD},
+       {"ANDNPS", LTYPE3, i386.AANDNPS},
+       {"ANDPD", LTYPE3, i386.AANDPD},
+       {"ANDPS", LTYPE3, i386.AANDPS},
+       {"CMPPD", LTYPEXC, i386.ACMPPD},
+       {"CMPPS", LTYPEXC, i386.ACMPPS},
+       {"CMPSD", LTYPEXC, i386.ACMPSD},
+       {"CMPSS", LTYPEXC, i386.ACMPSS},
+       {"COMISD", LTYPE3, i386.ACOMISD},
+       {"COMISS", LTYPE3, i386.ACOMISS},
+       {"CVTPL2PD", LTYPE3, i386.ACVTPL2PD},
+       {"CVTPL2PS", LTYPE3, i386.ACVTPL2PS},
+       {"CVTPD2PL", LTYPE3, i386.ACVTPD2PL},
+       {"CVTPD2PS", LTYPE3, i386.ACVTPD2PS},
+       {"CVTPS2PL", LTYPE3, i386.ACVTPS2PL},
+       {"CVTPS2PD", LTYPE3, i386.ACVTPS2PD},
+       {"CVTSD2SL", LTYPE3, i386.ACVTSD2SL},
+       {"CVTSD2SS", LTYPE3, i386.ACVTSD2SS},
+       {"CVTSL2SD", LTYPE3, i386.ACVTSL2SD},
+       {"CVTSL2SS", LTYPE3, i386.ACVTSL2SS},
+       {"CVTSS2SD", LTYPE3, i386.ACVTSS2SD},
+       {"CVTSS2SL", LTYPE3, i386.ACVTSS2SL},
+       {"CVTTPD2PL", LTYPE3, i386.ACVTTPD2PL},
+       {"CVTTPS2PL", LTYPE3, i386.ACVTTPS2PL},
+       {"CVTTSD2SL", LTYPE3, i386.ACVTTSD2SL},
+       {"CVTTSS2SL", LTYPE3, i386.ACVTTSS2SL},
+       {"DIVPD", LTYPE3, i386.ADIVPD},
+       {"DIVPS", LTYPE3, i386.ADIVPS},
+       {"DIVSD", LTYPE3, i386.ADIVSD},
+       {"DIVSS", LTYPE3, i386.ADIVSS},
+       {"MASKMOVOU", LTYPE3, i386.AMASKMOVOU},
+       {"MASKMOVDQU", LTYPE3, i386.AMASKMOVOU}, /* syn */
+       {"MAXPD", LTYPE3, i386.AMAXPD},
+       {"MAXPS", LTYPE3, i386.AMAXPS},
+       {"MAXSD", LTYPE3, i386.AMAXSD},
+       {"MAXSS", LTYPE3, i386.AMAXSS},
+       {"MINPD", LTYPE3, i386.AMINPD},
+       {"MINPS", LTYPE3, i386.AMINPS},
+       {"MINSD", LTYPE3, i386.AMINSD},
+       {"MINSS", LTYPE3, i386.AMINSS},
+       {"MOVAPD", LTYPE3, i386.AMOVAPD},
+       {"MOVAPS", LTYPE3, i386.AMOVAPS},
+       {"MOVO", LTYPE3, i386.AMOVO},
+       {"MOVOA", LTYPE3, i386.AMOVO}, /* syn */
+       {"MOVOU", LTYPE3, i386.AMOVOU},
+       {"MOVHLPS", LTYPE3, i386.AMOVHLPS},
+       {"MOVHPD", LTYPE3, i386.AMOVHPD},
+       {"MOVHPS", LTYPE3, i386.AMOVHPS},
+       {"MOVLHPS", LTYPE3, i386.AMOVLHPS},
+       {"MOVLPD", LTYPE3, i386.AMOVLPD},
+       {"MOVLPS", LTYPE3, i386.AMOVLPS},
+       {"MOVMSKPD", LTYPE3, i386.AMOVMSKPD},
+       {"MOVMSKPS", LTYPE3, i386.AMOVMSKPS},
+       {"MOVNTO", LTYPE3, i386.AMOVNTO},
+       {"MOVNTDQ", LTYPE3, i386.AMOVNTO}, /* syn */
+       {"MOVNTPD", LTYPE3, i386.AMOVNTPD},
+       {"MOVNTPS", LTYPE3, i386.AMOVNTPS},
+       {"MOVSD", LTYPE3, i386.AMOVSD},
+       {"MOVSS", LTYPE3, i386.AMOVSS},
+       {"MOVUPD", LTYPE3, i386.AMOVUPD},
+       {"MOVUPS", LTYPE3, i386.AMOVUPS},
+       {"MULPD", LTYPE3, i386.AMULPD},
+       {"MULPS", LTYPE3, i386.AMULPS},
+       {"MULSD", LTYPE3, i386.AMULSD},
+       {"MULSS", LTYPE3, i386.AMULSS},
+       {"ORPD", LTYPE3, i386.AORPD},
+       {"ORPS", LTYPE3, i386.AORPS},
+       {"PADDQ", LTYPE3, i386.APADDQ},
+       {"PAND", LTYPE3, i386.APAND},
+       {"PCMPEQB", LTYPE3, i386.APCMPEQB},
+       {"PMAXSW", LTYPE3, i386.APMAXSW},
+       {"PMAXUB", LTYPE3, i386.APMAXUB},
+       {"PMINSW", LTYPE3, i386.APMINSW},
+       {"PMINUB", LTYPE3, i386.APMINUB},
+       {"PMOVMSKB", LTYPE3, i386.APMOVMSKB},
+       {"PSADBW", LTYPE3, i386.APSADBW},
+       {"PSHUFB", LTYPE3, i386.APSHUFB},
+       {"PSHUFHW", LTYPEX, i386.APSHUFHW},
+       {"PSHUFL", LTYPEX, i386.APSHUFL},
+       {"PSHUFLW", LTYPEX, i386.APSHUFLW},
+       {"PSUBB", LTYPE3, i386.APSUBB},
+       {"PSUBL", LTYPE3, i386.APSUBL},
+       {"PSUBQ", LTYPE3, i386.APSUBQ},
+       {"PSUBSB", LTYPE3, i386.APSUBSB},
+       {"PSUBSW", LTYPE3, i386.APSUBSW},
+       {"PSUBUSB", LTYPE3, i386.APSUBUSB},
+       {"PSUBUSW", LTYPE3, i386.APSUBUSW},
+       {"PSUBW", LTYPE3, i386.APSUBW},
+       {"PUNPCKHQDQ", LTYPE3, i386.APUNPCKHQDQ},
+       {"PUNPCKLQDQ", LTYPE3, i386.APUNPCKLQDQ},
+       {"PXOR", LTYPE3, i386.APXOR},
+       {"RCPPS", LTYPE3, i386.ARCPPS},
+       {"RCPSS", LTYPE3, i386.ARCPSS},
+       {"RSQRTPS", LTYPE3, i386.ARSQRTPS},
+       {"RSQRTSS", LTYPE3, i386.ARSQRTSS},
+       {"SQRTPD", LTYPE3, i386.ASQRTPD},
+       {"SQRTPS", LTYPE3, i386.ASQRTPS},
+       {"SQRTSD", LTYPE3, i386.ASQRTSD},
+       {"SQRTSS", LTYPE3, i386.ASQRTSS},
+       {"SUBPD", LTYPE3, i386.ASUBPD},
+       {"SUBPS", LTYPE3, i386.ASUBPS},
+       {"SUBSD", LTYPE3, i386.ASUBSD},
+       {"SUBSS", LTYPE3, i386.ASUBSS},
+       {"UCOMISD", LTYPE3, i386.AUCOMISD},
+       {"UCOMISS", LTYPE3, i386.AUCOMISS},
+       {"UNPCKHPD", LTYPE3, i386.AUNPCKHPD},
+       {"UNPCKHPS", LTYPE3, i386.AUNPCKHPS},
+       {"UNPCKLPD", LTYPE3, i386.AUNPCKLPD},
+       {"UNPCKLPS", LTYPE3, i386.AUNPCKLPS},
+       {"XORPD", LTYPE3, i386.AXORPD},
+       {"XORPS", LTYPE3, i386.AXORPS},
+       {"USEFIELD", LTYPEN, i386.AUSEFIELD},
+       {"PCDATA", LTYPEPC, i386.APCDATA},
+       {"FUNCDATA", LTYPEF, i386.AFUNCDATA},
+}
+
+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) {
+       switch scale {
+       case 1,
+               2,
+               4,
+               8:
+               return
+       }
+
+       yyerror("scale must be 1248: %d", scale)
+}
+
+func syminit(s *Sym) {
+       s.type_ = LNAME
+       s.value = 0
+}
+
+func cclean() {
+       var g2 Addr2
+
+       g2.from = nullgen
+       g2.to = nullgen
+       outcode(i386.AEND, &g2)
+}
+
+var lastpc *obj.Prog
+
+func outcode(a int, g2 *Addr2) {
+       var p *obj.Prog
+       var pl *obj.Plist
+
+       if pass == 1 {
+               goto out
+       }
+
+       p = new(obj.Prog)
+       *p = obj.Prog{}
+       p.As = int16(a)
+       p.Lineno = stmtline
+       p.From = g2.from
+       p.To = g2.to
+       p.Pc = int64(pc)
+
+       if lastpc == nil {
+               pl = obj.Linknewplist(ctxt)
+               pl.Firstpc = p
+       } else {
+
+               lastpc.Link = p
+       }
+       lastpc = p
+
+out:
+       if a != i386.AGLOBL && a != i386.ADATA {
+               pc++
+       }
+}
diff --git a/src/cmd/new9a/a.y b/src/cmd/new9a/a.y
new file mode 100644 (file)
index 0000000..b366146
--- /dev/null
@@ -0,0 +1,991 @@
+// cmd/9a/a.y from Vita Nuova.
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// 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"
+%}
+%union
+{
+       Sym     *sym;
+       vlong   lval;
+       double  dval;
+       char    sval[8];
+       Addr    addr;
+}
+%left  '|'
+%left  '^'
+%left  '&'
+%left  '<' '>'
+%left  '+' '-'
+%left  '*' '/' '%'
+%token <lval>  LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
+%token <lval>  LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
+%token <lval>  LNOP LEND LRETT LWORD LTEXT LDATA LRETRN
+%token <lval>  LCONST LSP LSB LFP LPC LCREG LFLUSH
+%token <lval>  LREG LFREG LR LCR LF LFPSCR
+%token <lval>  LLR LCTR LSPR LSPREG LSEG LMSR
+%token <lval>  LPCDAT LFUNCDAT LSCHED LXLD LXST LXOP LXMV
+%token <lval>  LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA
+%token <dval>  LFCONST
+%token <sval>  LSCONST
+%token <sym>   LNAME LLAB LVAR
+%type  <lval>  con expr pointer offset sreg
+%type  <addr>  addr rreg regaddr name creg freg xlreg lr ctr
+%type  <addr>  imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask
+%%
+prog:
+|      prog 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;
+       }
+       line
+|      LNAME '=' expr ';'
+       {
+               $1->type = LVAR;
+               $1->value = $3;
+       }
+|      LVAR '=' expr ';'
+       {
+               if($1->value != $3)
+                       yyerror("redeclaration of %s", $1->name);
+               $1->value = $3;
+       }
+|      LSCHED ';'
+       {
+               nosched = $1;
+       }
+|      ';'
+|      inst ';'
+|      error ';'
+
+inst:
+/*
+ * load ints and bytes
+ */
+       LMOVW rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW addr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW regaddr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB addr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB regaddr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * load floats
+ */
+|      LFMOV addr ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV regaddr ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV fimm ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV freg ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV freg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV freg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * store ints and bytes
+ */
+|      LMOVW rreg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW rreg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB rreg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB rreg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * store floats
+ */
+|      LMOVW freg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW freg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * floating point status
+ */
+|      LMOVW fpscr ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW freg ','  fpscr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW freg ',' imm ',' fpscr
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LMOVW fpscr ',' creg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW imm ',' fpscrf
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMTFSB imm ',' con
+       {
+               outcode($1, &$2, $4, &nullgen);
+       }
+/*
+ * field moves (mtcrf)
+ */
+|      LMOVW rreg ',' imm ',' lcr
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LMOVW rreg ',' creg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW rreg ',' lcr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * integer operations
+ * logical instructions
+ * shift instructions
+ * unary instructions
+ */
+|      LADDW rreg ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LADDW imm ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LADDW rreg ',' imm ',' rreg
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LADDW rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LADDW imm ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LLOGW rreg ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LLOGW rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LSHW rreg ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LSHW rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LSHW imm ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LSHW imm ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LABS rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LABS rreg
+       {
+               outcode($1, &$2, NREG, &$2);
+       }
+/*
+ * multiply-accumulate
+ */
+|      LMA rreg ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+/*
+ * move immediate: macro for cau+or, addi, addis, and other combinations
+ */
+|      LMOVW imm ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW ximm ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * condition register operations
+ */
+|      LCROP cbit ',' cbit
+       {
+               outcode($1, &$2, $4.reg, &$4);
+       }
+|      LCROP cbit ',' con ',' cbit
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+/*
+ * condition register moves
+ * move from machine state register
+ */
+|      LMOVW creg ',' creg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW psr ',' creg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW lcr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW psr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW xlreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW rreg ',' xlreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW creg ',' psr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW rreg ',' psr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * branch, branch conditional
+ * branch conditional register
+ * branch conditional to count register
+ */
+|      LBRA rel
+       {
+               outcode($1, &nullgen, NREG, &$2);
+       }
+|      LBRA addr
+       {
+               outcode($1, &nullgen, NREG, &$2);
+       }
+|      LBRA '(' xlreg ')'
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LBRA ',' rel
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LBRA ',' addr
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LBRA ',' '(' xlreg ')'
+       {
+               outcode($1, &nullgen, NREG, &$4);
+       }
+|      LBRA creg ',' rel
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LBRA creg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LBRA creg ',' '(' xlreg ')'
+       {
+               outcode($1, &$2, NREG, &$5);
+       }
+|      LBRA con ',' rel
+       {
+               outcode($1, &nullgen, $2, &$4);
+       }
+|      LBRA con ',' addr
+       {
+               outcode($1, &nullgen, $2, &$4);
+       }
+|      LBRA con ',' '(' xlreg ')'
+       {
+               outcode($1, &nullgen, $2, &$5);
+       }
+|      LBRA con ',' con ',' rel
+       {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = $2;
+               outcode($1, &g, $4, &$6);
+       }
+|      LBRA con ',' con ',' addr
+       {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = $2;
+               outcode($1, &g, $4, &$6);
+       }
+|      LBRA con ',' con ',' '(' xlreg ')'
+       {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = $2;
+               outcode($1, &g, $4, &$7);
+       }
+/*
+ * conditional trap
+ */
+|      LTRAP rreg ',' sreg
+       {
+               outcode($1, &$2, $4, &nullgen);
+       }
+|      LTRAP imm ',' sreg
+       {
+               outcode($1, &$2, $4, &nullgen);
+       }
+|      LTRAP rreg comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+|      LTRAP comma
+       {
+               outcode($1, &nullgen, NREG, &nullgen);
+       }
+/*
+ * floating point operate
+ */
+|      LFCONV freg ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFADD freg ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFADD freg ',' freg ',' freg
+       {
+               outcode($1, &$2, $4.reg, &$6);
+       }
+|      LFMA freg ',' freg ',' freg ',' freg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+|      LFCMP freg ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFCMP freg ',' freg ',' creg
+       {
+               outcode($1, &$2, $6.reg, &$4);
+       }
+/*
+ * CMP
+ */
+|      LCMP rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LCMP rreg ',' imm
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LCMP rreg ',' rreg ',' creg
+       {
+               outcode($1, &$2, $6.reg, &$4);
+       }
+|      LCMP rreg ',' imm ',' creg
+       {
+               outcode($1, &$2, $6.reg, &$4);
+       }
+/*
+ * rotate and mask
+ */
+|      LRLWM  imm ',' rreg ',' imm ',' rreg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+|      LRLWM  imm ',' rreg ',' mask ',' rreg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+|      LRLWM  rreg ',' rreg ',' imm ',' rreg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+|      LRLWM  rreg ',' rreg ',' mask ',' rreg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+/*
+ * load/store multiple
+ */
+|      LMOVMW addr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVMW rreg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * various indexed load/store
+ * indexed unary (eg, cache clear)
+ */
+|      LXLD regaddr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LXLD regaddr ',' imm ',' rreg
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LXST rreg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LXST rreg ',' imm ',' regaddr
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LXMV regaddr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LXMV rreg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LXOP regaddr
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+/*
+ * NOP
+ */
+|      LNOP comma
+       {
+               outcode($1, &nullgen, NREG, &nullgen);
+       }
+|      LNOP rreg comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+|      LNOP freg comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+|      LNOP ',' rreg
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LNOP ',' freg
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+/*
+ * word
+ */
+|      LWORD imm comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+|      LWORD ximm comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+/*
+ * PCDATA
+ */
+|      LPCDAT imm ',' imm
+       {
+               if($2.type != D_CONST || $4.type != D_CONST)
+                       yyerror("arguments to PCDATA must be integer constants");
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * FUNCDATA
+ */
+|      LFUNCDAT imm ',' addr
+       {
+               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, &$2, NREG, &$4);
+       }
+/*
+ * END
+ */
+|      LEND comma
+       {
+               outcode($1, &nullgen, NREG, &nullgen);
+       }
+/*
+ * TEXT/GLOBL
+ */
+|      LTEXT name ',' imm
+       {
+               settext($2.sym);
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LTEXT name ',' con ',' imm
+       {
+               settext($2.sym);
+               $6.offset &= 0xffffffffull;
+               $6.offset |= (vlong)ArgsSizeUnknown << 32;
+               outcode($1, &$2, $4, &$6);
+       }
+|      LTEXT name ',' con ',' imm '-' con
+       {
+               settext($2.sym);
+               $6.offset &= 0xffffffffull;
+               $6.offset |= ($8 & 0xffffffffull) << 32;
+               outcode($1, &$2, $4, &$6);
+       }
+/*
+ * DATA
+ */
+|      LDATA name '/' con ',' imm
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LDATA name '/' con ',' ximm
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LDATA name '/' con ',' fimm
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+/*
+ * RETURN
+ */
+|      LRETRN  comma
+       {
+               outcode($1, &nullgen, NREG, &nullgen);
+       }
+
+rel:
+       con '(' LPC ')'
+       {
+               $$ = nullgen;
+               $$.type = D_BRANCH;
+               $$.offset = $1 + pc;
+       }
+|      LNAME offset
+       {
+               $1 = labellookup($1);
+               $$ = nullgen;
+               if(pass == 2 && $1->type != LLAB)
+                       yyerror("undefined label: %s", $1->labelname);
+               $$.type = D_BRANCH;
+               $$.offset = $1->value + $2;
+       }
+
+rreg:
+       sreg
+       {
+               $$ = nullgen;
+               $$.type = D_REG;
+               $$.reg = $1;
+       }
+
+xlreg:
+       lr
+|      ctr
+
+lr:
+       LLR
+       {
+               $$ = nullgen;
+               $$.type = D_SPR;
+               $$.offset = $1;
+       }
+
+lcr:
+       LCR
+       {
+               $$ = nullgen;
+               $$.type = D_CREG;
+               $$.reg = NREG;  /* whole register */
+       }
+
+ctr:
+       LCTR
+       {
+               $$ = nullgen;
+               $$.type = D_SPR;
+               $$.offset = $1;
+       }
+
+msr:
+       LMSR
+       {
+               $$ = nullgen;
+               $$.type = D_MSR;
+       }
+
+psr:
+       LSPREG
+       {
+               $$ = nullgen;
+               $$.type = D_SPR;
+               $$.offset = $1;
+       }
+|      LSPR '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = $1;
+               $$.offset = $3;
+       }
+|      msr
+
+fpscr:
+       LFPSCR
+       {
+               $$ = nullgen;
+               $$.type = D_FPSCR;
+               $$.reg = NREG;
+       }
+
+fpscrf:
+       LFPSCR '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FPSCR;
+               $$.reg = $3;
+       }
+
+freg:
+       LFREG
+       {
+               $$ = nullgen;
+               $$.type = D_FREG;
+               $$.reg = $1;
+       }
+|      LF '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FREG;
+               $$.reg = $3;
+       }
+
+creg:
+       LCREG
+       {
+               $$ = nullgen;
+               $$.type = D_CREG;
+               $$.reg = $1;
+       }
+|      LCR '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_CREG;
+               $$.reg = $3;
+       }
+
+
+cbit:  con
+       {
+               $$ = nullgen;
+               $$.type = D_REG;
+               $$.reg = $1;
+       }
+
+mask:
+       con ',' con
+       {
+               int mb, me;
+               uint32 v;
+
+               $$ = nullgen;
+               $$.type = D_CONST;
+               mb = $1;
+               me = $3;
+               if(mb < 0 || mb > 31 || me < 0 || me > 31){
+                       yyerror("illegal mask start/end value(s)");
+                       mb = me = 0;
+               }
+               if(mb <= me)
+                       v = ((uint32)~0L>>mb) & (~0L<<(31-me));
+               else
+                       v = ~(((uint32)~0L>>(me+1)) & (~0L<<(31-(mb-1))));
+               $$.offset = v;
+       }
+
+ximm:
+       '$' addr
+       {
+               $$ = $2;
+               $$.type = D_CONST;
+       }
+|      '$' LSCONST
+       {
+               $$ = nullgen;
+               $$.type = D_SCONST;
+               memcpy($$.u.sval, $2, sizeof($$.u.sval));
+       }
+
+fimm:
+       '$' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = $2;
+       }
+|      '$' '-' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = -$3;
+       }
+
+imm:   '$' con
+       {
+               $$ = nullgen;
+               $$.type = D_CONST;
+               $$.offset = $2;
+       }
+
+sreg:
+       LREG
+|      LR '(' con ')'
+       {
+               if($$ < 0 || $$ >= NREG)
+                       print("register value out of range\n");
+               $$ = $3;
+       }
+
+regaddr:
+       '(' sreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.reg = $2;
+               $$.offset = 0;
+       }
+|      '(' sreg '+' sreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.reg = $2;
+               $$.scale = $4;
+               $$.offset = 0;
+       }
+
+addr:
+       name
+|      con '(' sreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.reg = $3;
+               $$.offset = $1;
+       }
+
+name:
+       con '(' pointer ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = $3;
+               $$.sym = nil;
+               $$.offset = $1;
+       }
+|      LNAME offset '(' pointer ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = $4;
+               $$.sym = linklookup(ctxt, $1->name, 0);
+               $$.offset = $2;
+       }
+|      LNAME '<' '>' offset '(' LSB ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = D_STATIC;
+               $$.sym = linklookup(ctxt, $1->name, 0);
+               $$.offset = $4;
+       }
+
+comma:
+|      ','
+
+offset:
+       {
+               $$ = 0;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+
+pointer:
+       LSB
+|      LSP
+|      LFP
+
+con:
+       LCONST
+|      LVAR
+       {
+               $$ = $1->value;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '~' con
+       {
+               $$ = ~$2;
+       }
+|      '(' expr ')'
+       {
+               $$ = $2;
+       }
+
+expr:
+       con
+|      expr '+' expr
+       {
+               $$ = $1 + $3;
+       }
+|      expr '-' expr
+       {
+               $$ = $1 - $3;
+       }
+|      expr '*' expr
+       {
+               $$ = $1 * $3;
+       }
+|      expr '/' expr
+       {
+               $$ = $1 / $3;
+       }
+|      expr '%' expr
+       {
+               $$ = $1 % $3;
+       }
+|      expr '<' '<' expr
+       {
+               $$ = $1 << $4;
+       }
+|      expr '>' '>' expr
+       {
+               $$ = $1 >> $4;
+       }
+|      expr '&' expr
+       {
+               $$ = $1 & $3;
+       }
+|      expr '^' expr
+       {
+               $$ = $1 ^ $3;
+       }
+|      expr '|' expr
+       {
+               $$ = $1 | $3;
+       }
diff --git a/src/cmd/new9a/lex.go b/src/cmd/new9a/lex.go
new file mode 100644 (file)
index 0000000..9fad91f
--- /dev/null
@@ -0,0 +1,688 @@
+// cmd/9a/lex.c from Vita Nuova.
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package main
+
+const (
+       Plan9   = 1 << 0
+       Unix    = 1 << 1
+       Windows = 1 << 2
+)
+
+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++
+}
+
+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{}
+       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)
+
+       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()
+       }
+
+       if assemble(argv[0]) != 0 {
+               errorexit()
+       }
+       obj.Bflush(&bstdout)
+       if nerrors > 0 {
+               errorexit()
+       }
+       main.Exits("")
+}
+
+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()
+       }
+
+       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
+}
+
+var itab = []struct {
+       name  string
+       type_ uint16
+       value uint16
+}{
+       {"SP", LSP, ppc64.D_AUTO},
+       {"SB", LSB, ppc64.D_EXTERN},
+       {"FP", LFP, ppc64.D_PARAM},
+       {"PC", LPC, ppc64.D_BRANCH},
+       {"LR", LLR, ppc64.D_LR},
+       {"CTR", LCTR, ppc64.D_CTR},
+       {"XER", LSPREG, ppc64.D_XER},
+       {"MSR", LMSR, ppc64.D_MSR},
+       {"FPSCR", LFPSCR, ppc64.D_FPSCR},
+       {"SPR", LSPR, ppc64.D_SPR},
+       {"DCR", LSPR, ppc64.D_DCR},
+       {"CR", LCR, 0},
+       {"CR0", LCREG, 0},
+       {"CR1", LCREG, 1},
+       {"CR2", LCREG, 2},
+       {"CR3", LCREG, 3},
+       {"CR4", LCREG, 4},
+       {"CR5", LCREG, 5},
+       {"CR6", LCREG, 6},
+       {"CR7", LCREG, 7},
+       {"R", LR, 0},
+       {"R0", LREG, 0},
+       {"R1", LREG, 1},
+       {"R2", LREG, 2},
+       {"R3", LREG, 3},
+       {"R4", LREG, 4},
+       {"R5", LREG, 5},
+       {"R6", LREG, 6},
+       {"R7", LREG, 7},
+       {"R8", LREG, 8},
+       {"R9", LREG, 9},
+       {"R10", LREG, 10},
+       {"R11", LREG, 11},
+       {"R12", LREG, 12},
+       {"R13", LREG, 13},
+       {"R14", LREG, 14},
+       {"R15", LREG, 15},
+       {"R16", LREG, 16},
+       {"R17", LREG, 17},
+       {"R18", LREG, 18},
+       {"R19", LREG, 19},
+       {"R20", LREG, 20},
+       {"R21", LREG, 21},
+       {"R22", LREG, 22},
+       {"R23", LREG, 23},
+       {"R24", LREG, 24},
+       {"R25", LREG, 25},
+       {"R26", LREG, 26},
+       {"R27", LREG, 27},
+       {"R28", LREG, 28},
+       {"R29", LREG, 29},
+       {"g", LREG, 30}, // avoid unintentionally clobbering g using R30
+       {"R31", LREG, 31},
+       {"F", LF, 0},
+       {"F0", LFREG, 0},
+       {"F1", LFREG, 1},
+       {"F2", LFREG, 2},
+       {"F3", LFREG, 3},
+       {"F4", LFREG, 4},
+       {"F5", LFREG, 5},
+       {"F6", LFREG, 6},
+       {"F7", LFREG, 7},
+       {"F8", LFREG, 8},
+       {"F9", LFREG, 9},
+       {"F10", LFREG, 10},
+       {"F11", LFREG, 11},
+       {"F12", LFREG, 12},
+       {"F13", LFREG, 13},
+       {"F14", LFREG, 14},
+       {"F15", LFREG, 15},
+       {"F16", LFREG, 16},
+       {"F17", LFREG, 17},
+       {"F18", LFREG, 18},
+       {"F19", LFREG, 19},
+       {"F20", LFREG, 20},
+       {"F21", LFREG, 21},
+       {"F22", LFREG, 22},
+       {"F23", LFREG, 23},
+       {"F24", LFREG, 24},
+       {"F25", LFREG, 25},
+       {"F26", LFREG, 26},
+       {"F27", LFREG, 27},
+       {"F28", LFREG, 28},
+       {"F29", LFREG, 29},
+       {"F30", LFREG, 30},
+       {"F31", LFREG, 31},
+       {"CREQV", LCROP, ppc64.ACREQV},
+       {"CRXOR", LCROP, ppc64.ACRXOR},
+       {"CRAND", LCROP, ppc64.ACRAND},
+       {"CROR", LCROP, ppc64.ACROR},
+       {"CRANDN", LCROP, ppc64.ACRANDN},
+       {"CRORN", LCROP, ppc64.ACRORN},
+       {"CRNAND", LCROP, ppc64.ACRNAND},
+       {"CRNOR", LCROP, ppc64.ACRNOR},
+       {"ADD", LADDW, ppc64.AADD},
+       {"ADDV", LADDW, ppc64.AADDV},
+       {"ADDCC", LADDW, ppc64.AADDCC},
+       {"ADDVCC", LADDW, ppc64.AADDVCC},
+       {"ADDC", LADDW, ppc64.AADDC},
+       {"ADDCV", LADDW, ppc64.AADDCV},
+       {"ADDCCC", LADDW, ppc64.AADDCCC},
+       {"ADDCVCC", LADDW, ppc64.AADDCVCC},
+       {"ADDE", LLOGW, ppc64.AADDE},
+       {"ADDEV", LLOGW, ppc64.AADDEV},
+       {"ADDECC", LLOGW, ppc64.AADDECC},
+       {"ADDEVCC", LLOGW, ppc64.AADDEVCC},
+       {"ADDME", LABS, ppc64.AADDME},
+       {"ADDMEV", LABS, ppc64.AADDMEV},
+       {"ADDMECC", LABS, ppc64.AADDMECC},
+       {"ADDMEVCC", LABS, ppc64.AADDMEVCC},
+       {"ADDZE", LABS, ppc64.AADDZE},
+       {"ADDZEV", LABS, ppc64.AADDZEV},
+       {"ADDZECC", LABS, ppc64.AADDZECC},
+       {"ADDZEVCC", LABS, ppc64.AADDZEVCC},
+       {"SUB", LADDW, ppc64.ASUB},
+       {"SUBV", LADDW, ppc64.ASUBV},
+       {"SUBCC", LADDW, ppc64.ASUBCC},
+       {"SUBVCC", LADDW, ppc64.ASUBVCC},
+       {"SUBE", LLOGW, ppc64.ASUBE},
+       {"SUBECC", LLOGW, ppc64.ASUBECC},
+       {"SUBEV", LLOGW, ppc64.ASUBEV},
+       {"SUBEVCC", LLOGW, ppc64.ASUBEVCC},
+       {"SUBC", LADDW, ppc64.ASUBC},
+       {"SUBCCC", LADDW, ppc64.ASUBCCC},
+       {"SUBCV", LADDW, ppc64.ASUBCV},
+       {"SUBCVCC", LADDW, ppc64.ASUBCVCC},
+       {"SUBME", LABS, ppc64.ASUBME},
+       {"SUBMEV", LABS, ppc64.ASUBMEV},
+       {"SUBMECC", LABS, ppc64.ASUBMECC},
+       {"SUBMEVCC", LABS, ppc64.ASUBMEVCC},
+       {"SUBZE", LABS, ppc64.ASUBZE},
+       {"SUBZEV", LABS, ppc64.ASUBZEV},
+       {"SUBZECC", LABS, ppc64.ASUBZECC},
+       {"SUBZEVCC", LABS, ppc64.ASUBZEVCC},
+       {"AND", LADDW, ppc64.AAND},
+       {"ANDCC", LADDW, ppc64.AANDCC}, /* includes andil & andiu */
+       {"ANDN", LLOGW, ppc64.AANDN},
+       {"ANDNCC", LLOGW, ppc64.AANDNCC},
+       {"EQV", LLOGW, ppc64.AEQV},
+       {"EQVCC", LLOGW, ppc64.AEQVCC},
+       {"NAND", LLOGW, ppc64.ANAND},
+       {"NANDCC", LLOGW, ppc64.ANANDCC},
+       {"NOR", LLOGW, ppc64.ANOR},
+       {"NORCC", LLOGW, ppc64.ANORCC},
+       {"OR", LADDW, ppc64.AOR}, /* includes oril & oriu */
+       {"ORCC", LADDW, ppc64.AORCC},
+       {"ORN", LLOGW, ppc64.AORN},
+       {"ORNCC", LLOGW, ppc64.AORNCC},
+       {"XOR", LADDW, ppc64.AXOR}, /* includes xoril & xoriu */
+       {"XORCC", LLOGW, ppc64.AXORCC},
+       {"EXTSB", LABS, ppc64.AEXTSB},
+       {"EXTSBCC", LABS, ppc64.AEXTSBCC},
+       {"EXTSH", LABS, ppc64.AEXTSH},
+       {"EXTSHCC", LABS, ppc64.AEXTSHCC},
+       {"CNTLZW", LABS, ppc64.ACNTLZW},
+       {"CNTLZWCC", LABS, ppc64.ACNTLZWCC},
+       {"RLWMI", LRLWM, ppc64.ARLWMI},
+       {"RLWMICC", LRLWM, ppc64.ARLWMICC},
+       {"RLWNM", LRLWM, ppc64.ARLWNM},
+       {"RLWNMCC", LRLWM, ppc64.ARLWNMCC},
+       {"SLW", LSHW, ppc64.ASLW},
+       {"SLWCC", LSHW, ppc64.ASLWCC},
+       {"SRW", LSHW, ppc64.ASRW},
+       {"SRWCC", LSHW, ppc64.ASRWCC},
+       {"SRAW", LSHW, ppc64.ASRAW},
+       {"SRAWCC", LSHW, ppc64.ASRAWCC},
+       {"BR", LBRA, ppc64.ABR},
+       {"BC", LBRA, ppc64.ABC},
+       {"BCL", LBRA, ppc64.ABC},
+       {"BL", LBRA, ppc64.ABL},
+       {"BEQ", LBRA, ppc64.ABEQ},
+       {"BNE", LBRA, ppc64.ABNE},
+       {"BGT", LBRA, ppc64.ABGT},
+       {"BGE", LBRA, ppc64.ABGE},
+       {"BLT", LBRA, ppc64.ABLT},
+       {"BLE", LBRA, ppc64.ABLE},
+       {"BVC", LBRA, ppc64.ABVC},
+       {"BVS", LBRA, ppc64.ABVS},
+       {"CMP", LCMP, ppc64.ACMP},
+       {"CMPU", LCMP, ppc64.ACMPU},
+       {"CMPW", LCMP, ppc64.ACMPW},
+       {"CMPWU", LCMP, ppc64.ACMPWU},
+       {"DIVW", LLOGW, ppc64.ADIVW},
+       {"DIVWV", LLOGW, ppc64.ADIVWV},
+       {"DIVWCC", LLOGW, ppc64.ADIVWCC},
+       {"DIVWVCC", LLOGW, ppc64.ADIVWVCC},
+       {"DIVWU", LLOGW, ppc64.ADIVWU},
+       {"DIVWUV", LLOGW, ppc64.ADIVWUV},
+       {"DIVWUCC", LLOGW, ppc64.ADIVWUCC},
+       {"DIVWUVCC", LLOGW, ppc64.ADIVWUVCC},
+       {"FABS", LFCONV, ppc64.AFABS},
+       {"FABSCC", LFCONV, ppc64.AFABSCC},
+       {"FNEG", LFCONV, ppc64.AFNEG},
+       {"FNEGCC", LFCONV, ppc64.AFNEGCC},
+       {"FNABS", LFCONV, ppc64.AFNABS},
+       {"FNABSCC", LFCONV, ppc64.AFNABSCC},
+       {"FADD", LFADD, ppc64.AFADD},
+       {"FADDCC", LFADD, ppc64.AFADDCC},
+       {"FSUB", LFADD, ppc64.AFSUB},
+       {"FSUBCC", LFADD, ppc64.AFSUBCC},
+       {"FMUL", LFADD, ppc64.AFMUL},
+       {"FMULCC", LFADD, ppc64.AFMULCC},
+       {"FDIV", LFADD, ppc64.AFDIV},
+       {"FDIVCC", LFADD, ppc64.AFDIVCC},
+       {"FRSP", LFCONV, ppc64.AFRSP},
+       {"FRSPCC", LFCONV, ppc64.AFRSPCC},
+       {"FCTIW", LFCONV, ppc64.AFCTIW},
+       {"FCTIWCC", LFCONV, ppc64.AFCTIWCC},
+       {"FCTIWZ", LFCONV, ppc64.AFCTIWZ},
+       {"FCTIWZCC", LFCONV, ppc64.AFCTIWZCC},
+       {"FMADD", LFMA, ppc64.AFMADD},
+       {"FMADDCC", LFMA, ppc64.AFMADDCC},
+       {"FMSUB", LFMA, ppc64.AFMSUB},
+       {"FMSUBCC", LFMA, ppc64.AFMSUBCC},
+       {"FNMADD", LFMA, ppc64.AFNMADD},
+       {"FNMADDCC", LFMA, ppc64.AFNMADDCC},
+       {"FNMSUB", LFMA, ppc64.AFNMSUB},
+       {"FNMSUBCC", LFMA, ppc64.AFNMSUBCC},
+       {"FMADDS", LFMA, ppc64.AFMADDS},
+       {"FMADDSCC", LFMA, ppc64.AFMADDSCC},
+       {"FMSUBS", LFMA, ppc64.AFMSUBS},
+       {"FMSUBSCC", LFMA, ppc64.AFMSUBSCC},
+       {"FNMADDS", LFMA, ppc64.AFNMADDS},
+       {"FNMADDSCC", LFMA, ppc64.AFNMADDSCC},
+       {"FNMSUBS", LFMA, ppc64.AFNMSUBS},
+       {"FNMSUBSCC", LFMA, ppc64.AFNMSUBSCC},
+       {"FCMPU", LFCMP, ppc64.AFCMPU},
+       {"FCMPO", LFCMP, ppc64.AFCMPO},
+       {"MTFSB0", LMTFSB, ppc64.AMTFSB0},
+       {"MTFSB1", LMTFSB, ppc64.AMTFSB1},
+       {"FMOVD", LFMOV, ppc64.AFMOVD},
+       {"FMOVS", LFMOV, ppc64.AFMOVS},
+       {"FMOVDCC", LFCONV, ppc64.AFMOVDCC}, /* fmr. */
+       {"GLOBL", LTEXT, ppc64.AGLOBL},
+       {"MOVB", LMOVB, ppc64.AMOVB},
+       {"MOVBZ", LMOVB, ppc64.AMOVBZ},
+       {"MOVBU", LMOVB, ppc64.AMOVBU},
+       {"MOVBZU", LMOVB, ppc64.AMOVBZU},
+       {"MOVH", LMOVB, ppc64.AMOVH},
+       {"MOVHZ", LMOVB, ppc64.AMOVHZ},
+       {"MOVHU", LMOVB, ppc64.AMOVHU},
+       {"MOVHZU", LMOVB, ppc64.AMOVHZU},
+       {"MOVHBR", LXMV, ppc64.AMOVHBR},
+       {"MOVWBR", LXMV, ppc64.AMOVWBR},
+       {"MOVW", LMOVW, ppc64.AMOVW},
+       {"MOVWU", LMOVW, ppc64.AMOVWU},
+       {"MOVMW", LMOVMW, ppc64.AMOVMW},
+       {"MOVFL", LMOVW, ppc64.AMOVFL},
+       {"MULLW", LADDW, ppc64.AMULLW}, /* includes multiply immediate 10-139 */
+       {"MULLWV", LLOGW, ppc64.AMULLWV},
+       {"MULLWCC", LLOGW, ppc64.AMULLWCC},
+       {"MULLWVCC", LLOGW, ppc64.AMULLWVCC},
+       {"MULHW", LLOGW, ppc64.AMULHW},
+       {"MULHWCC", LLOGW, ppc64.AMULHWCC},
+       {"MULHWU", LLOGW, ppc64.AMULHWU},
+       {"MULHWUCC", LLOGW, ppc64.AMULHWUCC},
+       {"NEG", LABS, ppc64.ANEG},
+       {"NEGV", LABS, ppc64.ANEGV},
+       {"NEGCC", LABS, ppc64.ANEGCC},
+       {"NEGVCC", LABS, ppc64.ANEGVCC},
+       {"NOP", LNOP, ppc64.ANOP}, /* ori 0,0,0 */
+       {"SYSCALL", LNOP, ppc64.ASYSCALL},
+       {"UNDEF", LNOP, ppc64.AUNDEF},
+       {"RET", LRETRN, ppc64.ARETURN},
+       {"RETURN", LRETRN, ppc64.ARETURN},
+       {"RFI", LRETRN, ppc64.ARFI},
+       {"RFCI", LRETRN, ppc64.ARFCI},
+       {"DATA", LDATA, ppc64.ADATA},
+       {"END", LEND, ppc64.AEND},
+       {"TEXT", LTEXT, ppc64.ATEXT},
+
+       /* 64-bit instructions */
+       {"CNTLZD", LABS, ppc64.ACNTLZD},
+       {"CNTLZDCC", LABS, ppc64.ACNTLZDCC},
+       {"DIVD", LLOGW, ppc64.ADIVD},
+       {"DIVDCC", LLOGW, ppc64.ADIVDCC},
+       {"DIVDVCC", LLOGW, ppc64.ADIVDVCC},
+       {"DIVDV", LLOGW, ppc64.ADIVDV},
+       {"DIVDU", LLOGW, ppc64.ADIVDU},
+       {"DIVDUCC", LLOGW, ppc64.ADIVDUCC},
+       {"DIVDUVCC", LLOGW, ppc64.ADIVDUVCC},
+       {"DIVDUV", LLOGW, ppc64.ADIVDUV},
+       {"EXTSW", LABS, ppc64.AEXTSW},
+       {"EXTSWCC", LABS, ppc64.AEXTSWCC},
+       {"FCTID", LFCONV, ppc64.AFCTID},
+       {"FCTIDCC", LFCONV, ppc64.AFCTIDCC},
+       {"FCTIDZ", LFCONV, ppc64.AFCTIDZ},
+       {"FCTIDZCC", LFCONV, ppc64.AFCTIDZCC},
+       {"FCFID", LFCONV, ppc64.AFCFID},
+       {"FCFIDCC", LFCONV, ppc64.AFCFIDCC},
+       {"LDAR", LXLD, ppc64.ALDAR},
+       {"MOVD", LMOVW, ppc64.AMOVD},
+       {"MOVDU", LMOVW, ppc64.AMOVDU},
+       {"MOVWZ", LMOVW, ppc64.AMOVWZ},
+       {"MOVWZU", LMOVW, ppc64.AMOVWZU},
+       {"MULHD", LLOGW, ppc64.AMULHD},
+       {"MULHDCC", LLOGW, ppc64.AMULHDCC},
+       {"MULHDU", LLOGW, ppc64.AMULHDU},
+       {"MULHDUCC", LLOGW, ppc64.AMULHDUCC},
+       {"MULLD", LADDW, ppc64.AMULLD}, /* includes multiply immediate? */
+       {"MULLDCC", LLOGW, ppc64.AMULLDCC},
+       {"MULLDVCC", LLOGW, ppc64.AMULLDVCC},
+       {"MULLDV", LLOGW, ppc64.AMULLDV},
+       {"RFID", LRETRN, ppc64.ARFID},
+       {"HRFID", LRETRN, ppc64.AHRFID},
+       {"RLDMI", LRLWM, ppc64.ARLDMI},
+       {"RLDMICC", LRLWM, ppc64.ARLDMICC},
+       {"RLDC", LRLWM, ppc64.ARLDC},
+       {"RLDCCC", LRLWM, ppc64.ARLDCCC},
+       {"RLDCR", LRLWM, ppc64.ARLDCR},
+       {"RLDCRCC", LRLWM, ppc64.ARLDCRCC},
+       {"RLDCL", LRLWM, ppc64.ARLDCL},
+       {"RLDCLCC", LRLWM, ppc64.ARLDCLCC},
+       {"SLBIA", LNOP, ppc64.ASLBIA},
+       {"SLBIE", LNOP, ppc64.ASLBIE},
+       {"SLBMFEE", LABS, ppc64.ASLBMFEE},
+       {"SLBMFEV", LABS, ppc64.ASLBMFEV},
+       {"SLBMTE", LABS, ppc64.ASLBMTE},
+       {"SLD", LSHW, ppc64.ASLD},
+       {"SLDCC", LSHW, ppc64.ASLDCC},
+       {"SRD", LSHW, ppc64.ASRD},
+       {"SRAD", LSHW, ppc64.ASRAD},
+       {"SRADCC", LSHW, ppc64.ASRADCC},
+       {"SRDCC", LSHW, ppc64.ASRDCC},
+       {"STDCCC", LXST, ppc64.ASTDCCC},
+       {"TD", LADDW, ppc64.ATD},
+
+       /* pseudo instructions */
+       {"REM", LLOGW, ppc64.AREM},
+       {"REMCC", LLOGW, ppc64.AREMCC},
+       {"REMV", LLOGW, ppc64.AREMV},
+       {"REMVCC", LLOGW, ppc64.AREMVCC},
+       {"REMU", LLOGW, ppc64.AREMU},
+       {"REMUCC", LLOGW, ppc64.AREMUCC},
+       {"REMUV", LLOGW, ppc64.AREMUV},
+       {"REMUVCC", LLOGW, ppc64.AREMUVCC},
+       {"REMD", LLOGW, ppc64.AREMD},
+       {"REMDCC", LLOGW, ppc64.AREMDCC},
+       {"REMDV", LLOGW, ppc64.AREMDV},
+       {"REMDVCC", LLOGW, ppc64.AREMDVCC},
+       {"REMDU", LLOGW, ppc64.AREMDU},
+       {"REMDUCC", LLOGW, ppc64.AREMDUCC},
+       {"REMDUV", LLOGW, ppc64.AREMDUV},
+       {"REMDUVCC", LLOGW, ppc64.AREMDUVCC},
+
+       /* special instructions */
+       {"DCBF", LXOP, ppc64.ADCBF},
+       {"DCBI", LXOP, ppc64.ADCBI},
+       {"DCBST", LXOP, ppc64.ADCBST},
+       {"DCBT", LXOP, ppc64.ADCBT},
+       {"DCBTST", LXOP, ppc64.ADCBTST},
+       {"DCBZ", LXOP, ppc64.ADCBZ},
+       {"ICBI", LXOP, ppc64.AICBI},
+       {"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},
+       {"TLBIEL", LNOP, ppc64.ATLBIEL},
+       {"LSW", LXLD, ppc64.ALSW},
+       {"STSW", LXST, ppc64.ASTSW},
+       {"ISYNC", LRETRN, ppc64.AISYNC},
+       {"SYNC", LRETRN, ppc64.ASYNC},
+       {"TLBSYNC", LRETRN, ppc64.ATLBSYNC},
+       {"PTESYNC", LRETRN, ppc64.APTESYNC},
+
+       /*      "TW",           LADDW,  ATW,*/
+       {"WORD", LWORD, ppc64.AWORD},
+       {"DWORD", LWORD, ppc64.ADWORD},
+       {"SCHED", LSCHED, 0},
+       {"NOSCHED", LSCHED, 0x80},
+       {"PCDATA", LPCDAT, ppc64.APCDATA},
+       {"FUNCDATA", LFUNCDAT, ppc64.AFUNCDATA},
+}
+
+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() {
+       outcode(ppc64.AEND, &nullgen, ppc64.NREG, &nullgen)
+}
+
+var lastpc *obj.Prog
+
+func outcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr) {
+       var p *obj.Prog
+       var pl *obj.Plist
+
+       if pass == 1 {
+               goto out
+       }
+
+       if g1.Scale != ppc64.NREG {
+               if reg != ppc64.NREG || g2.Scale != ppc64.NREG {
+                       yyerror("bad addressing modes")
+               }
+               reg = int(g1.Scale)
+       } else if g2.Scale != ppc64.NREG {
+               if reg != ppc64.NREG {
+                       yyerror("bad addressing modes")
+               }
+               reg = int(g2.Scale)
+       }
+
+       p = ctxt.Arch.Prg()
+       p.As = int16(a)
+       p.Lineno = lineno
+       if nosched != 0 {
+               p.Mark |= ppc64.NOSCHED
+       }
+       p.From = *g1
+       p.Reg = uint8(reg)
+       p.To = *g2
+       p.Pc = int64(pc)
+
+       if lastpc == nil {
+               pl = obj.Linknewplist(ctxt)
+               pl.Firstpc = p
+       } else {
+
+               lastpc.Link = p
+       }
+       lastpc = p
+
+out:
+       if a != ppc64.AGLOBL && a != ppc64.ADATA {
+               pc++
+       }
+}
+
+func outgcode(a int, g1 *obj.Addr, reg int, g2 *obj.Addr, g3 *obj.Addr) {
+       var p *obj.Prog
+       var pl *obj.Plist
+
+       if pass == 1 {
+               goto out
+       }
+
+       p = ctxt.Arch.Prg()
+       p.As = int16(a)
+       p.Lineno = lineno
+       if nosched != 0 {
+               p.Mark |= ppc64.NOSCHED
+       }
+       p.From = *g1
+       p.Reg = uint8(reg)
+       p.From3 = *g2
+       p.To = *g3
+       p.Pc = int64(pc)
+
+       if lastpc == nil {
+               pl = obj.Linknewplist(ctxt)
+               pl.Firstpc = p
+       } else {
+
+               lastpc.Link = p
+       }
+       lastpc = p
+
+out:
+       if a != ppc64.AGLOBL && a != ppc64.ADATA {
+               pc++
+       }
+}