From 9e2f8fdb6f54d539bafc9e2bef4b266def1e3e74 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 21 Jan 2015 11:36:15 -0500 Subject: [PATCH] =?utf8?q?[dev.cc]=20cmd/new5a=20etc,=20cmd/internal/asm:?= =?utf8?q?=20initial=20C=20=E2=86=92=20Go=20conversion?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/cmd/internal/asm/asm.go | 1102 +++++++++++++++++++++++++++++++ src/cmd/internal/asm/lexbody.go | 804 ++++++++++++++++++++++ src/cmd/internal/asm/macbody.go | 992 ++++++++++++++++++++++++++++ src/cmd/new5a/a.y | 741 +++++++++++++++++++++ src/cmd/new5a/lex.go | 491 ++++++++++++++ src/cmd/new6a/a.y | 684 +++++++++++++++++++ src/cmd/new6a/lex.go | 1102 +++++++++++++++++++++++++++++++ src/cmd/new8a/a.y | 680 +++++++++++++++++++ src/cmd/new8a/lex.go | 887 +++++++++++++++++++++++++ src/cmd/new9a/a.y | 991 +++++++++++++++++++++++++++ src/cmd/new9a/lex.go | 688 +++++++++++++++++++ 11 files changed, 9162 insertions(+) create mode 100644 src/cmd/internal/asm/asm.go create mode 100644 src/cmd/internal/asm/lexbody.go create mode 100644 src/cmd/internal/asm/macbody.go create mode 100644 src/cmd/new5a/a.y create mode 100644 src/cmd/new5a/lex.go create mode 100644 src/cmd/new6a/a.y create mode 100644 src/cmd/new6a/lex.go create mode 100644 src/cmd/new8a/a.y create mode 100644 src/cmd/new8a/lex.go create mode 100644 src/cmd/new9a/a.y create mode 100644 src/cmd/new9a/lex.go diff --git a/src/cmd/internal/asm/asm.go b/src/cmd/internal/asm/asm.go new file mode 100644 index 0000000000..264c119f3d --- /dev/null +++ b/src/cmd/internal/asm/asm.go @@ -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 index 0000000000..d835e7b117 --- /dev/null +++ b/src/cmd/internal/asm/lexbody.go @@ -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 index 0000000000..d8ec242400 --- /dev/null +++ b/src/cmd/internal/asm/macbody.go @@ -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 = "" + 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 index 0000000000..d365c75343 --- /dev/null +++ b/src/cmd/new5a/a.y @@ -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 +#include /* if we don't, bison will, and a.h re-#defines getc */ +#include +#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 LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5 +%token LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA +%token LTYPEB LTYPEC LTYPED LTYPEE +%token LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK +%token LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD +%token LCONST LSP LSB LFP LPC +%token LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR +%token LCOND LS LAT +%token LFCONST +%token LSCONST +%token LNAME LLAB LVAR +%type con expr oexpr pointer offset sreg spreg creg +%type rcon cond reglist +%type gen rel reg regreg freg shift fcon frcon +%type 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<' '>' 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 index 0000000000..17255d00cf --- /dev/null +++ b/src/cmd/new5a/lex.go @@ -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 index 0000000000..29011c7ffb --- /dev/null +++ b/src/cmd/new6a/a.y @@ -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 +#include /* if we don't, bison will, and a.h re-#defines getc */ +#include +#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 LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 +%token LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG LTYPEPC +%token LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT LTYPEF +%token LCONST LFP LPC LSB +%token LBREG LLREG LSREG LFREG LMREG LXREG +%token LFCONST +%token LSCONST LSP +%token LNAME LLAB LVAR +%type con con2 expr pointer offset +%type mem imm imm2 reg nam rel rem rim rom omem nmem +%type nonnon nonrel nonrem rimnon rimrem remrim +%type spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 +%type 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 index 0000000000..264c119f3d --- /dev/null +++ b/src/cmd/new6a/lex.go @@ -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 index 0000000000..c810d38577 --- /dev/null +++ b/src/cmd/new8a/a.y @@ -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 +#include /* if we don't, bison will, and a.h re-#defines getc */ +#include +#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 LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 +%token LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC +%token LTYPEX LTYPEPC LTYPEF LCONST LFP LPC LSB +%token LBREG LLREG LSREG LFREG LXREG +%token LFCONST +%token LSCONST LSP +%token LNAME LLAB LVAR +%type con expr pointer offset +%type con2 +%type mem imm imm2 reg nam rel rem rim rom omem nmem +%type nonnon nonrel nonrem rimnon rimrem remrim +%type 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 index 0000000000..f9ea92a92f --- /dev/null +++ b/src/cmd/new8a/lex.go @@ -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 index 0000000000..b366146156 --- /dev/null +++ b/src/cmd/new9a/a.y @@ -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 +#include /* if we don't, bison will, and a.h re-#defines getc */ +#include +#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 LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP +%token LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW +%token LNOP LEND LRETT LWORD LTEXT LDATA LRETRN +%token LCONST LSP LSB LFP LPC LCREG LFLUSH +%token LREG LFREG LR LCR LF LFPSCR +%token LLR LCTR LSPR LSPREG LSEG LMSR +%token LPCDAT LFUNCDAT LSCHED LXLD LXST LXOP LXMV +%token LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA +%token LFCONST +%token LSCONST +%token LNAME LLAB LVAR +%type con expr pointer offset sreg +%type addr rreg regaddr name creg freg xlreg lr ctr +%type 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 index 0000000000..9fad91f72a --- /dev/null +++ b/src/cmd/new9a/lex.go @@ -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++ + } +} -- 2.48.1