]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.power64] all: merge default (dd5014ed9b01) into dev.power64
authorRuss Cox <rsc@golang.org>
Wed, 29 Oct 2014 15:45:01 +0000 (11:45 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 29 Oct 2014 15:45:01 +0000 (11:45 -0400)
Still passes on amd64.

LGTM=austin
R=austin
CC=golang-codereviews
https://golang.org/cl/165110043

158 files changed:
.hgignore
include/link.h
lib/codereview/codereview.cfg
lib/codereview/codereview.py
src/cmd/5a/a.h
src/cmd/5a/a.y
src/cmd/5a/y.tab.c
src/cmd/5a/y.tab.h
src/cmd/6a/a.h
src/cmd/6a/a.y
src/cmd/6a/y.tab.c
src/cmd/8a/a.h
src/cmd/8a/a.y
src/cmd/8a/y.tab.c
src/cmd/9a/Makefile [new file with mode: 0644]
src/cmd/9a/a.h [new file with mode: 0644]
src/cmd/9a/a.y [new file with mode: 0644]
src/cmd/9a/doc.go [new file with mode: 0644]
src/cmd/9a/lex.c [new file with mode: 0644]
src/cmd/9a/y.tab.c [new file with mode: 0644]
src/cmd/9a/y.tab.h [new file with mode: 0644]
src/cmd/9c/Makefile [new file with mode: 0644]
src/cmd/9c/Notes [new file with mode: 0644]
src/cmd/9c/cgen.c [new file with mode: 0644]
src/cmd/9c/doc.go [new file with mode: 0644]
src/cmd/9c/gc.h [new file with mode: 0644]
src/cmd/9c/list.c [new file with mode: 0644]
src/cmd/9c/machcap.c [new file with mode: 0644]
src/cmd/9c/mul.c [new file with mode: 0644]
src/cmd/9c/peep.c [new file with mode: 0644]
src/cmd/9c/reg.c [new file with mode: 0644]
src/cmd/9c/sgen.c [new file with mode: 0644]
src/cmd/9c/swt.c [new file with mode: 0644]
src/cmd/9c/txt.c [new file with mode: 0644]
src/cmd/9g/cgen.c [new file with mode: 0644]
src/cmd/9g/doc.go [new file with mode: 0644]
src/cmd/9g/galign.c [new file with mode: 0644]
src/cmd/9g/gg.h [new file with mode: 0644]
src/cmd/9g/ggen.c [new file with mode: 0644]
src/cmd/9g/gobj.c [new file with mode: 0644]
src/cmd/9g/gsubr.c [new file with mode: 0644]
src/cmd/9g/opt.h [new file with mode: 0644]
src/cmd/9g/peep.c [new file with mode: 0644]
src/cmd/9g/prog.c [new file with mode: 0644]
src/cmd/9g/reg.c [new file with mode: 0644]
src/cmd/9l/9.out.h [new file with mode: 0644]
src/cmd/9l/Makefile [new file with mode: 0644]
src/cmd/9l/asm.c [new file with mode: 0644]
src/cmd/9l/doc.go [new file with mode: 0644]
src/cmd/9l/l.h [new file with mode: 0644]
src/cmd/9l/list.c [new file with mode: 0644]
src/cmd/9l/obj.c [new file with mode: 0644]
src/cmd/cc/lexbody
src/cmd/cc/pgen.c
src/cmd/cgo/main.go
src/cmd/dist/build.c
src/cmd/dist/buildgc.c
src/cmd/dist/buildruntime.c
src/cmd/dist/unix.c
src/cmd/gc/pgen.c
src/cmd/gc/popt.c
src/cmd/gc/walk.c
src/cmd/ld/data.c
src/cmd/ld/doc.go
src/cmd/ld/dwarf.c
src/cmd/ld/elf.c
src/cmd/ld/ldelf.c
src/cmd/ld/lib.c
src/cmd/ld/macho.c
src/cmd/ld/symtab.c
src/debug/elf/elf.go
src/debug/elf/file.go
src/debug/elf/file_test.go
src/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj [new file with mode: 0644]
src/go/build/build.go
src/go/build/syslist.go
src/hash/crc32/crc32_generic.go
src/liblink/asm9.c [new file with mode: 0644]
src/liblink/list9.c [new file with mode: 0644]
src/liblink/obj9.c [new file with mode: 0644]
src/liblink/objfile.c
src/liblink/sched9.c [new file with mode: 0644]
src/math/abs_power64x.s [new file with mode: 0644]
src/math/big/arith_power64x.s [new file with mode: 0644]
src/math/stubs_power64x.s [new file with mode: 0644]
src/os/signal/sig.s
src/reflect/all_test.go
src/reflect/asm_power64x.s [new file with mode: 0644]
src/runtime/arch_power64.go [new file with mode: 0644]
src/runtime/arch_power64.h [new file with mode: 0644]
src/runtime/arch_power64le.go [new file with mode: 0644]
src/runtime/arch_power64le.h [new file with mode: 0644]
src/runtime/asm_386.s
src/runtime/asm_amd64.s
src/runtime/asm_amd64p32.s
src/runtime/asm_arm.s
src/runtime/asm_power64x.s [new file with mode: 0644]
src/runtime/atomic_power64x.s [new file with mode: 0644]
src/runtime/debug/stubs.s
src/runtime/defs1_linux.go
src/runtime/defs3_linux.go [new file with mode: 0644]
src/runtime/defs_linux.go
src/runtime/defs_linux_power64.h [new file with mode: 0644]
src/runtime/defs_linux_power64le.h [new file with mode: 0644]
src/runtime/gcinfo_test.go
src/runtime/malloc.go
src/runtime/mem_linux.c
src/runtime/memclr_386.s
src/runtime/memclr_amd64.s
src/runtime/memclr_plan9_386.s
src/runtime/memclr_power64x.s [new file with mode: 0644]
src/runtime/memmove_power64x.s [new file with mode: 0644]
src/runtime/mgc0.c
src/runtime/noasm.go [moved from src/runtime/noasm_arm.go with 96% similarity]
src/runtime/os_linux.c
src/runtime/panic.c
src/runtime/panic.go
src/runtime/proc.c
src/runtime/race_amd64.s
src/runtime/rt0_linux_power64.s [new file with mode: 0644]
src/runtime/rt0_linux_power64le.s [new file with mode: 0644]
src/runtime/runtime.c
src/runtime/signal_linux_power64.h [new file with mode: 0644]
src/runtime/signal_linux_power64le.h [new file with mode: 0644]
src/runtime/signal_power64x.c [new file with mode: 0644]
src/runtime/string.go
src/runtime/sys_darwin_386.s
src/runtime/sys_darwin_amd64.s
src/runtime/sys_dragonfly_386.s
src/runtime/sys_freebsd_386.s
src/runtime/sys_linux_amd64.s
src/runtime/sys_linux_arm.s
src/runtime/sys_linux_power64x.s [new file with mode: 0644]
src/runtime/sys_nacl_386.s
src/runtime/sys_nacl_amd64p32.s
src/runtime/sys_nacl_arm.s
src/runtime/sys_openbsd_386.s
src/runtime/sys_power64x.c [new file with mode: 0644]
src/runtime/sys_solaris_amd64.s
src/runtime/sys_windows_386.s
src/runtime/sys_windows_amd64.s
src/runtime/thunk.s
src/sync/atomic/asm_power64x.s [new file with mode: 0644]
src/syscall/asm.s
src/syscall/asm_linux_power64x.s [new file with mode: 0644]
src/syscall/mkall.sh
src/syscall/mkerrors.sh
src/syscall/syscall_linux_power64x.go [new file with mode: 0644]
src/syscall/types_linux.go
src/syscall/zerrors_linux_power64.go [new file with mode: 0644]
src/syscall/zerrors_linux_power64le.go [new file with mode: 0644]
src/syscall/zsyscall_linux_power64.go [new file with mode: 0644]
src/syscall/zsyscall_linux_power64le.go [new file with mode: 0644]
src/syscall/zsysnum_linux_power64.go [new file with mode: 0644]
src/syscall/zsysnum_linux_power64le.go [new file with mode: 0644]
src/syscall/ztypes_linux_power64.go [new file with mode: 0644]
src/syscall/ztypes_linux_power64le.go [new file with mode: 0644]
test/nosplit.go

index 0071161139335b11fd083077f038ed0d34fabb45..a833065f2e4bd82090f343e3ee7bc8f84085496f 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -2,13 +2,13 @@ syntax:glob
 .DS_Store
 .git
 .gitignore
-*.[568ao]
-*.a[568o]
+*.[5689ao]
+*.a[5689o]
 *.so
 *.pyc
 ._*
 .nfs.*
-[568a].out
+[5689a].out
 *~
 *.orig
 *.rej
index 05e117c87ee0310a994aaf47d753161454ad7795..c80f467580cd80f2210221e05deacda7112434a1 100644 (file)
@@ -62,9 +62,9 @@ struct        Addr
        short   type;
        uint8   index;
        int8    scale;
-       int8    reg;    // for 5l
-       int8    name; // for 5l
-       int8    class;  // for 5l
+       int8    reg;    // for 5l, 9l
+       int8    name; // for 5l, 9l
+       int8    class;  // for 5l, 9l
        uint8   etype; // for 5g, 6g, 8g
        int32   offset2;        // for 5l, 8l
        struct Node*    node; // for 5g, 6g, 8g
@@ -89,9 +89,10 @@ struct       Prog
        int32   lineno;
        Prog*   link;
        short   as;
-       uchar   reg; // arm only
+       uchar   reg; // arm, power64 only
        uchar   scond; // arm only
        Addr    from;
+       Addr    from3; // power64 only, fma and rlwm
        Addr    to;
        
        // for 5g, 6g, 8g internal use
@@ -103,11 +104,11 @@ struct    Prog
        Prog*   comefrom;       // 6l, 8l
        Prog*   pcrel;  // 5l
        int32   spadj;
-       uchar   mark;
+       uint16  mark;
+       uint16  optab;  // 5l, 9l
        uchar   back;   // 6l, 8l
        uchar   ft;     /* 6l, 8l oclass cache */
        uchar   tt;     // 6l, 8l
-       uint16  optab;  // 5l
        uchar   isize;  // 6l, 8l
 
        char    width;  /* fake for DATA */
@@ -233,10 +234,12 @@ enum
 enum
 {
        R_ADDR = 1,
+       R_ADDRPOWER, // relocation for loading 31-bit address using addis and addi/ld/st for Power
        R_SIZE,
        R_CALL, // relocation for direct PC-relative call
        R_CALLARM, // relocation for ARM direct call
        R_CALLIND, // marker for indirect call (no actual relocating necessary)
+       R_CALLPOWER, // relocation for Power direct call
        R_CONST,
        R_PCREL,
        R_TLS,
@@ -529,6 +532,9 @@ void        span6(Link *ctxt, LSym *s);
 // asm8.c
 void   span8(Link *ctxt, LSym *s);
 
+// asm9.c
+void   span9(Link *ctxt, LSym *s);
+
 // data.c
 vlong  addaddr(Link *ctxt, LSym *s, LSym *t);
 vlong  addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add);
@@ -576,10 +582,11 @@ Prog*     copyp(Link*, Prog*);
 Prog*  appendp(Link*, Prog*);
 vlong  atolwhex(char*);
 
-// list[568].c
+// list[5689].c
 void   listinit5(void);
 void   listinit6(void);
 void   listinit8(void);
+void   listinit9(void);
 
 // obj.c
 int    linklinefmt(Link *ctxt, Fmt *fp);
@@ -611,20 +618,24 @@ char*     headstr(int);
 extern char*   anames5[];
 extern char*   anames6[];
 extern char*   anames8[];
+extern char*   anames9[];
 
 extern char*   cnames5[];
+extern char*   cnames9[];
 
 extern LinkArch        link386;
 extern LinkArch        linkamd64;
 extern LinkArch        linkamd64p32;
 extern LinkArch        linkarm;
+extern LinkArch        linkpower64;
+extern LinkArch        linkpower64le;
 
 #pragma        varargck        type    "A"     int
 #pragma        varargck        type    "D"     Addr*
 #pragma        varargck        type    "lD"    Addr*
 #pragma        varargck        type    "P"     Prog*
 #pragma        varargck        type    "R"     int
-#pragma varargck       type    "^"     int
+#pragma        varargck        type    "^"     int // for 5l/9l, C_* classes (liblink internal)
 
 // TODO(ality): remove this workaround.
 //   It's here because Pconv in liblink/list?.c references %L.
index 2801ebf8d6ea0e5b4c9f3b8918dc91989ed96279..43dbf3ce3b817d7998070c0fe33078c4479a63d4 100644 (file)
@@ -1 +1,2 @@
 defaultcc: golang-codereviews@googlegroups.com
+contributors: http://go.googlecode.com/hg/CONTRIBUTORS
index fdf11d1f48f924ed261319c61af3a0a4329f42db..263385b79f991090a6dc4abcc0dc5adad39d4286 100644 (file)
@@ -3603,11 +3603,17 @@ class MercurialVCS(VersionControlSystem):
                        if use_hg_shell:
                                base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], silent_ok=True)
                        else:
-                               base_content = str(self.repo[base_rev][oldrelpath].data())
+                                try:
+                                        base_content = str(self.repo[base_rev][oldrelpath].data())
+                                except Exception:
+                                        pass
                        is_binary = "\0" in base_content  # Mercurial's heuristic
                if status != "R":
-                       new_content = open(relpath, "rb").read()
-                       is_binary = is_binary or "\0" in new_content
+                        try:
+                                new_content = open(relpath, "rb").read()
+                                is_binary = is_binary or "\0" in new_content
+                        except Exception:
+                                pass
                if is_binary and base_content and use_hg_shell:
                        # Fetch again without converting newlines
                        base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath],
index bb60fe7de2505ec8ad46b6c43180c71bb06dd68a..df9838ad37cea770abf54cd705e812f6f81b5814 100644 (file)
@@ -67,6 +67,7 @@ struct        Sym
        int32   value;
        ushort  type;
        char    *name;
+       char*   labelname;
        char    sym;
 };
 #define        S       ((Sym*)0)
@@ -136,6 +137,8 @@ void        newio(void);
 void   newfile(char*, int);
 Sym*   slookup(char*);
 Sym*   lookup(void);
+Sym*   labellookup(Sym*);
+void   settext(LSym*);
 void   syminit(Sym*);
 int32  yylex(void);
 int    getc(void);
index ad647606ef893dafae8ac173bdf2288dac57807e..d365c753433f1052d0b5d322e95f36d1750c0cef 100644 (file)
@@ -73,15 +73,11 @@ prog:
        line
 
 line:
-       LLAB ':'
-       {
-               if($1->value != pc)
-                       yyerror("redeclaration of %s", $1->name);
-               $1->value = pc;
-       }
-       line
-|      LNAME ':'
+       LNAME ':'
        {
+               $1 = labellookup($1);
+               if($1->type == LLAB && $1->value != pc)
+                       yyerror("redeclaration of %s", $1->labelname);
                $1->type = LLAB;
                $1->value = pc;
        }
@@ -218,18 +214,21 @@ inst:
  */
 |      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);
@@ -373,15 +372,10 @@ rel:
        }
 |      LNAME offset
        {
+               $1 = labellookup($1);
                $$ = nullgen;
-               if(pass == 2)
-                       yyerror("undefined label: %s", $1->name);
-               $$.type = D_BRANCH;
-               $$.offset = $2;
-       }
-|      LLAB offset
-       {
-               $$ = nullgen;
+               if(pass == 2 && $1->type != LLAB)
+                       yyerror("undefined label: %s", $1->labelname);
                $$.type = D_BRANCH;
                $$.offset = $1->value + $2;
        }
index a6251b83529296468f3d153ac92287d66bcd4181..ace80c7e0eb1325f90e60708ae1098569ad17ada 100644 (file)
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
-/* Bison implementation for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -26,7 +29,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -44,7 +47,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.7.12-4996"
+#define YYBISON_VERSION "2.3"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
 /* Pure parsers.  */
 #define YYPURE 0
 
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
-
-
-
-/* Copy the first part of user declarations.  */
-/* Line 371 of yacc.c  */
-#line 31 "a.y"
-
-#include <u.h>
-#include <stdio.h>     /* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../runtime/funcdata.h"
+/* Using locations.  */
+#define YYLSP_NEEDED 0
 
-/* Line 371 of yacc.c  */
-#line 76 "y.tab.c"
 
-# ifndef YY_NULL
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULL nullptr
-#  else
-#   define YY_NULL 0
-#  endif
-# endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* In a future release of Bison, this section will be replaced
-   by #include "y.tab.h".  */
-#ifndef YY_YY_Y_TAB_H_INCLUDED
-# define YY_YY_Y_TAB_H_INCLUDED
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
 
 /* Tokens.  */
 #ifndef YYTOKENTYPE
@@ -210,49 +168,60 @@ extern int yydebug;
 
 
 
+
+/* Copy the first part of user declarations.  */
+#line 31 "a.y"
+
+#include <u.h>
+#include <stdio.h>     /* if we don't, bison will, and a.h re-#defines getc */
+#include <libc.h>
+#include "a.h"
+#include "../../runtime/funcdata.h"
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-/* Line 387 of yacc.c  */
 #line 39 "a.y"
-
+{
        Sym     *sym;
        int32   lval;
        double  dval;
        char    sval[8];
        Addr    addr;
-
-
-/* Line 387 of yacc.c  */
-#line 228 "y.tab.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 193 of yacc.c.  */
+#line 212 "y.tab.c"
+       YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
-extern YYSTYPE yylval;
 
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-#endif /* !YY_YY_Y_TAB_H_INCLUDED  */
 
 /* Copy the second part of user declarations.  */
 
-/* Line 390 of yacc.c  */
-#line 256 "y.tab.c"
+
+/* Line 216 of yacc.c.  */
+#line 225 "y.tab.c"
 
 #ifdef short
 # undef short
@@ -305,45 +274,36 @@ typedef short int yytype_int16;
 # if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(Msgid) Msgid
-# endif
-#endif
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later.  */
-# if (! defined __GNUC__ || __GNUC__ < 2 \
-      || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
-#  define __attribute__(Spec) /* empty */
+#  define YY_(msgid) msgid
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(E) ((void) (E))
+# define YYUSE(e) ((void) (e))
 #else
-# define YYUSE(E) /* empty */
+# define YYUSE(e) /* empty */
 #endif
 
-
 /* Identity function, used to suppress warnings about constant conditions.  */
 #ifndef lint
-# define YYID(N) (N)
+# define YYID(n) (n)
 #else
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static int
-YYID (int yyi)
+YYID (int i)
 #else
 static int
-YYID (yyi)
-    int yyi;
+YYID (i)
+    int i;
 #endif
 {
-  return yyi;
+  return i;
 }
 #endif
 
@@ -364,12 +324,11 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
 #     endif
 #    endif
 #   endif
@@ -392,24 +351,24 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
+#  if (defined __cplusplus && ! defined _STDLIB_H \
        && ! ((defined YYMALLOC || defined malloc) \
             && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -425,9 +384,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-};
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
 
 /* The size of the maximum gap between one aligned stack and the next.  */
 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -438,19 +397,35 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
-# define YYCOPY_NEEDED 1
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (YYID (0))
+#  endif
+# endif
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                          \
+# define YYSTACK_RELOCATE(Stack)                                       \
     do                                                                 \
       {                                                                        \
        YYSIZE_T yynewbytes;                                            \
-       YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-       Stack = &yyptr->Stack_alloc;                                    \
+       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
+       Stack = &yyptr->Stack;                                          \
        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
        yyptr += yynewbytes / sizeof (*yyptr);                          \
       }                                                                        \
@@ -458,39 +433,19 @@ union yyalloc
 
 #endif
 
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(Dst, Src, Count) \
-      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
-#  else
-#   define YYCOPY(Dst, Src, Count)              \
-      do                                        \
-        {                                       \
-          YYSIZE_T yyi;                         \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (Dst)[yyi] = (Src)[yyi];            \
-        }                                       \
-      while (YYID (0))
-#  endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   609
+#define YYLAST   640
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  71
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  35
+#define YYNNTS  34
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  133
+#define YYNRULES  130
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  339
+#define YYNSTATES  333
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -540,101 +495,100 @@ static const yytype_uint8 yytranslate[] =
    YYRHS.  */
 static const yytype_uint16 yyprhs[] =
 {
-       0,     0,     3,     4,     5,     9,    10,    15,    16,    21,
-      26,    31,    33,    36,    39,    47,    54,    60,    66,    72,
-      77,    82,    86,    90,    95,   102,   110,   118,   126,   133,
-     140,   144,   149,   156,   165,   172,   177,   181,   187,   193,
-     201,   208,   221,   229,   239,   242,   247,   252,   255,   256,
-     259,   262,   263,   266,   271,   274,   277,   280,   283,   288,
-     291,   293,   296,   300,   302,   306,   310,   312,   314,   316,
-     321,   323,   325,   327,   329,   331,   333,   335,   339,   341,
-     346,   348,   353,   355,   357,   359,   361,   364,   366,   372,
-     377,   382,   387,   392,   394,   396,   398,   400,   405,   407,
-     409,   411,   416,   418,   420,   422,   427,   432,   438,   446,
-     447,   450,   453,   455,   457,   459,   461,   463,   466,   469,
-     472,   476,   477,   480,   482,   486,   490,   494,   498,   502,
-     507,   512,   516,   520
+       0,     0,     3,     4,     5,     9,    10,    15,    20,    25,
+      27,    30,    33,    41,    48,    54,    60,    66,    71,    76,
+      80,    84,    89,    96,   104,   112,   120,   127,   134,   138,
+     143,   150,   159,   166,   171,   175,   181,   187,   195,   202,
+     215,   223,   233,   236,   241,   246,   249,   250,   253,   256,
+     257,   260,   265,   268,   271,   274,   279,   282,   284,   287,
+     291,   293,   297,   301,   303,   305,   307,   312,   314,   316,
+     318,   320,   322,   324,   326,   330,   332,   337,   339,   344,
+     346,   348,   350,   352,   355,   357,   363,   368,   373,   378,
+     383,   385,   387,   389,   391,   396,   398,   400,   402,   407,
+     409,   411,   413,   418,   423,   429,   437,   438,   441,   444,
+     446,   448,   450,   452,   454,   457,   460,   463,   467,   468,
+     471,   473,   477,   481,   485,   489,   493,   498,   503,   507,
+     511
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
       72,     0,    -1,    -1,    -1,    72,    73,    74,    -1,    -1,
-      59,    61,    75,    74,    -1,    -1,    58,    61,    76,    74,
-      -1,    58,    62,   105,    63,    -1,    60,    62,   105,    63,
-      -1,    63,    -1,    77,    63,    -1,     1,    63,    -1,    13,
-      78,    89,    64,    96,    64,    91,    -1,    13,    78,    89,
-      64,    96,    64,    -1,    13,    78,    89,    64,    91,    -1,
-      14,    78,    89,    64,    91,    -1,    15,    78,    84,    64,
-      84,    -1,    16,    78,    79,    80,    -1,    16,    78,    79,
-      85,    -1,    35,    79,    86,    -1,    17,    79,    80,    -1,
-      18,    78,    79,    84,    -1,    19,    78,    89,    64,    96,
-      79,    -1,    20,    78,    87,    64,    65,    83,    66,    -1,
-      20,    78,    65,    83,    66,    64,    87,    -1,    21,    78,
-      91,    64,    86,    64,    91,    -1,    21,    78,    91,    64,
-      86,    79,    -1,    21,    78,    79,    86,    64,    91,    -1,
-      22,    78,    79,    -1,    23,   100,    64,    90,    -1,    23,
-     100,    64,   103,    64,    90,    -1,    23,   100,    64,   103,
-      64,    90,     9,   103,    -1,    24,   100,    11,   103,    64,
-      81,    -1,    25,    78,    91,    79,    -1,    28,    79,    81,
-      -1,    29,    78,    99,    64,    99,    -1,    31,    78,    98,
-      64,    99,    -1,    31,    78,    98,    64,    48,    64,    99,
-      -1,    32,    78,    99,    64,    99,    79,    -1,    30,    78,
-     103,    64,   105,    64,    96,    64,    97,    64,    97,   104,
-      -1,    33,    78,    91,    64,    91,    64,    92,    -1,    34,
-      78,    91,    64,    91,    64,    91,    64,    96,    -1,    36,
-      88,    -1,    43,    84,    64,    84,    -1,    44,    84,    64,
-      84,    -1,    26,    79,    -1,    -1,    78,    53,    -1,    78,
-      54,    -1,    -1,    64,    79,    -1,   103,    67,    41,    68,
-      -1,    58,   101,    -1,    59,   101,    -1,    69,   103,    -1,
-      69,    88,    -1,    69,    10,    69,    88,    -1,    69,    57,
-      -1,    82,    -1,    69,    56,    -1,    69,     9,    56,    -1,
-      96,    -1,    96,     9,    96,    -1,    96,    79,    83,    -1,
-      91,    -1,    81,    -1,    93,    -1,    93,    67,    96,    68,
-      -1,    51,    -1,    52,    -1,   103,    -1,    88,    -1,    99,
-      -1,    86,    -1,   100,    -1,    67,    96,    68,    -1,    86,
-      -1,   103,    67,    95,    68,    -1,   100,    -1,   100,    67,
-      95,    68,    -1,    87,    -1,    91,    -1,    90,    -1,    93,
-      -1,    69,   103,    -1,    96,    -1,    67,    96,    64,    96,
-      68,    -1,    96,     6,     6,    94,    -1,    96,     7,     7,
-      94,    -1,    96,     9,     7,    94,    -1,    96,    55,     7,
-      94,    -1,    96,    -1,   103,    -1,    46,    -1,    41,    -1,
-      45,    67,   105,    68,    -1,    95,    -1,    38,    -1,    50,
-      -1,    49,    67,   105,    68,    -1,    99,    -1,    82,    -1,
-      48,    -1,    47,    67,   103,    68,    -1,   103,    67,   102,
-      68,    -1,    58,   101,    67,   102,    68,    -1,    58,     6,
-       7,   101,    67,    39,    68,    -1,    -1,     8,   103,    -1,
-       9,   103,    -1,    39,    -1,    38,    -1,    40,    -1,    37,
-      -1,    60,    -1,     9,   103,    -1,     8,   103,    -1,    70,
-     103,    -1,    67,   105,    68,    -1,    -1,    64,   105,    -1,
-     103,    -1,   105,     8,   105,    -1,   105,     9,   105,    -1,
-     105,    10,   105,    -1,   105,    11,   105,    -1,   105,    12,
-     105,    -1,   105,     6,     6,   105,    -1,   105,     7,     7,
-     105,    -1,   105,     5,   105,    -1,   105,     4,   105,    -1,
-     105,     3,   105,    -1
+      58,    61,    75,    74,    -1,    58,    62,   104,    63,    -1,
+      60,    62,   104,    63,    -1,    63,    -1,    76,    63,    -1,
+       1,    63,    -1,    13,    77,    88,    64,    95,    64,    90,
+      -1,    13,    77,    88,    64,    95,    64,    -1,    13,    77,
+      88,    64,    90,    -1,    14,    77,    88,    64,    90,    -1,
+      15,    77,    83,    64,    83,    -1,    16,    77,    78,    79,
+      -1,    16,    77,    78,    84,    -1,    35,    78,    85,    -1,
+      17,    78,    79,    -1,    18,    77,    78,    83,    -1,    19,
+      77,    88,    64,    95,    78,    -1,    20,    77,    86,    64,
+      65,    82,    66,    -1,    20,    77,    65,    82,    66,    64,
+      86,    -1,    21,    77,    90,    64,    85,    64,    90,    -1,
+      21,    77,    90,    64,    85,    78,    -1,    21,    77,    78,
+      85,    64,    90,    -1,    22,    77,    78,    -1,    23,    99,
+      64,    89,    -1,    23,    99,    64,   102,    64,    89,    -1,
+      23,    99,    64,   102,    64,    89,     9,   102,    -1,    24,
+      99,    11,   102,    64,    80,    -1,    25,    77,    90,    78,
+      -1,    28,    78,    80,    -1,    29,    77,    98,    64,    98,
+      -1,    31,    77,    97,    64,    98,    -1,    31,    77,    97,
+      64,    48,    64,    98,    -1,    32,    77,    98,    64,    98,
+      78,    -1,    30,    77,   102,    64,   104,    64,    95,    64,
+      96,    64,    96,   103,    -1,    33,    77,    90,    64,    90,
+      64,    91,    -1,    34,    77,    90,    64,    90,    64,    90,
+      64,    95,    -1,    36,    87,    -1,    43,    83,    64,    83,
+      -1,    44,    83,    64,    83,    -1,    26,    78,    -1,    -1,
+      77,    53,    -1,    77,    54,    -1,    -1,    64,    78,    -1,
+     102,    67,    41,    68,    -1,    58,   100,    -1,    69,   102,
+      -1,    69,    87,    -1,    69,    10,    69,    87,    -1,    69,
+      57,    -1,    81,    -1,    69,    56,    -1,    69,     9,    56,
+      -1,    95,    -1,    95,     9,    95,    -1,    95,    78,    82,
+      -1,    90,    -1,    80,    -1,    92,    -1,    92,    67,    95,
+      68,    -1,    51,    -1,    52,    -1,   102,    -1,    87,    -1,
+      98,    -1,    85,    -1,    99,    -1,    67,    95,    68,    -1,
+      85,    -1,   102,    67,    94,    68,    -1,    99,    -1,    99,
+      67,    94,    68,    -1,    86,    -1,    90,    -1,    89,    -1,
+      92,    -1,    69,   102,    -1,    95,    -1,    67,    95,    64,
+      95,    68,    -1,    95,     6,     6,    93,    -1,    95,     7,
+       7,    93,    -1,    95,     9,     7,    93,    -1,    95,    55,
+       7,    93,    -1,    95,    -1,   102,    -1,    46,    -1,    41,
+      -1,    45,    67,   104,    68,    -1,    94,    -1,    38,    -1,
+      50,    -1,    49,    67,   104,    68,    -1,    98,    -1,    81,
+      -1,    48,    -1,    47,    67,   102,    68,    -1,   102,    67,
+     101,    68,    -1,    58,   100,    67,   101,    68,    -1,    58,
+       6,     7,   100,    67,    39,    68,    -1,    -1,     8,   102,
+      -1,     9,   102,    -1,    39,    -1,    38,    -1,    40,    -1,
+      37,    -1,    60,    -1,     9,   102,    -1,     8,   102,    -1,
+      70,   102,    -1,    67,   104,    68,    -1,    -1,    64,   104,
+      -1,   102,    -1,   104,     8,   104,    -1,   104,     9,   104,
+      -1,   104,    10,   104,    -1,   104,    11,   104,    -1,   104,
+      12,   104,    -1,   104,     6,     6,   104,    -1,   104,     7,
+       7,   104,    -1,   104,     5,   104,    -1,   104,     4,   104,
+      -1,   104,     3,   104,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,    68,    68,    70,    69,    77,    76,    84,    83,    89,
-      94,   100,   101,   102,   108,   112,   116,   123,   130,   137,
-     141,   148,   155,   162,   169,   176,   185,   197,   201,   205,
-     212,   219,   225,   231,   240,   247,   254,   261,   265,   269,
-     273,   280,   302,   310,   319,   326,   335,   346,   352,   355,
-     359,   364,   365,   368,   374,   382,   389,   395,   400,   405,
-     411,   414,   420,   428,   432,   441,   447,   448,   449,   450,
-     455,   461,   467,   473,   474,   477,   478,   486,   495,   496,
-     505,   506,   512,   515,   516,   517,   519,   527,   535,   544,
-     550,   556,   562,   570,   576,   584,   585,   589,   597,   598,
-     604,   605,   613,   614,   617,   623,   631,   639,   647,   657,
-     660,   664,   670,   671,   672,   675,   676,   680,   684,   688,
-     692,   698,   701,   707,   708,   712,   716,   720,   724,   728,
-     732,   736,   740,   744
+       0,    68,    68,    70,    69,    77,    76,    85,    90,    96,
+      97,    98,   104,   108,   112,   119,   126,   133,   137,   144,
+     151,   158,   165,   172,   181,   193,   197,   201,   208,   215,
+     222,   229,   239,   246,   253,   260,   264,   268,   272,   279,
+     301,   309,   318,   325,   334,   345,   351,   354,   358,   363,
+     364,   367,   373,   383,   389,   394,   399,   405,   408,   414,
+     422,   426,   435,   441,   442,   443,   444,   449,   455,   461,
+     467,   468,   471,   472,   480,   489,   490,   499,   500,   506,
+     509,   510,   511,   513,   521,   529,   538,   544,   550,   556,
+     564,   570,   578,   579,   583,   591,   592,   598,   599,   607,
+     608,   611,   617,   625,   633,   641,   651,   654,   658,   664,
+     665,   666,   669,   670,   674,   678,   682,   686,   692,   695,
+     701,   702,   706,   710,   714,   718,   722,   726,   730,   734,
+     738
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || 0
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -647,11 +601,11 @@ static const char *const yytname[] =
   "LSP", "LSB", "LFP", "LPC", "LTYPEX", "LTYPEPC", "LTYPEF", "LR", "LREG",
   "LF", "LFREG", "LC", "LCREG", "LPSR", "LFCR", "LCOND", "LS", "LAT",
   "LFCONST", "LSCONST", "LNAME", "LLAB", "LVAR", "':'", "'='", "';'",
-  "','", "'['", "']'", "'('", "')'", "'$'", "'~'", "$accept", "prog",
-  "$@1", "line", "$@2", "$@3", "inst", "cond", "comma", "rel", "ximm",
-  "fcon", "reglist", "gen", "nireg", "ireg", "ioreg", "oreg", "imsr",
-  "imm", "reg", "regreg", "shift", "rcon", "sreg", "spreg", "creg",
-  "frcon", "freg", "name", "offset", "pointer", "con", "oexpr", "expr", YY_NULL
+  "','", "'['", "']'", "'('", "')'", "'$'", "'~'", "$accept", "prog", "@1",
+  "line", "@2", "inst", "cond", "comma", "rel", "ximm", "fcon", "reglist",
+  "gen", "nireg", "ireg", "ioreg", "oreg", "imsr", "imm", "reg", "regreg",
+  "shift", "rcon", "sreg", "spreg", "creg", "frcon", "freg", "name",
+  "offset", "pointer", "con", "oexpr", "expr", 0
 };
 #endif
 
@@ -674,279 +628,282 @@ static const yytype_uint16 yytoknum[] =
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    71,    72,    73,    72,    75,    74,    76,    74,    74,
-      74,    74,    74,    74,    77,    77,    77,    77,    77,    77,
-      77,    77,    77,    77,    77,    77,    77,    77,    77,    77,
-      77,    77,    77,    77,    77,    77,    77,    77,    77,    77,
-      77,    77,    77,    77,    77,    77,    77,    77,    78,    78,
-      78,    79,    79,    80,    80,    80,    81,    81,    81,    81,
-      81,    82,    82,    83,    83,    83,    84,    84,    84,    84,
-      84,    84,    84,    84,    84,    85,    85,    86,    87,    87,
-      88,    88,    88,    89,    89,    89,    90,    91,    92,    93,
-      93,    93,    93,    94,    94,    95,    95,    95,    96,    96,
-      97,    97,    98,    98,    99,    99,   100,   100,   100,   101,
-     101,   101,   102,   102,   102,   103,   103,   103,   103,   103,
-     103,   104,   104,   105,   105,   105,   105,   105,   105,   105,
-     105,   105,   105,   105
+       0,    71,    72,    73,    72,    75,    74,    74,    74,    74,
+      74,    74,    76,    76,    76,    76,    76,    76,    76,    76,
+      76,    76,    76,    76,    76,    76,    76,    76,    76,    76,
+      76,    76,    76,    76,    76,    76,    76,    76,    76,    76,
+      76,    76,    76,    76,    76,    76,    77,    77,    77,    78,
+      78,    79,    79,    80,    80,    80,    80,    80,    81,    81,
+      82,    82,    82,    83,    83,    83,    83,    83,    83,    83,
+      83,    83,    84,    84,    85,    86,    86,    87,    87,    87,
+      88,    88,    88,    89,    90,    91,    92,    92,    92,    92,
+      93,    93,    94,    94,    94,    95,    95,    96,    96,    97,
+      97,    98,    98,    99,    99,    99,   100,   100,   100,   101,
+     101,   101,   102,   102,   102,   102,   102,   102,   103,   103,
+     104,   104,   104,   104,   104,   104,   104,   104,   104,   104,
+     104
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     0,     0,     3,     0,     4,     0,     4,     4,
-       4,     1,     2,     2,     7,     6,     5,     5,     5,     4,
-       4,     3,     3,     4,     6,     7,     7,     7,     6,     6,
-       3,     4,     6,     8,     6,     4,     3,     5,     5,     7,
-       6,    12,     7,     9,     2,     4,     4,     2,     0,     2,
-       2,     0,     2,     4,     2,     2,     2,     2,     4,     2,
-       1,     2,     3,     1,     3,     3,     1,     1,     1,     4,
-       1,     1,     1,     1,     1,     1,     1,     3,     1,     4,
-       1,     4,     1,     1,     1,     1,     2,     1,     5,     4,
-       4,     4,     4,     1,     1,     1,     1,     4,     1,     1,
-       1,     4,     1,     1,     1,     4,     4,     5,     7,     0,
-       2,     2,     1,     1,     1,     1,     1,     2,     2,     2,
-       3,     0,     2,     1,     3,     3,     3,     3,     3,     4,
-       4,     3,     3,     3
+       0,     2,     0,     0,     3,     0,     4,     4,     4,     1,
+       2,     2,     7,     6,     5,     5,     5,     4,     4,     3,
+       3,     4,     6,     7,     7,     7,     6,     6,     3,     4,
+       6,     8,     6,     4,     3,     5,     5,     7,     6,    12,
+       7,     9,     2,     4,     4,     2,     0,     2,     2,     0,
+       2,     4,     2,     2,     2,     4,     2,     1,     2,     3,
+       1,     3,     3,     1,     1,     1,     4,     1,     1,     1,
+       1,     1,     1,     1,     3,     1,     4,     1,     4,     1,
+       1,     1,     1,     2,     1,     5,     4,     4,     4,     4,
+       1,     1,     1,     1,     4,     1,     1,     1,     4,     1,
+       1,     1,     4,     4,     5,     7,     0,     2,     2,     1,
+       1,     1,     1,     1,     2,     2,     2,     3,     0,     2,
+       1,     3,     3,     3,     3,     3,     4,     4,     3,     3,
+       3
 };
 
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
-   Performed when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,     3,     1,     0,     0,    48,    48,    48,    48,    51,
-      48,    48,    48,    48,    48,     0,     0,    48,    51,    51,
-      48,    48,    48,    48,    48,    48,    51,     0,     0,     0,
-       0,     0,     0,    11,     4,     0,    13,     0,     0,     0,
-      51,    51,     0,    51,     0,     0,    51,    51,     0,     0,
-     115,   109,   116,     0,     0,     0,     0,     0,     0,    47,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,    78,
-      82,    44,    80,     0,    99,    96,     0,    95,     0,   104,
-      70,    71,     0,    67,    60,     0,    73,    66,    68,    98,
-      87,    74,    72,     0,     7,     0,     5,     0,    12,    49,
-      50,     0,     0,    84,    83,    85,     0,     0,     0,    52,
-     109,   109,    22,     0,     0,     0,     0,     0,     0,     0,
-       0,    87,    30,   118,   117,     0,     0,     0,     0,   123,
-       0,   119,     0,     0,     0,    51,    36,     0,     0,     0,
-     103,     0,   102,     0,     0,     0,     0,    21,     0,     0,
-       0,     0,     0,     0,     0,    61,    59,    57,    56,     0,
+       2,     3,     1,     0,     0,    46,    46,    46,    46,    49,
+      46,    46,    46,    46,    46,     0,     0,    46,    49,    49,
+      46,    46,    46,    46,    46,    46,    49,     0,     0,     0,
+       0,     0,     9,     4,     0,    11,     0,     0,     0,    49,
+      49,     0,    49,     0,     0,    49,    49,     0,     0,   112,
+     106,   113,     0,     0,     0,     0,     0,     0,    45,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    75,    79,
+      42,    77,     0,    96,    93,     0,    92,     0,   101,    67,
+      68,     0,    64,    57,     0,    70,    63,    65,    95,    84,
+      71,    69,     0,     5,     0,     0,    10,    47,    48,     0,
+       0,    81,    80,    82,     0,     0,     0,    50,   106,    20,
+       0,     0,     0,     0,     0,     0,     0,     0,    84,    28,
+     115,   114,     0,     0,     0,     0,   120,     0,   116,     0,
+       0,     0,    49,    34,     0,     0,     0,   100,     0,    99,
+       0,     0,     0,     0,    19,     0,     0,     0,     0,     0,
+       0,     0,    58,    56,    54,    53,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    83,     0,     0,     0,
+     106,    17,    18,    72,    73,     0,    52,     0,    21,     0,
+       0,    49,     0,     0,     0,     0,   106,   107,   108,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      86,     0,     0,     0,   109,    19,    20,    75,    76,     0,
-      54,    55,     0,    23,     0,     0,    51,     0,     0,     0,
-       0,   109,   110,   111,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   120,    31,     0,   113,   112,
-     114,     0,     0,    35,     0,     0,     0,     0,     0,     0,
-       0,    77,     0,     0,     0,     0,    62,     0,    45,     0,
-       0,     0,     0,     0,    46,     8,     9,     6,    10,    16,
-      87,    17,    18,    54,     0,     0,    51,     0,     0,     0,
-       0,     0,    51,     0,     0,   133,   132,   131,     0,     0,
-     124,   125,   126,   127,   128,     0,   106,     0,    37,     0,
-     104,    38,    51,     0,     0,    81,    79,    97,   105,    58,
-      69,    89,    93,    94,    90,    91,    92,    15,    53,    24,
-       0,    64,    65,     0,    29,    51,    28,     0,   107,   129,
-     130,    32,    34,     0,     0,    40,     0,     0,    14,    26,
-      25,    27,     0,     0,     0,    39,     0,    42,     0,   108,
-      33,     0,     0,     0,     0,   100,     0,     0,    43,     0,
-       0,     0,     0,   121,    88,   101,     0,    41,   122
+     117,    29,     0,   110,   109,   111,     0,     0,    33,     0,
+       0,     0,     0,     0,     0,     0,    74,     0,     0,     0,
+       0,    59,     0,    43,     0,     0,     0,     0,     0,    44,
+       6,     7,     8,    14,    84,    15,    16,    52,     0,     0,
+      49,     0,     0,     0,     0,     0,    49,     0,     0,   130,
+     129,   128,     0,     0,   121,   122,   123,   124,   125,     0,
+     103,     0,    35,     0,   101,    36,    49,     0,     0,    78,
+      76,    94,   102,    55,    66,    86,    90,    91,    87,    88,
+      89,    13,    51,    22,     0,    61,    62,     0,    27,    49,
+      26,     0,   104,   126,   127,    30,    32,     0,     0,    38,
+       0,     0,    12,    24,    23,    25,     0,     0,     0,    37,
+       0,    40,     0,   105,    31,     0,     0,     0,     0,    97,
+       0,     0,    41,     0,     0,     0,     0,   118,    85,    98,
+       0,    39,   119
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     1,     3,    34,   168,   166,    35,    37,   109,   112,
-      83,    84,   185,    85,   176,    69,    70,    86,   102,   103,
-      87,   317,    88,   281,    89,   121,   326,   141,    91,    72,
-     128,   211,   129,   337,   130
+      -1,     1,     3,    33,   163,    34,    36,   107,   109,    82,
+      83,   180,    84,   172,    68,    69,    85,   100,   101,    86,
+     311,    87,   275,    88,   118,   320,   138,    90,    71,   125,
+     206,   126,   331,   127
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -128
+#define YYPACT_NINF -125
 static const yytype_int16 yypact[] =
 {
-    -128,     4,  -128,   315,   -35,  -128,  -128,  -128,  -128,   -10,
-    -128,  -128,  -128,  -128,  -128,    44,    44,  -128,   -10,   -10,
-    -128,  -128,  -128,  -128,  -128,  -128,   -10,   416,   371,   371,
-     -49,     9,    32,  -128,  -128,    38,  -128,   487,   487,   344,
-      69,   -10,   391,    69,   487,   209,   489,    69,   317,   317,
-    -128,    49,  -128,   317,   317,    42,    48,   106,    67,  -128,
-      61,   191,    25,    93,   191,    67,    67,    68,   170,  -128,
-    -128,  -128,    72,    84,  -128,  -128,    86,  -128,   109,  -128,
-    -128,  -128,   233,  -128,  -128,    80,  -128,  -128,   115,  -128,
-     426,  -128,    84,   120,  -128,   317,  -128,   317,  -128,  -128,
-    -128,   317,   137,  -128,  -128,  -128,   148,   155,   397,  -128,
-      74,    74,  -128,   164,   371,   204,   240,   207,   206,    68,
-     223,  -128,  -128,  -128,  -128,   270,   317,   317,   227,  -128,
-     183,  -128,    90,   160,   317,   -10,  -128,   234,   237,    16,
-    -128,   254,  -128,   255,   256,   257,   240,  -128,   212,   168,
-     548,   317,   317,   428,   258,  -128,  -128,  -128,    84,   371,
-     240,   318,   316,   335,   348,   371,   315,   502,   315,   512,
-    -128,   240,   240,   371,    49,  -128,  -128,  -128,  -128,   289,
-    -128,  -128,   330,  -128,   240,   291,    11,   307,   168,   312,
-      68,    74,  -128,  -128,   160,   317,   317,   317,   377,   379,
-     317,   317,   317,   317,   317,  -128,  -128,   324,  -128,  -128,
-    -128,   325,   337,  -128,    77,   317,   338,   126,    77,   240,
-     240,  -128,   339,   342,   249,   347,  -128,   416,  -128,   352,
-     170,   170,   170,   170,  -128,  -128,  -128,  -128,  -128,  -128,
-     362,  -128,  -128,   227,    -2,   359,   -10,   366,   240,   240,
-     240,   240,   375,   336,   384,   562,   590,   597,   317,   317,
-     213,   213,  -128,  -128,  -128,   385,  -128,    61,  -128,   357,
-     395,  -128,   -10,   396,   398,  -128,  -128,  -128,  -128,  -128,
-    -128,  -128,  -128,  -128,  -128,  -128,  -128,   240,  -128,  -128,
-     434,  -128,  -128,   400,  -128,   432,  -128,   424,  -128,   436,
-     436,   459,  -128,   240,    77,  -128,   402,   240,  -128,  -128,
-    -128,  -128,   404,   317,   411,  -128,   240,  -128,   415,  -128,
-    -128,   216,   418,   240,   413,  -128,   421,   240,  -128,   317,
-     216,   419,   302,   425,  -128,  -128,   317,  -128,   573
+    -125,     7,  -125,   308,   -41,  -125,  -125,  -125,  -125,   -19,
+    -125,  -125,  -125,  -125,  -125,    80,    80,  -125,   -19,   -19,
+    -125,  -125,  -125,  -125,  -125,  -125,   -19,   405,   364,   364,
+     -31,   -15,  -125,  -125,    -2,  -125,   528,   528,   337,   -18,
+     -19,   409,   -18,   528,   230,   187,   -18,   448,   448,  -125,
+     257,  -125,   448,   448,    -6,    15,    94,   309,  -125,    49,
+      19,    44,    95,    19,   309,   309,    63,   391,  -125,  -125,
+    -125,    90,   137,  -125,  -125,   145,  -125,   146,  -125,  -125,
+    -125,    66,  -125,  -125,    52,  -125,  -125,   150,  -125,   147,
+    -125,   137,    57,  -125,   448,   448,  -125,  -125,  -125,   448,
+     167,  -125,  -125,  -125,   184,   200,   431,  -125,    47,  -125,
+     201,   364,   217,   189,   223,   221,    63,   228,  -125,  -125,
+    -125,  -125,   289,   448,   448,   231,  -125,   181,  -125,   411,
+      54,   448,   -19,  -125,   237,   238,    12,  -125,   240,  -125,
+     241,   244,   246,   189,  -125,   245,   114,   319,   448,   448,
+     417,   243,  -125,  -125,  -125,   137,   364,   189,   293,   312,
+     313,   341,   364,   308,   542,   552,  -125,   189,   189,   364,
+     257,  -125,  -125,  -125,  -125,   282,  -125,   315,  -125,   189,
+     287,    42,   296,   114,   303,    63,    47,  -125,  -125,    54,
+     448,   448,   448,   363,   369,   448,   448,   448,   448,   448,
+    -125,  -125,   306,  -125,  -125,  -125,   311,   316,  -125,    53,
+     448,   321,    65,    53,   189,   189,  -125,   318,   324,   250,
+     325,  -125,   405,  -125,   326,   391,   391,   391,   391,  -125,
+    -125,  -125,  -125,  -125,   317,  -125,  -125,   231,   130,   328,
+     -19,   323,   189,   189,   189,   189,   334,   336,   340,   602,
+     621,   628,   448,   448,   197,   197,  -125,  -125,  -125,   352,
+    -125,    49,  -125,   516,   359,  -125,   -19,   366,   371,  -125,
+    -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,
+    -125,   189,  -125,  -125,   474,  -125,  -125,   361,  -125,   165,
+    -125,   399,  -125,   235,   235,   432,  -125,   189,    53,  -125,
+     376,   189,  -125,  -125,  -125,  -125,   377,   448,   380,  -125,
+     189,  -125,   383,  -125,  -125,   112,   385,   189,   386,  -125,
+     388,   189,  -125,   448,   112,   382,   267,   395,  -125,  -125,
+     448,  -125,   613
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -128,  -128,  -128,   -77,  -128,  -128,  -128,   538,    50,   382,
-     -57,   429,    33,    -7,  -128,   -48,   -43,   -21,    36,  -127,
-     -23,  -128,    29,    17,  -101,   -28,   161,  -128,   -37,    -8,
-     -65,   299,     2,  -128,   -32
+    -125,  -125,  -125,   292,  -125,  -125,   578,    45,   354,   -56,
+     400,   -48,   -25,  -125,    -7,   -42,   -21,    -5,  -124,     5,
+    -125,   -10,    89,  -118,   -28,   140,  -125,   -46,     4,   -90,
+     277,    -4,  -125,   -16
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -64
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -61
 static const yytype_int16 yytable[] =
 {
-      90,    90,   117,   136,     2,   206,    71,    55,    57,    90,
-      90,    90,    94,    95,   104,   104,    90,    56,    56,   147,
-     248,   104,    93,   120,   137,   216,   142,   143,    36,    73,
-      92,    92,   107,    48,    49,   135,   208,   209,   210,   245,
-     148,    92,   144,   145,   113,   180,   181,   118,   222,   223,
-     123,   124,    48,    49,    41,   125,   131,   126,   127,    42,
-     177,   157,    50,   167,   138,   169,   105,   105,    59,    60,
-      96,   189,   155,   105,   106,    41,    67,   -63,    99,   100,
-     115,    50,   126,   127,   158,    52,    90,   223,   186,   235,
-     108,   237,    53,   114,    97,    54,   119,   122,    48,    49,
-     178,    98,    51,   170,    52,    74,   132,   183,    75,   243,
-     179,    53,    76,    77,    54,   133,    92,   134,   148,   224,
-      99,   100,    99,   100,    78,    79,   253,    50,   192,   193,
-      82,    90,   229,    41,   207,   146,   212,    90,   301,   149,
-      78,    79,   252,   240,   159,    90,    99,   100,   239,   241,
-      52,   150,   228,   151,   225,   124,   246,    53,   234,   101,
-      54,    92,   139,   255,   256,   257,   242,    92,   260,   261,
-     262,   263,   264,    78,   270,    92,   152,   268,    48,    49,
-     271,   272,   160,   269,   165,   213,   195,   196,   197,   198,
-     199,   200,   201,   202,   203,   204,   273,   274,   208,   209,
-     210,   171,   282,   282,   282,   282,   279,    50,    74,    75,
-     302,    75,   172,    76,    77,    76,    77,    48,    49,   173,
-     291,   186,   186,   202,   203,   204,   299,   300,   294,    73,
-      52,   182,   283,   283,   283,   283,   249,    53,    78,    79,
-      54,    48,   153,   154,    99,   100,    50,   309,   284,   285,
-     286,   205,   195,   196,   197,   198,   199,   200,   201,   202,
-     203,   204,    99,   100,   308,   324,   325,   315,   184,    52,
-      50,   187,   311,   188,   116,   314,    68,   191,    74,    54,
-     221,    75,   292,   293,   318,    76,    77,   190,   322,   155,
-     156,    51,   118,    52,   194,   328,   289,   332,   214,   331,
-      68,   215,   296,    54,   338,   195,   196,   197,   198,   199,
-     200,   201,   202,   203,   204,   320,     4,   277,   217,   218,
-     219,   220,   305,   231,   230,    48,    49,   227,     5,     6,
-       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-      17,    18,   232,    19,    20,    21,    22,    23,    24,    25,
-      26,    27,    48,    49,    50,   233,   244,   247,    28,    29,
-     195,   196,   197,   198,   199,   200,   201,   202,   203,   204,
-     335,   245,   250,    30,    31,    32,   251,    52,    33,    48,
-      49,    50,    74,   258,    53,    75,   259,    54,   265,    76,
-      77,    78,    79,   266,   226,    80,    81,    99,   100,    48,
-      49,   267,    51,   297,    52,    48,    49,   275,    50,    74,
-     276,    68,    75,    82,    54,   278,    76,    77,    78,    79,
-     280,   303,    80,    81,    48,    49,   287,   288,    50,    51,
-     290,    52,   161,   162,    50,   163,    48,    49,    68,   295,
-      82,    54,    48,    49,   200,   201,   202,   203,   204,   110,
-     111,    52,   298,    50,   101,   174,   111,    52,    53,   304,
-     306,    54,   307,   312,    68,    50,   310,    54,   313,   316,
-      74,    50,   319,    75,    51,   321,    52,    76,    77,   323,
-     329,   164,   327,    68,   226,   330,    54,   334,    52,   336,
-     175,   333,   140,   254,    52,    53,    41,     0,    54,     0,
-       0,    68,     0,     0,    54,   195,   196,   197,   198,   199,
-     200,   201,   202,   203,   204,   195,   196,   197,   198,   199,
-     200,   201,   202,   203,   204,    74,     0,    74,    75,     0,
-      75,     0,    76,    77,    76,    77,     0,     0,     0,     0,
-      99,   100,    99,   100,    38,    39,    40,     0,    43,    44,
-      45,    46,    47,    41,     0,    58,   101,     0,    61,    62,
-      63,    64,    65,    66,     0,   236,   196,   197,   198,   199,
-     200,   201,   202,   203,   204,   238,   195,   196,   197,   198,
-     199,   200,   201,   202,   203,   204,   208,   209,   210,    75,
-       0,     0,     0,    76,    77,   197,   198,   199,   200,   201,
-     202,   203,   204,   198,   199,   200,   201,   202,   203,   204
+      89,    89,   114,   133,    92,   201,    70,     2,    89,    89,
+      89,    55,    55,   105,   134,    89,   139,   140,   176,    54,
+      56,   211,    35,    72,    91,    91,   103,   103,   217,   218,
+      93,    94,   104,   103,    91,    97,    98,   110,   112,   145,
+     115,   102,   102,   120,   121,    40,    40,    95,   102,   128,
+     117,   242,    47,    48,    41,   123,   124,   135,   129,   144,
+     154,    96,   132,    58,    59,   218,    77,    78,   152,   141,
+     142,    66,    97,    98,    47,   150,   151,   155,   164,   165,
+     237,    49,   130,    89,   106,   181,   178,   111,    47,    48,
+     116,   119,   203,   204,   205,   166,   247,    97,    98,   173,
+      77,    78,   175,    49,    51,   131,    40,    91,   -60,   184,
+     174,    52,    77,   264,    53,   145,   156,    49,    81,   187,
+     188,   162,   152,   153,    50,   202,    51,   207,    89,   224,
+     143,   223,   219,    67,    89,   295,    53,   229,    50,   234,
+      51,    89,    77,    78,   236,   220,   121,    52,    97,    98,
+      53,   240,    91,   158,   159,    74,   160,   146,    91,    75,
+      76,   318,   319,   262,   136,    91,   265,   266,   203,   204,
+     205,   239,   233,   235,   249,   250,   251,   208,   246,   254,
+     255,   256,   257,   258,   190,   191,   192,   193,   194,   195,
+     196,   197,   198,   199,   263,   286,   287,   276,   276,   276,
+     276,   273,   161,    73,   147,   296,    74,   197,   198,   199,
+      75,    76,   148,   149,   285,   181,   181,   157,    72,   267,
+     268,   277,   277,   277,   277,    73,   243,    73,    74,    40,
+      74,   167,    75,    76,    75,    76,   293,   294,    47,    48,
+      97,    98,   303,   195,   196,   197,   198,   199,   168,   200,
+     288,    40,   309,   190,   191,   192,   193,   194,   195,   196,
+     197,   198,   199,   122,   169,   123,   124,    49,   177,   308,
+     190,   191,   192,   193,   194,   195,   196,   197,   198,   199,
+     115,   179,   316,    97,    98,   283,   302,   182,   183,   322,
+      51,   290,   185,   325,   305,   113,   186,    67,   189,   225,
+      53,   209,   210,   314,   212,   213,   312,   326,   214,     4,
+     215,   299,   222,   216,   332,   278,   279,   280,   271,   226,
+     227,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,   329,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    47,    48,    73,   228,   238,
+      74,    28,    29,   241,    75,    76,   239,   203,   204,   205,
+      74,   244,    97,    98,    75,    76,    30,   245,    31,   252,
+     259,    32,    47,    48,    49,    73,   253,   221,    74,   260,
+     261,   281,    75,    76,    77,    78,   269,   284,    79,    80,
+      97,    98,   270,   272,   274,    50,   282,    51,   289,    47,
+      48,    49,    73,   291,    67,    74,    81,    53,   292,    75,
+      76,    77,    78,    47,    48,    79,    80,    47,    48,    47,
+      48,    99,    50,   298,    51,    47,    48,   304,    49,    73,
+     300,    67,    74,    81,    53,   301,    75,    76,   306,    47,
+      48,   307,    49,   310,   315,   313,    49,   317,    49,   321,
+     328,    51,   324,   323,    49,   230,    47,    48,    52,   330,
+     171,    53,   137,    50,   327,    51,   248,   108,    49,    51,
+       0,    51,    67,   221,     0,    53,    52,    51,    52,    53,
+      99,    53,    47,    48,    52,    49,     0,    53,     0,   170,
+       0,    51,     0,     0,     0,     0,     0,     0,    67,     0,
+       0,    53,     0,     0,     0,     0,     0,     0,    51,     0,
+       0,    49,     0,     0,     0,    52,     0,     0,    53,   190,
+     191,   192,   193,   194,   195,   196,   197,   198,   199,     0,
+       0,     0,     0,     0,    51,     0,     0,     0,     0,     0,
+       0,    67,     0,     0,    53,   190,   191,   192,   193,   194,
+     195,   196,   197,   198,   199,   190,   191,   192,   193,   194,
+     195,   196,   197,   198,   199,     0,    73,     0,     0,    74,
+       0,     0,     0,    75,    76,     0,     0,     0,     0,     0,
+     297,    97,    98,     0,    37,    38,    39,     0,    42,    43,
+      44,    45,    46,     0,     0,    57,     0,    99,    60,    61,
+      62,    63,    64,    65,     0,   231,   191,   192,   193,   194,
+     195,   196,   197,   198,   199,   232,   190,   191,   192,   193,
+     194,   195,   196,   197,   198,   199,   192,   193,   194,   195,
+     196,   197,   198,   199,   193,   194,   195,   196,   197,   198,
+     199
 };
 
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-128)))
-
-#define yytable_value_is_error(Yytable_value) \
-  YYID (0)
-
 static const yytype_int16 yycheck[] =
 {
-      28,    29,    45,    60,     0,   132,    27,    15,    16,    37,
-      38,    39,    61,    62,    37,    38,    44,    15,    16,    67,
-       9,    44,    29,    46,    61,     9,    63,    64,    63,    27,
-      28,    29,    39,     8,     9,    58,    38,    39,    40,    41,
-      68,    39,    65,    66,    42,   110,   111,    45,   149,   150,
-      48,    49,     8,     9,    64,     6,    54,     8,     9,     9,
-     108,    82,    37,    95,    62,    97,    37,    38,    18,    19,
-      61,   119,    56,    44,    38,    64,    26,    66,    53,    54,
-      44,    37,     8,     9,    82,    60,   114,   188,   116,   166,
-      40,   168,    67,    43,    62,    70,    46,    47,     8,     9,
-     108,    63,    58,   101,    60,    38,    64,   114,    41,   174,
-     108,    67,    45,    46,    70,    67,   114,    11,   146,   151,
-      53,    54,    53,    54,    47,    48,   191,    37,   126,   127,
-      69,   159,   160,    64,   132,    67,   134,   165,   265,    67,
-      47,    48,   190,   171,    64,   173,    53,    54,   171,   172,
-      60,    67,   159,    67,   152,   153,   184,    67,   165,    69,
-      70,   159,    69,   195,   196,   197,   173,   165,   200,   201,
-     202,   203,   204,    47,    48,   173,    67,   214,     8,     9,
-     217,   218,    67,   215,    64,   135,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,   219,   220,    38,    39,
-      40,    64,   230,   231,   232,   233,   227,    37,    38,    41,
-     267,    41,    64,    45,    46,    45,    46,     8,     9,    64,
-     248,   249,   250,    10,    11,    12,   258,   259,   251,   227,
-      60,    67,   230,   231,   232,   233,   186,    67,    47,    48,
-      70,     8,     9,    10,    53,    54,    37,   290,   231,   232,
-     233,    68,     3,     4,     5,     6,     7,     8,     9,    10,
-      11,    12,    53,    54,   287,    49,    50,   304,    64,    60,
-      37,    64,   295,    67,    65,   303,    67,     7,    38,    70,
-      68,    41,   249,   250,   307,    45,    46,    64,   316,    56,
-      57,    58,   290,    60,    67,   323,   246,   329,    64,   327,
-      67,    64,   252,    70,   336,     3,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,   313,     1,    68,    64,    64,
-      64,    64,   272,     7,     6,     8,     9,    69,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,     7,    28,    29,    30,    31,    32,    33,    34,
-      35,    36,     8,     9,    37,     7,    67,    66,    43,    44,
+      28,    29,    44,    59,    29,   129,    27,     0,    36,    37,
+      38,    15,    16,    38,    60,    43,    62,    63,   108,    15,
+      16,     9,    63,    27,    28,    29,    36,    37,   146,   147,
+      61,    62,    37,    43,    38,    53,    54,    41,    43,    67,
+      44,    36,    37,    47,    48,    64,    64,    62,    43,    53,
+      45,     9,     8,     9,     9,     8,     9,    61,    64,    66,
+      81,    63,    57,    18,    19,   183,    47,    48,    56,    64,
+      65,    26,    53,    54,     8,     9,    10,    81,    94,    95,
+     170,    37,    67,   111,    39,   113,   111,    42,     8,     9,
+      45,    46,    38,    39,    40,    99,   186,    53,    54,   106,
+      47,    48,   106,    37,    60,    11,    64,   111,    66,   116,
+     106,    67,    47,    48,    70,   143,    64,    37,    69,   123,
+     124,    64,    56,    57,    58,   129,    60,   131,   156,   157,
+      67,   156,   148,    67,   162,   259,    70,   162,    58,   167,
+      60,   169,    47,    48,   169,   149,   150,    67,    53,    54,
+      70,   179,   156,     6,     7,    41,     9,    67,   162,    45,
+      46,    49,    50,   209,    69,   169,   212,   213,    38,    39,
+      40,    41,   167,   168,   190,   191,   192,   132,   185,   195,
+     196,   197,   198,   199,     3,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,   210,   243,   244,   225,   226,   227,
+     228,   222,    55,    38,    67,   261,    41,    10,    11,    12,
+      45,    46,    67,    67,   242,   243,   244,    67,   222,   214,
+     215,   225,   226,   227,   228,    38,   181,    38,    41,    64,
+      41,    64,    45,    46,    45,    46,   252,   253,     8,     9,
+      53,    54,   284,     8,     9,    10,    11,    12,    64,    68,
+     245,    64,   298,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    12,     6,    64,     8,     9,    37,    67,   297,
        3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-      68,    41,    65,    58,    59,    60,    64,    60,    63,     8,
-       9,    37,    38,     6,    67,    41,     7,    70,    64,    45,
-      46,    47,    48,    68,    56,    51,    52,    53,    54,     8,
-       9,    64,    58,    67,    60,     8,     9,    68,    37,    38,
-      68,    67,    41,    69,    70,    68,    45,    46,    47,    48,
-      68,    64,    51,    52,     8,     9,    64,    68,    37,    58,
-      64,    60,     6,     7,    37,     9,     8,     9,    67,    64,
-      69,    70,     8,     9,     8,     9,    10,    11,    12,    58,
-      59,    60,    68,    37,    69,    58,    59,    60,    67,    64,
-      64,    70,    64,    39,    67,    37,    66,    70,     9,    67,
-      38,    37,    68,    41,    58,    64,    60,    45,    46,    64,
-      67,    55,    64,    67,    56,    64,    70,    68,    60,    64,
-     108,   330,    63,   194,    60,    67,    64,    -1,    70,    -1,
+     284,    64,   310,    53,    54,   240,   281,    64,    67,   317,
+      60,   246,    64,   321,   289,    65,     7,    67,    67,     6,
+      70,    64,    64,   307,    64,    64,   301,   323,    64,     1,
+      64,   266,    69,    68,   330,   226,   227,   228,    68,     7,
+       7,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    23,    24,    25,    26,    68,    28,    29,    30,    31,
+      32,    33,    34,    35,    36,     8,     9,    38,     7,    67,
+      41,    43,    44,    66,    45,    46,    41,    38,    39,    40,
+      41,    65,    53,    54,    45,    46,    58,    64,    60,     6,
+      64,    63,     8,     9,    37,    38,     7,    56,    41,    68,
+      64,    64,    45,    46,    47,    48,    68,    64,    51,    52,
+      53,    54,    68,    68,    68,    58,    68,    60,    64,     8,
+       9,    37,    38,    67,    67,    41,    69,    70,    68,    45,
+      46,    47,    48,     8,     9,    51,    52,     8,     9,     8,
+       9,    69,    58,    64,    60,     8,     9,    66,    37,    38,
+      64,    67,    41,    69,    70,    64,    45,    46,    39,     8,
+       9,     9,    37,    67,    64,    68,    37,    64,    37,    64,
+      68,    60,    64,    67,    37,   163,     8,     9,    67,    64,
+     106,    70,    62,    58,   324,    60,   189,    58,    37,    60,
+      -1,    60,    67,    56,    -1,    70,    67,    60,    67,    70,
+      69,    70,     8,     9,    67,    37,    -1,    70,    -1,    58,
+      -1,    60,    -1,    -1,    -1,    -1,    -1,    -1,    67,    -1,
+      -1,    70,    -1,    -1,    -1,    -1,    -1,    -1,    60,    -1,
+      -1,    37,    -1,    -1,    -1,    67,    -1,    -1,    70,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    -1,
+      -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,
       -1,    67,    -1,    -1,    70,     3,     4,     5,     6,     7,
        8,     9,    10,    11,    12,     3,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    38,    -1,    38,    41,    -1,
-      41,    -1,    45,    46,    45,    46,    -1,    -1,    -1,    -1,
-      53,    54,    53,    54,     6,     7,     8,    -1,    10,    11,
-      12,    13,    14,    64,    -1,    17,    69,    -1,    20,    21,
+       8,     9,    10,    11,    12,    -1,    38,    -1,    -1,    41,
+      -1,    -1,    -1,    45,    46,    -1,    -1,    -1,    -1,    -1,
+      64,    53,    54,    -1,     6,     7,     8,    -1,    10,    11,
+      12,    13,    14,    -1,    -1,    17,    -1,    69,    20,    21,
       22,    23,    24,    25,    -1,    63,     4,     5,     6,     7,
        8,     9,    10,    11,    12,    63,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,    38,    39,    40,    41,
-      -1,    -1,    -1,    45,    46,     5,     6,     7,     8,     9,
-      10,    11,    12,     6,     7,     8,     9,    10,    11,    12
+       7,     8,     9,    10,    11,    12,     5,     6,     7,     8,
+       9,    10,    11,    12,     6,     7,     8,     9,    10,    11,
+      12
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -956,37 +913,37 @@ static const yytype_uint8 yystos[] =
        0,    72,     0,    73,     1,    13,    14,    15,    16,    17,
       18,    19,    20,    21,    22,    23,    24,    25,    26,    28,
       29,    30,    31,    32,    33,    34,    35,    36,    43,    44,
-      58,    59,    60,    63,    74,    77,    63,    78,    78,    78,
-      78,    64,    79,    78,    78,    78,    78,    78,     8,     9,
-      37,    58,    60,    67,    70,   100,   103,   100,    78,    79,
-      79,    78,    78,    78,    78,    78,    78,    79,    67,    86,
-      87,    88,   100,   103,    38,    41,    45,    46,    47,    48,
-      51,    52,    69,    81,    82,    84,    88,    91,    93,    95,
-      96,    99,   103,    84,    61,    62,    61,    62,    63,    53,
-      54,    69,    89,    90,    91,    93,    89,    84,    79,    79,
-      58,    59,    80,   103,    79,    89,    65,    87,   103,    79,
-      91,    96,    79,   103,   103,     6,     8,     9,   101,   103,
-     105,   103,    64,    67,    11,    91,    81,    99,   103,    69,
-      82,    98,    99,    99,    91,    91,    67,    86,    96,    67,
-      67,    67,    67,     9,    10,    56,    57,    88,   103,    64,
-      67,     6,     7,     9,    55,    64,    76,   105,    75,   105,
-     103,    64,    64,    64,    58,    80,    85,    86,   100,   103,
-     101,   101,    67,    84,    64,    83,    96,    64,    67,    86,
-      64,     7,   103,   103,    67,     3,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    68,    90,   103,    38,    39,
-      40,   102,   103,    79,    64,    64,     9,    64,    64,    64,
-      64,    68,    95,    95,   105,   103,    56,    69,    84,    96,
-       6,     7,     7,     7,    84,    74,    63,    74,    63,    91,
-      96,    91,    84,   101,    67,    41,    96,    66,     9,    79,
-      65,    64,    86,   101,   102,   105,   105,   105,     6,     7,
-     105,   105,   105,   105,   105,    64,    68,    64,    99,   105,
-      48,    99,    99,    91,    91,    68,    68,    68,    68,    88,
-      68,    94,    96,   103,    94,    94,    94,    64,    68,    79,
-      64,    96,    83,    83,    91,    64,    79,    67,    68,   105,
-     105,    90,    81,    64,    64,    79,    64,    64,    91,    87,
-      66,    91,    39,     9,    96,    99,    67,    92,    91,    68,
-     103,    64,    96,    64,    49,    50,    97,    64,    96,    67,
-      64,    96,   105,    97,    68,    68,    64,   104,   105
+      58,    60,    63,    74,    76,    63,    77,    77,    77,    77,
+      64,    78,    77,    77,    77,    77,    77,     8,     9,    37,
+      58,    60,    67,    70,    99,   102,    99,    77,    78,    78,
+      77,    77,    77,    77,    77,    77,    78,    67,    85,    86,
+      87,    99,   102,    38,    41,    45,    46,    47,    48,    51,
+      52,    69,    80,    81,    83,    87,    90,    92,    94,    95,
+      98,   102,    83,    61,    62,    62,    63,    53,    54,    69,
+      88,    89,    90,    92,    88,    83,    78,    78,    58,    79,
+     102,    78,    88,    65,    86,   102,    78,    90,    95,    78,
+     102,   102,     6,     8,     9,   100,   102,   104,   102,    64,
+      67,    11,    90,    80,    98,   102,    69,    81,    97,    98,
+      98,    90,    90,    67,    85,    95,    67,    67,    67,    67,
+       9,    10,    56,    57,    87,   102,    64,    67,     6,     7,
+       9,    55,    64,    75,   104,   104,   102,    64,    64,    64,
+      58,    79,    84,    85,    99,   102,   100,    67,    83,    64,
+      82,    95,    64,    67,    85,    64,     7,   102,   102,    67,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      68,    89,   102,    38,    39,    40,   101,   102,    78,    64,
+      64,     9,    64,    64,    64,    64,    68,    94,    94,   104,
+     102,    56,    69,    83,    95,     6,     7,     7,     7,    83,
+      74,    63,    63,    90,    95,    90,    83,   100,    67,    41,
+      95,    66,     9,    78,    65,    64,    85,   100,   101,   104,
+     104,   104,     6,     7,   104,   104,   104,   104,   104,    64,
+      68,    64,    98,   104,    48,    98,    98,    90,    90,    68,
+      68,    68,    68,    87,    68,    93,    95,   102,    93,    93,
+      93,    64,    68,    78,    64,    95,    82,    82,    90,    64,
+      78,    67,    68,   104,   104,    89,    80,    64,    64,    78,
+      64,    64,    90,    86,    66,    90,    39,     9,    95,    98,
+      67,    91,    90,    68,   102,    64,    95,    64,    49,    50,
+      96,    64,    95,    67,    64,    95,   104,    96,    68,    68,
+      64,   103,   104
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1001,50 +958,78 @@ static const yytype_uint8 yystos[] =
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  However,
-   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
-   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
-   discussed.  */
+   Once GCC version 2 has supplanted version 1, this can go.  */
 
 #define YYFAIL         goto yyerrlab
-#if defined YYFAIL
-  /* This is here to suppress warnings from the GCC cpp's
-     -Wunused-macros.  Normally we don't worry about that warning, but
-     some users do, and we want to make it easy for users to remove
-     YYFAIL uses, which will produce warnings from Bison 2.5.  */
-#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
+#define YYBACKUP(Token, Value)                                 \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK (1);                                          \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
       yyerror (YY_("syntax error: cannot back up")); \
       YYERROR;                                                 \
     }                                                          \
 while (YYID (0))
 
-/* Error token number */
+
 #define YYTERROR       1
 #define YYERRCODE      256
 
 
-/* This macro is provided for backward compatibility. */
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (YYID (N))                                                    \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
 #ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+             (Loc).first_line, (Loc).first_column,     \
+             (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
 #endif
 
 
 /* YYLEX -- calling `yylex' with the right arguments.  */
+
 #ifdef YYLEX_PARAM
 # define YYLEX yylex (YYLEX_PARAM)
 #else
@@ -1094,8 +1079,6 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
     YYSTYPE const * const yyvaluep;
 #endif
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
@@ -1104,7 +1087,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
 # else
   YYUSE (yyoutput);
 # endif
-  YYUSE (yytype);
+  switch (yytype)
+    {
+      default:
+       break;
+    }
 }
 
 
@@ -1141,20 +1128,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
 #else
 static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
   YYFPRINTF (stderr, "\n");
 }
 
@@ -1188,11 +1172,11 @@ yy_reduce_print (yyvsp, yyrule)
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      fprintf (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
                       &(yyvsp[(yyi + 1) - (yynrhs)])
                                       );
-      YYFPRINTF (stderr, "\n");
+      fprintf (stderr, "\n");
     }
 }
 
@@ -1229,6 +1213,7 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
+\f
 
 #if YYERROR_VERBOSE
 
@@ -1331,145 +1316,115 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store.  */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
 {
-  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = YY_NULL;
-  /* Arguments of yyformat. */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
-  int yycount = 0;
-
-  /* There are many possibilities here to consider:
-     - Assume YYFAIL is not used.  It's too flawed to consider.  See
-       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
-       for details.  YYERROR is fine as it does not invoke this
-       function.
-     - If this state is a consistent state with a default action, then
-       the only way this function was invoked is if the default action
-       is an error action.  In that case, don't check for expected
-       tokens because there are none.
-     - The only way there can be no lookahead present (in yychar) is if
-       this state is a consistent state with a default action.  Thus,
-       detecting the absence of a lookahead is sufficient to determine
-       that there is no unexpected or expected token to report.  In that
-       case, just report a simple "syntax error".
-     - Don't assume there isn't a lookahead just because this state is a
-       consistent state with a default action.  There might have been a
-       previous inconsistent state, consistent state with a non-default
-       action, or user semantic action that manipulated yychar.
-     - Of course, the expected token list depends on states to have
-       correct lookahead information, and it depends on the parser not
-       to perform extra reductions after fetching a lookahead from the
-       scanner and before detecting a syntax error.  Thus, state merging
-       (from LALR or IELR) and default reductions corrupt the expected
-       token list.  However, the list is correct for canonical LR with
-       one exception: it will still contain any token that will not be
-       accepted due to an error action in a later state.
-  */
-  if (yytoken != YYEMPTY)
-    {
-      int yyn = yypact[*yyssp];
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                    return 2;
-                  yysize = yysize1;
-                }
-              }
-        }
-    }
+  int yyn = yypact[yystate];
 
-  switch (yycount)
-    {
-# define YYCASE_(N, S)                      \
-      case N:                               \
-        yyformat = S;                       \
-      break
-      YYCASE_(0, YY_("syntax error"));
-      YYCASE_(1, YY_("syntax error, unexpected %s"));
-      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
-      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
-      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
-    }
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+        constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+                   + sizeof yyexpecting - 1
+                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                      * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+        YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+         {
+           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+             {
+               yycount = 1;
+               yysize = yysize0;
+               yyformat[sizeof yyunexpected - 1] = '\0';
+               break;
+             }
+           yyarg[yycount++] = yytname[yyx];
+           yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+           yysize_overflow |= (yysize1 < yysize);
+           yysize = yysize1;
+           yyfmt = yystpcpy (yyfmt, yyprefix);
+           yyprefix = yyor;
+         }
 
-  {
-    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-      return 2;
-    yysize = yysize1;
-  }
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
 
-  if (*yymsg_alloc < yysize)
-    {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
-    }
+      if (yysize_overflow)
+       return YYSIZE_MAXIMUM;
 
-  /* Avoid sprintf, as that infringes on the user's name space.
-     Don't have undefined behavior even if the translation
-     produced a string with the wrong number of "%s"s.  */
-  {
-    char *yyp = *yymsg;
-    int yyi = 0;
-    while ((*yyp = *yyformat) != '\0')
-      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
-          yyformat += 2;
-        }
-      else
-        {
-          yyp++;
-          yyformat++;
-        }
-  }
-  return 0;
+      if (yyresult)
+       {
+         /* Avoid sprintf, as that infringes on the user's name space.
+            Don't have undefined behavior even if the translation
+            produced a string with the wrong number of "%s"s.  */
+         char *yyp = yyresult;
+         int yyi = 0;
+         while ((*yyp = *yyf) != '\0')
+           {
+             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+               {
+                 yyp += yytnamerr (yyp, yyarg[yyi++]);
+                 yyf += 2;
+               }
+             else
+               {
+                 yyp++;
+                 yyf++;
+               }
+           }
+       }
+      return yysize;
+    }
 }
 #endif /* YYERROR_VERBOSE */
+\f
 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1494,31 +1449,44 @@ yydestruct (yymsg, yytype, yyvaluep)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  YYUSE (yytype);
-}
+  switch (yytype)
+    {
 
+      default:
+       break;
+    }
+}
+\f
 
+/* Prevent warnings from -Wmissing-prototypes.  */
 
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
 
-/* The lookahead symbol.  */
-int yychar;
 
 
-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END
-#endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
-#endif
+/* The look-ahead symbol.  */
+int yychar;
 
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
 
 /* Number of syntax errors so far.  */
 int yynerrs;
 
 
+
 /*----------.
 | yyparse.  |
 `----------*/
@@ -1545,37 +1513,14 @@ yyparse ()
 #endif
 #endif
 {
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
-
-    /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
-
-       Refer to the stacks through separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
-
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
-
-    YYSIZE_T yystacksize;
-
+  
+  int yystate;
   int yyn;
   int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
   int yytoken = 0;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-
 #if YYERROR_VERBOSE
   /* Buffer for error messages, and its allocated size.  */
   char yymsgbuf[128];
@@ -1583,22 +1528,54 @@ yyparse ()
   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
 #endif
 
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
 
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yyssp = yyss = yyssa;
-  yyvsp = yyvs = yyvsa;
-  yystacksize = YYINITDEPTH;
-
   YYDPRINTF ((stderr, "Starting parse\n"));
 
   yystate = 0;
   yyerrstatus = 0;
   yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
+  yychar = YYEMPTY;            /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1625,6 +1602,7 @@ yyparse ()
        YYSTYPE *yyvs1 = yyvs;
        yytype_int16 *yyss1 = yyss;
 
+
        /* Each stack pointer address is followed by the size of the
           data in use in that stack, in bytes.  This used to be a
           conditional around just the two extra args, but that might
@@ -1632,6 +1610,7 @@ yyparse ()
        yyoverflow (YY_("memory exhausted"),
                    &yyss1, yysize * sizeof (*yyssp),
                    &yyvs1, yysize * sizeof (*yyvsp),
+
                    &yystacksize);
 
        yyss = yyss1;
@@ -1654,8 +1633,9 @@ yyparse ()
          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
        if (! yyptr)
          goto yyexhaustedlab;
-       YYSTACK_RELOCATE (yyss_alloc, yyss);
-       YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+       YYSTACK_RELOCATE (yyss);
+       YYSTACK_RELOCATE (yyvs);
+
 #  undef YYSTACK_RELOCATE
        if (yyss1 != yyssa)
          YYSTACK_FREE (yyss1);
@@ -1666,6 +1646,7 @@ yyparse ()
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
+
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
                  (unsigned long int) yystacksize));
 
@@ -1675,9 +1656,6 @@ yyparse ()
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
   goto yybackup;
 
 /*-----------.
@@ -1686,16 +1664,16 @@ yyparse ()
 yybackup:
 
   /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
+     look-ahead token if we need one and don't already have one.  */
 
-  /* First try to decide what to do without reference to lookahead token.  */
+  /* First try to decide what to do without reference to look-ahead token.  */
   yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
+  if (yyn == YYPACT_NINF)
     goto yydefault;
 
-  /* Not known => get a lookahead token if don't already have one.  */
+  /* Not known => get a look-ahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -1721,27 +1699,29 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+       goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
 
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   /* Count tokens shifted since error; after three, turn off error
      status.  */
   if (yyerrstatus)
     yyerrstatus--;
 
-  /* Shift the lookahead token.  */
+  /* Shift the look-ahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
 
   yystate = yyn;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -1778,7 +1758,6 @@ yyreduce:
   switch (yyn)
     {
         case 3:
-/* Line 1787 of yacc.c  */
 #line 70 "a.y"
     {
                stmtline = lineno;
@@ -1786,36 +1765,26 @@ yyreduce:
     break;
 
   case 5:
-/* Line 1787 of yacc.c  */
 #line 77 "a.y"
     {
-               if((yyvsp[(1) - (2)].sym)->value != pc)
-                       yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->name);
-               (yyvsp[(1) - (2)].sym)->value = pc;
-       }
-    break;
-
-  case 7:
-/* Line 1787 of yacc.c  */
-#line 84 "a.y"
-    {
+               (yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
+               if((yyvsp[(1) - (2)].sym)->type == LLAB && (yyvsp[(1) - (2)].sym)->value != pc)
+                       yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->labelname);
                (yyvsp[(1) - (2)].sym)->type = LLAB;
                (yyvsp[(1) - (2)].sym)->value = pc;
        }
     break;
 
-  case 9:
-/* Line 1787 of yacc.c  */
-#line 90 "a.y"
+  case 7:
+#line 86 "a.y"
     {
                (yyvsp[(1) - (4)].sym)->type = LVAR;
                (yyvsp[(1) - (4)].sym)->value = (yyvsp[(3) - (4)].lval);
        }
     break;
 
-  case 10:
-/* Line 1787 of yacc.c  */
-#line 95 "a.y"
+  case 8:
+#line 91 "a.y"
     {
                if((yyvsp[(1) - (4)].sym)->value != (yyvsp[(3) - (4)].lval))
                        yyerror("redeclaration of %s", (yyvsp[(1) - (4)].sym)->name);
@@ -1823,97 +1792,85 @@ yyreduce:
        }
     break;
 
-  case 14:
-/* Line 1787 of yacc.c  */
-#line 109 "a.y"
+  case 12:
+#line 105 "a.y"
     {
                outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].lval), &(yyvsp[(7) - (7)].addr));
        }
     break;
 
-  case 15:
-/* Line 1787 of yacc.c  */
-#line 113 "a.y"
+  case 13:
+#line 109 "a.y"
     {
                outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].lval), &nullgen);
        }
     break;
 
-  case 16:
-/* Line 1787 of yacc.c  */
-#line 117 "a.y"
+  case 14:
+#line 113 "a.y"
     {
                outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
-  case 17:
-/* Line 1787 of yacc.c  */
-#line 124 "a.y"
+  case 15:
+#line 120 "a.y"
     {
                outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
-  case 18:
-/* Line 1787 of yacc.c  */
-#line 131 "a.y"
+  case 16:
+#line 127 "a.y"
     {
                outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
-  case 19:
-/* Line 1787 of yacc.c  */
-#line 138 "a.y"
+  case 17:
+#line 134 "a.y"
     {
                outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
-  case 20:
-/* Line 1787 of yacc.c  */
-#line 142 "a.y"
+  case 18:
+#line 138 "a.y"
     {
                outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
-  case 21:
-/* Line 1787 of yacc.c  */
-#line 149 "a.y"
+  case 19:
+#line 145 "a.y"
     {
                outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
        }
     break;
 
-  case 22:
-/* Line 1787 of yacc.c  */
-#line 156 "a.y"
+  case 20:
+#line 152 "a.y"
     {
                outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
        }
     break;
 
-  case 23:
-/* Line 1787 of yacc.c  */
-#line 163 "a.y"
+  case 21:
+#line 159 "a.y"
     {
                outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
-  case 24:
-/* Line 1787 of yacc.c  */
-#line 170 "a.y"
+  case 22:
+#line 166 "a.y"
     {
                outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].lval), &nullgen);
        }
     break;
 
-  case 25:
-/* Line 1787 of yacc.c  */
-#line 177 "a.y"
+  case 23:
+#line 173 "a.y"
     {
                Addr g;
 
@@ -1924,9 +1881,8 @@ yyreduce:
        }
     break;
 
-  case 26:
-/* Line 1787 of yacc.c  */
-#line 186 "a.y"
+  case 24:
+#line 182 "a.y"
     {
                Addr g;
 
@@ -1937,127 +1893,115 @@ yyreduce:
        }
     break;
 
-  case 27:
-/* Line 1787 of yacc.c  */
-#line 198 "a.y"
+  case 25:
+#line 194 "a.y"
     {
                outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(5) - (7)].addr), (yyvsp[(3) - (7)].addr).reg, &(yyvsp[(7) - (7)].addr));
        }
     break;
 
-  case 28:
-/* Line 1787 of yacc.c  */
-#line 202 "a.y"
+  case 26:
+#line 198 "a.y"
     {
                outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(5) - (6)].addr), (yyvsp[(3) - (6)].addr).reg, &(yyvsp[(3) - (6)].addr));
        }
     break;
 
-  case 29:
-/* Line 1787 of yacc.c  */
-#line 206 "a.y"
+  case 27:
+#line 202 "a.y"
     {
                outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(4) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(6) - (6)].addr));
        }
     break;
 
-  case 30:
-/* Line 1787 of yacc.c  */
-#line 213 "a.y"
+  case 28:
+#line 209 "a.y"
     {
                outcode((yyvsp[(1) - (3)].lval), (yyvsp[(2) - (3)].lval), &nullgen, NREG, &nullgen);
        }
     break;
 
-  case 31:
-/* Line 1787 of yacc.c  */
-#line 220 "a.y"
+  case 29:
+#line 216 "a.y"
     {
+               settext((yyvsp[(2) - (4)].addr).sym);
                (yyvsp[(4) - (4)].addr).type = D_CONST2;
                (yyvsp[(4) - (4)].addr).offset2 = ArgsSizeUnknown;
                outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
-  case 32:
-/* Line 1787 of yacc.c  */
-#line 226 "a.y"
+  case 30:
+#line 223 "a.y"
     {
+               settext((yyvsp[(2) - (6)].addr).sym);
                (yyvsp[(6) - (6)].addr).type = D_CONST2;
                (yyvsp[(6) - (6)].addr).offset2 = ArgsSizeUnknown;
                outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
        }
     break;
 
-  case 33:
-/* Line 1787 of yacc.c  */
-#line 232 "a.y"
+  case 31:
+#line 230 "a.y"
     {
+               settext((yyvsp[(2) - (8)].addr).sym);
                (yyvsp[(6) - (8)].addr).type = D_CONST2;
                (yyvsp[(6) - (8)].addr).offset2 = (yyvsp[(8) - (8)].lval);
                outcode((yyvsp[(1) - (8)].lval), Always, &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].lval), &(yyvsp[(6) - (8)].addr));
        }
     break;
 
-  case 34:
-/* Line 1787 of yacc.c  */
-#line 241 "a.y"
+  case 32:
+#line 240 "a.y"
     {
                outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
        }
     break;
 
-  case 35:
-/* Line 1787 of yacc.c  */
-#line 248 "a.y"
+  case 33:
+#line 247 "a.y"
     {
                outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &(yyvsp[(3) - (4)].addr), NREG, &nullgen);
        }
     break;
 
-  case 36:
-/* Line 1787 of yacc.c  */
-#line 255 "a.y"
+  case 34:
+#line 254 "a.y"
     {
                outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
        }
     break;
 
-  case 37:
-/* Line 1787 of yacc.c  */
-#line 262 "a.y"
+  case 35:
+#line 261 "a.y"
     {
                outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
-  case 38:
-/* Line 1787 of yacc.c  */
-#line 266 "a.y"
+  case 36:
+#line 265 "a.y"
     {
                outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
-  case 39:
-/* Line 1787 of yacc.c  */
-#line 270 "a.y"
+  case 37:
+#line 269 "a.y"
     {
                outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].lval), &(yyvsp[(7) - (7)].addr));
        }
     break;
 
-  case 40:
-/* Line 1787 of yacc.c  */
-#line 274 "a.y"
+  case 38:
+#line 273 "a.y"
     {
                outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr).reg, &nullgen);
        }
     break;
 
-  case 41:
-/* Line 1787 of yacc.c  */
-#line 281 "a.y"
+  case 39:
+#line 280 "a.y"
     {
                Addr g;
 
@@ -2078,17 +2022,15 @@ yyreduce:
        }
     break;
 
-  case 42:
-/* Line 1787 of yacc.c  */
-#line 303 "a.y"
+  case 40:
+#line 302 "a.y"
     {
                outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].addr).reg, &(yyvsp[(7) - (7)].addr));
        }
     break;
 
-  case 43:
-/* Line 1787 of yacc.c  */
-#line 311 "a.y"
+  case 41:
+#line 310 "a.y"
     {
                (yyvsp[(7) - (9)].addr).type = D_REGREG2;
                (yyvsp[(7) - (9)].addr).offset = (yyvsp[(9) - (9)].lval);
@@ -2096,17 +2038,15 @@ yyreduce:
        }
     break;
 
-  case 44:
-/* Line 1787 of yacc.c  */
-#line 320 "a.y"
+  case 42:
+#line 319 "a.y"
     {
                outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].addr), NREG, &nullgen);
        }
     break;
 
-  case 45:
-/* Line 1787 of yacc.c  */
-#line 327 "a.y"
+  case 43:
+#line 326 "a.y"
     {
                if((yyvsp[(2) - (4)].addr).type != D_CONST || (yyvsp[(4) - (4)].addr).type != D_CONST)
                        yyerror("arguments to PCDATA must be integer constants");
@@ -2114,9 +2054,8 @@ yyreduce:
        }
     break;
 
-  case 46:
-/* Line 1787 of yacc.c  */
-#line 336 "a.y"
+  case 44:
+#line 335 "a.y"
     {
                if((yyvsp[(2) - (4)].addr).type != D_CONST)
                        yyerror("index for FUNCDATA must be integer constant");
@@ -2126,41 +2065,36 @@ yyreduce:
        }
     break;
 
-  case 47:
-/* Line 1787 of yacc.c  */
-#line 347 "a.y"
+  case 45:
+#line 346 "a.y"
     {
                outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, NREG, &nullgen);
        }
     break;
 
-  case 48:
-/* Line 1787 of yacc.c  */
-#line 352 "a.y"
+  case 46:
+#line 351 "a.y"
     {
                (yyval.lval) = Always;
        }
     break;
 
-  case 49:
-/* Line 1787 of yacc.c  */
-#line 356 "a.y"
+  case 47:
+#line 355 "a.y"
     {
                (yyval.lval) = ((yyvsp[(1) - (2)].lval) & ~C_SCOND) | (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 50:
-/* Line 1787 of yacc.c  */
-#line 360 "a.y"
+  case 48:
+#line 359 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (2)].lval) | (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 53:
-/* Line 1787 of yacc.c  */
-#line 369 "a.y"
+  case 51:
+#line 368 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_BRANCH;
@@ -2168,31 +2102,20 @@ yyreduce:
        }
     break;
 
-  case 54:
-/* Line 1787 of yacc.c  */
-#line 375 "a.y"
-    {
-               (yyval.addr) = nullgen;
-               if(pass == 2)
-                       yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->name);
-               (yyval.addr).type = D_BRANCH;
-               (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
-       }
-    break;
-
-  case 55:
-/* Line 1787 of yacc.c  */
-#line 383 "a.y"
+  case 52:
+#line 374 "a.y"
     {
+               (yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
                (yyval.addr) = nullgen;
+               if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
+                       yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
                (yyval.addr).type = D_BRANCH;
                (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 56:
-/* Line 1787 of yacc.c  */
-#line 390 "a.y"
+  case 53:
+#line 384 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_CONST;
@@ -2200,27 +2123,24 @@ yyreduce:
        }
     break;
 
-  case 57:
-/* Line 1787 of yacc.c  */
-#line 396 "a.y"
+  case 54:
+#line 390 "a.y"
     {
                (yyval.addr) = (yyvsp[(2) - (2)].addr);
                (yyval.addr).type = D_CONST;
        }
     break;
 
-  case 58:
-/* Line 1787 of yacc.c  */
-#line 401 "a.y"
+  case 55:
+#line 395 "a.y"
     {
                (yyval.addr) = (yyvsp[(4) - (4)].addr);
                (yyval.addr).type = D_OCONST;
        }
     break;
 
-  case 59:
-/* Line 1787 of yacc.c  */
-#line 406 "a.y"
+  case 56:
+#line 400 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SCONST;
@@ -2228,9 +2148,8 @@ yyreduce:
        }
     break;
 
-  case 61:
-/* Line 1787 of yacc.c  */
-#line 415 "a.y"
+  case 58:
+#line 409 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2238,9 +2157,8 @@ yyreduce:
        }
     break;
 
-  case 62:
-/* Line 1787 of yacc.c  */
-#line 421 "a.y"
+  case 59:
+#line 415 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2248,17 +2166,15 @@ yyreduce:
        }
     break;
 
-  case 63:
-/* Line 1787 of yacc.c  */
-#line 429 "a.y"
+  case 60:
+#line 423 "a.y"
     {
                (yyval.lval) = 1 << (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 64:
-/* Line 1787 of yacc.c  */
-#line 433 "a.y"
+  case 61:
+#line 427 "a.y"
     {
                int i;
                (yyval.lval)=0;
@@ -2269,26 +2185,23 @@ yyreduce:
        }
     break;
 
-  case 65:
-/* Line 1787 of yacc.c  */
-#line 442 "a.y"
+  case 62:
+#line 436 "a.y"
     {
                (yyval.lval) = (1<<(yyvsp[(1) - (3)].lval)) | (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 69:
-/* Line 1787 of yacc.c  */
-#line 451 "a.y"
+  case 66:
+#line 445 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (4)].addr);
                (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
        }
     break;
 
-  case 70:
-/* Line 1787 of yacc.c  */
-#line 456 "a.y"
+  case 67:
+#line 450 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_PSR;
@@ -2296,9 +2209,8 @@ yyreduce:
        }
     break;
 
-  case 71:
-/* Line 1787 of yacc.c  */
-#line 462 "a.y"
+  case 68:
+#line 456 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FPCR;
@@ -2306,9 +2218,8 @@ yyreduce:
        }
     break;
 
-  case 72:
-/* Line 1787 of yacc.c  */
-#line 468 "a.y"
+  case 69:
+#line 462 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_OREG;
@@ -2316,9 +2227,8 @@ yyreduce:
        }
     break;
 
-  case 76:
-/* Line 1787 of yacc.c  */
-#line 479 "a.y"
+  case 73:
+#line 473 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (1)].addr);
                if((yyvsp[(1) - (1)].addr).name != D_EXTERN && (yyvsp[(1) - (1)].addr).name != D_STATIC) {
@@ -2326,9 +2236,8 @@ yyreduce:
        }
     break;
 
-  case 77:
-/* Line 1787 of yacc.c  */
-#line 487 "a.y"
+  case 74:
+#line 481 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_OREG;
@@ -2337,9 +2246,8 @@ yyreduce:
        }
     break;
 
-  case 79:
-/* Line 1787 of yacc.c  */
-#line 497 "a.y"
+  case 76:
+#line 491 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_OREG;
@@ -2348,9 +2256,8 @@ yyreduce:
        }
     break;
 
-  case 81:
-/* Line 1787 of yacc.c  */
-#line 507 "a.y"
+  case 78:
+#line 501 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (4)].addr);
                (yyval.addr).type = D_OREG;
@@ -2358,9 +2265,8 @@ yyreduce:
        }
     break;
 
-  case 86:
-/* Line 1787 of yacc.c  */
-#line 520 "a.y"
+  case 83:
+#line 514 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_CONST;
@@ -2368,9 +2274,8 @@ yyreduce:
        }
     break;
 
-  case 87:
-/* Line 1787 of yacc.c  */
-#line 528 "a.y"
+  case 84:
+#line 522 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_REG;
@@ -2378,9 +2283,8 @@ yyreduce:
        }
     break;
 
-  case 88:
-/* Line 1787 of yacc.c  */
-#line 536 "a.y"
+  case 85:
+#line 530 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_REGREG;
@@ -2389,9 +2293,8 @@ yyreduce:
        }
     break;
 
-  case 89:
-/* Line 1787 of yacc.c  */
-#line 545 "a.y"
+  case 86:
+#line 539 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SHIFT;
@@ -2399,9 +2302,8 @@ yyreduce:
        }
     break;
 
-  case 90:
-/* Line 1787 of yacc.c  */
-#line 551 "a.y"
+  case 87:
+#line 545 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SHIFT;
@@ -2409,9 +2311,8 @@ yyreduce:
        }
     break;
 
-  case 91:
-/* Line 1787 of yacc.c  */
-#line 557 "a.y"
+  case 88:
+#line 551 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SHIFT;
@@ -2419,9 +2320,8 @@ yyreduce:
        }
     break;
 
-  case 92:
-/* Line 1787 of yacc.c  */
-#line 563 "a.y"
+  case 89:
+#line 557 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SHIFT;
@@ -2429,9 +2329,8 @@ yyreduce:
        }
     break;
 
-  case 93:
-/* Line 1787 of yacc.c  */
-#line 571 "a.y"
+  case 90:
+#line 565 "a.y"
     {
                if((yyval.lval) < 0 || (yyval.lval) >= 16)
                        print("register value out of range\n");
@@ -2439,9 +2338,8 @@ yyreduce:
        }
     break;
 
-  case 94:
-/* Line 1787 of yacc.c  */
-#line 577 "a.y"
+  case 91:
+#line 571 "a.y"
     {
                if((yyval.lval) < 0 || (yyval.lval) >= 32)
                        print("shift value out of range\n");
@@ -2449,17 +2347,15 @@ yyreduce:
        }
     break;
 
-  case 96:
-/* Line 1787 of yacc.c  */
-#line 586 "a.y"
+  case 93:
+#line 580 "a.y"
     {
                (yyval.lval) = REGPC;
        }
     break;
 
-  case 97:
-/* Line 1787 of yacc.c  */
-#line 590 "a.y"
+  case 94:
+#line 584 "a.y"
     {
                if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
                        print("register value out of range\n");
@@ -2467,17 +2363,15 @@ yyreduce:
        }
     break;
 
-  case 99:
-/* Line 1787 of yacc.c  */
-#line 599 "a.y"
+  case 96:
+#line 593 "a.y"
     {
                (yyval.lval) = REGSP;
        }
     break;
 
-  case 101:
-/* Line 1787 of yacc.c  */
-#line 606 "a.y"
+  case 98:
+#line 600 "a.y"
     {
                if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
                        print("register value out of range\n");
@@ -2485,9 +2379,8 @@ yyreduce:
        }
     break;
 
-  case 104:
-/* Line 1787 of yacc.c  */
-#line 618 "a.y"
+  case 101:
+#line 612 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FREG;
@@ -2495,9 +2388,8 @@ yyreduce:
        }
     break;
 
-  case 105:
-/* Line 1787 of yacc.c  */
-#line 624 "a.y"
+  case 102:
+#line 618 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FREG;
@@ -2505,9 +2397,8 @@ yyreduce:
        }
     break;
 
-  case 106:
-/* Line 1787 of yacc.c  */
-#line 632 "a.y"
+  case 103:
+#line 626 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_OREG;
@@ -2517,9 +2408,8 @@ yyreduce:
        }
     break;
 
-  case 107:
-/* Line 1787 of yacc.c  */
-#line 640 "a.y"
+  case 104:
+#line 634 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_OREG;
@@ -2529,9 +2419,8 @@ yyreduce:
        }
     break;
 
-  case 108:
-/* Line 1787 of yacc.c  */
-#line 648 "a.y"
+  case 105:
+#line 642 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_OREG;
@@ -2541,182 +2430,151 @@ yyreduce:
        }
     break;
 
-  case 109:
-/* Line 1787 of yacc.c  */
-#line 657 "a.y"
+  case 106:
+#line 651 "a.y"
     {
                (yyval.lval) = 0;
        }
     break;
 
-  case 110:
-/* Line 1787 of yacc.c  */
-#line 661 "a.y"
+  case 107:
+#line 655 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 111:
-/* Line 1787 of yacc.c  */
-#line 665 "a.y"
+  case 108:
+#line 659 "a.y"
     {
                (yyval.lval) = -(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 116:
-/* Line 1787 of yacc.c  */
-#line 677 "a.y"
+  case 113:
+#line 671 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
        }
     break;
 
-  case 117:
-/* Line 1787 of yacc.c  */
-#line 681 "a.y"
+  case 114:
+#line 675 "a.y"
     {
                (yyval.lval) = -(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 118:
-/* Line 1787 of yacc.c  */
-#line 685 "a.y"
+  case 115:
+#line 679 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 119:
-/* Line 1787 of yacc.c  */
-#line 689 "a.y"
+  case 116:
+#line 683 "a.y"
     {
                (yyval.lval) = ~(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 120:
-/* Line 1787 of yacc.c  */
-#line 693 "a.y"
+  case 117:
+#line 687 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (3)].lval);
        }
     break;
 
-  case 121:
-/* Line 1787 of yacc.c  */
-#line 698 "a.y"
+  case 118:
+#line 692 "a.y"
     {
                (yyval.lval) = 0;
        }
     break;
 
-  case 122:
-/* Line 1787 of yacc.c  */
-#line 702 "a.y"
+  case 119:
+#line 696 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 124:
-/* Line 1787 of yacc.c  */
-#line 709 "a.y"
+  case 121:
+#line 703 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 125:
-/* Line 1787 of yacc.c  */
-#line 713 "a.y"
+  case 122:
+#line 707 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 126:
-/* Line 1787 of yacc.c  */
-#line 717 "a.y"
+  case 123:
+#line 711 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 127:
-/* Line 1787 of yacc.c  */
-#line 721 "a.y"
+  case 124:
+#line 715 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 128:
-/* Line 1787 of yacc.c  */
-#line 725 "a.y"
+  case 125:
+#line 719 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 129:
-/* Line 1787 of yacc.c  */
-#line 729 "a.y"
+  case 126:
+#line 723 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 130:
-/* Line 1787 of yacc.c  */
-#line 733 "a.y"
+  case 127:
+#line 727 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 131:
-/* Line 1787 of yacc.c  */
-#line 737 "a.y"
+  case 128:
+#line 731 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 132:
-/* Line 1787 of yacc.c  */
-#line 741 "a.y"
+  case 129:
+#line 735 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 133:
-/* Line 1787 of yacc.c  */
-#line 745 "a.y"
+  case 130:
+#line 739 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
        }
     break;
 
 
-/* Line 1787 of yacc.c  */
-#line 2707 "y.tab.c"
+/* Line 1267 of yacc.c.  */
+#line 2576 "y.tab.c"
       default: break;
     }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -2725,6 +2583,7 @@ yyreduce:
 
   *++yyvsp = yyval;
 
+
   /* Now `shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
@@ -2744,10 +2603,6 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -2755,36 +2610,37 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (YY_("syntax error"));
 #else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
-                                        yyssp, yytoken)
       {
-        char const *yymsgp = YY_("syntax error");
-        int yysyntax_error_status;
-        yysyntax_error_status = YYSYNTAX_ERROR;
-        if (yysyntax_error_status == 0)
-          yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
-          {
-            if (yymsg != yymsgbuf)
-              YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
-            if (!yymsg)
-              {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
-              }
-            else
-              {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
-              }
-          }
-        yyerror (yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
+       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+         {
+           YYSIZE_T yyalloc = 2 * yysize;
+           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+             yyalloc = YYSTACK_ALLOC_MAXIMUM;
+           if (yymsg != yymsgbuf)
+             YYSTACK_FREE (yymsg);
+           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+           if (yymsg)
+             yymsg_alloc = yyalloc;
+           else
+             {
+               yymsg = yymsgbuf;
+               yymsg_alloc = sizeof yymsgbuf;
+             }
+         }
+
+       if (0 < yysize && yysize <= yymsg_alloc)
+         {
+           (void) yysyntax_error (yymsg, yystate, yychar);
+           yyerror (yymsg);
+         }
+       else
+         {
+           yyerror (YY_("syntax error"));
+           if (yysize != 0)
+             goto yyexhaustedlab;
+         }
       }
-# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -2792,7 +2648,7 @@ yyerrlab:
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse lookahead token after an
+      /* If just tried and failed to reuse look-ahead token after an
         error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -2809,7 +2665,7 @@ yyerrlab:
        }
     }
 
-  /* Else will try to reuse lookahead token after shifting the error
+  /* Else will try to reuse look-ahead token after shifting the error
      token.  */
   goto yyerrlab1;
 
@@ -2843,7 +2699,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
+      if (yyn != YYPACT_NINF)
        {
          yyn += YYTERROR;
          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -2866,9 +2722,10 @@ yyerrlab1:
       YY_STACK_PRINT (yyss, yyssp);
     }
 
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -2892,7 +2749,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined yyoverflow || YYERROR_VERBOSE
+#ifndef yyoverflow
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2903,14 +2760,9 @@ yyexhaustedlab:
 #endif
 
 yyreturn:
-  if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval);
-    }
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval);
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -2934,3 +2786,4 @@ yyreturn:
 }
 
 
+
index f11fb85c6a47ef83b2e40c06b165f96772d383cc..f75cb22a752b821354419b6f5811d1611dbed157 100644 (file)
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
-/* Bison interface for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-#ifndef YY_YY_Y_TAB_H_INCLUDED
-# define YY_YY_Y_TAB_H_INCLUDED
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
-
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -148,41 +141,24 @@ extern int yydebug;
 
 
 
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-/* Line 2053 of yacc.c  */
 #line 39 "a.y"
-
+{
        Sym     *sym;
        int32   lval;
        double  dval;
        char    sval[8];
        Addr    addr;
-
-
-/* Line 2053 of yacc.c  */
-#line 166 "y.tab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1529 of yacc.c.  */
+#line 157 "y.tab.h"
+       YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 extern YYSTYPE yylval;
 
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-#endif /* !YY_YY_Y_TAB_H_INCLUDED  */
index b3fb0bb19f3db7e5b372a9eb79902fc59889ac90..e1927b6d40e8505630a01af73157dddcc1b164f5 100644 (file)
@@ -70,6 +70,7 @@ struct        Sym
        vlong   value;
        ushort  type;
        char    *name;
+       char*   labelname;
        char    sym;
 };
 #define        S       ((Sym*)0)
@@ -148,6 +149,8 @@ void        newio(void);
 void   newfile(char*, int);
 Sym*   slookup(char*);
 Sym*   lookup(void);
+Sym*   labellookup(Sym*);
+void   settext(LSym*);
 void   syminit(Sym*);
 int32  yylex(void);
 int    getc(void);
index 1089d4061c5e5a0e248369154029439f502dcb70..29011c7ffb05e478fd875918bc51f584132d6fde 100644 (file)
@@ -71,15 +71,11 @@ prog:
        line
 
 line:
-       LLAB ':'
-       {
-               if($1->value != pc)
-                       yyerror("redeclaration of %s", $1->name);
-               $1->value = pc;
-       }
-       line
-|      LNAME ':'
+       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;
        }
@@ -197,11 +193,13 @@ spec1:    /* DATA */
 spec2: /* TEXT */
        mem ',' imm2
        {
+               settext($1.sym);
                $$.from = $1;
                $$.to = $3;
        }
 |      mem ',' con ',' imm2
        {
+               settext($1.sym);
                $$.from = $1;
                $$.from.scale = $3;
                $$.to = $5;
@@ -363,15 +361,10 @@ rel:
        }
 |      LNAME offset
        {
+               $1 = labellookup($1);
                $$ = nullgen;
-               if(pass == 2)
-                       yyerror("undefined label: %s", $1->name);
-               $$.type = D_BRANCH;
-               $$.offset = $2;
-       }
-|      LLAB offset
-       {
-               $$ = nullgen;
+               if(pass == 2 && $1->type != LLAB)
+                       yyerror("undefined label: %s", $1->labelname);
                $$.type = D_BRANCH;
                $$.offset = $1->value + $2;
        }
index b69fd95b531b7a5399d92044762845e9452b43a4..a698079d23f7f8a02a358e4a868cf326a518ba6e 100644 (file)
@@ -411,16 +411,16 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   560
+#define YYLAST   549
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  56
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  42
+#define YYNNTS  41
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  137
+#define YYNRULES  134
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  277
+#define YYNSTATES  271
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -469,91 +469,91 @@ static const yytype_uint8 yytranslate[] =
    YYRHS.  */
 static const yytype_uint16 yyprhs[] =
 {
-       0,     0,     3,     4,     5,     9,    10,    15,    16,    21,
-      23,    26,    29,    33,    37,    40,    43,    46,    49,    52,
+       0,     0,     3,     4,     5,     9,    10,    15,    17,    20,
+      23,    27,    31,    34,    37,    40,    43,    46,    49,    52,
       55,    58,    61,    64,    67,    70,    73,    76,    79,    82,
-      85,    88,    91,    94,    95,    97,   101,   105,   108,   110,
-     113,   115,   118,   120,   124,   130,   134,   140,   143,   145,
-     147,   149,   153,   159,   163,   169,   172,   174,   178,   184,
-     190,   191,   193,   197,   203,   207,   211,   213,   215,   217,
-     219,   222,   225,   227,   229,   231,   233,   238,   241,   244,
-     246,   248,   250,   252,   254,   256,   258,   261,   264,   267,
-     270,   273,   278,   284,   288,   290,   292,   294,   299,   304,
-     309,   316,   326,   336,   340,   344,   350,   359,   361,   368,
-     374,   382,   383,   386,   389,   391,   393,   395,   397,   399,
-     402,   405,   408,   412,   414,   417,   421,   426,   428,   432,
-     436,   440,   444,   448,   453,   458,   462,   466
+      85,    88,    89,    91,    95,    99,   102,   104,   107,   109,
+     112,   114,   118,   124,   128,   134,   137,   139,   141,   143,
+     147,   153,   157,   163,   166,   168,   172,   178,   184,   185,
+     187,   191,   197,   201,   205,   207,   209,   211,   213,   216,
+     219,   221,   223,   225,   227,   232,   235,   237,   239,   241,
+     243,   245,   247,   249,   252,   255,   258,   261,   264,   269,
+     275,   279,   281,   283,   285,   290,   295,   300,   307,   317,
+     327,   331,   335,   341,   350,   352,   359,   365,   373,   374,
+     377,   380,   382,   384,   386,   388,   390,   393,   396,   399,
+     403,   405,   408,   412,   417,   419,   423,   427,   431,   435,
+     439,   444,   449,   453,   457
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
       57,     0,    -1,    -1,    -1,    57,    58,    59,    -1,    -1,
-      46,    48,    60,    59,    -1,    -1,    45,    48,    61,    59,
-      -1,    49,    -1,    62,    49,    -1,     1,    49,    -1,    45,
-      50,    97,    -1,    47,    50,    97,    -1,    13,    63,    -1,
-      14,    67,    -1,    15,    66,    -1,    16,    64,    -1,    17,
-      65,    -1,    21,    68,    -1,    19,    69,    -1,    22,    70,
-      -1,    18,    71,    -1,    20,    72,    -1,    25,    73,    -1,
-      26,    74,    -1,    27,    75,    -1,    28,    76,    -1,    29,
-      77,    -1,    30,    78,    -1,    23,    79,    -1,    24,    80,
-      -1,    31,    81,    -1,    -1,    51,    -1,    84,    51,    82,
-      -1,    82,    51,    84,    -1,    84,    51,    -1,    84,    -1,
-      51,    82,    -1,    82,    -1,    51,    85,    -1,    85,    -1,
-      88,    51,    85,    -1,    92,    11,    95,    51,    88,    -1,
-      89,    51,    87,    -1,    89,    51,    95,    51,    87,    -1,
-      51,    83,    -1,    83,    -1,    63,    -1,    67,    -1,    84,
-      51,    82,    -1,    84,    51,    82,    48,    37,    -1,    84,
-      51,    82,    -1,    84,    51,    82,    48,    38,    -1,    84,
-      51,    -1,    84,    -1,    84,    51,    82,    -1,    86,    51,
-      82,    51,    95,    -1,    88,    51,    82,    51,    86,    -1,
-      -1,    88,    -1,    89,    51,    88,    -1,    89,    51,    95,
-      51,    88,    -1,    84,    51,    84,    -1,    84,    51,    84,
-      -1,    86,    -1,    89,    -1,    85,    -1,    91,    -1,    10,
-      86,    -1,    10,    90,    -1,    86,    -1,    90,    -1,    82,
-      -1,    88,    -1,    95,    52,    34,    53,    -1,    45,    93,
-      -1,    46,    93,    -1,    36,    -1,    39,    -1,    37,    -1,
-      40,    -1,    44,    -1,    38,    -1,    41,    -1,    54,    96,
-      -1,    54,    95,    -1,    54,    92,    -1,    54,    43,    -1,
-      54,    42,    -1,    54,    52,    42,    53,    -1,    54,    52,
-       9,    42,    53,    -1,    54,     9,    42,    -1,    90,    -1,
-      91,    -1,    95,    -1,    95,    52,    37,    53,    -1,    95,
-      52,    44,    53,    -1,    95,    52,    38,    53,    -1,    95,
-      52,    37,    10,    95,    53,    -1,    95,    52,    37,    53,
-      52,    37,    10,    95,    53,    -1,    95,    52,    37,    53,
-      52,    38,    10,    95,    53,    -1,    52,    37,    53,    -1,
-      52,    44,    53,    -1,    52,    37,    10,    95,    53,    -1,
-      52,    37,    53,    52,    37,    10,    95,    53,    -1,    92,
-      -1,    92,    52,    37,    10,    95,    53,    -1,    45,    93,
-      52,    94,    53,    -1,    45,     6,     7,    93,    52,    35,
-      53,    -1,    -1,     8,    95,    -1,     9,    95,    -1,    35,
-      -1,    44,    -1,    33,    -1,    32,    -1,    47,    -1,     9,
-      95,    -1,     8,    95,    -1,    55,    95,    -1,    52,    97,
-      53,    -1,    32,    -1,     9,    32,    -1,    32,     9,    32,
-      -1,     9,    32,     9,    32,    -1,    95,    -1,    97,     8,
-      97,    -1,    97,     9,    97,    -1,    97,    10,    97,    -1,
-      97,    11,    97,    -1,    97,    12,    97,    -1,    97,     6,
-       6,    97,    -1,    97,     7,     7,    97,    -1,    97,     5,
-      97,    -1,    97,     4,    97,    -1,    97,     3,    97,    -1
+      45,    48,    60,    59,    -1,    49,    -1,    61,    49,    -1,
+       1,    49,    -1,    45,    50,    96,    -1,    47,    50,    96,
+      -1,    13,    62,    -1,    14,    66,    -1,    15,    65,    -1,
+      16,    63,    -1,    17,    64,    -1,    21,    67,    -1,    19,
+      68,    -1,    22,    69,    -1,    18,    70,    -1,    20,    71,
+      -1,    25,    72,    -1,    26,    73,    -1,    27,    74,    -1,
+      28,    75,    -1,    29,    76,    -1,    30,    77,    -1,    23,
+      78,    -1,    24,    79,    -1,    31,    80,    -1,    -1,    51,
+      -1,    83,    51,    81,    -1,    81,    51,    83,    -1,    83,
+      51,    -1,    83,    -1,    51,    81,    -1,    81,    -1,    51,
+      84,    -1,    84,    -1,    87,    51,    84,    -1,    91,    11,
+      94,    51,    87,    -1,    88,    51,    86,    -1,    88,    51,
+      94,    51,    86,    -1,    51,    82,    -1,    82,    -1,    62,
+      -1,    66,    -1,    83,    51,    81,    -1,    83,    51,    81,
+      48,    37,    -1,    83,    51,    81,    -1,    83,    51,    81,
+      48,    38,    -1,    83,    51,    -1,    83,    -1,    83,    51,
+      81,    -1,    85,    51,    81,    51,    94,    -1,    87,    51,
+      81,    51,    85,    -1,    -1,    87,    -1,    88,    51,    87,
+      -1,    88,    51,    94,    51,    87,    -1,    83,    51,    83,
+      -1,    83,    51,    83,    -1,    85,    -1,    88,    -1,    84,
+      -1,    90,    -1,    10,    85,    -1,    10,    89,    -1,    85,
+      -1,    89,    -1,    81,    -1,    87,    -1,    94,    52,    34,
+      53,    -1,    45,    92,    -1,    36,    -1,    39,    -1,    37,
+      -1,    40,    -1,    44,    -1,    38,    -1,    41,    -1,    54,
+      95,    -1,    54,    94,    -1,    54,    91,    -1,    54,    43,
+      -1,    54,    42,    -1,    54,    52,    42,    53,    -1,    54,
+      52,     9,    42,    53,    -1,    54,     9,    42,    -1,    89,
+      -1,    90,    -1,    94,    -1,    94,    52,    37,    53,    -1,
+      94,    52,    44,    53,    -1,    94,    52,    38,    53,    -1,
+      94,    52,    37,    10,    94,    53,    -1,    94,    52,    37,
+      53,    52,    37,    10,    94,    53,    -1,    94,    52,    37,
+      53,    52,    38,    10,    94,    53,    -1,    52,    37,    53,
+      -1,    52,    44,    53,    -1,    52,    37,    10,    94,    53,
+      -1,    52,    37,    53,    52,    37,    10,    94,    53,    -1,
+      91,    -1,    91,    52,    37,    10,    94,    53,    -1,    45,
+      92,    52,    93,    53,    -1,    45,     6,     7,    92,    52,
+      35,    53,    -1,    -1,     8,    94,    -1,     9,    94,    -1,
+      35,    -1,    44,    -1,    33,    -1,    32,    -1,    47,    -1,
+       9,    94,    -1,     8,    94,    -1,    55,    94,    -1,    52,
+      96,    53,    -1,    32,    -1,     9,    32,    -1,    32,     9,
+      32,    -1,     9,    32,     9,    32,    -1,    94,    -1,    96,
+       8,    96,    -1,    96,     9,    96,    -1,    96,    10,    96,
+      -1,    96,    11,    96,    -1,    96,    12,    96,    -1,    96,
+       6,     6,    96,    -1,    96,     7,     7,    96,    -1,    96,
+       5,    96,    -1,    96,     4,    96,    -1,    96,     3,    96,
+      -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,    66,    66,    68,    67,    75,    74,    82,    81,    87,
-      88,    89,    92,    97,   103,   104,   105,   106,   107,   108,
-     109,   110,   111,   112,   113,   114,   115,   116,   117,   118,
-     119,   120,   121,   124,   128,   135,   142,   149,   154,   161,
-     166,   173,   178,   183,   190,   198,   203,   211,   216,   223,
-     224,   227,   232,   242,   247,   257,   262,   267,   274,   282,
-     292,   296,   303,   308,   316,   325,   336,   337,   340,   341,
-     342,   346,   350,   351,   354,   355,   358,   364,   372,   380,
-     385,   390,   395,   400,   405,   410,   416,   424,   430,   441,
-     447,   453,   459,   465,   473,   474,   477,   483,   489,   495,
-     501,   510,   519,   528,   533,   538,   546,   556,   560,   569,
-     576,   585,   588,   592,   598,   599,   603,   606,   607,   611,
-     615,   619,   623,   629,   634,   639,   644,   651,   652,   656,
-     660,   664,   668,   672,   676,   680,   684,   688
+       0,    66,    66,    68,    67,    75,    74,    83,    84,    85,
+      88,    93,    99,   100,   101,   102,   103,   104,   105,   106,
+     107,   108,   109,   110,   111,   112,   113,   114,   115,   116,
+     117,   120,   124,   131,   138,   145,   150,   157,   162,   169,
+     174,   179,   186,   194,   200,   209,   214,   221,   222,   225,
+     230,   240,   245,   255,   260,   265,   272,   280,   290,   294,
+     301,   306,   314,   323,   334,   335,   338,   339,   340,   344,
+     348,   349,   352,   353,   356,   362,   373,   378,   383,   388,
+     393,   398,   403,   409,   417,   423,   434,   440,   446,   452,
+     458,   466,   467,   470,   476,   482,   488,   494,   503,   512,
+     521,   526,   531,   539,   549,   553,   562,   569,   578,   581,
+     585,   591,   592,   596,   599,   600,   604,   608,   612,   616,
+     622,   627,   632,   637,   644,   645,   649,   653,   657,   661,
+     665,   669,   673,   677,   681
 };
 #endif
 
@@ -569,7 +569,7 @@ static const char *const yytname[] =
   "LTYPEF", "LCONST", "LFP", "LPC", "LSB", "LBREG", "LLREG", "LSREG",
   "LFREG", "LMREG", "LXREG", "LFCONST", "LSCONST", "LSP", "LNAME", "LLAB",
   "LVAR", "':'", "';'", "'='", "','", "'('", "')'", "'$'", "'~'",
-  "$accept", "prog", "@1", "line", "@2", "@3", "inst", "nonnon", "rimrem",
+  "$accept", "prog", "@1", "line", "@2", "inst", "nonnon", "rimrem",
   "remrim", "rimnon", "nonrem", "nonrel", "spec1", "spec2", "spec3",
   "spec4", "spec5", "spec6", "spec7", "spec8", "spec9", "spec10", "spec11",
   "spec12", "spec13", "rem", "rom", "rim", "rel", "reg", "imm2", "imm",
@@ -594,39 +594,39 @@ static const yytype_uint16 yytoknum[] =
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    56,    57,    58,    57,    60,    59,    61,    59,    59,
-      59,    59,    62,    62,    62,    62,    62,    62,    62,    62,
-      62,    62,    62,    62,    62,    62,    62,    62,    62,    62,
-      62,    62,    62,    63,    63,    64,    65,    66,    66,    67,
-      67,    68,    68,    68,    69,    70,    70,    71,    71,    72,
-      72,    73,    73,    74,    74,    75,    75,    75,    76,    77,
-      78,    78,    79,    79,    80,    81,    82,    82,    83,    83,
-      83,    83,    83,    83,    84,    84,    85,    85,    85,    86,
-      86,    86,    86,    86,    86,    86,    87,    88,    88,    88,
-      88,    88,    88,    88,    89,    89,    90,    90,    90,    90,
-      90,    90,    90,    90,    90,    90,    90,    91,    91,    92,
-      92,    93,    93,    93,    94,    94,    94,    95,    95,    95,
-      95,    95,    95,    96,    96,    96,    96,    97,    97,    97,
-      97,    97,    97,    97,    97,    97,    97,    97
+       0,    56,    57,    58,    57,    60,    59,    59,    59,    59,
+      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
+      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
+      61,    62,    62,    63,    64,    65,    65,    66,    66,    67,
+      67,    67,    68,    69,    69,    70,    70,    71,    71,    72,
+      72,    73,    73,    74,    74,    74,    75,    76,    77,    77,
+      78,    78,    79,    80,    81,    81,    82,    82,    82,    82,
+      82,    82,    83,    83,    84,    84,    85,    85,    85,    85,
+      85,    85,    85,    86,    87,    87,    87,    87,    87,    87,
+      87,    88,    88,    89,    89,    89,    89,    89,    89,    89,
+      89,    89,    89,    89,    90,    90,    91,    91,    92,    92,
+      92,    93,    93,    93,    94,    94,    94,    94,    94,    94,
+      95,    95,    95,    95,    96,    96,    96,    96,    96,    96,
+      96,    96,    96,    96,    96
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     0,     0,     3,     0,     4,     0,     4,     1,
-       2,     2,     3,     3,     2,     2,     2,     2,     2,     2,
+       0,     2,     0,     0,     3,     0,     4,     1,     2,     2,
+       3,     3,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     0,     1,     3,     3,     2,     1,     2,
-       1,     2,     1,     3,     5,     3,     5,     2,     1,     1,
-       1,     3,     5,     3,     5,     2,     1,     3,     5,     5,
-       0,     1,     3,     5,     3,     3,     1,     1,     1,     1,
-       2,     2,     1,     1,     1,     1,     4,     2,     2,     1,
-       1,     1,     1,     1,     1,     1,     2,     2,     2,     2,
-       2,     4,     5,     3,     1,     1,     1,     4,     4,     4,
-       6,     9,     9,     3,     3,     5,     8,     1,     6,     5,
-       7,     0,     2,     2,     1,     1,     1,     1,     1,     2,
-       2,     2,     3,     1,     2,     3,     4,     1,     3,     3,
-       3,     3,     3,     4,     4,     3,     3,     3
+       2,     0,     1,     3,     3,     2,     1,     2,     1,     2,
+       1,     3,     5,     3,     5,     2,     1,     1,     1,     3,
+       5,     3,     5,     2,     1,     3,     5,     5,     0,     1,
+       3,     5,     3,     3,     1,     1,     1,     1,     2,     2,
+       1,     1,     1,     1,     4,     2,     1,     1,     1,     1,
+       1,     1,     1,     2,     2,     2,     2,     2,     4,     5,
+       3,     1,     1,     1,     4,     4,     4,     6,     9,     9,
+       3,     3,     5,     8,     1,     6,     5,     7,     0,     2,
+       2,     1,     1,     1,     1,     1,     2,     2,     2,     3,
+       1,     2,     3,     4,     1,     3,     3,     3,     3,     3,
+       4,     4,     3,     3,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -634,89 +634,89 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,     3,     1,     0,     0,    33,     0,     0,     0,     0,
-       0,     0,    33,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    60,     0,     0,     0,     0,     9,     4,     0,
-      11,    34,    14,     0,     0,   117,    79,    81,    84,    80,
-      82,    85,    83,   111,   118,     0,     0,     0,    15,    40,
-      66,    67,    94,    95,   107,    96,     0,    16,    74,    38,
-      75,    17,     0,    18,     0,     0,   111,   111,     0,    22,
-      48,    68,    72,    73,    69,    96,    20,     0,    34,    49,
-      50,    23,   111,     0,     0,    19,    42,     0,     0,    21,
-       0,    30,     0,    31,     0,    24,     0,    25,     0,    26,
-      56,    27,     0,    28,     0,    29,    61,    32,     0,     7,
-       0,     5,     0,    10,   120,   119,     0,     0,     0,     0,
-      39,     0,     0,   127,     0,   121,     0,     0,     0,    90,
-      89,     0,    88,    87,    37,     0,     0,    70,    71,    77,
-      78,    47,     0,     0,    77,    41,     0,     0,     0,     0,
-       0,     0,     0,    55,     0,     0,     0,     0,    12,     0,
-      13,   111,   112,   113,     0,     0,   103,   104,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,   122,     0,
-       0,     0,     0,    93,     0,     0,    35,    36,     0,     0,
-      43,     0,    45,     0,    62,     0,    64,    51,    53,    57,
-       0,     0,    65,     8,     6,     0,   116,   114,   115,     0,
-       0,     0,   137,   136,   135,     0,     0,   128,   129,   130,
-     131,   132,     0,     0,    97,    99,    98,     0,    91,    76,
-       0,     0,   123,    86,     0,     0,     0,     0,     0,     0,
-       0,   109,   105,     0,   133,   134,     0,     0,     0,    92,
-      44,   124,     0,    46,    63,    52,    54,    58,    59,     0,
-       0,   108,   100,     0,     0,     0,   125,   110,     0,     0,
-       0,   126,   106,     0,     0,   101,   102
+       2,     3,     1,     0,     0,    31,     0,     0,     0,     0,
+       0,     0,    31,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    58,     0,     0,     0,     7,     4,     0,     9,
+      32,    12,     0,     0,   114,    76,    78,    81,    77,    79,
+      82,    80,   108,   115,     0,     0,     0,    13,    38,    64,
+      65,    91,    92,   104,    93,     0,    14,    72,    36,    73,
+      15,     0,    16,     0,     0,   108,     0,    20,    46,    66,
+      70,    71,    67,    93,    18,     0,    32,    47,    48,    21,
+     108,     0,     0,    17,    40,     0,     0,    19,     0,    28,
+       0,    29,     0,    22,     0,    23,     0,    24,    54,    25,
+       0,    26,     0,    27,    59,    30,     0,     5,     0,     0,
+       8,   117,   116,     0,     0,     0,     0,    37,     0,     0,
+     124,     0,   118,     0,     0,     0,    87,    86,     0,    85,
+      84,    35,     0,     0,    68,    69,    75,    45,     0,     0,
+      75,    39,     0,     0,     0,     0,     0,     0,     0,    53,
+       0,     0,     0,     0,    10,    11,   108,   109,   110,     0,
+       0,   100,   101,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   119,     0,     0,     0,     0,    90,     0,
+       0,    33,    34,     0,     0,    41,     0,    43,     0,    60,
+       0,    62,    49,    51,    55,     0,     0,    63,     6,     0,
+     113,   111,   112,     0,     0,     0,   134,   133,   132,     0,
+       0,   125,   126,   127,   128,   129,     0,     0,    94,    96,
+      95,     0,    88,    74,     0,     0,   120,    83,     0,     0,
+       0,     0,     0,     0,     0,   106,   102,     0,   130,   131,
+       0,     0,     0,    89,    42,   121,     0,    44,    61,    50,
+      52,    56,    57,     0,     0,   105,    97,     0,     0,     0,
+     122,   107,     0,     0,     0,   123,   103,     0,     0,    98,
+      99
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     1,     3,    28,   159,   157,    29,    32,    61,    63,
-      57,    48,    85,    76,    89,    69,    81,    95,    97,    99,
-     101,   103,   105,    91,    93,   107,    58,    70,    59,    71,
-      50,   192,    60,    51,    52,    53,    54,   119,   209,    55,
-     233,   124
+      -1,     1,     3,    27,   153,    28,    31,    60,    62,    56,
+      47,    83,    74,    87,    67,    79,    93,    95,    97,    99,
+     101,   103,    89,    91,   105,    57,    68,    58,    69,    49,
+     187,    59,    50,    51,    52,    53,   116,   203,    54,   227,
+     121
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -94
+#define YYPACT_NINF -89
 static const yytype_int16 yypact[] =
 {
-     -94,    15,   -94,   218,   -28,   -25,   264,   285,   285,   340,
-     163,     2,   319,    97,   415,   415,   285,   285,   285,   285,
-     306,   -24,   -24,   285,   -17,   -14,     4,   -94,   -94,    48,
-     -94,   -94,   -94,   481,   481,   -94,   -94,   -94,   -94,   -94,
-     -94,   -94,   -94,    19,   -94,   340,   399,   481,   -94,   -94,
-     -94,   -94,   -94,   -94,    46,    47,   385,   -94,   -94,    52,
-     -94,   -94,    59,   -94,    60,   374,    19,    56,   243,   -94,
-     -94,   -94,   -94,   -94,   -94,    63,   -94,   106,   340,   -94,
-     -94,   -94,    56,   138,   481,   -94,   -94,    69,    72,   -94,
-      74,   -94,    76,   -94,    77,   -94,    79,   -94,    80,   -94,
-      81,   -94,    83,   -94,    89,   -94,   -94,   -94,    94,   -94,
-     481,   -94,   481,   -94,   -94,   -94,   119,   481,   481,    98,
-     -94,    -1,   100,   -94,    84,   -94,   117,    23,   426,   -94,
-     -94,   433,   -94,   -94,   -94,   340,   285,   -94,   -94,    98,
-     -94,   -94,    75,   481,   -94,   -94,   138,   122,   440,   444,
-     285,   340,   340,   340,   340,   340,   285,   218,   393,   218,
-     393,    56,   -94,   -94,   -15,   481,   105,   -94,   481,   481,
-     481,   156,   162,   481,   481,   481,   481,   481,   -94,   165,
-       0,   123,   133,   -94,   474,   134,   -94,   -94,   136,   140,
-     -94,     7,   -94,   141,   -94,   143,   -94,   148,   149,   -94,
-     147,   160,   -94,   -94,   -94,   164,   -94,   -94,   -94,   167,
-     168,   180,   533,   541,   548,   481,   481,    58,    58,   -94,
-     -94,   -94,   481,   481,   171,   -94,   -94,   172,   -94,   -94,
-     -24,   192,   217,   -94,   175,   -24,   219,   216,   481,   306,
-     220,   -94,   -94,   247,    33,    33,   205,   208,    41,   -94,
-     -94,   253,   234,   -94,   -94,   -94,   -94,   -94,   -94,   215,
-     481,   -94,   -94,   259,   260,   239,   -94,   -94,   221,   481,
-     481,   -94,   -94,   223,   224,   -94,   -94
+     -89,    18,   -89,   163,    -5,   -13,   219,   253,   253,   335,
+     194,    16,   274,   369,   418,   418,   253,   253,   253,   253,
+     240,     0,     0,   253,   -17,    19,   -89,   -89,    24,   -89,
+     -89,   -89,   479,   479,   -89,   -89,   -89,   -89,   -89,   -89,
+     -89,   -89,   111,   -89,   335,   397,   479,   -89,   -89,   -89,
+     -89,   -89,   -89,    33,    51,   390,   -89,   -89,    65,   -89,
+     -89,    72,   -89,    73,   356,   111,   314,   -89,   -89,   -89,
+     -89,   -89,   -89,    74,   -89,    30,   335,   -89,   -89,   -89,
+      70,   422,   479,   -89,   -89,    82,    86,   -89,    88,   -89,
+      89,   -89,    90,   -89,    91,   -89,    92,   -89,   101,   -89,
+     105,   -89,   114,   -89,   -89,   -89,   116,   -89,   479,   479,
+     -89,   -89,   -89,   118,   479,   479,   120,   -89,     5,   115,
+     -89,    83,   -89,   133,   -12,   404,   -89,   -89,   439,   -89,
+     -89,   -89,   335,   253,   -89,   -89,   120,   -89,     9,   479,
+     -89,   -89,   422,   141,   119,   452,   253,   335,   335,   335,
+     335,   335,   253,   163,   327,   327,    70,   -89,   -89,     4,
+     479,   143,   -89,   479,   479,   479,   190,   191,   479,   479,
+     479,   479,   479,   -89,   187,     6,   148,   152,   -89,   470,
+     156,   -89,   -89,   158,   162,   -89,     8,   -89,   164,   -89,
+     166,   -89,   170,   171,   -89,   169,   172,   -89,   -89,   173,
+     -89,   -89,   -89,   161,   176,   199,   102,   530,   537,   479,
+     479,    39,    39,   -89,   -89,   -89,   479,   479,   185,   -89,
+     -89,   189,   -89,   -89,     0,   208,   234,   -89,   193,     0,
+     211,   212,   479,   240,   217,   -89,   -89,   255,    55,    55,
+     214,   215,    59,   -89,   -89,   260,   241,   -89,   -89,   -89,
+     -89,   -89,   -89,   222,   479,   -89,   -89,   262,   276,   256,
+     -89,   -89,   242,   479,   479,   -89,   -89,   243,   246,   -89,
+     -89
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-     -94,   -94,   -94,   -43,   -94,   -94,   -94,   266,   -94,   -94,
-     -94,   273,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
-     -94,   -94,   -94,   -94,   -94,   -94,    26,   229,    32,   -11,
-      -9,    57,    -8,    71,    -2,    -6,     1,   -60,   -94,   -10,
-     -94,   -93
+     -89,   -89,   -89,   134,   -89,   -89,   289,   -89,   -89,   -89,
+     290,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
+     -89,   -89,   -89,   -89,   -89,    -2,   237,    11,   -11,    -9,
+      76,    -8,    87,    -4,     2,    -3,   -56,   -89,   -10,   -89,
+     -88
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -726,124 +726,120 @@ static const yytype_int16 yypgoto[] =
 #define YYTABLE_NINF -1
 static const yytype_uint16 yytable[] =
 {
-      75,    72,    86,    88,    74,    87,   139,   140,    73,   165,
-     223,   102,    77,   104,   106,     2,   231,   158,   206,   160,
-     207,    30,   144,   114,   115,   116,    31,   117,   118,   208,
-      56,   109,    49,   110,   111,    64,   123,   125,    49,   232,
-      62,   173,   174,   175,   176,   177,   133,    43,    94,    96,
-      98,   100,   166,   224,   112,   108,   137,   132,    75,    72,
-     180,   181,    74,   138,   117,   118,    73,   182,   175,   176,
-     177,   120,   145,    88,   123,   212,   213,   214,   263,   264,
-     217,   218,   219,   220,   221,    90,    92,   168,   169,   170,
-     171,   172,   173,   174,   175,   176,   177,   113,   126,   127,
-     123,   205,   123,   134,   120,    33,    34,   162,   163,   188,
-     135,   136,   180,   181,   203,   142,   204,   143,   115,   182,
-     146,   123,   244,   245,   147,   148,   161,   149,   150,    35,
-     151,   152,   153,   189,   154,   190,    88,   178,   193,   195,
-     155,   194,    82,    67,    44,   156,    33,    34,    83,    84,
-     164,    56,    47,   167,   179,   210,   188,   211,   123,   123,
-     123,   186,   215,   123,   123,   123,   123,   123,   187,   216,
-      35,    33,    34,    65,   115,   222,   225,   197,   198,   199,
-     200,   201,   196,    82,    67,    44,   226,   228,   202,   229,
-      84,   230,   234,    47,   235,    35,   236,   237,   238,    36,
-      37,    38,    39,    40,    41,   123,   123,    42,    66,    67,
-      44,   239,   246,   247,    68,    46,   240,   243,    47,     4,
-     241,   242,   250,   248,   251,   249,   252,   254,   257,   191,
-     258,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
-     268,    33,    34,    65,   256,   259,   255,   260,   261,   273,
-     274,   262,   265,    24,    25,    26,   266,    27,   267,   269,
-     270,   271,    33,    34,   272,    35,   275,   276,    79,    36,
-      37,    38,    39,    40,    41,    80,     0,    42,    66,    67,
-      44,   253,     0,    33,    34,    46,    35,   141,    47,     0,
-      36,    37,    38,    39,    40,    41,     0,     0,    42,    43,
-       0,    44,     0,     0,     0,    45,    46,    35,     0,    47,
-       0,    36,    37,    38,    39,    40,    41,    33,    34,    42,
-      43,     0,    44,     0,     0,     0,     0,    46,     0,    56,
-      47,     0,    36,    37,    38,    39,    40,    41,    33,    34,
-      42,    35,     0,     0,     0,    36,    37,    38,    39,    40,
-      41,     0,     0,    42,    43,     0,    44,     0,     0,     0,
-      78,    46,    35,     0,    47,     0,    36,    37,    38,    39,
-      40,    41,    33,    34,    42,    43,     0,    44,     0,     0,
-       0,     0,    46,    33,   128,    47,   168,   169,   170,   171,
-     172,   173,   174,   175,   176,   177,    35,    33,    34,     0,
-      36,    37,    38,    39,    40,    41,     0,    35,    42,     0,
-       0,    44,     0,    33,    34,     0,    46,   129,   130,    47,
-      43,    35,    44,     0,    33,    34,   121,   131,     0,     0,
-      47,    33,   184,   122,     0,     0,    44,    35,    33,    34,
-       0,    84,    33,    34,    47,     0,     0,     0,    35,     0,
-      43,     0,    44,     0,     0,    35,     0,    46,   183,     0,
-      47,     0,    35,    44,     0,   185,    35,     0,    84,     0,
-      44,    47,    33,    34,     0,    84,     0,    44,    47,    33,
-      34,    44,    84,     0,   191,    47,    84,     0,    56,    47,
-       0,     0,     0,     0,     0,     0,    35,     0,     0,     0,
-       0,     0,     0,    35,     0,     0,   227,     0,     0,     0,
-       0,    44,     0,     0,     0,     0,    84,     0,    44,    47,
-       0,     0,     0,    84,     0,     0,    47,   169,   170,   171,
-     172,   173,   174,   175,   176,   177,   170,   171,   172,   173,
-     174,   175,   176,   177,   171,   172,   173,   174,   175,   176,
-     177
+      73,    70,    84,    86,    48,    85,    71,    63,    75,   136,
+      48,   100,    72,   102,   104,   160,   217,   225,     2,    61,
+     154,   155,   111,   112,   140,   175,   176,    92,    94,    96,
+      98,   107,   177,   108,   106,   120,   122,   200,    30,   201,
+     226,   139,   117,   183,    29,   130,   175,   176,   202,   170,
+     171,   172,   129,   177,    55,   134,    73,    70,   161,   218,
+     135,    42,    71,   168,   169,   170,   171,   172,    72,   109,
+     141,    86,   120,   110,   117,   206,   207,   208,   114,   115,
+     211,   212,   213,   214,   215,   123,   163,   164,   165,   166,
+     167,   168,   169,   170,   171,   172,   257,   258,   120,   120,
+     199,    88,    90,   124,   157,   158,   164,   165,   166,   167,
+     168,   169,   170,   171,   172,   112,   131,   113,   120,   114,
+     115,   238,   239,   132,   133,   156,   138,    32,    33,   184,
+     181,   185,    86,   142,   188,   190,   173,   189,   143,   144,
+     145,   146,   147,   148,   182,   192,   193,   194,   195,   196,
+     204,    34,   149,   120,   120,   120,   150,   191,   120,   120,
+     120,   120,   120,   197,     4,   151,    43,   152,   162,   112,
+     174,    82,   159,   186,    46,   183,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,   205,   209,   216,   210,   120,
+     120,   219,    32,    33,    64,   220,   240,   241,    24,   222,
+      25,   223,    26,   224,   235,   228,   244,   229,   230,   231,
+     232,   248,   251,   233,   252,   234,    34,    32,    33,   236,
+      35,    36,    37,    38,    39,    40,   237,   242,    41,    65,
+     245,    43,   243,   246,   262,    66,    45,   186,   249,    46,
+     250,    34,   253,   267,   268,    35,    36,    37,    38,    39,
+      40,    32,    33,    41,    42,   254,    43,   255,   256,   259,
+      44,    45,   263,   260,    46,   261,    35,    36,    37,    38,
+      39,    40,    32,    33,    41,    34,   264,   198,   265,    35,
+      36,    37,    38,    39,    40,   266,   269,    41,    42,   270,
+      43,    77,    78,   137,   247,    45,    34,    55,    46,     0,
+      35,    36,    37,    38,    39,    40,     0,     0,    41,    42,
+       0,    43,    32,    33,    64,    76,    45,     0,     0,    46,
+     163,   164,   165,   166,   167,   168,   169,   170,   171,   172,
+       0,     0,     0,    32,    33,     0,    34,     0,     0,     0,
+      35,    36,    37,    38,    39,    40,     0,     0,    41,    65,
+       0,    43,     0,     0,    32,    33,    45,    34,     0,    46,
+       0,    35,    36,    37,    38,    39,    40,    32,    33,    41,
+      42,     0,    43,     0,     0,     0,     0,    45,    34,     0,
+      46,     0,    35,    36,    37,    38,    39,    40,    32,   125,
+      41,    34,     0,    43,     0,    32,    33,     0,    45,     0,
+       0,    46,    32,    33,    80,     0,    43,     0,     0,     0,
+      81,    82,    34,    55,    46,     0,    32,    33,     0,    34,
+      32,    33,   126,   127,   118,    42,    34,    43,     0,     0,
+       0,   119,   128,     0,    43,    46,   178,    32,   179,    82,
+      34,    43,    46,     0,    34,     0,    82,     0,     0,    46,
+      32,    33,     0,    42,     0,    43,     0,    80,     0,    43,
+      45,    34,     0,    46,    82,     0,     0,    46,    32,    33,
+       0,   180,     0,     0,    34,     0,    43,    32,    33,     0,
+       0,    82,     0,     0,    46,     0,     0,     0,     0,    43,
+       0,     0,    34,     0,    82,     0,    55,    46,     0,     0,
+       0,    34,   221,     0,     0,     0,     0,    43,     0,     0,
+       0,     0,    82,     0,     0,    46,    43,     0,     0,     0,
+       0,    82,     0,     0,    46,   165,   166,   167,   168,   169,
+     170,   171,   172,   166,   167,   168,   169,   170,   171,   172
 };
 
 static const yytype_int16 yycheck[] =
 {
-      10,    10,    13,    13,    10,    13,    66,    67,    10,    10,
-      10,    20,    11,    21,    22,     0,     9,   110,    33,   112,
-      35,    49,    82,    33,    34,     6,    51,     8,     9,    44,
-      54,    48,     6,    50,    48,     9,    46,    47,    12,    32,
-       8,     8,     9,    10,    11,    12,    56,    45,    16,    17,
-      18,    19,    53,    53,    50,    23,    65,    56,    68,    68,
-      37,    38,    68,    65,     8,     9,    68,    44,    10,    11,
-      12,    45,    83,    83,    84,   168,   169,   170,    37,    38,
-     173,   174,   175,   176,   177,    14,    15,     3,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    49,    52,    52,
-     110,   161,   112,    51,    78,     8,     9,   117,   118,    34,
-      51,    51,    37,    38,   157,    52,   159,    11,   128,    44,
-      51,   131,   215,   216,    52,    51,     7,    51,    51,    32,
-      51,    51,    51,   143,    51,   146,   146,    53,   148,   149,
-      51,   149,    45,    46,    47,    51,     8,     9,    51,    52,
-      52,    54,    55,    53,    37,   165,    34,    52,   168,   169,
-     170,   135,     6,   173,   174,   175,   176,   177,   136,     7,
-      32,     8,     9,    10,   184,    10,    53,   151,   152,   153,
-     154,   155,   150,    45,    46,    47,    53,    53,   156,    53,
-      52,    51,    51,    55,    51,    32,    48,    48,    51,    36,
-      37,    38,    39,    40,    41,   215,   216,    44,    45,    46,
-      47,    51,   222,   223,    51,    52,    52,    37,    55,     1,
-      53,    53,   230,    52,    32,    53,     9,   235,   238,    54,
-     239,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
-     260,     8,     9,    10,    38,    35,    37,    10,    53,   269,
-     270,    53,     9,    45,    46,    47,    32,    49,    53,    10,
-      10,    32,     8,     9,    53,    32,    53,    53,    12,    36,
-      37,    38,    39,    40,    41,    12,    -1,    44,    45,    46,
-      47,   234,    -1,     8,     9,    52,    32,    68,    55,    -1,
+      10,    10,    13,    13,     6,    13,    10,     9,    11,    65,
+      12,    20,    10,    21,    22,    10,    10,     9,     0,     8,
+     108,   109,    32,    33,    80,    37,    38,    16,    17,    18,
+      19,    48,    44,    50,    23,    45,    46,    33,    51,    35,
+      32,    11,    44,    34,    49,    55,    37,    38,    44,    10,
+      11,    12,    55,    44,    54,    64,    66,    66,    53,    53,
+      64,    45,    66,     8,     9,    10,    11,    12,    66,    50,
+      81,    81,    82,    49,    76,   163,   164,   165,     8,     9,
+     168,   169,   170,   171,   172,    52,     3,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    37,    38,   108,   109,
+     156,    14,    15,    52,   114,   115,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,   125,    51,     6,   128,     8,
+       9,   209,   210,    51,    51,     7,    52,     8,     9,   139,
+     132,   142,   142,    51,   144,   145,    53,   145,    52,    51,
+      51,    51,    51,    51,   133,   147,   148,   149,   150,   151,
+     160,    32,    51,   163,   164,   165,    51,   146,   168,   169,
+     170,   171,   172,   152,     1,    51,    47,    51,    53,   179,
+      37,    52,    52,    54,    55,    34,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    52,     6,    10,     7,   209,
+     210,    53,     8,     9,    10,    53,   216,   217,    45,    53,
+      47,    53,    49,    51,    53,    51,   224,    51,    48,    48,
+      51,   229,   232,    51,   233,    52,    32,     8,     9,    53,
+      36,    37,    38,    39,    40,    41,    37,    52,    44,    45,
+      32,    47,    53,     9,   254,    51,    52,    54,    37,    55,
+      38,    32,    35,   263,   264,    36,    37,    38,    39,    40,
+      41,     8,     9,    44,    45,    10,    47,    53,    53,     9,
+      51,    52,    10,    32,    55,    53,    36,    37,    38,    39,
+      40,    41,     8,     9,    44,    32,    10,   153,    32,    36,
+      37,    38,    39,    40,    41,    53,    53,    44,    45,    53,
+      47,    12,    12,    66,   228,    52,    32,    54,    55,    -1,
       36,    37,    38,    39,    40,    41,    -1,    -1,    44,    45,
-      -1,    47,    -1,    -1,    -1,    51,    52,    32,    -1,    55,
+      -1,    47,     8,     9,    10,    51,    52,    -1,    -1,    55,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      -1,    -1,    -1,     8,     9,    -1,    32,    -1,    -1,    -1,
+      36,    37,    38,    39,    40,    41,    -1,    -1,    44,    45,
+      -1,    47,    -1,    -1,     8,     9,    52,    32,    -1,    55,
       -1,    36,    37,    38,    39,    40,    41,     8,     9,    44,
-      45,    -1,    47,    -1,    -1,    -1,    -1,    52,    -1,    54,
+      45,    -1,    47,    -1,    -1,    -1,    -1,    52,    32,    -1,
       55,    -1,    36,    37,    38,    39,    40,    41,     8,     9,
-      44,    32,    -1,    -1,    -1,    36,    37,    38,    39,    40,
-      41,    -1,    -1,    44,    45,    -1,    47,    -1,    -1,    -1,
-      51,    52,    32,    -1,    55,    -1,    36,    37,    38,    39,
-      40,    41,     8,     9,    44,    45,    -1,    47,    -1,    -1,
-      -1,    -1,    52,     8,     9,    55,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,    32,     8,     9,    -1,
-      36,    37,    38,    39,    40,    41,    -1,    32,    44,    -1,
-      -1,    47,    -1,     8,     9,    -1,    52,    42,    43,    55,
-      45,    32,    47,    -1,     8,     9,    37,    52,    -1,    -1,
-      55,     8,     9,    44,    -1,    -1,    47,    32,     8,     9,
-      -1,    52,     8,     9,    55,    -1,    -1,    -1,    32,    -1,
-      45,    -1,    47,    -1,    -1,    32,    -1,    52,    42,    -1,
-      55,    -1,    32,    47,    -1,    42,    32,    -1,    52,    -1,
-      47,    55,     8,     9,    -1,    52,    -1,    47,    55,     8,
-       9,    47,    52,    -1,    54,    55,    52,    -1,    54,    55,
-      -1,    -1,    -1,    -1,    -1,    -1,    32,    -1,    -1,    -1,
-      -1,    -1,    -1,    32,    -1,    -1,    42,    -1,    -1,    -1,
-      -1,    47,    -1,    -1,    -1,    -1,    52,    -1,    47,    55,
-      -1,    -1,    -1,    52,    -1,    -1,    55,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,     5,     6,     7,     8,
-       9,    10,    11,    12,     6,     7,     8,     9,    10,    11,
-      12
+      44,    32,    -1,    47,    -1,     8,     9,    -1,    52,    -1,
+      -1,    55,     8,     9,    45,    -1,    47,    -1,    -1,    -1,
+      51,    52,    32,    54,    55,    -1,     8,     9,    -1,    32,
+       8,     9,    42,    43,    37,    45,    32,    47,    -1,    -1,
+      -1,    44,    52,    -1,    47,    55,    42,     8,     9,    52,
+      32,    47,    55,    -1,    32,    -1,    52,    -1,    -1,    55,
+       8,     9,    -1,    45,    -1,    47,    -1,    45,    -1,    47,
+      52,    32,    -1,    55,    52,    -1,    -1,    55,     8,     9,
+      -1,    42,    -1,    -1,    32,    -1,    47,     8,     9,    -1,
+      -1,    52,    -1,    -1,    55,    -1,    -1,    -1,    -1,    47,
+      -1,    -1,    32,    -1,    52,    -1,    54,    55,    -1,    -1,
+      -1,    32,    42,    -1,    -1,    -1,    -1,    47,    -1,    -1,
+      -1,    -1,    52,    -1,    -1,    55,    47,    -1,    -1,    -1,
+      -1,    52,    -1,    -1,    55,     5,     6,     7,     8,     9,
+      10,    11,    12,     6,     7,     8,     9,    10,    11,    12
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -852,32 +848,32 @@ static const yytype_uint8 yystos[] =
 {
        0,    57,     0,    58,     1,    13,    14,    15,    16,    17,
       18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    45,    46,    47,    49,    59,    62,
-      49,    51,    63,     8,     9,    32,    36,    37,    38,    39,
-      40,    41,    44,    45,    47,    51,    52,    55,    67,    82,
-      86,    89,    90,    91,    92,    95,    54,    66,    82,    84,
-      88,    64,    84,    65,    82,    10,    45,    46,    51,    71,
-      83,    85,    86,    90,    91,    95,    69,    92,    51,    63,
-      67,    72,    45,    51,    52,    68,    85,    88,    95,    70,
-      89,    79,    89,    80,    84,    73,    84,    74,    84,    75,
-      84,    76,    86,    77,    88,    78,    88,    81,    84,    48,
-      50,    48,    50,    49,    95,    95,     6,     8,     9,    93,
-      82,    37,    44,    95,    97,    95,    52,    52,     9,    42,
-      43,    52,    92,    95,    51,    51,    51,    86,    90,    93,
-      93,    83,    52,    11,    93,    85,    51,    52,    51,    51,
-      51,    51,    51,    51,    51,    51,    51,    61,    97,    60,
-      97,     7,    95,    95,    52,    10,    53,    53,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    53,    37,
-      37,    38,    44,    42,     9,    42,    82,    84,    34,    95,
-      85,    54,    87,    95,    88,    95,    84,    82,    82,    82,
-      82,    82,    84,    59,    59,    93,    33,    35,    44,    94,
-      95,    52,    97,    97,    97,     6,     7,    97,    97,    97,
-      97,    97,    10,    10,    53,    53,    53,    42,    53,    53,
-      51,     9,    32,    96,    51,    51,    48,    48,    51,    51,
-      52,    53,    53,    37,    97,    97,    95,    95,    52,    53,
-      88,    32,     9,    87,    88,    37,    38,    95,    86,    35,
-      10,    53,    53,    37,    38,     9,    32,    53,    95,    10,
-      10,    32,    53,    95,    95,    53,    53
+      28,    29,    30,    31,    45,    47,    49,    59,    61,    49,
+      51,    62,     8,     9,    32,    36,    37,    38,    39,    40,
+      41,    44,    45,    47,    51,    52,    55,    66,    81,    85,
+      88,    89,    90,    91,    94,    54,    65,    81,    83,    87,
+      63,    83,    64,    81,    10,    45,    51,    70,    82,    84,
+      85,    89,    90,    94,    68,    91,    51,    62,    66,    71,
+      45,    51,    52,    67,    84,    87,    94,    69,    88,    78,
+      88,    79,    83,    72,    83,    73,    83,    74,    83,    75,
+      85,    76,    87,    77,    87,    80,    83,    48,    50,    50,
+      49,    94,    94,     6,     8,     9,    92,    81,    37,    44,
+      94,    96,    94,    52,    52,     9,    42,    43,    52,    91,
+      94,    51,    51,    51,    85,    89,    92,    82,    52,    11,
+      92,    84,    51,    52,    51,    51,    51,    51,    51,    51,
+      51,    51,    51,    60,    96,    96,     7,    94,    94,    52,
+      10,    53,    53,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    12,    53,    37,    37,    38,    44,    42,     9,
+      42,    81,    83,    34,    94,    84,    54,    86,    94,    87,
+      94,    83,    81,    81,    81,    81,    81,    83,    59,    92,
+      33,    35,    44,    93,    94,    52,    96,    96,    96,     6,
+       7,    96,    96,    96,    96,    96,    10,    10,    53,    53,
+      53,    42,    53,    53,    51,     9,    32,    95,    51,    51,
+      48,    48,    51,    51,    52,    53,    53,    37,    96,    96,
+      94,    94,    52,    53,    87,    32,     9,    86,    87,    37,
+      38,    94,    85,    35,    10,    53,    53,    37,    38,     9,
+      32,    53,    94,    10,    10,    32,    53,    94,    94,    53,
+      53
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1701,30 +1697,24 @@ yyreduce:
   case 5:
 #line 75 "a.y"
     {
-               if((yyvsp[(1) - (2)].sym)->value != pc)
-                       yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->name);
-               (yyvsp[(1) - (2)].sym)->value = pc;
-       }
-    break;
-
-  case 7:
-#line 82 "a.y"
-    {
+               (yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
+               if((yyvsp[(1) - (2)].sym)->type == LLAB && (yyvsp[(1) - (2)].sym)->value != pc)
+                       yyerror("redeclaration of %s (%s)", (yyvsp[(1) - (2)].sym)->labelname, (yyvsp[(1) - (2)].sym)->name);
                (yyvsp[(1) - (2)].sym)->type = LLAB;
                (yyvsp[(1) - (2)].sym)->value = pc;
        }
     break;
 
-  case 12:
-#line 93 "a.y"
+  case 10:
+#line 89 "a.y"
     {
                (yyvsp[(1) - (3)].sym)->type = LVAR;
                (yyvsp[(1) - (3)].sym)->value = (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 13:
-#line 98 "a.y"
+  case 11:
+#line 94 "a.y"
     {
                if((yyvsp[(1) - (3)].sym)->value != (yyvsp[(3) - (3)].lval))
                        yyerror("redeclaration of %s", (yyvsp[(1) - (3)].sym)->name);
@@ -1732,191 +1722,191 @@ yyreduce:
        }
     break;
 
+  case 12:
+#line 99 "a.y"
+    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
+    break;
+
+  case 13:
+#line 100 "a.y"
+    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
+    break;
+
   case 14:
-#line 103 "a.y"
+#line 101 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 15:
-#line 104 "a.y"
+#line 102 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 16:
-#line 105 "a.y"
+#line 103 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 17:
-#line 106 "a.y"
+#line 104 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 18:
-#line 107 "a.y"
+#line 105 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 19:
-#line 108 "a.y"
+#line 106 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 20:
-#line 109 "a.y"
+#line 107 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 21:
-#line 110 "a.y"
+#line 108 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 22:
-#line 111 "a.y"
+#line 109 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 23:
-#line 112 "a.y"
+#line 110 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 24:
-#line 113 "a.y"
+#line 111 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 25:
-#line 114 "a.y"
+#line 112 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 26:
-#line 115 "a.y"
+#line 113 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 27:
-#line 116 "a.y"
+#line 114 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 28:
-#line 117 "a.y"
+#line 115 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 29:
-#line 118 "a.y"
+#line 116 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 30:
-#line 119 "a.y"
+#line 117 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 31:
 #line 120 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 32:
-#line 121 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 33:
-#line 124 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 34:
-#line 129 "a.y"
+  case 32:
+#line 125 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 35:
-#line 136 "a.y"
+  case 33:
+#line 132 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 36:
-#line 143 "a.y"
+  case 34:
+#line 139 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 37:
-#line 150 "a.y"
+  case 35:
+#line 146 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (2)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 38:
-#line 155 "a.y"
+  case 36:
+#line 151 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 39:
-#line 162 "a.y"
+  case 37:
+#line 158 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 40:
-#line 167 "a.y"
+  case 38:
+#line 163 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
        }
     break;
 
-  case 41:
-#line 174 "a.y"
+  case 39:
+#line 170 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 42:
-#line 179 "a.y"
+  case 40:
+#line 175 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
        }
     break;
 
-  case 43:
-#line 184 "a.y"
+  case 41:
+#line 180 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 44:
-#line 191 "a.y"
+  case 42:
+#line 187 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
@@ -1924,49 +1914,51 @@ yyreduce:
        }
     break;
 
-  case 45:
-#line 199 "a.y"
+  case 43:
+#line 195 "a.y"
     {
+               settext((yyvsp[(1) - (3)].addr).sym);
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 46:
-#line 204 "a.y"
+  case 44:
+#line 201 "a.y"
     {
+               settext((yyvsp[(1) - (5)].addr).sym);
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
                (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
        }
     break;
 
-  case 47:
-#line 212 "a.y"
+  case 45:
+#line 210 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 48:
-#line 217 "a.y"
+  case 46:
+#line 215 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
        }
     break;
 
-  case 51:
-#line 228 "a.y"
+  case 49:
+#line 226 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 52:
-#line 233 "a.y"
+  case 50:
+#line 231 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
@@ -1976,16 +1968,16 @@ yyreduce:
        }
     break;
 
-  case 53:
-#line 243 "a.y"
+  case 51:
+#line 241 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 54:
-#line 248 "a.y"
+  case 52:
+#line 246 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
@@ -1995,32 +1987,32 @@ yyreduce:
        }
     break;
 
-  case 55:
-#line 258 "a.y"
+  case 53:
+#line 256 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (2)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 56:
-#line 263 "a.y"
+  case 54:
+#line 261 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 57:
-#line 268 "a.y"
+  case 55:
+#line 266 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 58:
-#line 275 "a.y"
+  case 56:
+#line 273 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
@@ -2028,8 +2020,8 @@ yyreduce:
        }
     break;
 
-  case 59:
-#line 283 "a.y"
+  case 57:
+#line 281 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(3) - (5)].addr);
                (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
@@ -2039,32 +2031,32 @@ yyreduce:
        }
     break;
 
-  case 60:
-#line 292 "a.y"
+  case 58:
+#line 290 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 61:
-#line 297 "a.y"
+  case 59:
+#line 295 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 62:
-#line 304 "a.y"
+  case 60:
+#line 302 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 63:
-#line 309 "a.y"
+  case 61:
+#line 307 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
@@ -2072,8 +2064,8 @@ yyreduce:
        }
     break;
 
-  case 64:
-#line 317 "a.y"
+  case 62:
+#line 315 "a.y"
     {
                if((yyvsp[(1) - (3)].addr).type != D_CONST || (yyvsp[(3) - (3)].addr).type != D_CONST)
                        yyerror("arguments to PCDATA must be integer constants");
@@ -2082,8 +2074,8 @@ yyreduce:
        }
     break;
 
-  case 65:
-#line 326 "a.y"
+  case 63:
+#line 324 "a.y"
     {
                if((yyvsp[(1) - (3)].addr).type != D_CONST)
                        yyerror("index for FUNCDATA must be integer constant");
@@ -2094,22 +2086,22 @@ yyreduce:
        }
     break;
 
-  case 70:
-#line 343 "a.y"
+  case 68:
+#line 341 "a.y"
     {
                (yyval.addr) = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 71:
-#line 347 "a.y"
+  case 69:
+#line 345 "a.y"
     {
                (yyval.addr) = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 76:
-#line 359 "a.y"
+  case 74:
+#line 357 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_BRANCH;
@@ -2117,84 +2109,76 @@ yyreduce:
        }
     break;
 
-  case 77:
-#line 365 "a.y"
-    {
-               (yyval.addr) = nullgen;
-               if(pass == 2)
-                       yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->name);
-               (yyval.addr).type = D_BRANCH;
-               (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
-       }
-    break;
-
-  case 78:
-#line 373 "a.y"
+  case 75:
+#line 363 "a.y"
     {
+               (yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
                (yyval.addr) = nullgen;
+               if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
+                       yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
                (yyval.addr).type = D_BRANCH;
                (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 79:
-#line 381 "a.y"
+  case 76:
+#line 374 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 80:
-#line 386 "a.y"
+  case 77:
+#line 379 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 81:
-#line 391 "a.y"
+  case 78:
+#line 384 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 82:
-#line 396 "a.y"
+  case 79:
+#line 389 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 83:
-#line 401 "a.y"
+  case 80:
+#line 394 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SP;
        }
     break;
 
-  case 84:
-#line 406 "a.y"
+  case 81:
+#line 399 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 85:
-#line 411 "a.y"
+  case 82:
+#line 404 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 86:
-#line 417 "a.y"
+  case 83:
+#line 410 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_CONST;
@@ -2202,8 +2186,8 @@ yyreduce:
        }
     break;
 
-  case 87:
-#line 425 "a.y"
+  case 84:
+#line 418 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_CONST;
@@ -2211,8 +2195,8 @@ yyreduce:
        }
     break;
 
-  case 88:
-#line 431 "a.y"
+  case 85:
+#line 424 "a.y"
     {
                (yyval.addr) = (yyvsp[(2) - (2)].addr);
                (yyval.addr).index = (yyvsp[(2) - (2)].addr).type;
@@ -2225,8 +2209,8 @@ yyreduce:
        }
     break;
 
-  case 89:
-#line 442 "a.y"
+  case 86:
+#line 435 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SCONST;
@@ -2234,8 +2218,8 @@ yyreduce:
        }
     break;
 
-  case 90:
-#line 448 "a.y"
+  case 87:
+#line 441 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2243,8 +2227,8 @@ yyreduce:
        }
     break;
 
-  case 91:
-#line 454 "a.y"
+  case 88:
+#line 447 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2252,8 +2236,8 @@ yyreduce:
        }
     break;
 
-  case 92:
-#line 460 "a.y"
+  case 89:
+#line 453 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2261,8 +2245,8 @@ yyreduce:
        }
     break;
 
-  case 93:
-#line 466 "a.y"
+  case 90:
+#line 459 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2270,8 +2254,8 @@ yyreduce:
        }
     break;
 
-  case 96:
-#line 478 "a.y"
+  case 93:
+#line 471 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_NONE;
@@ -2279,8 +2263,8 @@ yyreduce:
        }
     break;
 
-  case 97:
-#line 484 "a.y"
+  case 94:
+#line 477 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
@@ -2288,8 +2272,8 @@ yyreduce:
        }
     break;
 
-  case 98:
-#line 490 "a.y"
+  case 95:
+#line 483 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_SP;
@@ -2297,8 +2281,8 @@ yyreduce:
        }
     break;
 
-  case 99:
-#line 496 "a.y"
+  case 96:
+#line 489 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
@@ -2306,8 +2290,8 @@ yyreduce:
        }
     break;
 
-  case 100:
-#line 502 "a.y"
+  case 97:
+#line 495 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_NONE;
@@ -2318,8 +2302,8 @@ yyreduce:
        }
     break;
 
-  case 101:
-#line 511 "a.y"
+  case 98:
+#line 504 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
@@ -2330,8 +2314,8 @@ yyreduce:
        }
     break;
 
-  case 102:
-#line 520 "a.y"
+  case 99:
+#line 513 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
@@ -2342,24 +2326,24 @@ yyreduce:
        }
     break;
 
-  case 103:
-#line 529 "a.y"
+  case 100:
+#line 522 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(2) - (3)].lval);
        }
     break;
 
-  case 104:
-#line 534 "a.y"
+  case 101:
+#line 527 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_SP;
        }
     break;
 
-  case 105:
-#line 539 "a.y"
+  case 102:
+#line 532 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_NONE;
@@ -2369,8 +2353,8 @@ yyreduce:
        }
     break;
 
-  case 106:
-#line 547 "a.y"
+  case 103:
+#line 540 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(2) - (8)].lval);
@@ -2380,15 +2364,15 @@ yyreduce:
        }
     break;
 
-  case 107:
-#line 557 "a.y"
+  case 104:
+#line 550 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (1)].addr);
        }
     break;
 
-  case 108:
-#line 561 "a.y"
+  case 105:
+#line 554 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (6)].addr);
                (yyval.addr).index = (yyvsp[(3) - (6)].lval);
@@ -2397,8 +2381,8 @@ yyreduce:
        }
     break;
 
-  case 109:
-#line 570 "a.y"
+  case 106:
+#line 563 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(4) - (5)].lval);
@@ -2407,8 +2391,8 @@ yyreduce:
        }
     break;
 
-  case 110:
-#line 577 "a.y"
+  case 107:
+#line 570 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_STATIC;
@@ -2417,166 +2401,166 @@ yyreduce:
        }
     break;
 
-  case 111:
-#line 585 "a.y"
+  case 108:
+#line 578 "a.y"
     {
                (yyval.lval) = 0;
        }
     break;
 
-  case 112:
-#line 589 "a.y"
+  case 109:
+#line 582 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 113:
-#line 593 "a.y"
+  case 110:
+#line 586 "a.y"
     {
                (yyval.lval) = -(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 115:
-#line 600 "a.y"
+  case 112:
+#line 593 "a.y"
     {
                (yyval.lval) = D_AUTO;
        }
     break;
 
-  case 118:
-#line 608 "a.y"
+  case 115:
+#line 601 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
        }
     break;
 
-  case 119:
-#line 612 "a.y"
+  case 116:
+#line 605 "a.y"
     {
                (yyval.lval) = -(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 120:
-#line 616 "a.y"
+  case 117:
+#line 609 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 121:
-#line 620 "a.y"
+  case 118:
+#line 613 "a.y"
     {
                (yyval.lval) = ~(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 122:
-#line 624 "a.y"
+  case 119:
+#line 617 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (3)].lval);
        }
     break;
 
-  case 123:
-#line 630 "a.y"
+  case 120:
+#line 623 "a.y"
     {
                (yyval.lval) = ((yyvsp[(1) - (1)].lval) & 0xffffffffLL) +
                        ((vlong)ArgsSizeUnknown << 32);
        }
     break;
 
-  case 124:
-#line 635 "a.y"
+  case 121:
+#line 628 "a.y"
     {
                (yyval.lval) = (-(yyvsp[(2) - (2)].lval) & 0xffffffffLL) +
                        ((vlong)ArgsSizeUnknown << 32);
        }
     break;
 
-  case 125:
-#line 640 "a.y"
+  case 122:
+#line 633 "a.y"
     {
                (yyval.lval) = ((yyvsp[(1) - (3)].lval) & 0xffffffffLL) +
                        (((yyvsp[(3) - (3)].lval) & 0xffffLL) << 32);
        }
     break;
 
-  case 126:
-#line 645 "a.y"
+  case 123:
+#line 638 "a.y"
     {
                (yyval.lval) = (-(yyvsp[(2) - (4)].lval) & 0xffffffffLL) +
                        (((yyvsp[(4) - (4)].lval) & 0xffffLL) << 32);
        }
     break;
 
-  case 128:
-#line 653 "a.y"
+  case 125:
+#line 646 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 129:
-#line 657 "a.y"
+  case 126:
+#line 650 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 130:
-#line 661 "a.y"
+  case 127:
+#line 654 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 131:
-#line 665 "a.y"
+  case 128:
+#line 658 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 132:
-#line 669 "a.y"
+  case 129:
+#line 662 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 133:
-#line 673 "a.y"
+  case 130:
+#line 666 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 134:
-#line 677 "a.y"
+  case 131:
+#line 670 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 135:
-#line 681 "a.y"
+  case 132:
+#line 674 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 136:
-#line 685 "a.y"
+  case 133:
+#line 678 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 137:
-#line 689 "a.y"
+  case 134:
+#line 682 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
        }
@@ -2584,7 +2568,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 2588 "y.tab.c"
+#line 2572 "y.tab.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
index adc388ca9f4d0226fa76c8186930738636b6afc9..a1aca07aea7445458bcbed85d6f6c71d17925901 100644 (file)
@@ -70,6 +70,7 @@ struct        Sym
        int32   value;
        ushort  type;
        char    *name;
+       char*   labelname;
        char    sym;
 };
 #define        S       ((Sym*)0)
@@ -148,6 +149,8 @@ void        newio(void);
 void   newfile(char*, int);
 Sym*   slookup(char*);
 Sym*   lookup(void);
+Sym*   labellookup(Sym*);
+void   settext(LSym*);
 void   syminit(Sym*);
 int32  yylex(void);
 int    getc(void);
index 6bcf1313bf653548e2fd69699dac0f3fa1f0cf02..c810d385779d4ddb8ad4061688bff0c51bfe6434 100644 (file)
@@ -74,15 +74,11 @@ prog:
        line
 
 line:
-       LLAB ':'
-       {
-               if($1->value != pc)
-                       yyerror("redeclaration of %s", $1->name);
-               $1->value = pc;
-       }
-       line
-|      LNAME ':'
+       LNAME ':'
        {
+               $1 = labellookup($1);
+               if($1->type == LLAB && $1->value != pc)
+                       yyerror("redeclaration of %s", $1->labelname);
                $1->type = LLAB;
                $1->value = pc;
        }
@@ -199,11 +195,13 @@ spec1:    /* DATA */
 spec2: /* TEXT */
        mem ',' imm2
        {
+               settext($1.sym);
                $$.from = $1;
                $$.to = $3;
        }
 |      mem ',' con ',' imm2
        {
+               settext($1.sym);
                $$.from = $1;
                $$.from.scale = $3;
                $$.to = $5;
@@ -362,15 +360,10 @@ rel:
        }
 |      LNAME offset
        {
+               $1 = labellookup($1);
                $$ = nullgen;
-               if(pass == 2)
-                       yyerror("undefined label: %s", $1->name);
-               $$.type = D_BRANCH;
-               $$.offset = $2;
-       }
-|      LLAB offset
-       {
-               $$ = nullgen;
+               if(pass == 2 && $1->type != LLAB)
+                       yyerror("undefined label: %s", $1->labelname);
                $$.type = D_BRANCH;
                $$.offset = $1->value + $2;
        }
index 85279c21f98d710fec90dd8358c6611657a201fc..f284d8ea2eca10f7cf7b97b22c61bdda5f9820a8 100644 (file)
@@ -411,16 +411,16 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   546
+#define YYLAST   561
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  54
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  41
+#define YYNNTS  40
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  135
+#define YYNRULES  132
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  276
+#define YYNSTATES  270
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -469,91 +469,90 @@ static const yytype_uint8 yytranslate[] =
    YYRHS.  */
 static const yytype_uint16 yyprhs[] =
 {
-       0,     0,     3,     4,     5,     9,    10,    15,    16,    21,
-      23,    26,    29,    33,    37,    40,    43,    46,    49,    52,
+       0,     0,     3,     4,     5,     9,    10,    15,    17,    20,
+      23,    27,    31,    34,    37,    40,    43,    46,    49,    52,
       55,    58,    61,    64,    67,    70,    73,    76,    79,    82,
-      85,    88,    91,    92,    94,    98,   102,   105,   107,   110,
-     112,   115,   117,   121,   127,   131,   137,   140,   142,   145,
-     147,   149,   153,   159,   163,   169,   172,   174,   178,   182,
-     188,   194,   200,   204,   208,   210,   212,   214,   216,   219,
-     222,   224,   226,   228,   230,   232,   237,   240,   243,   245,
-     247,   249,   251,   253,   255,   258,   261,   264,   267,   272,
-     278,   282,   285,   287,   290,   294,   299,   301,   303,   305,
-     310,   315,   322,   332,   342,   346,   350,   355,   361,   370,
-     372,   379,   385,   393,   394,   397,   400,   402,   404,   406,
-     408,   410,   413,   416,   419,   423,   425,   429,   433,   437,
-     441,   445,   450,   455,   459,   463
+      85,    86,    88,    92,    96,    99,   101,   104,   106,   109,
+     111,   115,   121,   125,   131,   134,   136,   139,   141,   143,
+     147,   153,   157,   163,   166,   168,   172,   176,   182,   188,
+     194,   198,   202,   204,   206,   208,   210,   213,   216,   218,
+     220,   222,   224,   226,   231,   234,   236,   238,   240,   242,
+     244,   246,   249,   252,   255,   258,   263,   269,   273,   276,
+     278,   281,   285,   290,   292,   294,   296,   301,   306,   313,
+     323,   333,   337,   341,   346,   352,   361,   363,   370,   376,
+     384,   385,   388,   391,   393,   395,   397,   399,   401,   404,
+     407,   410,   414,   416,   420,   424,   428,   432,   436,   441,
+     446,   450,   454
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
       55,     0,    -1,    -1,    -1,    55,    56,    57,    -1,    -1,
-      44,    46,    58,    57,    -1,    -1,    43,    46,    59,    57,
-      -1,    47,    -1,    60,    47,    -1,     1,    47,    -1,    43,
-      48,    94,    -1,    45,    48,    94,    -1,    13,    61,    -1,
-      14,    65,    -1,    15,    64,    -1,    16,    62,    -1,    17,
-      63,    -1,    21,    66,    -1,    19,    67,    -1,    22,    68,
-      -1,    18,    69,    -1,    20,    70,    -1,    23,    71,    -1,
-      24,    72,    -1,    25,    73,    -1,    26,    74,    -1,    27,
-      75,    -1,    28,    76,    -1,    29,    77,    -1,    30,    78,
-      -1,    -1,    49,    -1,    81,    49,    79,    -1,    79,    49,
-      81,    -1,    81,    49,    -1,    81,    -1,    49,    79,    -1,
-      79,    -1,    49,    82,    -1,    82,    -1,    84,    49,    82,
-      -1,    90,    11,    93,    49,    84,    -1,    87,    49,    85,
-      -1,    87,    49,    93,    49,    85,    -1,    49,    80,    -1,
-      80,    -1,    10,    90,    -1,    61,    -1,    65,    -1,    81,
-      49,    79,    -1,    81,    49,    79,    46,    36,    -1,    81,
-      49,    79,    -1,    81,    49,    79,    46,    37,    -1,    81,
-      49,    -1,    81,    -1,    81,    49,    79,    -1,    87,    49,
-      84,    -1,    87,    49,    93,    49,    84,    -1,    83,    49,
-      79,    49,    93,    -1,    84,    49,    79,    49,    83,    -1,
-      81,    49,    81,    -1,    81,    49,    81,    -1,    83,    -1,
-      87,    -1,    82,    -1,    89,    -1,    10,    83,    -1,    10,
-      88,    -1,    83,    -1,    88,    -1,    84,    -1,    79,    -1,
-      84,    -1,    93,    50,    33,    51,    -1,    43,    91,    -1,
-      44,    91,    -1,    35,    -1,    38,    -1,    36,    -1,    39,
-      -1,    42,    -1,    37,    -1,    52,    93,    -1,    52,    90,
-      -1,    52,    41,    -1,    52,    40,    -1,    52,    50,    40,
-      51,    -1,    52,    50,     9,    40,    51,    -1,    52,     9,
-      40,    -1,    52,    86,    -1,    31,    -1,     9,    31,    -1,
-      31,     9,    31,    -1,     9,    31,     9,    31,    -1,    88,
-      -1,    89,    -1,    93,    -1,    93,    50,    36,    51,    -1,
-      93,    50,    42,    51,    -1,    93,    50,    36,    10,    93,
-      51,    -1,    93,    50,    36,    51,    50,    36,    10,    93,
-      51,    -1,    93,    50,    36,    51,    50,    37,    10,    93,
-      51,    -1,    50,    36,    51,    -1,    50,    42,    51,    -1,
-      93,    50,    37,    51,    -1,    50,    36,    10,    93,    51,
-      -1,    50,    36,    51,    50,    36,    10,    93,    51,    -1,
-      90,    -1,    90,    50,    36,    10,    93,    51,    -1,    43,
-      91,    50,    92,    51,    -1,    43,     6,     7,    91,    50,
-      34,    51,    -1,    -1,     8,    93,    -1,     9,    93,    -1,
-      34,    -1,    42,    -1,    32,    -1,    31,    -1,    45,    -1,
-       9,    93,    -1,     8,    93,    -1,    53,    93,    -1,    50,
-      94,    51,    -1,    93,    -1,    94,     8,    94,    -1,    94,
-       9,    94,    -1,    94,    10,    94,    -1,    94,    11,    94,
-      -1,    94,    12,    94,    -1,    94,     6,     6,    94,    -1,
-      94,     7,     7,    94,    -1,    94,     5,    94,    -1,    94,
-       4,    94,    -1,    94,     3,    94,    -1
+      43,    46,    58,    57,    -1,    47,    -1,    59,    47,    -1,
+       1,    47,    -1,    43,    48,    93,    -1,    45,    48,    93,
+      -1,    13,    60,    -1,    14,    64,    -1,    15,    63,    -1,
+      16,    61,    -1,    17,    62,    -1,    21,    65,    -1,    19,
+      66,    -1,    22,    67,    -1,    18,    68,    -1,    20,    69,
+      -1,    23,    70,    -1,    24,    71,    -1,    25,    72,    -1,
+      26,    73,    -1,    27,    74,    -1,    28,    75,    -1,    29,
+      76,    -1,    30,    77,    -1,    -1,    49,    -1,    80,    49,
+      78,    -1,    78,    49,    80,    -1,    80,    49,    -1,    80,
+      -1,    49,    78,    -1,    78,    -1,    49,    81,    -1,    81,
+      -1,    83,    49,    81,    -1,    89,    11,    92,    49,    83,
+      -1,    86,    49,    84,    -1,    86,    49,    92,    49,    84,
+      -1,    49,    79,    -1,    79,    -1,    10,    89,    -1,    60,
+      -1,    64,    -1,    80,    49,    78,    -1,    80,    49,    78,
+      46,    36,    -1,    80,    49,    78,    -1,    80,    49,    78,
+      46,    37,    -1,    80,    49,    -1,    80,    -1,    80,    49,
+      78,    -1,    86,    49,    83,    -1,    86,    49,    92,    49,
+      83,    -1,    82,    49,    78,    49,    92,    -1,    83,    49,
+      78,    49,    82,    -1,    80,    49,    80,    -1,    80,    49,
+      80,    -1,    82,    -1,    86,    -1,    81,    -1,    88,    -1,
+      10,    82,    -1,    10,    87,    -1,    82,    -1,    87,    -1,
+      83,    -1,    78,    -1,    83,    -1,    92,    50,    33,    51,
+      -1,    43,    90,    -1,    35,    -1,    38,    -1,    36,    -1,
+      39,    -1,    42,    -1,    37,    -1,    52,    92,    -1,    52,
+      89,    -1,    52,    41,    -1,    52,    40,    -1,    52,    50,
+      40,    51,    -1,    52,    50,     9,    40,    51,    -1,    52,
+       9,    40,    -1,    52,    85,    -1,    31,    -1,     9,    31,
+      -1,    31,     9,    31,    -1,     9,    31,     9,    31,    -1,
+      87,    -1,    88,    -1,    92,    -1,    92,    50,    36,    51,
+      -1,    92,    50,    42,    51,    -1,    92,    50,    36,    10,
+      92,    51,    -1,    92,    50,    36,    51,    50,    36,    10,
+      92,    51,    -1,    92,    50,    36,    51,    50,    37,    10,
+      92,    51,    -1,    50,    36,    51,    -1,    50,    42,    51,
+      -1,    92,    50,    37,    51,    -1,    50,    36,    10,    92,
+      51,    -1,    50,    36,    51,    50,    36,    10,    92,    51,
+      -1,    89,    -1,    89,    50,    36,    10,    92,    51,    -1,
+      43,    90,    50,    91,    51,    -1,    43,     6,     7,    90,
+      50,    34,    51,    -1,    -1,     8,    92,    -1,     9,    92,
+      -1,    34,    -1,    42,    -1,    32,    -1,    31,    -1,    45,
+      -1,     9,    92,    -1,     8,    92,    -1,    53,    92,    -1,
+      50,    93,    51,    -1,    92,    -1,    93,     8,    93,    -1,
+      93,     9,    93,    -1,    93,    10,    93,    -1,    93,    11,
+      93,    -1,    93,    12,    93,    -1,    93,     6,     6,    93,
+      -1,    93,     7,     7,    93,    -1,    93,     5,    93,    -1,
+      93,     4,    93,    -1,    93,     3,    93,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,    69,    69,    71,    70,    78,    77,    85,    84,    90,
-      91,    92,    95,   100,   106,   107,   108,   109,   110,   111,
-     112,   113,   114,   115,   116,   117,   118,   119,   120,   121,
-     122,   123,   126,   130,   137,   144,   151,   156,   163,   168,
-     175,   180,   185,   192,   200,   205,   213,   218,   223,   232,
-     233,   236,   241,   251,   256,   266,   271,   276,   283,   288,
-     296,   304,   314,   323,   334,   335,   338,   339,   340,   344,
-     348,   349,   350,   353,   354,   357,   363,   371,   379,   384,
-     389,   394,   399,   404,   411,   417,   428,   434,   440,   446,
-     452,   460,   469,   474,   479,   484,   491,   492,   495,   501,
-     507,   513,   522,   531,   540,   545,   550,   556,   564,   574,
-     578,   587,   594,   603,   606,   610,   616,   617,   621,   624,
-     625,   629,   633,   637,   641,   647,   648,   652,   656,   660,
-     664,   668,   672,   676,   680,   684
+       0,    69,    69,    71,    70,    78,    77,    86,    87,    88,
+      91,    96,   102,   103,   104,   105,   106,   107,   108,   109,
+     110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
+     122,   126,   133,   140,   147,   152,   159,   164,   171,   176,
+     181,   188,   196,   202,   211,   216,   221,   230,   231,   234,
+     239,   249,   254,   264,   269,   274,   281,   286,   294,   302,
+     312,   321,   332,   333,   336,   337,   338,   342,   346,   347,
+     348,   351,   352,   355,   361,   372,   377,   382,   387,   392,
+     397,   404,   410,   421,   427,   433,   439,   445,   453,   462,
+     467,   472,   477,   484,   485,   488,   494,   500,   506,   515,
+     524,   533,   538,   543,   549,   557,   567,   571,   580,   587,
+     596,   599,   603,   609,   610,   614,   617,   618,   622,   626,
+     630,   634,   640,   641,   645,   649,   653,   657,   661,   665,
+     669,   673,   677
 };
 #endif
 
@@ -569,10 +568,10 @@ static const char *const yytname[] =
   "LCONST", "LFP", "LPC", "LSB", "LBREG", "LLREG", "LSREG", "LFREG",
   "LXREG", "LFCONST", "LSCONST", "LSP", "LNAME", "LLAB", "LVAR", "':'",
   "';'", "'='", "','", "'('", "')'", "'$'", "'~'", "$accept", "prog", "@1",
-  "line", "@2", "@3", "inst", "nonnon", "rimrem", "remrim", "rimnon",
-  "nonrem", "nonrel", "spec1", "spec2", "spec3", "spec4", "spec5", "spec6",
-  "spec7", "spec8", "spec9", "spec10", "spec11", "spec12", "rem", "rom",
-  "rim", "rel", "reg", "imm", "imm2", "con2", "mem", "omem", "nmem", "nam",
+  "line", "@2", "inst", "nonnon", "rimrem", "remrim", "rimnon", "nonrem",
+  "nonrel", "spec1", "spec2", "spec3", "spec4", "spec5", "spec6", "spec7",
+  "spec8", "spec9", "spec10", "spec11", "spec12", "rem", "rom", "rim",
+  "rel", "reg", "imm", "imm2", "con2", "mem", "omem", "nmem", "nam",
   "offset", "pointer", "con", "expr", 0
 };
 #endif
@@ -594,39 +593,39 @@ static const yytype_uint16 yytoknum[] =
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    54,    55,    56,    55,    58,    57,    59,    57,    57,
-      57,    57,    60,    60,    60,    60,    60,    60,    60,    60,
-      60,    60,    60,    60,    60,    60,    60,    60,    60,    60,
-      60,    60,    61,    61,    62,    63,    64,    64,    65,    65,
-      66,    66,    66,    67,    68,    68,    69,    69,    69,    70,
-      70,    71,    71,    72,    72,    73,    73,    73,    74,    74,
-      75,    76,    77,    78,    79,    79,    80,    80,    80,    80,
-      80,    80,    80,    81,    81,    82,    82,    82,    83,    83,
-      83,    83,    83,    83,    84,    84,    84,    84,    84,    84,
-      84,    85,    86,    86,    86,    86,    87,    87,    88,    88,
-      88,    88,    88,    88,    88,    88,    88,    88,    88,    89,
-      89,    90,    90,    91,    91,    91,    92,    92,    92,    93,
-      93,    93,    93,    93,    93,    94,    94,    94,    94,    94,
-      94,    94,    94,    94,    94,    94
+       0,    54,    55,    56,    55,    58,    57,    57,    57,    57,
+      59,    59,    59,    59,    59,    59,    59,    59,    59,    59,
+      59,    59,    59,    59,    59,    59,    59,    59,    59,    59,
+      60,    60,    61,    62,    63,    63,    64,    64,    65,    65,
+      65,    66,    67,    67,    68,    68,    68,    69,    69,    70,
+      70,    71,    71,    72,    72,    72,    73,    73,    74,    75,
+      76,    77,    78,    78,    79,    79,    79,    79,    79,    79,
+      79,    80,    80,    81,    81,    82,    82,    82,    82,    82,
+      82,    83,    83,    83,    83,    83,    83,    83,    84,    85,
+      85,    85,    85,    86,    86,    87,    87,    87,    87,    87,
+      87,    87,    87,    87,    87,    87,    88,    88,    89,    89,
+      90,    90,    90,    91,    91,    91,    92,    92,    92,    92,
+      92,    92,    93,    93,    93,    93,    93,    93,    93,    93,
+      93,    93,    93
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     0,     0,     3,     0,     4,     0,     4,     1,
-       2,     2,     3,     3,     2,     2,     2,     2,     2,     2,
+       0,     2,     0,     0,     3,     0,     4,     1,     2,     2,
+       3,     3,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     0,     1,     3,     3,     2,     1,     2,     1,
-       2,     1,     3,     5,     3,     5,     2,     1,     2,     1,
-       1,     3,     5,     3,     5,     2,     1,     3,     3,     5,
-       5,     5,     3,     3,     1,     1,     1,     1,     2,     2,
-       1,     1,     1,     1,     1,     4,     2,     2,     1,     1,
-       1,     1,     1,     1,     2,     2,     2,     2,     4,     5,
-       3,     2,     1,     2,     3,     4,     1,     1,     1,     4,
-       4,     6,     9,     9,     3,     3,     4,     5,     8,     1,
-       6,     5,     7,     0,     2,     2,     1,     1,     1,     1,
-       1,     2,     2,     2,     3,     1,     3,     3,     3,     3,
-       3,     4,     4,     3,     3,     3
+       0,     1,     3,     3,     2,     1,     2,     1,     2,     1,
+       3,     5,     3,     5,     2,     1,     2,     1,     1,     3,
+       5,     3,     5,     2,     1,     3,     3,     5,     5,     5,
+       3,     3,     1,     1,     1,     1,     2,     2,     1,     1,
+       1,     1,     1,     4,     2,     1,     1,     1,     1,     1,
+       1,     2,     2,     2,     2,     4,     5,     3,     2,     1,
+       2,     3,     4,     1,     1,     1,     4,     4,     6,     9,
+       9,     3,     3,     4,     5,     8,     1,     6,     5,     7,
+       0,     2,     2,     1,     1,     1,     1,     1,     2,     2,
+       2,     3,     1,     3,     3,     3,     3,     3,     4,     4,
+       3,     3,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -634,89 +633,85 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,     3,     1,     0,     0,    32,     0,     0,     0,     0,
-       0,     0,    32,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     9,     4,     0,    11,
-      33,    14,     0,     0,   119,    78,    80,    83,    79,    81,
-      82,   113,   120,     0,     0,     0,    15,    39,    64,    65,
-      96,    97,   109,    98,     0,    16,    73,    37,    74,    17,
-       0,    18,     0,     0,   113,   113,     0,    22,    47,    66,
-      70,    72,    71,    67,    98,    20,     0,    33,    49,    50,
-      23,   113,     0,     0,    19,    41,     0,     0,    21,     0,
-      24,     0,    25,     0,    26,    56,    27,     0,    28,     0,
-      29,     0,    30,     0,    31,     0,     7,     0,     5,     0,
-      10,   122,   121,     0,     0,     0,     0,    38,     0,     0,
-     125,     0,   123,     0,     0,     0,    87,    86,     0,    85,
-      84,    36,     0,     0,    68,    69,    48,    76,    77,     0,
-      46,     0,     0,    76,    40,     0,     0,     0,     0,     0,
-      55,     0,     0,     0,     0,     0,     0,    12,     0,    13,
-     113,   114,   115,     0,     0,   104,   105,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   124,     0,     0,
-       0,     0,    90,     0,     0,    34,    35,     0,     0,    42,
-       0,    44,     0,    51,    53,    57,    58,     0,     0,     0,
-      62,    63,     8,     6,     0,   118,   116,   117,     0,     0,
-       0,   135,   134,   133,     0,     0,   126,   127,   128,   129,
-     130,     0,     0,    99,   106,   100,     0,    88,    75,     0,
-       0,    92,    91,     0,     0,     0,     0,     0,     0,     0,
-     111,   107,     0,   131,   132,     0,     0,     0,    89,    43,
-      93,     0,    45,    52,    54,    59,    60,    61,     0,     0,
-     110,   101,     0,     0,     0,    94,   112,     0,     0,     0,
-      95,   108,     0,     0,   102,   103
+       2,     3,     1,     0,     0,    30,     0,     0,     0,     0,
+       0,     0,    30,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     7,     4,     0,     9,    31,
+      12,     0,     0,   116,    75,    77,    80,    76,    78,    79,
+     110,   117,     0,     0,     0,    13,    37,    62,    63,    93,
+      94,   106,    95,     0,    14,    71,    35,    72,    15,     0,
+      16,     0,     0,   110,     0,    20,    45,    64,    68,    70,
+      69,    65,    95,    18,     0,    31,    47,    48,    21,   110,
+       0,     0,    17,    39,     0,     0,    19,     0,    22,     0,
+      23,     0,    24,    54,    25,     0,    26,     0,    27,     0,
+      28,     0,    29,     0,     5,     0,     0,     8,   119,   118,
+       0,     0,     0,     0,    36,     0,     0,   122,     0,   120,
+       0,     0,     0,    84,    83,     0,    82,    81,    34,     0,
+       0,    66,    67,    46,    74,     0,    44,     0,     0,    74,
+      38,     0,     0,     0,     0,     0,    53,     0,     0,     0,
+       0,     0,     0,    10,    11,   110,   111,   112,     0,     0,
+     101,   102,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   121,     0,     0,     0,     0,    87,     0,     0,
+      32,    33,     0,     0,    40,     0,    42,     0,    49,    51,
+      55,    56,     0,     0,     0,    60,    61,     6,     0,   115,
+     113,   114,     0,     0,     0,   132,   131,   130,     0,     0,
+     123,   124,   125,   126,   127,     0,     0,    96,   103,    97,
+       0,    85,    73,     0,     0,    89,    88,     0,     0,     0,
+       0,     0,     0,     0,   108,   104,     0,   128,   129,     0,
+       0,     0,    86,    41,    90,     0,    43,    50,    52,    57,
+      58,    59,     0,     0,   107,    98,     0,     0,     0,    91,
+     109,     0,     0,     0,    92,   105,     0,     0,    99,   100
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     1,     3,    27,   158,   156,    28,    31,    59,    61,
-      55,    46,    84,    75,    88,    67,    80,    90,    92,    94,
-      96,    98,   100,   102,   104,    56,    68,    57,    69,    48,
-      58,   191,   232,    49,    50,    51,    52,   116,   208,    53,
-     121
+      -1,     1,     3,    26,   152,    27,    30,    58,    60,    54,
+      45,    82,    73,    86,    65,    78,    88,    90,    92,    94,
+      96,    98,   100,   102,    55,    66,    56,    67,    47,    57,
+     186,   226,    48,    49,    50,    51,   113,   202,    52,   118
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -104
+#define YYPACT_NINF -89
 static const yytype_int16 yypact[] =
 {
-    -104,     4,  -104,   173,   -26,   -25,   277,   297,   297,   349,
-     225,   -14,   329,   396,    18,   297,   297,   297,    18,   171,
-     -20,   297,   297,     2,    -4,    26,  -104,  -104,    43,  -104,
-    -104,  -104,   478,   478,  -104,  -104,  -104,  -104,  -104,  -104,
-    -104,   111,  -104,   349,   402,   478,  -104,  -104,  -104,  -104,
-    -104,  -104,   -12,    -5,    83,  -104,  -104,    44,  -104,  -104,
-      46,  -104,    49,   349,   111,   113,   245,  -104,  -104,  -104,
-    -104,  -104,  -104,  -104,    50,  -104,   100,   349,  -104,  -104,
-    -104,   113,   420,   478,  -104,  -104,    64,    66,  -104,    78,
-    -104,    80,  -104,    85,  -104,    89,  -104,    93,  -104,    98,
-    -104,   101,  -104,   112,  -104,   121,  -104,   478,  -104,   478,
-    -104,  -104,  -104,   153,   478,   478,   135,  -104,     8,   163,
-    -104,    74,  -104,   179,    52,   427,  -104,  -104,   445,  -104,
-    -104,  -104,   349,   297,  -104,  -104,  -104,   135,  -104,   381,
-    -104,    33,   478,  -104,  -104,   420,   186,   451,   349,   349,
-     349,   460,   349,   349,   297,   297,   173,   172,   173,   172,
-     113,  -104,  -104,     5,   478,   180,  -104,   478,   478,   478,
-     226,   224,   478,   478,   478,   478,   478,  -104,   235,    36,
-     195,   196,  -104,   466,   197,  -104,  -104,   199,   202,  -104,
-      21,  -104,   203,   211,   219,  -104,  -104,   217,   222,   223,
-    -104,  -104,  -104,  -104,   229,  -104,  -104,  -104,   240,   241,
-     237,   232,   527,   534,   478,   478,   134,   134,  -104,  -104,
-    -104,   478,   478,   243,  -104,  -104,   248,  -104,  -104,   -20,
-     263,   287,  -104,   249,   264,   265,   -20,   478,   171,   269,
-    -104,  -104,   294,   214,   214,   256,   258,   119,  -104,  -104,
-     301,   280,  -104,  -104,  -104,  -104,  -104,  -104,   266,   478,
-    -104,  -104,   308,   311,   292,  -104,  -104,   273,   478,   478,
-    -104,  -104,   274,   278,  -104,  -104
+     -89,     8,   -89,   211,   -33,   -23,   288,   308,   308,   360,
+     236,   -11,   340,    54,    41,   308,   308,   308,    41,   106,
+     -13,   308,   308,    62,    -4,   -89,   -89,    45,   -89,   -89,
+     -89,   484,   484,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
+      81,   -89,   360,   413,   484,   -89,   -89,   -89,   -89,   -89,
+     -89,    38,    48,   407,   -89,   -89,    -2,   -89,   -89,    64,
+     -89,    78,   360,    81,   256,   -89,   -89,   -89,   -89,   -89,
+     -89,   -89,    61,   -89,   107,   360,   -89,   -89,   -89,    59,
+     431,   484,   -89,   -89,    86,    79,   -89,    87,   -89,    89,
+     -89,    91,   -89,    97,   -89,   102,   -89,   116,   -89,   120,
+     -89,   148,   -89,   151,   -89,   484,   484,   -89,   -89,   -89,
+     123,   484,   484,   105,   -89,     1,   150,   -89,   169,   -89,
+     166,     9,    69,   -89,   -89,   456,   -89,   -89,   -89,   360,
+     308,   -89,   -89,   -89,   105,   392,   -89,   -17,   484,   -89,
+     -89,   431,   170,   460,   360,   360,   360,   469,   360,   360,
+     308,   308,   211,   179,   179,    59,   -89,   -89,     6,   484,
+     154,   -89,   484,   484,   484,   201,   149,   484,   484,   484,
+     484,   484,   -89,   198,    13,   158,   159,   -89,   480,   160,
+     -89,   -89,   162,   165,   -89,     0,   -89,   167,   171,   172,
+     -89,   -89,   193,   199,   200,   -89,   -89,   -89,   197,   -89,
+     -89,   -89,   168,   204,   214,   534,   542,   549,   484,   484,
+     113,   113,   -89,   -89,   -89,   484,   484,   207,   -89,   -89,
+     208,   -89,   -89,   -13,   220,   251,   -89,   209,   226,   231,
+     -13,   484,   106,   229,   -89,   -89,   259,   184,   184,   219,
+     225,    80,   -89,   -89,   268,   249,   -89,   -89,   -89,   -89,
+     -89,   -89,   232,   484,   -89,   -89,   272,   274,   269,   -89,
+     -89,   239,   484,   484,   -89,   -89,   252,   253,   -89,   -89
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -104,  -104,  -104,  -103,  -104,  -104,  -104,   319,  -104,  -104,
-    -104,   331,  -104,  -104,  -104,  -104,  -104,  -104,  -104,  -104,
-    -104,  -104,  -104,  -104,  -104,    19,   275,    -2,    -6,    -9,
-      -8,   115,  -104,    22,     1,    -1,    -3,   -48,  -104,   -10,
-     -66
+     -89,   -89,   -89,   153,   -89,   -89,   290,   -89,   -89,   -89,
+     295,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
+     -89,   -89,   -89,   -89,    18,   246,    20,    -7,    -9,    -8,
+      84,   -89,    51,    -3,    -6,     4,   -50,   -89,   -10,   -88
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -726,120 +721,124 @@ static const yytype_int16 yypgoto[] =
 #define YYTABLE_NINF -1
 static const yytype_uint16 yytable[] =
 {
-      74,    70,    71,    87,     2,    86,    60,    85,    76,    73,
-      99,    72,   101,    91,    93,    95,   137,   138,   164,   103,
-     105,    29,   111,   112,    30,    47,    32,    33,    62,    41,
-     230,    47,    54,   143,   120,   122,    89,   205,   123,   206,
-      97,   157,   108,   159,   130,   124,   222,   207,   106,    34,
-     107,   129,   231,   202,   134,   203,    74,    70,    71,   165,
-     136,    41,   117,    42,   135,    73,   187,    72,    44,   179,
-     180,    45,    87,   120,   109,   181,   144,   167,   168,   169,
-     170,   171,   172,   173,   174,   175,   176,   223,   179,   180,
-     110,    32,   125,   131,   181,   132,   117,   120,   133,   120,
-     141,   211,   212,   213,   161,   162,   216,   217,   218,   219,
-     220,   142,   204,   145,    34,   112,   146,   113,   120,   114,
-     115,   114,   115,   126,   127,   177,    41,   147,    42,   148,
-     134,   186,   188,   128,   149,    87,    45,   192,   150,   189,
-     135,   197,   151,   196,   174,   175,   176,   152,   243,   244,
-     153,   185,   200,   201,   209,   262,   263,   120,   120,   120,
-     160,   154,   120,   120,   120,   120,   120,   193,   194,   195,
-     155,   198,   199,   112,     4,   167,   168,   169,   170,   171,
-     172,   173,   174,   175,   176,   163,     5,     6,     7,     8,
-       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    22,   120,   120,    35,    36,    37,    38,
-      39,   245,   246,    40,   166,   178,    23,    24,    25,   187,
-      26,   249,   172,   173,   174,   175,   176,   256,   255,   257,
-     210,   215,   214,    32,    33,    63,   168,   169,   170,   171,
-     172,   173,   174,   175,   176,   221,   224,   225,   227,   267,
-     228,   229,   233,    32,    33,   139,    34,   234,   272,   273,
-      35,    36,    37,    38,    39,   235,   236,    40,    64,    65,
-      42,   237,   238,   242,    66,    44,    34,    54,    45,   239,
-      35,    36,    37,    38,    39,    32,    33,    40,    64,    65,
-      42,   240,   241,   247,   250,    44,   251,    54,    45,   248,
-     253,   190,   254,   258,   259,    32,    33,   260,    34,   261,
-     264,   265,    35,    36,    37,    38,    39,   266,   268,    40,
-      41,   269,    42,   270,   271,   274,    43,    44,    34,   275,
-      45,    78,    35,    36,    37,    38,    39,    32,    33,    40,
-      41,   140,    42,    79,     0,     0,     0,    44,   252,    54,
-      45,     0,     0,     0,     0,     0,     0,    32,    33,     0,
-      34,     0,     0,     0,    35,    36,    37,    38,    39,     0,
-       0,    40,    41,     0,    42,     0,     0,     0,    77,    44,
-      34,     0,    45,     0,    35,    36,    37,    38,    39,    32,
-      33,    40,    41,     0,    42,     0,     0,     0,     0,    44,
-       0,     0,    45,     0,    32,    33,     0,     0,     0,     0,
-      32,    33,    34,     0,     0,     0,    35,    36,    37,    38,
-      39,     0,     0,    40,     0,     0,    42,    34,    32,    33,
-       0,    44,     0,    34,    45,    32,    33,     0,   118,    81,
-      65,    42,     0,     0,   119,    82,    83,    42,    54,    45,
-       0,    34,    83,    32,   183,    45,     0,     0,    34,    32,
-      33,     0,     0,    81,    65,    42,     0,   182,    32,    33,
-      83,     0,    42,    45,    32,    33,    34,    83,     0,     0,
-      45,     0,    34,     0,     0,   184,    32,    33,     0,     0,
-      42,    34,     0,     0,     0,    83,    42,    34,    45,     0,
-       0,    83,     0,   190,    45,    42,   226,     0,     0,    34,
-      83,    42,    54,    45,     0,     0,    83,     0,     0,    45,
-       0,     0,     0,    42,     0,     0,     0,     0,    83,     0,
-       0,    45,   169,   170,   171,   172,   173,   174,   175,   176,
-     170,   171,   172,   173,   174,   175,   176
+      72,    68,    69,    85,    71,    84,    83,    70,     2,   224,
+      97,   159,    99,   134,    28,    74,   182,   153,   154,   174,
+     175,   108,   109,   216,    46,   176,    29,    61,    59,   139,
+      46,   225,    40,   117,   119,    89,    91,    93,   199,    53,
+     200,   101,   103,   127,   106,   174,   175,   128,   201,    31,
+      32,   176,   160,   131,    72,    68,    69,   126,    71,   132,
+     114,    70,    31,    32,   217,    87,   133,   111,   112,    95,
+      85,   117,    33,   140,   205,   206,   207,    31,    32,   210,
+     211,   212,   213,   214,    40,    33,    41,   110,   120,   111,
+     112,    43,   107,   114,    44,   117,   117,    79,   121,    41,
+      33,   156,   157,    80,    81,   198,    53,    44,   104,   177,
+     105,   137,   109,   129,    41,   117,   256,   257,   138,    81,
+     237,   238,    44,   169,   170,   171,   131,   130,   183,   142,
+     155,    85,   132,   187,   184,   141,   143,   192,   144,   191,
+     145,    34,    35,    36,    37,    38,   146,   180,    39,   203,
+     181,   147,   117,   117,   117,   158,   209,   117,   117,   117,
+     117,   117,   188,   189,   190,   148,   193,   194,   109,   149,
+     195,   196,   162,   163,   164,   165,   166,   167,   168,   169,
+     170,   171,   162,   163,   164,   165,   166,   167,   168,   169,
+     170,   171,   167,   168,   169,   170,   171,   150,   117,   117,
+     151,   161,   173,   182,   204,   239,   240,   208,   215,   218,
+     219,   221,     4,   222,   223,   243,   227,   228,   229,   234,
+     172,   250,   249,   251,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,   230,   261,    31,    32,    62,   233,   231,   232,
+     236,   244,   266,   267,    23,   235,    24,   241,    25,   242,
+     245,   185,   247,   252,    31,    32,   135,    33,   248,   253,
+     254,    34,    35,    36,    37,    38,   255,   258,    39,    63,
+     259,    41,   262,   260,   263,    64,    43,    33,    53,    44,
+     265,    34,    35,    36,    37,    38,    31,    32,    39,    63,
+     264,    41,    76,   268,   269,   197,    43,    77,    53,    44,
+     136,   246,     0,     0,     0,     0,    31,    32,     0,    33,
+       0,     0,     0,    34,    35,    36,    37,    38,     0,     0,
+      39,    40,     0,    41,     0,     0,     0,    42,    43,    33,
+       0,    44,     0,    34,    35,    36,    37,    38,    31,    32,
+      39,    40,     0,    41,     0,     0,     0,     0,    43,     0,
+      53,    44,     0,     0,     0,     0,     0,     0,    31,    32,
+       0,    33,     0,     0,     0,    34,    35,    36,    37,    38,
+       0,     0,    39,    40,     0,    41,     0,     0,     0,    75,
+      43,    33,     0,    44,     0,    34,    35,    36,    37,    38,
+      31,    32,    39,    40,     0,    41,     0,     0,     0,     0,
+      43,     0,     0,    44,     0,    31,   122,     0,     0,     0,
+       0,    31,    32,    33,     0,     0,     0,    34,    35,    36,
+      37,    38,     0,     0,    39,     0,     0,    41,    33,    31,
+      32,     0,    43,     0,    33,    44,     0,   123,   124,   115,
+      40,     0,    41,     0,     0,   116,     0,   125,    41,     0,
+      44,     0,    33,    81,    31,   178,    44,     0,    31,    32,
+       0,     0,     0,     0,    79,     0,    41,    31,    32,     0,
+       0,    81,     0,     0,    44,     0,     0,    33,    31,    32,
+       0,    33,    31,    32,     0,     0,   179,     0,     0,     0,
+      33,    41,     0,     0,     0,    41,    81,     0,     0,    44,
+      81,    33,   185,    44,    41,    33,     0,     0,     0,    81,
+     220,    53,    44,     0,     0,    41,     0,     0,     0,    41,
+      81,     0,     0,    44,    81,     0,     0,    44,   163,   164,
+     165,   166,   167,   168,   169,   170,   171,   164,   165,   166,
+     167,   168,   169,   170,   171,   165,   166,   167,   168,   169,
+     170,   171
 };
 
 static const yytype_int16 yycheck[] =
 {
-      10,    10,    10,    13,     0,    13,     8,    13,    11,    10,
-      19,    10,    20,    15,    16,    17,    64,    65,    10,    21,
-      22,    47,    32,    33,    49,     6,     8,     9,     9,    43,
-       9,    12,    52,    81,    44,    45,    14,    32,    50,    34,
-      18,   107,    46,   109,    54,    50,    10,    42,    46,    31,
-      48,    54,    31,   156,    63,   158,    66,    66,    66,    51,
-      63,    43,    43,    45,    63,    66,    33,    66,    50,    36,
-      37,    53,    82,    83,    48,    42,    82,     3,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    51,    36,    37,
-      47,     8,     9,    49,    42,    49,    77,   107,    49,   109,
-      50,   167,   168,   169,   114,   115,   172,   173,   174,   175,
-     176,    11,   160,    49,    31,   125,    50,     6,   128,     8,
-       9,     8,     9,    40,    41,    51,    43,    49,    45,    49,
-     139,   133,   142,    50,    49,   145,    53,   147,    49,   145,
-     139,   151,    49,   151,    10,    11,    12,    49,   214,   215,
-      49,   132,   154,   155,   164,    36,    37,   167,   168,   169,
-       7,    49,   172,   173,   174,   175,   176,   148,   149,   150,
-      49,   152,   153,   183,     1,     3,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    50,    13,    14,    15,    16,
-      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,   214,   215,    35,    36,    37,    38,
-      39,   221,   222,    42,    51,    36,    43,    44,    45,    33,
-      47,   229,     8,     9,    10,    11,    12,   237,   236,   238,
-      50,     7,     6,     8,     9,    10,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    10,    51,    51,    51,   259,
-      51,    49,    49,     8,     9,    10,    31,    46,   268,   269,
-      35,    36,    37,    38,    39,    46,    49,    42,    43,    44,
-      45,    49,    49,    36,    49,    50,    31,    52,    53,    50,
-      35,    36,    37,    38,    39,     8,     9,    42,    43,    44,
-      45,    51,    51,    50,    31,    50,     9,    52,    53,    51,
-      36,    52,    37,    34,    10,     8,     9,    51,    31,    51,
-       9,    31,    35,    36,    37,    38,    39,    51,    10,    42,
-      43,    10,    45,    31,    51,    51,    49,    50,    31,    51,
-      53,    12,    35,    36,    37,    38,    39,     8,     9,    42,
-      43,    66,    45,    12,    -1,    -1,    -1,    50,   233,    52,
-      53,    -1,    -1,    -1,    -1,    -1,    -1,     8,     9,    -1,
-      31,    -1,    -1,    -1,    35,    36,    37,    38,    39,    -1,
-      -1,    42,    43,    -1,    45,    -1,    -1,    -1,    49,    50,
-      31,    -1,    53,    -1,    35,    36,    37,    38,    39,     8,
-       9,    42,    43,    -1,    45,    -1,    -1,    -1,    -1,    50,
-      -1,    -1,    53,    -1,     8,     9,    -1,    -1,    -1,    -1,
-       8,     9,    31,    -1,    -1,    -1,    35,    36,    37,    38,
-      39,    -1,    -1,    42,    -1,    -1,    45,    31,     8,     9,
-      -1,    50,    -1,    31,    53,     8,     9,    -1,    36,    43,
-      44,    45,    -1,    -1,    42,    49,    50,    45,    52,    53,
-      -1,    31,    50,     8,     9,    53,    -1,    -1,    31,     8,
-       9,    -1,    -1,    43,    44,    45,    -1,    40,     8,     9,
-      50,    -1,    45,    53,     8,     9,    31,    50,    -1,    -1,
-      53,    -1,    31,    -1,    -1,    40,     8,     9,    -1,    -1,
-      45,    31,    -1,    -1,    -1,    50,    45,    31,    53,    -1,
-      -1,    50,    -1,    52,    53,    45,    40,    -1,    -1,    31,
-      50,    45,    52,    53,    -1,    -1,    50,    -1,    -1,    53,
-      -1,    -1,    -1,    45,    -1,    -1,    -1,    -1,    50,    -1,
-      -1,    53,     5,     6,     7,     8,     9,    10,    11,    12,
-       6,     7,     8,     9,    10,    11,    12
+      10,    10,    10,    13,    10,    13,    13,    10,     0,     9,
+      19,    10,    20,    63,    47,    11,    33,   105,   106,    36,
+      37,    31,    32,    10,     6,    42,    49,     9,     8,    79,
+      12,    31,    43,    43,    44,    15,    16,    17,    32,    52,
+      34,    21,    22,    53,    48,    36,    37,    49,    42,     8,
+       9,    42,    51,    62,    64,    64,    64,    53,    64,    62,
+      42,    64,     8,     9,    51,    14,    62,     8,     9,    18,
+      80,    81,    31,    80,   162,   163,   164,     8,     9,   167,
+     168,   169,   170,   171,    43,    31,    45,     6,    50,     8,
+       9,    50,    47,    75,    53,   105,   106,    43,    50,    45,
+      31,   111,   112,    49,    50,   155,    52,    53,    46,    40,
+      48,    50,   122,    49,    45,   125,    36,    37,    11,    50,
+     208,   209,    53,    10,    11,    12,   135,    49,   138,    50,
+       7,   141,   135,   143,   141,    49,    49,   147,    49,   147,
+      49,    35,    36,    37,    38,    39,    49,   129,    42,   159,
+     130,    49,   162,   163,   164,    50,     7,   167,   168,   169,
+     170,   171,   144,   145,   146,    49,   148,   149,   178,    49,
+     150,   151,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,     8,     9,    10,    11,    12,    49,   208,   209,
+      49,    51,    36,    33,    50,   215,   216,     6,    10,    51,
+      51,    51,     1,    51,    49,   223,    49,    46,    46,    51,
+      51,   231,   230,   232,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    49,   253,     8,     9,    10,    50,    49,    49,
+      36,    31,   262,   263,    43,    51,    45,    50,    47,    51,
+       9,    52,    36,    34,     8,     9,    10,    31,    37,    10,
+      51,    35,    36,    37,    38,    39,    51,     9,    42,    43,
+      31,    45,    10,    51,    10,    49,    50,    31,    52,    53,
+      51,    35,    36,    37,    38,    39,     8,     9,    42,    43,
+      31,    45,    12,    51,    51,   152,    50,    12,    52,    53,
+      64,   227,    -1,    -1,    -1,    -1,     8,     9,    -1,    31,
+      -1,    -1,    -1,    35,    36,    37,    38,    39,    -1,    -1,
+      42,    43,    -1,    45,    -1,    -1,    -1,    49,    50,    31,
+      -1,    53,    -1,    35,    36,    37,    38,    39,     8,     9,
+      42,    43,    -1,    45,    -1,    -1,    -1,    -1,    50,    -1,
+      52,    53,    -1,    -1,    -1,    -1,    -1,    -1,     8,     9,
+      -1,    31,    -1,    -1,    -1,    35,    36,    37,    38,    39,
+      -1,    -1,    42,    43,    -1,    45,    -1,    -1,    -1,    49,
+      50,    31,    -1,    53,    -1,    35,    36,    37,    38,    39,
+       8,     9,    42,    43,    -1,    45,    -1,    -1,    -1,    -1,
+      50,    -1,    -1,    53,    -1,     8,     9,    -1,    -1,    -1,
+      -1,     8,     9,    31,    -1,    -1,    -1,    35,    36,    37,
+      38,    39,    -1,    -1,    42,    -1,    -1,    45,    31,     8,
+       9,    -1,    50,    -1,    31,    53,    -1,    40,    41,    36,
+      43,    -1,    45,    -1,    -1,    42,    -1,    50,    45,    -1,
+      53,    -1,    31,    50,     8,     9,    53,    -1,     8,     9,
+      -1,    -1,    -1,    -1,    43,    -1,    45,     8,     9,    -1,
+      -1,    50,    -1,    -1,    53,    -1,    -1,    31,     8,     9,
+      -1,    31,     8,     9,    -1,    -1,    40,    -1,    -1,    -1,
+      31,    45,    -1,    -1,    -1,    45,    50,    -1,    -1,    53,
+      50,    31,    52,    53,    45,    31,    -1,    -1,    -1,    50,
+      40,    52,    53,    -1,    -1,    45,    -1,    -1,    -1,    45,
+      50,    -1,    -1,    53,    50,    -1,    -1,    53,     4,     5,
+       6,     7,     8,     9,    10,    11,    12,     5,     6,     7,
+       8,     9,    10,    11,    12,     6,     7,     8,     9,    10,
+      11,    12
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -848,32 +847,31 @@ static const yytype_uint8 yystos[] =
 {
        0,    55,     0,    56,     1,    13,    14,    15,    16,    17,
       18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    43,    44,    45,    47,    57,    60,    47,
-      49,    61,     8,     9,    31,    35,    36,    37,    38,    39,
-      42,    43,    45,    49,    50,    53,    65,    79,    83,    87,
-      88,    89,    90,    93,    52,    64,    79,    81,    84,    62,
-      81,    63,    79,    10,    43,    44,    49,    69,    80,    82,
-      83,    84,    88,    89,    93,    67,    90,    49,    61,    65,
-      70,    43,    49,    50,    66,    82,    84,    93,    68,    87,
-      71,    81,    72,    81,    73,    81,    74,    87,    75,    83,
-      76,    84,    77,    81,    78,    81,    46,    48,    46,    48,
-      47,    93,    93,     6,     8,     9,    91,    79,    36,    42,
-      93,    94,    93,    50,    50,     9,    40,    41,    50,    90,
-      93,    49,    49,    49,    83,    88,    90,    91,    91,    10,
-      80,    50,    11,    91,    82,    49,    50,    49,    49,    49,
-      49,    49,    49,    49,    49,    49,    59,    94,    58,    94,
-       7,    93,    93,    50,    10,    51,    51,     3,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    51,    36,    36,
-      37,    42,    40,     9,    40,    79,    81,    33,    93,    82,
-      52,    85,    93,    79,    79,    79,    84,    93,    79,    79,
-      81,    81,    57,    57,    91,    32,    34,    42,    92,    93,
-      50,    94,    94,    94,     6,     7,    94,    94,    94,    94,
-      94,    10,    10,    51,    51,    51,    40,    51,    51,    49,
-       9,    31,    86,    49,    46,    46,    49,    49,    49,    50,
-      51,    51,    36,    94,    94,    93,    93,    50,    51,    84,
-      31,     9,    85,    36,    37,    84,    93,    83,    34,    10,
-      51,    51,    36,    37,     9,    31,    51,    93,    10,    10,
-      31,    51,    93,    93,    51,    51
+      28,    29,    30,    43,    45,    47,    57,    59,    47,    49,
+      60,     8,     9,    31,    35,    36,    37,    38,    39,    42,
+      43,    45,    49,    50,    53,    64,    78,    82,    86,    87,
+      88,    89,    92,    52,    63,    78,    80,    83,    61,    80,
+      62,    78,    10,    43,    49,    68,    79,    81,    82,    83,
+      87,    88,    92,    66,    89,    49,    60,    64,    69,    43,
+      49,    50,    65,    81,    83,    92,    67,    86,    70,    80,
+      71,    80,    72,    80,    73,    86,    74,    82,    75,    83,
+      76,    80,    77,    80,    46,    48,    48,    47,    92,    92,
+       6,     8,     9,    90,    78,    36,    42,    92,    93,    92,
+      50,    50,     9,    40,    41,    50,    89,    92,    49,    49,
+      49,    82,    87,    89,    90,    10,    79,    50,    11,    90,
+      81,    49,    50,    49,    49,    49,    49,    49,    49,    49,
+      49,    49,    58,    93,    93,     7,    92,    92,    50,    10,
+      51,    51,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    51,    36,    36,    37,    42,    40,     9,    40,
+      78,    80,    33,    92,    81,    52,    84,    92,    78,    78,
+      78,    83,    92,    78,    78,    80,    80,    57,    90,    32,
+      34,    42,    91,    92,    50,    93,    93,    93,     6,     7,
+      93,    93,    93,    93,    93,    10,    10,    51,    51,    51,
+      40,    51,    51,    49,     9,    31,    85,    49,    46,    46,
+      49,    49,    49,    50,    51,    51,    36,    93,    93,    92,
+      92,    50,    51,    83,    31,     9,    84,    36,    37,    83,
+      92,    82,    34,    10,    51,    51,    36,    37,     9,    31,
+      51,    92,    10,    10,    31,    51,    92,    92,    51,    51
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1697,30 +1695,24 @@ yyreduce:
   case 5:
 #line 78 "a.y"
     {
-               if((yyvsp[(1) - (2)].sym)->value != pc)
-                       yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->name);
-               (yyvsp[(1) - (2)].sym)->value = pc;
-       }
-    break;
-
-  case 7:
-#line 85 "a.y"
-    {
+               (yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
+               if((yyvsp[(1) - (2)].sym)->type == LLAB && (yyvsp[(1) - (2)].sym)->value != pc)
+                       yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->labelname);
                (yyvsp[(1) - (2)].sym)->type = LLAB;
                (yyvsp[(1) - (2)].sym)->value = pc;
        }
     break;
 
-  case 12:
-#line 96 "a.y"
+  case 10:
+#line 92 "a.y"
     {
                (yyvsp[(1) - (3)].sym)->type = LVAR;
                (yyvsp[(1) - (3)].sym)->value = (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 13:
-#line 101 "a.y"
+  case 11:
+#line 97 "a.y"
     {
                if((yyvsp[(1) - (3)].sym)->value != (yyvsp[(3) - (3)].lval))
                        yyerror("redeclaration of %s", (yyvsp[(1) - (3)].sym)->name);
@@ -1728,186 +1720,186 @@ yyreduce:
        }
     break;
 
+  case 12:
+#line 102 "a.y"
+    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
+    break;
+
+  case 13:
+#line 103 "a.y"
+    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
+    break;
+
   case 14:
-#line 106 "a.y"
+#line 104 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 15:
-#line 107 "a.y"
+#line 105 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 16:
-#line 108 "a.y"
+#line 106 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 17:
-#line 109 "a.y"
+#line 107 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 18:
-#line 110 "a.y"
+#line 108 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 19:
-#line 111 "a.y"
+#line 109 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 20:
-#line 112 "a.y"
+#line 110 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 21:
-#line 113 "a.y"
+#line 111 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 22:
-#line 114 "a.y"
+#line 112 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 23:
-#line 115 "a.y"
+#line 113 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 24:
-#line 116 "a.y"
+#line 114 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 25:
-#line 117 "a.y"
+#line 115 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 26:
-#line 118 "a.y"
+#line 116 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 27:
-#line 119 "a.y"
+#line 117 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 28:
-#line 120 "a.y"
+#line 118 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 29:
-#line 121 "a.y"
+#line 119 "a.y"
     { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
     break;
 
   case 30:
 #line 122 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 31:
-#line 123 "a.y"
-    { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
-    break;
-
-  case 32:
-#line 126 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 33:
-#line 131 "a.y"
+  case 31:
+#line 127 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 34:
-#line 138 "a.y"
+  case 32:
+#line 134 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 35:
-#line 145 "a.y"
+  case 33:
+#line 141 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 36:
-#line 152 "a.y"
+  case 34:
+#line 148 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (2)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 37:
-#line 157 "a.y"
+  case 35:
+#line 153 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 38:
-#line 164 "a.y"
+  case 36:
+#line 160 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 39:
-#line 169 "a.y"
+  case 37:
+#line 165 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
        }
     break;
 
-  case 40:
-#line 176 "a.y"
+  case 38:
+#line 172 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 41:
-#line 181 "a.y"
+  case 39:
+#line 177 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
        }
     break;
 
-  case 42:
-#line 186 "a.y"
+  case 40:
+#line 182 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 43:
-#line 193 "a.y"
+  case 41:
+#line 189 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
@@ -1915,41 +1907,43 @@ yyreduce:
        }
     break;
 
-  case 44:
-#line 201 "a.y"
+  case 42:
+#line 197 "a.y"
     {
+               settext((yyvsp[(1) - (3)].addr).sym);
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 45:
-#line 206 "a.y"
+  case 43:
+#line 203 "a.y"
     {
+               settext((yyvsp[(1) - (5)].addr).sym);
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
                (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
        }
     break;
 
-  case 46:
-#line 214 "a.y"
+  case 44:
+#line 212 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 47:
-#line 219 "a.y"
+  case 45:
+#line 217 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
        }
     break;
 
-  case 48:
-#line 224 "a.y"
+  case 46:
+#line 222 "a.y"
     {
                (yyval.addr2).from = nullgen;
                (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
@@ -1958,16 +1952,16 @@ yyreduce:
        }
     break;
 
-  case 51:
-#line 237 "a.y"
+  case 49:
+#line 235 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 52:
-#line 242 "a.y"
+  case 50:
+#line 240 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
@@ -1977,16 +1971,16 @@ yyreduce:
        }
     break;
 
-  case 53:
-#line 252 "a.y"
+  case 51:
+#line 250 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 54:
-#line 257 "a.y"
+  case 52:
+#line 255 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
@@ -1996,40 +1990,40 @@ yyreduce:
        }
     break;
 
-  case 55:
-#line 267 "a.y"
+  case 53:
+#line 265 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (2)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 56:
-#line 272 "a.y"
+  case 54:
+#line 270 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
                (yyval.addr2).to = nullgen;
        }
     break;
 
-  case 57:
-#line 277 "a.y"
+  case 55:
+#line 275 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 58:
-#line 284 "a.y"
+  case 56:
+#line 282 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
        }
     break;
 
-  case 59:
-#line 289 "a.y"
+  case 57:
+#line 287 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
@@ -2037,8 +2031,8 @@ yyreduce:
        }
     break;
 
-  case 60:
-#line 297 "a.y"
+  case 58:
+#line 295 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
                (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
@@ -2046,8 +2040,8 @@ yyreduce:
        }
     break;
 
-  case 61:
-#line 305 "a.y"
+  case 59:
+#line 303 "a.y"
     {
                (yyval.addr2).from = (yyvsp[(3) - (5)].addr);
                (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
@@ -2057,8 +2051,8 @@ yyreduce:
        }
     break;
 
-  case 62:
-#line 315 "a.y"
+  case 60:
+#line 313 "a.y"
     {
                if((yyvsp[(1) - (3)].addr).type != D_CONST || (yyvsp[(3) - (3)].addr).type != D_CONST)
                        yyerror("arguments to PCDATA must be integer constants");
@@ -2067,8 +2061,8 @@ yyreduce:
        }
     break;
 
-  case 63:
-#line 324 "a.y"
+  case 61:
+#line 322 "a.y"
     {
                if((yyvsp[(1) - (3)].addr).type != D_CONST)
                        yyerror("index for FUNCDATA must be integer constant");
@@ -2079,22 +2073,22 @@ yyreduce:
        }
     break;
 
-  case 68:
-#line 341 "a.y"
+  case 66:
+#line 339 "a.y"
     {
                (yyval.addr) = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 69:
-#line 345 "a.y"
+  case 67:
+#line 343 "a.y"
     {
                (yyval.addr) = (yyvsp[(2) - (2)].addr);
        }
     break;
 
-  case 75:
-#line 358 "a.y"
+  case 73:
+#line 356 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_BRANCH;
@@ -2102,76 +2096,68 @@ yyreduce:
        }
     break;
 
-  case 76:
-#line 364 "a.y"
-    {
-               (yyval.addr) = nullgen;
-               if(pass == 2)
-                       yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->name);
-               (yyval.addr).type = D_BRANCH;
-               (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
-       }
-    break;
-
-  case 77:
-#line 372 "a.y"
+  case 74:
+#line 362 "a.y"
     {
+               (yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
                (yyval.addr) = nullgen;
+               if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
+                       yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
                (yyval.addr).type = D_BRANCH;
                (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 78:
-#line 380 "a.y"
+  case 75:
+#line 373 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 79:
-#line 385 "a.y"
+  case 76:
+#line 378 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 80:
-#line 390 "a.y"
+  case 77:
+#line 383 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 81:
-#line 395 "a.y"
+  case 78:
+#line 388 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 82:
-#line 400 "a.y"
+  case 79:
+#line 393 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SP;
        }
     break;
 
-  case 83:
-#line 405 "a.y"
+  case 80:
+#line 398 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 84:
-#line 412 "a.y"
+  case 81:
+#line 405 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_CONST;
@@ -2179,8 +2165,8 @@ yyreduce:
        }
     break;
 
-  case 85:
-#line 418 "a.y"
+  case 82:
+#line 411 "a.y"
     {
                (yyval.addr) = (yyvsp[(2) - (2)].addr);
                (yyval.addr).index = (yyvsp[(2) - (2)].addr).type;
@@ -2193,8 +2179,8 @@ yyreduce:
        }
     break;
 
-  case 86:
-#line 429 "a.y"
+  case 83:
+#line 422 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_SCONST;
@@ -2202,8 +2188,8 @@ yyreduce:
        }
     break;
 
-  case 87:
-#line 435 "a.y"
+  case 84:
+#line 428 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2211,8 +2197,8 @@ yyreduce:
        }
     break;
 
-  case 88:
-#line 441 "a.y"
+  case 85:
+#line 434 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2220,8 +2206,8 @@ yyreduce:
        }
     break;
 
-  case 89:
-#line 447 "a.y"
+  case 86:
+#line 440 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2229,8 +2215,8 @@ yyreduce:
        }
     break;
 
-  case 90:
-#line 453 "a.y"
+  case 87:
+#line 446 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_FCONST;
@@ -2238,8 +2224,8 @@ yyreduce:
        }
     break;
 
-  case 91:
-#line 461 "a.y"
+  case 88:
+#line 454 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_CONST2;
@@ -2248,40 +2234,40 @@ yyreduce:
        }
     break;
 
-  case 92:
-#line 470 "a.y"
+  case 89:
+#line 463 "a.y"
     {
                (yyval.con2).v1 = (yyvsp[(1) - (1)].lval);
                (yyval.con2).v2 = ArgsSizeUnknown;
        }
     break;
 
-  case 93:
-#line 475 "a.y"
+  case 90:
+#line 468 "a.y"
     {
                (yyval.con2).v1 = -(yyvsp[(2) - (2)].lval);
                (yyval.con2).v2 = ArgsSizeUnknown;
        }
     break;
 
-  case 94:
-#line 480 "a.y"
+  case 91:
+#line 473 "a.y"
     {
                (yyval.con2).v1 = (yyvsp[(1) - (3)].lval);
                (yyval.con2).v2 = (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 95:
-#line 485 "a.y"
+  case 92:
+#line 478 "a.y"
     {
                (yyval.con2).v1 = -(yyvsp[(2) - (4)].lval);
                (yyval.con2).v2 = (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 98:
-#line 496 "a.y"
+  case 95:
+#line 489 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_NONE;
@@ -2289,8 +2275,8 @@ yyreduce:
        }
     break;
 
-  case 99:
-#line 502 "a.y"
+  case 96:
+#line 495 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
@@ -2298,8 +2284,8 @@ yyreduce:
        }
     break;
 
-  case 100:
-#line 508 "a.y"
+  case 97:
+#line 501 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_SP;
@@ -2307,8 +2293,8 @@ yyreduce:
        }
     break;
 
-  case 101:
-#line 514 "a.y"
+  case 98:
+#line 507 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_NONE;
@@ -2319,8 +2305,8 @@ yyreduce:
        }
     break;
 
-  case 102:
-#line 523 "a.y"
+  case 99:
+#line 516 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
@@ -2331,8 +2317,8 @@ yyreduce:
        }
     break;
 
-  case 103:
-#line 532 "a.y"
+  case 100:
+#line 525 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
@@ -2343,24 +2329,24 @@ yyreduce:
        }
     break;
 
-  case 104:
-#line 541 "a.y"
+  case 101:
+#line 534 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(2) - (3)].lval);
        }
     break;
 
-  case 105:
-#line 546 "a.y"
+  case 102:
+#line 539 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_SP;
        }
     break;
 
-  case 106:
-#line 551 "a.y"
+  case 103:
+#line 544 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
@@ -2368,8 +2354,8 @@ yyreduce:
        }
     break;
 
-  case 107:
-#line 557 "a.y"
+  case 104:
+#line 550 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+D_NONE;
@@ -2379,8 +2365,8 @@ yyreduce:
        }
     break;
 
-  case 108:
-#line 565 "a.y"
+  case 105:
+#line 558 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_INDIR+(yyvsp[(2) - (8)].lval);
@@ -2390,15 +2376,15 @@ yyreduce:
        }
     break;
 
-  case 109:
-#line 575 "a.y"
+  case 106:
+#line 568 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (1)].addr);
        }
     break;
 
-  case 110:
-#line 579 "a.y"
+  case 107:
+#line 572 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (6)].addr);
                (yyval.addr).index = (yyvsp[(3) - (6)].lval);
@@ -2407,8 +2393,8 @@ yyreduce:
        }
     break;
 
-  case 111:
-#line 588 "a.y"
+  case 108:
+#line 581 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = (yyvsp[(4) - (5)].lval);
@@ -2417,8 +2403,8 @@ yyreduce:
        }
     break;
 
-  case 112:
-#line 595 "a.y"
+  case 109:
+#line 588 "a.y"
     {
                (yyval.addr) = nullgen;
                (yyval.addr).type = D_STATIC;
@@ -2427,134 +2413,134 @@ yyreduce:
        }
     break;
 
-  case 113:
-#line 603 "a.y"
+  case 110:
+#line 596 "a.y"
     {
                (yyval.lval) = 0;
        }
     break;
 
-  case 114:
-#line 607 "a.y"
+  case 111:
+#line 600 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 115:
-#line 611 "a.y"
+  case 112:
+#line 604 "a.y"
     {
                (yyval.lval) = -(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 117:
-#line 618 "a.y"
+  case 114:
+#line 611 "a.y"
     {
                (yyval.lval) = D_AUTO;
        }
     break;
 
-  case 120:
-#line 626 "a.y"
+  case 117:
+#line 619 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
        }
     break;
 
-  case 121:
-#line 630 "a.y"
+  case 118:
+#line 623 "a.y"
     {
                (yyval.lval) = -(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 122:
-#line 634 "a.y"
+  case 119:
+#line 627 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 123:
-#line 638 "a.y"
+  case 120:
+#line 631 "a.y"
     {
                (yyval.lval) = ~(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 124:
-#line 642 "a.y"
+  case 121:
+#line 635 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (3)].lval);
        }
     break;
 
-  case 126:
-#line 649 "a.y"
+  case 123:
+#line 642 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 127:
-#line 653 "a.y"
+  case 124:
+#line 646 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 128:
-#line 657 "a.y"
+  case 125:
+#line 650 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 129:
-#line 661 "a.y"
+  case 126:
+#line 654 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 130:
-#line 665 "a.y"
+  case 127:
+#line 658 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 131:
-#line 669 "a.y"
+  case 128:
+#line 662 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 132:
-#line 673 "a.y"
+  case 129:
+#line 666 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 133:
-#line 677 "a.y"
+  case 130:
+#line 670 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 134:
-#line 681 "a.y"
+  case 131:
+#line 674 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 135:
-#line 685 "a.y"
+  case 132:
+#line 678 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
        }
@@ -2562,7 +2548,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 2566 "y.tab.c"
+#line 2552 "y.tab.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
diff --git a/src/cmd/9a/Makefile b/src/cmd/9a/Makefile
new file mode 100644 (file)
index 0000000..27290dd
--- /dev/null
@@ -0,0 +1,10 @@
+# Copyright 2012 The Go Authors.  All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include ../../Make.dist
+
+install: y.tab.h
+
+y.tab.h: a.y
+       LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
diff --git a/src/cmd/9a/a.h b/src/cmd/9a/a.h
new file mode 100644 (file)
index 0000000..7a01fc9
--- /dev/null
@@ -0,0 +1,170 @@
+// cmd/9a/a.h 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 <bio.h>
+#include <link.h>
+#include "../9l/9.out.h"
+
+#ifndef        EXTERN
+#define        EXTERN  extern
+#endif
+
+#undef getc
+#undef ungetc
+#undef BUFSIZ
+
+#define        getc    ccgetc
+#define        ungetc  ccungetc
+
+typedef        struct  Sym     Sym;
+typedef        struct  Io      Io;
+
+#define        MAXALIGN        7
+#define        FPCHIP          1
+#define        NSYMB           8192
+#define        BUFSIZ          8192
+#define        HISTSZ          20
+#define        NINCLUDE        10
+#define        NHUNK           10000
+#ifndef EOF
+#define        EOF             (-1)
+#endif
+#define        IGN             (-2)
+#define        GETC()          ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
+#define        NHASH           503
+#define        STRINGSZ        200
+#define        NMACRO          10
+
+struct Sym
+{
+       Sym*    link;
+       char*   macro;
+       vlong   value;
+       ushort  type;
+       char    *name;
+       char*   labelname;
+       char    sym;
+};
+#define        S       ((Sym*)0)
+
+EXTERN struct
+{
+       char*   p;
+       int     c;
+} fi;
+
+struct Io
+{
+       Io*     link;
+       char    b[BUFSIZ];
+       char*   p;
+       short   c;
+       short   f;
+};
+#define        I       ((Io*)0)
+
+enum
+{
+       CLAST,
+       CMACARG,
+       CMACRO,
+       CPREPROC,
+};
+
+EXTERN int     debug[256];
+EXTERN Sym*    hash[NHASH];
+EXTERN char**  Dlist;
+EXTERN int     nDlist;
+EXTERN int     newflag;
+EXTERN char*   hunk;
+EXTERN char**  include;
+EXTERN Io*     iofree;
+EXTERN Io*     ionext;
+EXTERN Io*     iostack;
+EXTERN int32   lineno;
+EXTERN int     nerrors;
+EXTERN int32   nhunk;
+EXTERN int     nosched;
+EXTERN int     ninclude;
+EXTERN int32   nsymb;
+EXTERN Addr    nullgen;
+EXTERN char*   outfile;
+EXTERN int     pass;
+EXTERN int32   pc;
+EXTERN int     peekc;
+EXTERN int     sym;
+EXTERN char*   symb;
+EXTERN int     thechar;
+EXTERN char*   thestring;
+EXTERN int32   thunk;
+EXTERN Biobuf  obuf;
+EXTERN Link*   ctxt;
+EXTERN Biobuf  bstdout;
+
+void*  alloc(int32);
+void*  allocn(void*, int32, int32);
+void   ensuresymb(int32);
+void   errorexit(void);
+void   pushio(void);
+void   newio(void);
+void   newfile(char*, int);
+Sym*   slookup(char*);
+Sym*   lookup(void);
+Sym*   labellookup(Sym*);
+void   settext(LSym*);
+void   syminit(Sym*);
+int32  yylex(void);
+int    getc(void);
+int    getnsc(void);
+void   unget(int);
+int    escchar(int);
+void   cinit(void);
+void   pinit(char*);
+void   cclean(void);
+void   outcode(int, Addr*, int, Addr*);
+void   outgcode(int, Addr*, int, Addr*, Addr*);
+int    filbuf(void);
+Sym*   getsym(void);
+void   domacro(void);
+void   macund(void);
+void   macdef(void);
+void   macexpand(Sym*, char*);
+void   macinc(void);
+void   macprag(void);
+void   maclin(void);
+void   macif(int);
+void   macend(void);
+void   dodefine(char*);
+void   prfile(int32);
+void   linehist(char*, int);
+void   gethunk(void);
+void   yyerror(char*, ...);
+int    yyparse(void);
+void   setinclude(char*);
+int    assemble(char*);
diff --git a/src/cmd/9a/a.y b/src/cmd/9a/a.y
new file mode 100644 (file)
index 0000000..b366146
--- /dev/null
@@ -0,0 +1,991 @@
+// cmd/9a/a.y from Vita Nuova.
+//
+//     Copyright Â© 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright Â© 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright Â© 1997-1999 Vita Nuova Limited
+//     Portions Copyright Â© 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright Â© 2004,2006 Bruce Ellis
+//     Portions Copyright Â© 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright Â© 2000-2008 Lucent Technologies Inc. and others
+//     Portions Copyright Â© 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+%{
+#include <u.h>
+#include <stdio.h>     /* if we don't, bison will, and a.h re-#defines getc */
+#include <libc.h>
+#include "a.h"
+#include "../../runtime/funcdata.h"
+%}
+%union
+{
+       Sym     *sym;
+       vlong   lval;
+       double  dval;
+       char    sval[8];
+       Addr    addr;
+}
+%left  '|'
+%left  '^'
+%left  '&'
+%left  '<' '>'
+%left  '+' '-'
+%left  '*' '/' '%'
+%token <lval>  LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
+%token <lval>  LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
+%token <lval>  LNOP LEND LRETT LWORD LTEXT LDATA LRETRN
+%token <lval>  LCONST LSP LSB LFP LPC LCREG LFLUSH
+%token <lval>  LREG LFREG LR LCR LF LFPSCR
+%token <lval>  LLR LCTR LSPR LSPREG LSEG LMSR
+%token <lval>  LPCDAT LFUNCDAT LSCHED LXLD LXST LXOP LXMV
+%token <lval>  LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA
+%token <dval>  LFCONST
+%token <sval>  LSCONST
+%token <sym>   LNAME LLAB LVAR
+%type  <lval>  con expr pointer offset sreg
+%type  <addr>  addr rreg regaddr name creg freg xlreg lr ctr
+%type  <addr>  imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask
+%%
+prog:
+|      prog line
+
+line:
+       LNAME ':'
+       {
+               $1 = labellookup($1);
+               if($1->type == LLAB && $1->value != pc)
+                       yyerror("redeclaration of %s", $1->labelname);
+               $1->type = LLAB;
+               $1->value = pc;
+       }
+       line
+|      LNAME '=' expr ';'
+       {
+               $1->type = LVAR;
+               $1->value = $3;
+       }
+|      LVAR '=' expr ';'
+       {
+               if($1->value != $3)
+                       yyerror("redeclaration of %s", $1->name);
+               $1->value = $3;
+       }
+|      LSCHED ';'
+       {
+               nosched = $1;
+       }
+|      ';'
+|      inst ';'
+|      error ';'
+
+inst:
+/*
+ * load ints and bytes
+ */
+       LMOVW rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW addr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW regaddr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB addr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB regaddr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * load floats
+ */
+|      LFMOV addr ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV regaddr ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV fimm ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV freg ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV freg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFMOV freg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * store ints and bytes
+ */
+|      LMOVW rreg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW rreg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB rreg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVB rreg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * store floats
+ */
+|      LMOVW freg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW freg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * floating point status
+ */
+|      LMOVW fpscr ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW freg ','  fpscr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW freg ',' imm ',' fpscr
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LMOVW fpscr ',' creg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW imm ',' fpscrf
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMTFSB imm ',' con
+       {
+               outcode($1, &$2, $4, &nullgen);
+       }
+/*
+ * field moves (mtcrf)
+ */
+|      LMOVW rreg ',' imm ',' lcr
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LMOVW rreg ',' creg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW rreg ',' lcr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * integer operations
+ * logical instructions
+ * shift instructions
+ * unary instructions
+ */
+|      LADDW rreg ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LADDW imm ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LADDW rreg ',' imm ',' rreg
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LADDW rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LADDW imm ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LLOGW rreg ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LLOGW rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LSHW rreg ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LSHW rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LSHW imm ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LSHW imm ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LABS rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LABS rreg
+       {
+               outcode($1, &$2, NREG, &$2);
+       }
+/*
+ * multiply-accumulate
+ */
+|      LMA rreg ',' sreg ',' rreg
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+/*
+ * move immediate: macro for cau+or, addi, addis, and other combinations
+ */
+|      LMOVW imm ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW ximm ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * condition register operations
+ */
+|      LCROP cbit ',' cbit
+       {
+               outcode($1, &$2, $4.reg, &$4);
+       }
+|      LCROP cbit ',' con ',' cbit
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+/*
+ * condition register moves
+ * move from machine state register
+ */
+|      LMOVW creg ',' creg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW psr ',' creg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW lcr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW psr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW xlreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW rreg ',' xlreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW creg ',' psr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVW rreg ',' psr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * branch, branch conditional
+ * branch conditional register
+ * branch conditional to count register
+ */
+|      LBRA rel
+       {
+               outcode($1, &nullgen, NREG, &$2);
+       }
+|      LBRA addr
+       {
+               outcode($1, &nullgen, NREG, &$2);
+       }
+|      LBRA '(' xlreg ')'
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LBRA ',' rel
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LBRA ',' addr
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LBRA ',' '(' xlreg ')'
+       {
+               outcode($1, &nullgen, NREG, &$4);
+       }
+|      LBRA creg ',' rel
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LBRA creg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LBRA creg ',' '(' xlreg ')'
+       {
+               outcode($1, &$2, NREG, &$5);
+       }
+|      LBRA con ',' rel
+       {
+               outcode($1, &nullgen, $2, &$4);
+       }
+|      LBRA con ',' addr
+       {
+               outcode($1, &nullgen, $2, &$4);
+       }
+|      LBRA con ',' '(' xlreg ')'
+       {
+               outcode($1, &nullgen, $2, &$5);
+       }
+|      LBRA con ',' con ',' rel
+       {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = $2;
+               outcode($1, &g, $4, &$6);
+       }
+|      LBRA con ',' con ',' addr
+       {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = $2;
+               outcode($1, &g, $4, &$6);
+       }
+|      LBRA con ',' con ',' '(' xlreg ')'
+       {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = $2;
+               outcode($1, &g, $4, &$7);
+       }
+/*
+ * conditional trap
+ */
+|      LTRAP rreg ',' sreg
+       {
+               outcode($1, &$2, $4, &nullgen);
+       }
+|      LTRAP imm ',' sreg
+       {
+               outcode($1, &$2, $4, &nullgen);
+       }
+|      LTRAP rreg comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+|      LTRAP comma
+       {
+               outcode($1, &nullgen, NREG, &nullgen);
+       }
+/*
+ * floating point operate
+ */
+|      LFCONV freg ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFADD freg ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFADD freg ',' freg ',' freg
+       {
+               outcode($1, &$2, $4.reg, &$6);
+       }
+|      LFMA freg ',' freg ',' freg ',' freg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+|      LFCMP freg ',' freg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LFCMP freg ',' freg ',' creg
+       {
+               outcode($1, &$2, $6.reg, &$4);
+       }
+/*
+ * CMP
+ */
+|      LCMP rreg ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LCMP rreg ',' imm
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LCMP rreg ',' rreg ',' creg
+       {
+               outcode($1, &$2, $6.reg, &$4);
+       }
+|      LCMP rreg ',' imm ',' creg
+       {
+               outcode($1, &$2, $6.reg, &$4);
+       }
+/*
+ * rotate and mask
+ */
+|      LRLWM  imm ',' rreg ',' imm ',' rreg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+|      LRLWM  imm ',' rreg ',' mask ',' rreg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+|      LRLWM  rreg ',' rreg ',' imm ',' rreg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+|      LRLWM  rreg ',' rreg ',' mask ',' rreg
+       {
+               outgcode($1, &$2, $4.reg, &$6, &$8);
+       }
+/*
+ * load/store multiple
+ */
+|      LMOVMW addr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LMOVMW rreg ',' addr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * various indexed load/store
+ * indexed unary (eg, cache clear)
+ */
+|      LXLD regaddr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LXLD regaddr ',' imm ',' rreg
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LXST rreg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LXST rreg ',' imm ',' regaddr
+       {
+               outgcode($1, &$2, NREG, &$4, &$6);
+       }
+|      LXMV regaddr ',' rreg
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LXMV rreg ',' regaddr
+       {
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LXOP regaddr
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+/*
+ * NOP
+ */
+|      LNOP comma
+       {
+               outcode($1, &nullgen, NREG, &nullgen);
+       }
+|      LNOP rreg comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+|      LNOP freg comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+|      LNOP ',' rreg
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LNOP ',' freg
+       {
+               outcode($1, &nullgen, NREG, &$3);
+       }
+|      LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+/*
+ * word
+ */
+|      LWORD imm comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+|      LWORD ximm comma
+       {
+               outcode($1, &$2, NREG, &nullgen);
+       }
+/*
+ * PCDATA
+ */
+|      LPCDAT imm ',' imm
+       {
+               if($2.type != D_CONST || $4.type != D_CONST)
+                       yyerror("arguments to PCDATA must be integer constants");
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * FUNCDATA
+ */
+|      LFUNCDAT imm ',' addr
+       {
+               if($2.type != D_CONST)
+                       yyerror("index for FUNCDATA must be integer constant");
+               if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
+                       yyerror("value for FUNCDATA must be symbol reference");
+               outcode($1, &$2, NREG, &$4);
+       }
+/*
+ * END
+ */
+|      LEND comma
+       {
+               outcode($1, &nullgen, NREG, &nullgen);
+       }
+/*
+ * TEXT/GLOBL
+ */
+|      LTEXT name ',' imm
+       {
+               settext($2.sym);
+               outcode($1, &$2, NREG, &$4);
+       }
+|      LTEXT name ',' con ',' imm
+       {
+               settext($2.sym);
+               $6.offset &= 0xffffffffull;
+               $6.offset |= (vlong)ArgsSizeUnknown << 32;
+               outcode($1, &$2, $4, &$6);
+       }
+|      LTEXT name ',' con ',' imm '-' con
+       {
+               settext($2.sym);
+               $6.offset &= 0xffffffffull;
+               $6.offset |= ($8 & 0xffffffffull) << 32;
+               outcode($1, &$2, $4, &$6);
+       }
+/*
+ * DATA
+ */
+|      LDATA name '/' con ',' imm
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LDATA name '/' con ',' ximm
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+|      LDATA name '/' con ',' fimm
+       {
+               outcode($1, &$2, $4, &$6);
+       }
+/*
+ * RETURN
+ */
+|      LRETRN  comma
+       {
+               outcode($1, &nullgen, NREG, &nullgen);
+       }
+
+rel:
+       con '(' LPC ')'
+       {
+               $$ = nullgen;
+               $$.type = D_BRANCH;
+               $$.offset = $1 + pc;
+       }
+|      LNAME offset
+       {
+               $1 = labellookup($1);
+               $$ = nullgen;
+               if(pass == 2 && $1->type != LLAB)
+                       yyerror("undefined label: %s", $1->labelname);
+               $$.type = D_BRANCH;
+               $$.offset = $1->value + $2;
+       }
+
+rreg:
+       sreg
+       {
+               $$ = nullgen;
+               $$.type = D_REG;
+               $$.reg = $1;
+       }
+
+xlreg:
+       lr
+|      ctr
+
+lr:
+       LLR
+       {
+               $$ = nullgen;
+               $$.type = D_SPR;
+               $$.offset = $1;
+       }
+
+lcr:
+       LCR
+       {
+               $$ = nullgen;
+               $$.type = D_CREG;
+               $$.reg = NREG;  /* whole register */
+       }
+
+ctr:
+       LCTR
+       {
+               $$ = nullgen;
+               $$.type = D_SPR;
+               $$.offset = $1;
+       }
+
+msr:
+       LMSR
+       {
+               $$ = nullgen;
+               $$.type = D_MSR;
+       }
+
+psr:
+       LSPREG
+       {
+               $$ = nullgen;
+               $$.type = D_SPR;
+               $$.offset = $1;
+       }
+|      LSPR '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = $1;
+               $$.offset = $3;
+       }
+|      msr
+
+fpscr:
+       LFPSCR
+       {
+               $$ = nullgen;
+               $$.type = D_FPSCR;
+               $$.reg = NREG;
+       }
+
+fpscrf:
+       LFPSCR '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FPSCR;
+               $$.reg = $3;
+       }
+
+freg:
+       LFREG
+       {
+               $$ = nullgen;
+               $$.type = D_FREG;
+               $$.reg = $1;
+       }
+|      LF '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_FREG;
+               $$.reg = $3;
+       }
+
+creg:
+       LCREG
+       {
+               $$ = nullgen;
+               $$.type = D_CREG;
+               $$.reg = $1;
+       }
+|      LCR '(' con ')'
+       {
+               $$ = nullgen;
+               $$.type = D_CREG;
+               $$.reg = $3;
+       }
+
+
+cbit:  con
+       {
+               $$ = nullgen;
+               $$.type = D_REG;
+               $$.reg = $1;
+       }
+
+mask:
+       con ',' con
+       {
+               int mb, me;
+               uint32 v;
+
+               $$ = nullgen;
+               $$.type = D_CONST;
+               mb = $1;
+               me = $3;
+               if(mb < 0 || mb > 31 || me < 0 || me > 31){
+                       yyerror("illegal mask start/end value(s)");
+                       mb = me = 0;
+               }
+               if(mb <= me)
+                       v = ((uint32)~0L>>mb) & (~0L<<(31-me));
+               else
+                       v = ~(((uint32)~0L>>(me+1)) & (~0L<<(31-(mb-1))));
+               $$.offset = v;
+       }
+
+ximm:
+       '$' addr
+       {
+               $$ = $2;
+               $$.type = D_CONST;
+       }
+|      '$' LSCONST
+       {
+               $$ = nullgen;
+               $$.type = D_SCONST;
+               memcpy($$.u.sval, $2, sizeof($$.u.sval));
+       }
+
+fimm:
+       '$' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = $2;
+       }
+|      '$' '-' LFCONST
+       {
+               $$ = nullgen;
+               $$.type = D_FCONST;
+               $$.u.dval = -$3;
+       }
+
+imm:   '$' con
+       {
+               $$ = nullgen;
+               $$.type = D_CONST;
+               $$.offset = $2;
+       }
+
+sreg:
+       LREG
+|      LR '(' con ')'
+       {
+               if($$ < 0 || $$ >= NREG)
+                       print("register value out of range\n");
+               $$ = $3;
+       }
+
+regaddr:
+       '(' sreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.reg = $2;
+               $$.offset = 0;
+       }
+|      '(' sreg '+' sreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.reg = $2;
+               $$.scale = $4;
+               $$.offset = 0;
+       }
+
+addr:
+       name
+|      con '(' sreg ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.reg = $3;
+               $$.offset = $1;
+       }
+
+name:
+       con '(' pointer ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = $3;
+               $$.sym = nil;
+               $$.offset = $1;
+       }
+|      LNAME offset '(' pointer ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = $4;
+               $$.sym = linklookup(ctxt, $1->name, 0);
+               $$.offset = $2;
+       }
+|      LNAME '<' '>' offset '(' LSB ')'
+       {
+               $$ = nullgen;
+               $$.type = D_OREG;
+               $$.name = D_STATIC;
+               $$.sym = linklookup(ctxt, $1->name, 0);
+               $$.offset = $4;
+       }
+
+comma:
+|      ','
+
+offset:
+       {
+               $$ = 0;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+
+pointer:
+       LSB
+|      LSP
+|      LFP
+
+con:
+       LCONST
+|      LVAR
+       {
+               $$ = $1->value;
+       }
+|      '-' con
+       {
+               $$ = -$2;
+       }
+|      '+' con
+       {
+               $$ = $2;
+       }
+|      '~' con
+       {
+               $$ = ~$2;
+       }
+|      '(' expr ')'
+       {
+               $$ = $2;
+       }
+
+expr:
+       con
+|      expr '+' expr
+       {
+               $$ = $1 + $3;
+       }
+|      expr '-' expr
+       {
+               $$ = $1 - $3;
+       }
+|      expr '*' expr
+       {
+               $$ = $1 * $3;
+       }
+|      expr '/' expr
+       {
+               $$ = $1 / $3;
+       }
+|      expr '%' expr
+       {
+               $$ = $1 % $3;
+       }
+|      expr '<' '<' expr
+       {
+               $$ = $1 << $4;
+       }
+|      expr '>' '>' expr
+       {
+               $$ = $1 >> $4;
+       }
+|      expr '&' expr
+       {
+               $$ = $1 & $3;
+       }
+|      expr '^' expr
+       {
+               $$ = $1 ^ $3;
+       }
+|      expr '|' expr
+       {
+               $$ = $1 | $3;
+       }
diff --git a/src/cmd/9a/doc.go b/src/cmd/9a/doc.go
new file mode 100644 (file)
index 0000000..44bf89d
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+
+9a is a version of the Plan 9 assembler.  The original is documented at
+
+       http://plan9.bell-labs.com/magic/man2html/1/8a
+
+Go-specific considerations are documented at
+
+       http://golang.org/doc/asm
+
+Its target architecture is the Power64, referred to by these tools as
+power64 (big endian) or power64le (little endian).
+
+*/
+package main
diff --git a/src/cmd/9a/lex.c b/src/cmd/9a/lex.c
new file mode 100644 (file)
index 0000000..26f21f7
--- /dev/null
@@ -0,0 +1,725 @@
+// 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.
+
+#define        EXTERN
+#include <u.h>
+#include <libc.h>
+#include "a.h"
+#include "y.tab.h"
+
+enum
+{
+       Plan9   = 1<<0,
+       Unix    = 1<<1,
+       Windows = 1<<2,
+};
+
+int
+systemtype(int sys)
+{
+#ifdef _WIN32
+       return sys&Windows;
+#else
+       return sys&Plan9;
+#endif
+}
+
+int
+pathchar(void)
+{
+       return '/';
+}
+
+int
+Lconv(Fmt *fp)
+{
+       return linklinefmt(ctxt, fp);
+}
+
+void
+dodef(char *p)
+{
+       if(nDlist%8 == 0)
+               Dlist = allocn(Dlist, nDlist*sizeof(char *),
+                       8*sizeof(char *));
+       Dlist[nDlist++] = p;
+}
+
+LinkArch*       thelinkarch = &linkpower64;
+
+void
+usage(void)
+{
+       print("usage: %ca [options] file.c...\n", thechar);
+       flagprint(1);
+       errorexit();
+}
+
+void
+main(int argc, char *argv[])
+{
+       char *p;
+
+       thechar = '9';
+       thestring = "power64";
+
+       // Allow GOARCH=thestring or GOARCH=thestringsuffix,
+       // but not other values.        
+       p = getgoarch();
+       if(strncmp(p, thestring, strlen(thestring)) != 0)
+               sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
+       if(strcmp(p, "power64le") == 0)
+               thelinkarch = &linkpower64le;
+
+       ctxt = linknew(thelinkarch);
+       ctxt->diag = yyerror;
+       ctxt->bso = &bstdout;
+       ctxt->enforce_data_order = 1;
+       Binit(&bstdout, 1, OWRITE);
+       listinit9();
+       fmtinstall('L', Lconv);
+
+       ensuresymb(NSYMB);
+       memset(debug, 0, sizeof(debug));
+       cinit();
+       outfile = 0;
+       setinclude(".");
+
+       flagfn1("D", "name[=value]: add #define", dodef);
+       flagfn1("I", "dir: add dir to include path", setinclude);
+       flagcount("S", "print assembly and machine code", &debug['S']);
+       flagcount("m", "debug preprocessor macros", &debug['m']);
+       flagstr("o", "file: set output file", &outfile);
+       flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
+
+       flagparse(&argc, &argv, usage);
+       ctxt->debugasm = debug['S'];
+
+       if(argc < 1)
+               usage();
+       if(argc > 1){
+               print("can't assemble multiple files\n");
+               errorexit();
+       }
+
+       if(assemble(argv[0]))
+               errorexit();
+       Bflush(&bstdout);
+       exits(0);
+}
+
+int
+assemble(char *file)
+{
+       char *ofile, *p;
+       int i, of;
+
+       ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
+       strcpy(ofile, file);
+       p = utfrrune(ofile, pathchar());
+       if(p) {
+               include[0] = ofile;
+               *p++ = 0;
+       } else
+               p = ofile;
+       if(outfile == 0) {
+               outfile = p;
+               if(outfile){
+                       p = utfrrune(outfile, '.');
+                       if(p)
+                               if(p[1] == 's' && p[2] == 0)
+                                       p[0] = 0;
+                       p = utfrune(outfile, 0);
+                       p[0] = '.';
+                       p[1] = thechar;
+                       p[2] = 0;
+               } else
+                       outfile = "/dev/null";
+       }
+
+       of = create(outfile, OWRITE, 0664);
+       if(of < 0) {
+               yyerror("%ca: cannot create %s", thechar, outfile);
+               errorexit();
+       }
+       Binit(&obuf, of, OWRITE);
+       Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
+       Bprint(&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)
+                       return nerrors;
+       }
+
+       writeobj(ctxt, &obuf);
+       Bflush(&obuf);
+       return 0;
+}
+
+struct
+{
+       char    *name;
+       ushort  type;
+       ushort  value;
+} itab[] =
+{
+       "SP",           LSP,    D_AUTO,
+       "SB",           LSB,    D_EXTERN,
+       "FP",           LFP,    D_PARAM,
+       "PC",           LPC,    D_BRANCH,
+
+       "LR",           LLR,    D_LR,
+       "CTR",          LCTR,   D_CTR,
+
+       "XER",          LSPREG, D_XER,
+       "MSR",          LMSR,   D_MSR,
+       "FPSCR",        LFPSCR, D_FPSCR,
+       "SPR",          LSPR,   D_SPR,
+       "DCR",          LSPR,   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,
+       "R30",          LREG,   30,
+       "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, ACREQV,
+       "CRXOR",        LCROP, ACRXOR,
+       "CRAND",        LCROP, ACRAND,
+       "CROR",         LCROP, ACROR,
+       "CRANDN",       LCROP, ACRANDN,
+       "CRORN",        LCROP, ACRORN,
+       "CRNAND",       LCROP, ACRNAND,
+       "CRNOR",        LCROP, ACRNOR,
+
+       "ADD",          LADDW, AADD,
+       "ADDV",         LADDW, AADDV,
+       "ADDCC",        LADDW, AADDCC,
+       "ADDVCC",       LADDW, AADDVCC,
+       "ADDC",         LADDW, AADDC,
+       "ADDCV",        LADDW, AADDCV,
+       "ADDCCC",       LADDW, AADDCCC,
+       "ADDCVCC",      LADDW, AADDCVCC,
+       "ADDE",         LLOGW, AADDE,
+       "ADDEV",        LLOGW, AADDEV,
+       "ADDECC",       LLOGW, AADDECC,
+       "ADDEVCC",      LLOGW, AADDEVCC,
+
+       "ADDME",        LABS, AADDME,
+       "ADDMEV",       LABS, AADDMEV,
+       "ADDMECC",      LABS, AADDMECC,
+       "ADDMEVCC",     LABS, AADDMEVCC,
+       "ADDZE",        LABS, AADDZE,
+       "ADDZEV",       LABS, AADDZEV,
+       "ADDZECC",      LABS, AADDZECC,
+       "ADDZEVCC",     LABS, AADDZEVCC,
+
+       "SUB",          LADDW, ASUB,
+       "SUBV",         LADDW, ASUBV,
+       "SUBCC",        LADDW, ASUBCC,
+       "SUBVCC",       LADDW, ASUBVCC,
+       "SUBE",         LLOGW, ASUBE,
+       "SUBECC",       LLOGW, ASUBECC,
+       "SUBEV",        LLOGW, ASUBEV,
+       "SUBEVCC",      LLOGW, ASUBEVCC,
+       "SUBC",         LADDW, ASUBC,
+       "SUBCCC",       LADDW, ASUBCCC,
+       "SUBCV",        LADDW, ASUBCV,
+       "SUBCVCC",      LADDW, ASUBCVCC,
+
+       "SUBME",        LABS, ASUBME,
+       "SUBMEV",       LABS, ASUBMEV,
+       "SUBMECC",      LABS, ASUBMECC,
+       "SUBMEVCC",     LABS, ASUBMEVCC,
+       "SUBZE",        LABS, ASUBZE,
+       "SUBZEV",       LABS, ASUBZEV,
+       "SUBZECC",      LABS, ASUBZECC,
+       "SUBZEVCC",     LABS, ASUBZEVCC,
+
+       "AND",          LADDW, AAND,
+       "ANDCC",        LADDW, AANDCC,  /* includes andil & andiu */
+       "ANDN",         LLOGW, AANDN,
+       "ANDNCC",       LLOGW, AANDNCC,
+       "EQV",          LLOGW, AEQV,
+       "EQVCC",        LLOGW, AEQVCC,
+       "NAND",         LLOGW, ANAND,
+       "NANDCC",       LLOGW, ANANDCC,
+       "NOR",          LLOGW, ANOR,
+       "NORCC",        LLOGW, ANORCC,
+       "OR",           LADDW, AOR,     /* includes oril & oriu */
+       "ORCC",         LADDW, AORCC,
+       "ORN",          LLOGW, AORN,
+       "ORNCC",        LLOGW, AORNCC,
+       "XOR",          LADDW, AXOR,    /* includes xoril & xoriu */
+       "XORCC",        LLOGW, AXORCC,
+
+       "EXTSB",        LABS,   AEXTSB,
+       "EXTSBCC",      LABS,   AEXTSBCC,
+       "EXTSH",        LABS, AEXTSH,
+       "EXTSHCC",      LABS, AEXTSHCC,
+
+       "CNTLZW",       LABS, ACNTLZW,
+       "CNTLZWCC",     LABS, ACNTLZWCC,
+
+       "RLWMI",        LRLWM, ARLWMI,
+       "RLWMICC",      LRLWM, ARLWMICC,
+       "RLWNM",        LRLWM, ARLWNM,
+       "RLWNMCC", LRLWM, ARLWNMCC,
+
+       "SLW",          LSHW, ASLW,
+       "SLWCC",        LSHW, ASLWCC,
+       "SRW",          LSHW, ASRW,
+       "SRWCC",        LSHW, ASRWCC,
+       "SRAW",         LSHW, ASRAW,
+       "SRAWCC",       LSHW, ASRAWCC,
+
+       "BR",           LBRA, ABR,
+       "BC",           LBRA, ABC,
+       "BCL",          LBRA, ABC,
+       "BL",           LBRA, ABL,
+       "BEQ",          LBRA, ABEQ,
+       "BNE",          LBRA, ABNE,
+       "BGT",          LBRA, ABGT,
+       "BGE",          LBRA, ABGE,
+       "BLT",          LBRA, ABLT,
+       "BLE",          LBRA, ABLE,
+       "BVC",          LBRA, ABVC,
+       "BVS",          LBRA, ABVS,
+
+       "CMP",          LCMP, ACMP,
+       "CMPU",         LCMP, ACMPU,
+       "CMPW",         LCMP, ACMPW,
+       "CMPWU",        LCMP, ACMPWU,
+
+       "DIVW",         LLOGW, ADIVW,
+       "DIVWV",        LLOGW, ADIVWV,
+       "DIVWCC",       LLOGW, ADIVWCC,
+       "DIVWVCC",      LLOGW, ADIVWVCC,
+       "DIVWU",        LLOGW, ADIVWU,
+       "DIVWUV",       LLOGW, ADIVWUV,
+       "DIVWUCC",      LLOGW, ADIVWUCC,
+       "DIVWUVCC",     LLOGW, ADIVWUVCC,
+
+       "FABS",         LFCONV, AFABS,
+       "FABSCC",       LFCONV, AFABSCC,
+       "FNEG",         LFCONV, AFNEG,
+       "FNEGCC",       LFCONV, AFNEGCC,
+       "FNABS",        LFCONV, AFNABS,
+       "FNABSCC",      LFCONV, AFNABSCC,
+
+       "FADD",         LFADD,  AFADD,
+       "FADDCC",       LFADD,  AFADDCC,
+       "FSUB",         LFADD,  AFSUB,
+       "FSUBCC",       LFADD,  AFSUBCC,
+       "FMUL",         LFADD,  AFMUL,
+       "FMULCC",       LFADD,  AFMULCC,
+       "FDIV",         LFADD,  AFDIV,
+       "FDIVCC",       LFADD,  AFDIVCC,
+       "FRSP",         LFCONV, AFRSP,
+       "FRSPCC",       LFCONV, AFRSPCC,
+       "FCTIW",        LFCONV, AFCTIW,
+       "FCTIWCC",      LFCONV, AFCTIWCC,
+       "FCTIWZ",       LFCONV, AFCTIWZ,
+       "FCTIWZCC",     LFCONV, AFCTIWZCC,
+
+       "FMADD",        LFMA, AFMADD,
+       "FMADDCC",      LFMA, AFMADDCC,
+       "FMSUB",        LFMA, AFMSUB,
+       "FMSUBCC",      LFMA, AFMSUBCC,
+       "FNMADD",       LFMA, AFNMADD,
+       "FNMADDCC",     LFMA, AFNMADDCC,
+       "FNMSUB",       LFMA, AFNMSUB,
+       "FNMSUBCC",     LFMA, AFNMSUBCC,
+       "FMADDS",       LFMA, AFMADDS,
+       "FMADDSCC",     LFMA, AFMADDSCC,
+       "FMSUBS",       LFMA, AFMSUBS,
+       "FMSUBSCC",     LFMA, AFMSUBSCC,
+       "FNMADDS",      LFMA, AFNMADDS,
+       "FNMADDSCC",    LFMA, AFNMADDSCC,
+       "FNMSUBS",      LFMA, AFNMSUBS,
+       "FNMSUBSCC",    LFMA, AFNMSUBSCC,
+
+       "FCMPU",        LFCMP, AFCMPU,
+       "FCMPO",        LFCMP, AFCMPO,
+       "MTFSB0",       LMTFSB, AMTFSB0,
+       "MTFSB1",       LMTFSB, AMTFSB1,
+
+       "FMOVD",        LFMOV, AFMOVD,
+       "FMOVS",        LFMOV, AFMOVS,
+       "FMOVDCC",      LFCONV, AFMOVDCC,       /* fmr. */
+
+       "GLOBL",        LTEXT, AGLOBL,
+
+       "MOVB",         LMOVB, AMOVB,
+       "MOVBZ",        LMOVB, AMOVBZ,
+       "MOVBU",        LMOVB, AMOVBU,
+       "MOVBZU", LMOVB, AMOVBZU,
+       "MOVH",         LMOVB, AMOVH,
+       "MOVHZ",        LMOVB, AMOVHZ,
+       "MOVHU",        LMOVB, AMOVHU,
+       "MOVHZU", LMOVB, AMOVHZU,
+       "MOVHBR",       LXMV, AMOVHBR,
+       "MOVWBR",       LXMV, AMOVWBR,
+       "MOVW",         LMOVW, AMOVW,
+       "MOVWU",        LMOVW, AMOVWU,
+       "MOVMW",        LMOVMW, AMOVMW,
+       "MOVFL",        LMOVW,  AMOVFL,
+
+       "MULLW",        LADDW, AMULLW,          /* includes multiply immediate 10-139 */
+       "MULLWV",       LLOGW, AMULLWV,
+       "MULLWCC",      LLOGW, AMULLWCC,
+       "MULLWVCC",     LLOGW, AMULLWVCC,
+
+       "MULHW",        LLOGW, AMULHW,
+       "MULHWCC",      LLOGW, AMULHWCC,
+       "MULHWU",       LLOGW, AMULHWU,
+       "MULHWUCC",     LLOGW, AMULHWUCC,
+
+       "NEG",          LABS, ANEG,
+       "NEGV",         LABS, ANEGV,
+       "NEGCC",        LABS, ANEGCC,
+       "NEGVCC",       LABS, ANEGVCC,
+
+       "NOP",          LNOP, ANOP,     /* ori 0,0,0 */
+       "SYSCALL",      LNOP, ASYSCALL,
+       "UNDEF",        LNOP, AUNDEF,
+
+       "RETURN",       LRETRN, ARETURN,
+       "RFI",          LRETRN, ARFI,
+       "RFCI",         LRETRN, ARFCI,
+
+       "DATA",         LDATA, ADATA,
+       "END",          LEND, AEND,
+       "TEXT",         LTEXT, ATEXT,
+
+       /* 64-bit instructions */
+       "CNTLZD",       LABS,   ACNTLZD,
+       "CNTLZDCC",     LABS,   ACNTLZDCC,
+       "DIVD", LLOGW,  ADIVD,
+       "DIVDCC",       LLOGW,  ADIVDCC,
+       "DIVDVCC",      LLOGW,  ADIVDVCC,
+       "DIVDV",        LLOGW,  ADIVDV,
+       "DIVDU",        LLOGW,  ADIVDU,
+       "DIVDUCC",      LLOGW,  ADIVDUCC,
+       "DIVDUVCC",     LLOGW,  ADIVDUVCC,
+       "DIVDUV",       LLOGW,  ADIVDUV,
+       "EXTSW",        LABS, AEXTSW,
+       "EXTSWCC",      LABS, AEXTSWCC,
+       "FCTID",        LFCONV, AFCTID,
+       "FCTIDCC",      LFCONV, AFCTIDCC,
+       "FCTIDZ",       LFCONV, AFCTIDZ,
+       "FCTIDZCC",     LFCONV, AFCTIDZCC,
+       "FCFID",        LFCONV, AFCFID,
+       "FCFIDCC",      LFCONV, AFCFIDCC,
+       "LDAR", LXLD, ALDAR,
+       "MOVD", LMOVW,  AMOVD,
+       "MOVDU",        LMOVW,  AMOVDU,
+       "MOVWZ",        LMOVW,  AMOVWZ,
+       "MOVWZU",       LMOVW,  AMOVWZU,
+       "MULHD",        LLOGW,  AMULHD,
+       "MULHDCC",      LLOGW,  AMULHDCC,
+       "MULHDU",       LLOGW,  AMULHDU,
+       "MULHDUCC",     LLOGW,  AMULHDUCC,
+       "MULLD",        LADDW,  AMULLD, /* includes multiply immediate? */
+       "MULLDCC",      LLOGW,  AMULLDCC,
+       "MULLDVCC",     LLOGW,  AMULLDVCC,
+       "MULLDV",       LLOGW,  AMULLDV,
+       "RFID", LRETRN, ARFID,
+       "HRFID", LRETRN, AHRFID,
+       "RLDMI",        LRLWM,  ARLDMI,
+       "RLDMICC",      LRLWM,  ARLDMICC,
+       "RLDC", LRLWM,  ARLDC,
+       "RLDCCC",       LRLWM,  ARLDCCC,
+       "RLDCR",        LRLWM,  ARLDCR,
+       "RLDCRCC",      LRLWM,  ARLDCRCC,
+       "RLDCL",        LRLWM,  ARLDCL,
+       "RLDCLCC",      LRLWM,  ARLDCLCC,
+       "SLBIA",        LNOP,   ASLBIA,
+       "SLBIE",        LNOP,   ASLBIE,
+       "SLBMFEE",      LABS,   ASLBMFEE,
+       "SLBMFEV",      LABS,   ASLBMFEV,
+       "SLBMTE",       LABS,   ASLBMTE,
+       "SLD",  LSHW,   ASLD,
+       "SLDCC",        LSHW,   ASLDCC,
+       "SRD",  LSHW,   ASRD,
+       "SRAD", LSHW,   ASRAD,
+       "SRADCC",       LSHW,   ASRADCC,
+       "SRDCC",        LSHW,   ASRDCC,
+       "STDCCC",       LXST,   ASTDCCC,
+       "TD",   LADDW,  ATD,
+
+       /* pseudo instructions */
+       "REM",  LLOGW,  AREM,
+       "REMCC",        LLOGW,  AREMCC,
+       "REMV", LLOGW,  AREMV,
+       "REMVCC",       LLOGW,  AREMVCC,
+       "REMU", LLOGW,  AREMU,
+       "REMUCC",       LLOGW,  AREMUCC,
+       "REMUV",        LLOGW,  AREMUV,
+       "REMUVCC",      LLOGW,  AREMUVCC,
+       "REMD", LLOGW,  AREMD,
+       "REMDCC",       LLOGW,  AREMDCC,
+       "REMDV",        LLOGW,  AREMDV,
+       "REMDVCC",      LLOGW,  AREMDVCC,
+       "REMDU",        LLOGW,  AREMDU,
+       "REMDUCC",      LLOGW,  AREMDUCC,
+       "REMDUV",       LLOGW,  AREMDUV,
+       "REMDUVCC",     LLOGW,  AREMDUVCC,
+
+/* special instructions */
+       "DCBF",         LXOP,   ADCBF,
+       "DCBI",         LXOP,   ADCBI,
+       "DCBST",        LXOP,   ADCBST,
+       "DCBT",         LXOP,   ADCBT,
+       "DCBTST",       LXOP,   ADCBTST,
+       "DCBZ",         LXOP,   ADCBZ,
+       "ICBI",         LXOP,   AICBI,
+
+       "ECIWX",        LXLD,   AECIWX,
+       "ECOWX",        LXST,   AECOWX,
+       "LWAR", LXLD, ALWAR,
+       "LWAR", LXLD, ALWAR,
+       "STWCCC", LXST, ASTWCCC,
+       "EIEIO",        LRETRN, AEIEIO,
+       "TLBIE",        LNOP,   ATLBIE,
+       "TLBIEL",       LNOP,   ATLBIEL,
+       "LSW",  LXLD, ALSW,
+       "STSW", LXST, ASTSW,
+       
+       "ISYNC",        LRETRN, AISYNC,
+       "SYNC",         LRETRN, ASYNC,
+       "TLBSYNC",      LRETRN, ATLBSYNC,
+       "PTESYNC",      LRETRN, APTESYNC,
+/*     "TW",           LADDW,  ATW,*/
+
+       "WORD",         LWORD, AWORD,
+       "DWORD",        LWORD, ADWORD,
+       "SCHED",        LSCHED, 0,
+       "NOSCHED",      LSCHED, 0x80,
+
+       "PCDATA",       LPCDAT, APCDATA,
+       "FUNCDATA",     LFUNCDAT,       AFUNCDATA,
+
+       0
+};
+
+void
+cinit(void)
+{
+       Sym *s;
+       int i;
+
+       nullgen.type = D_NONE;
+       nullgen.name = D_NONE;
+       nullgen.reg = NREG;
+       nullgen.scale = NREG; // replaced Gen.xreg with Prog.scale
+
+       nerrors = 0;
+       iostack = I;
+       iofree = I;
+       peekc = IGN;
+       nhunk = 0;
+       for(i=0; i<NHASH; i++)
+               hash[i] = S;
+       for(i=0; itab[i].name; i++) {
+               s = slookup(itab[i].name);
+               s->type = itab[i].type;
+               s->value = itab[i].value;
+       }
+}
+
+void
+syminit(Sym *s)
+{
+
+       s->type = LNAME;
+       s->value = 0;
+}
+
+void
+cclean(void)
+{
+
+       outcode(AEND, &nullgen, NREG, &nullgen);
+}
+
+static Prog *lastpc;
+
+void
+outcode(int a, Addr *g1, int reg, Addr *g2)
+{
+       Prog *p;
+       Plist *pl;
+
+       if(pass == 1)
+               goto out;
+
+       if(g1->scale != NREG) {
+               if(reg != NREG || g2->scale != NREG)
+                       yyerror("bad addressing modes");
+               reg = g1->scale;
+       } else
+       if(g2->scale != NREG) {
+               if(reg != NREG)
+                       yyerror("bad addressing modes");
+               reg = g2->scale;
+       }
+
+       p = ctxt->arch->prg();
+       p->as = a;
+       p->lineno = lineno;
+       if(nosched)
+               p->mark |= NOSCHED;
+       p->from = *g1;
+       p->reg = reg;
+       p->to = *g2;
+       p->pc = pc;
+
+       if(lastpc == nil) {
+               pl = linknewplist(ctxt);
+               pl->firstpc = p;
+       } else
+               lastpc->link = p;
+       lastpc = p;
+out:
+       if(a != AGLOBL && a != ADATA)
+               pc++;
+}
+
+void
+outgcode(int a, Addr *g1, int reg, Addr *g2, Addr *g3)
+{
+       Prog *p;
+       Plist *pl;
+
+       if(pass == 1)
+               goto out;
+
+       p = ctxt->arch->prg();
+       p->as = a;
+       p->lineno = lineno;
+       if(nosched)
+               p->mark |= NOSCHED;
+       p->from = *g1;
+       p->reg = reg;
+       p->from3 = *g2;
+       p->to = *g3;
+       p->pc = pc;
+
+       if(lastpc == nil) {
+               pl = linknewplist(ctxt);
+               pl->firstpc = p;
+       } else
+               lastpc->link = p;
+       lastpc = p;
+out:
+       if(a != AGLOBL && a != ADATA)
+               pc++;
+}
+
+#include "../cc/lexbody"
+#include "../cc/macbody"
diff --git a/src/cmd/9a/y.tab.c b/src/cmd/9a/y.tab.c
new file mode 100644 (file)
index 0000000..6025a24
--- /dev/null
@@ -0,0 +1,3398 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     LMOVW = 258,
+     LMOVB = 259,
+     LABS = 260,
+     LLOGW = 261,
+     LSHW = 262,
+     LADDW = 263,
+     LCMP = 264,
+     LCROP = 265,
+     LBRA = 266,
+     LFMOV = 267,
+     LFCONV = 268,
+     LFCMP = 269,
+     LFADD = 270,
+     LFMA = 271,
+     LTRAP = 272,
+     LXORW = 273,
+     LNOP = 274,
+     LEND = 275,
+     LRETT = 276,
+     LWORD = 277,
+     LTEXT = 278,
+     LDATA = 279,
+     LRETRN = 280,
+     LCONST = 281,
+     LSP = 282,
+     LSB = 283,
+     LFP = 284,
+     LPC = 285,
+     LCREG = 286,
+     LFLUSH = 287,
+     LREG = 288,
+     LFREG = 289,
+     LR = 290,
+     LCR = 291,
+     LF = 292,
+     LFPSCR = 293,
+     LLR = 294,
+     LCTR = 295,
+     LSPR = 296,
+     LSPREG = 297,
+     LSEG = 298,
+     LMSR = 299,
+     LPCDAT = 300,
+     LFUNCDAT = 301,
+     LSCHED = 302,
+     LXLD = 303,
+     LXST = 304,
+     LXOP = 305,
+     LXMV = 306,
+     LRLWM = 307,
+     LMOVMW = 308,
+     LMOVEM = 309,
+     LMOVFL = 310,
+     LMTFSB = 311,
+     LMA = 312,
+     LFCONST = 313,
+     LSCONST = 314,
+     LNAME = 315,
+     LLAB = 316,
+     LVAR = 317
+   };
+#endif
+/* Tokens.  */
+#define LMOVW 258
+#define LMOVB 259
+#define LABS 260
+#define LLOGW 261
+#define LSHW 262
+#define LADDW 263
+#define LCMP 264
+#define LCROP 265
+#define LBRA 266
+#define LFMOV 267
+#define LFCONV 268
+#define LFCMP 269
+#define LFADD 270
+#define LFMA 271
+#define LTRAP 272
+#define LXORW 273
+#define LNOP 274
+#define LEND 275
+#define LRETT 276
+#define LWORD 277
+#define LTEXT 278
+#define LDATA 279
+#define LRETRN 280
+#define LCONST 281
+#define LSP 282
+#define LSB 283
+#define LFP 284
+#define LPC 285
+#define LCREG 286
+#define LFLUSH 287
+#define LREG 288
+#define LFREG 289
+#define LR 290
+#define LCR 291
+#define LF 292
+#define LFPSCR 293
+#define LLR 294
+#define LCTR 295
+#define LSPR 296
+#define LSPREG 297
+#define LSEG 298
+#define LMSR 299
+#define LPCDAT 300
+#define LFUNCDAT 301
+#define LSCHED 302
+#define LXLD 303
+#define LXST 304
+#define LXOP 305
+#define LXMV 306
+#define LRLWM 307
+#define LMOVMW 308
+#define LMOVEM 309
+#define LMOVFL 310
+#define LMTFSB 311
+#define LMA 312
+#define LFCONST 313
+#define LSCONST 314
+#define LNAME 315
+#define LLAB 316
+#define LVAR 317
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 30 "a.y"
+
+#include <u.h>
+#include <stdio.h>     /* if we don't, bison will, and a.h re-#defines getc */
+#include <libc.h>
+#include "a.h"
+#include "../../runtime/funcdata.h"
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 38 "a.y"
+{
+       Sym     *sym;
+       vlong   lval;
+       double  dval;
+       char    sval[8];
+       Addr    addr;
+}
+/* Line 193 of yacc.c.  */
+#line 236 "y.tab.c"
+       YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 249 "y.tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+            && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+        || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)                                       \
+    do                                                                 \
+      {                                                                        \
+       YYSIZE_T yynewbytes;                                            \
+       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
+       Stack = &yyptr->Stack;                                          \
+       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  2
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   862
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  81
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  31
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  183
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  453
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   317
+
+#define YYTRANSLATE(YYX)                                               \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,    79,    12,     5,     2,
+      77,    78,    10,     8,    76,     9,     2,    11,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    73,    75,
+       6,    74,     7,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     4,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     3,     2,    80,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     4,     7,     8,    13,    18,    23,    26,
+      28,    31,    34,    39,    44,    49,    54,    59,    64,    69,
+      74,    79,    84,    89,    94,    99,   104,   109,   114,   119,
+     124,   129,   134,   141,   146,   151,   156,   163,   168,   173,
+     180,   187,   194,   199,   204,   211,   216,   223,   228,   235,
+     240,   245,   248,   255,   260,   265,   270,   277,   282,   287,
+     292,   297,   302,   307,   312,   317,   320,   323,   328,   332,
+     336,   342,   347,   352,   359,   364,   369,   376,   383,   390,
+     399,   404,   409,   413,   416,   421,   426,   433,   442,   447,
+     454,   459,   464,   471,   478,   487,   496,   505,   514,   519,
+     524,   529,   536,   541,   548,   553,   558,   561,   564,   568,
+     572,   576,   580,   583,   587,   591,   596,   601,   604,   609,
+     616,   625,   632,   639,   646,   649,   654,   657,   659,   661,
+     663,   665,   667,   669,   671,   673,   678,   680,   682,   687,
+     689,   694,   696,   701,   703,   707,   710,   713,   716,   720,
+     723,   725,   730,   734,   740,   742,   747,   752,   758,   766,
+     767,   769,   770,   773,   776,   778,   780,   782,   784,   786,
+     789,   792,   795,   799,   801,   805,   809,   813,   817,   821,
+     826,   831,   835,   839
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      82,     0,    -1,    -1,    82,    83,    -1,    -1,    70,    73,
+      84,    83,    -1,    70,    74,   111,    75,    -1,    72,    74,
+     111,    75,    -1,    57,    75,    -1,    75,    -1,    85,    75,
+      -1,     1,    75,    -1,    13,    87,    76,    87,    -1,    13,
+     105,    76,    87,    -1,    13,   104,    76,    87,    -1,    14,
+      87,    76,    87,    -1,    14,   105,    76,    87,    -1,    14,
+     104,    76,    87,    -1,    22,   105,    76,    96,    -1,    22,
+     104,    76,    96,    -1,    22,   101,    76,    96,    -1,    22,
+      96,    76,    96,    -1,    22,    96,    76,   105,    -1,    22,
+      96,    76,   104,    -1,    13,    87,    76,   105,    -1,    13,
+      87,    76,   104,    -1,    14,    87,    76,   105,    -1,    14,
+      87,    76,   104,    -1,    13,    96,    76,   105,    -1,    13,
+      96,    76,   104,    -1,    13,    94,    76,    96,    -1,    13,
+      96,    76,    94,    -1,    13,    96,    76,   102,    76,    94,
+      -1,    13,    94,    76,    97,    -1,    13,   102,    76,    95,
+      -1,    66,   102,    76,   110,    -1,    13,    87,    76,   102,
+      76,    90,    -1,    13,    87,    76,    97,    -1,    13,    87,
+      76,    90,    -1,    18,    87,    76,   103,    76,    87,    -1,
+      18,   102,    76,   103,    76,    87,    -1,    18,    87,    76,
+     102,    76,    87,    -1,    18,    87,    76,    87,    -1,    18,
+     102,    76,    87,    -1,    16,    87,    76,   103,    76,    87,
+      -1,    16,    87,    76,    87,    -1,    17,    87,    76,   103,
+      76,    87,    -1,    17,    87,    76,    87,    -1,    17,   102,
+      76,   103,    76,    87,    -1,    17,   102,    76,    87,    -1,
+      15,    87,    76,    87,    -1,    15,    87,    -1,    67,    87,
+      76,   103,    76,    87,    -1,    13,   102,    76,    87,    -1,
+      13,   100,    76,    87,    -1,    20,    98,    76,    98,    -1,
+      20,    98,    76,   110,    76,    98,    -1,    13,    97,    76,
+      97,    -1,    13,    93,    76,    97,    -1,    13,    90,    76,
+      87,    -1,    13,    93,    76,    87,    -1,    13,    88,    76,
+      87,    -1,    13,    87,    76,    88,    -1,    13,    97,    76,
+      93,    -1,    13,    87,    76,    93,    -1,    21,    86,    -1,
+      21,   105,    -1,    21,    77,    88,    78,    -1,    21,    76,
+      86,    -1,    21,    76,   105,    -1,    21,    76,    77,    88,
+      78,    -1,    21,    97,    76,    86,    -1,    21,    97,    76,
+     105,    -1,    21,    97,    76,    77,    88,    78,    -1,    21,
+     110,    76,    86,    -1,    21,   110,    76,   105,    -1,    21,
+     110,    76,    77,    88,    78,    -1,    21,   110,    76,   110,
+      76,    86,    -1,    21,   110,    76,   110,    76,   105,    -1,
+      21,   110,    76,   110,    76,    77,    88,    78,    -1,    27,
+      87,    76,   103,    -1,    27,   102,    76,   103,    -1,    27,
+      87,   107,    -1,    27,   107,    -1,    23,    96,    76,    96,
+      -1,    25,    96,    76,    96,    -1,    25,    96,    76,    96,
+      76,    96,    -1,    26,    96,    76,    96,    76,    96,    76,
+      96,    -1,    24,    96,    76,    96,    -1,    24,    96,    76,
+      96,    76,    97,    -1,    19,    87,    76,    87,    -1,    19,
+      87,    76,   102,    -1,    19,    87,    76,    87,    76,    97,
+      -1,    19,    87,    76,   102,    76,    97,    -1,    62,   102,
+      76,    87,    76,   102,    76,    87,    -1,    62,   102,    76,
+      87,    76,    99,    76,    87,    -1,    62,    87,    76,    87,
+      76,   102,    76,    87,    -1,    62,    87,    76,    87,    76,
+      99,    76,    87,    -1,    63,   105,    76,    87,    -1,    63,
+      87,    76,   105,    -1,    58,   104,    76,    87,    -1,    58,
+     104,    76,   102,    76,    87,    -1,    59,    87,    76,   104,
+      -1,    59,    87,    76,   102,    76,   104,    -1,    61,   104,
+      76,    87,    -1,    61,    87,    76,   104,    -1,    60,   104,
+      -1,    29,   107,    -1,    29,    87,   107,    -1,    29,    96,
+     107,    -1,    29,    76,    87,    -1,    29,    76,    96,    -1,
+      29,   102,    -1,    32,   102,   107,    -1,    32,   100,   107,
+      -1,    55,   102,    76,   102,    -1,    56,   102,    76,   105,
+      -1,    30,   107,    -1,    33,   106,    76,   102,    -1,    33,
+     106,    76,   110,    76,   102,    -1,    33,   106,    76,   110,
+      76,   102,     9,   110,    -1,    34,   106,    11,   110,    76,
+     102,    -1,    34,   106,    11,   110,    76,   100,    -1,    34,
+     106,    11,   110,    76,   101,    -1,    35,   107,    -1,   110,
+      77,    40,    78,    -1,    70,   108,    -1,   103,    -1,    89,
+      -1,    91,    -1,    49,    -1,    46,    -1,    50,    -1,    54,
+      -1,    52,    -1,    51,    77,   110,    78,    -1,    92,    -1,
+      48,    -1,    48,    77,   110,    78,    -1,    44,    -1,    47,
+      77,   110,    78,    -1,    41,    -1,    46,    77,   110,    78,
+      -1,   110,    -1,   110,    76,   110,    -1,    79,   105,    -1,
+      79,    69,    -1,    79,    68,    -1,    79,     9,    68,    -1,
+      79,   110,    -1,    43,    -1,    45,    77,   110,    78,    -1,
+      77,   103,    78,    -1,    77,   103,     8,   103,    78,    -1,
+     106,    -1,   110,    77,   103,    78,    -1,   110,    77,   109,
+      78,    -1,    70,   108,    77,   109,    78,    -1,    70,     6,
+       7,   108,    77,    38,    78,    -1,    -1,    76,    -1,    -1,
+       8,   110,    -1,     9,   110,    -1,    38,    -1,    37,    -1,
+      39,    -1,    36,    -1,    72,    -1,     9,   110,    -1,     8,
+     110,    -1,    80,   110,    -1,    77,   111,    78,    -1,   110,
+      -1,   111,     8,   111,    -1,   111,     9,   111,    -1,   111,
+      10,   111,    -1,   111,    11,   111,    -1,   111,    12,   111,
+      -1,   111,     6,     6,   111,    -1,   111,     7,     7,   111,
+      -1,   111,     5,   111,    -1,   111,     4,   111,    -1,   111,
+       3,   111,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,    66,    66,    67,    71,    70,    79,    84,    90,    94,
+      95,    96,   102,   106,   110,   114,   118,   122,   129,   133,
+     137,   141,   145,   149,   156,   160,   164,   168,   175,   179,
+     186,   190,   194,   198,   202,   206,   213,   217,   221,   231,
+     235,   239,   243,   247,   251,   255,   259,   263,   267,   271,
+     275,   279,   286,   293,   297,   304,   308,   316,   320,   324,
+     328,   332,   336,   340,   344,   353,   357,   361,   365,   369,
+     373,   377,   381,   385,   389,   393,   397,   401,   409,   417,
+     428,   432,   436,   440,   447,   451,   455,   459,   463,   467,
+     474,   478,   482,   486,   493,   497,   501,   505,   512,   516,
+     524,   528,   532,   536,   540,   544,   548,   555,   559,   563,
+     567,   571,   575,   582,   586,   593,   602,   613,   620,   625,
+     632,   642,   646,   650,   657,   663,   669,   680,   688,   689,
+     692,   700,   708,   716,   723,   729,   735,   738,   746,   754,
+     760,   768,   774,   782,   790,   811,   816,   824,   830,   837,
+     845,   846,   854,   861,   871,   872,   881,   889,   897,   906,
+     907,   910,   913,   917,   923,   924,   925,   928,   929,   933,
+     937,   941,   945,   951,   952,   956,   960,   964,   968,   972,
+     976,   980,   984,   988
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "'|'", "'^'", "'&'", "'<'", "'>'", "'+'",
+  "'-'", "'*'", "'/'", "'%'", "LMOVW", "LMOVB", "LABS", "LLOGW", "LSHW",
+  "LADDW", "LCMP", "LCROP", "LBRA", "LFMOV", "LFCONV", "LFCMP", "LFADD",
+  "LFMA", "LTRAP", "LXORW", "LNOP", "LEND", "LRETT", "LWORD", "LTEXT",
+  "LDATA", "LRETRN", "LCONST", "LSP", "LSB", "LFP", "LPC", "LCREG",
+  "LFLUSH", "LREG", "LFREG", "LR", "LCR", "LF", "LFPSCR", "LLR", "LCTR",
+  "LSPR", "LSPREG", "LSEG", "LMSR", "LPCDAT", "LFUNCDAT", "LSCHED", "LXLD",
+  "LXST", "LXOP", "LXMV", "LRLWM", "LMOVMW", "LMOVEM", "LMOVFL", "LMTFSB",
+  "LMA", "LFCONST", "LSCONST", "LNAME", "LLAB", "LVAR", "':'", "'='",
+  "';'", "','", "'('", "')'", "'$'", "'~'", "$accept", "prog", "line",
+  "@1", "inst", "rel", "rreg", "xlreg", "lr", "lcr", "ctr", "msr", "psr",
+  "fpscr", "fpscrf", "freg", "creg", "cbit", "mask", "ximm", "fimm", "imm",
+  "sreg", "regaddr", "addr", "name", "comma", "offset", "pointer", "con",
+  "expr", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   124,    94,    38,    60,    62,    43,    45,
+      42,    47,    37,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
+     315,   316,   317,    58,    61,    59,    44,    40,    41,    36,
+     126
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    81,    82,    82,    84,    83,    83,    83,    83,    83,
+      83,    83,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    85,    85,    85,    85,    85,
+      85,    85,    85,    85,    85,    86,    86,    87,    88,    88,
+      89,    90,    91,    92,    93,    93,    93,    94,    95,    96,
+      96,    97,    97,    98,    99,   100,   100,   101,   101,   102,
+     103,   103,   104,   104,   105,   105,   106,   106,   106,   107,
+     107,   108,   108,   108,   109,   109,   109,   110,   110,   110,
+     110,   110,   110,   111,   111,   111,   111,   111,   111,   111,
+     111,   111,   111,   111
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     0,     4,     4,     4,     2,     1,
+       2,     2,     4,     4,     4,     4,     4,     4,     4,     4,
+       4,     4,     4,     4,     4,     4,     4,     4,     4,     4,
+       4,     4,     6,     4,     4,     4,     6,     4,     4,     6,
+       6,     6,     4,     4,     6,     4,     6,     4,     6,     4,
+       4,     2,     6,     4,     4,     4,     6,     4,     4,     4,
+       4,     4,     4,     4,     4,     2,     2,     4,     3,     3,
+       5,     4,     4,     6,     4,     4,     6,     6,     6,     8,
+       4,     4,     3,     2,     4,     4,     6,     8,     4,     6,
+       4,     4,     6,     6,     8,     8,     8,     8,     4,     4,
+       4,     6,     4,     6,     4,     4,     2,     2,     3,     3,
+       3,     3,     2,     3,     3,     4,     4,     2,     4,     6,
+       8,     6,     6,     6,     2,     4,     2,     1,     1,     1,
+       1,     1,     1,     1,     1,     4,     1,     1,     4,     1,
+       4,     1,     4,     1,     3,     2,     2,     2,     3,     2,
+       1,     4,     3,     5,     1,     4,     4,     5,     7,     0,
+       1,     0,     2,     2,     1,     1,     1,     1,     1,     2,
+       2,     2,     3,     1,     3,     3,     3,     3,     3,     4,
+       4,     3,     3,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       2,     0,     1,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   159,   159,
+     159,     0,     0,     0,   159,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     9,     3,
+       0,    11,     0,     0,   167,   141,   150,   139,     0,   131,
+       0,   137,   130,   132,     0,   134,   133,   161,   168,     0,
+       0,     0,     0,     0,   128,     0,   129,   136,     0,     0,
+       0,     0,     0,     0,   127,     0,     0,   154,     0,     0,
+       0,     0,    51,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   143,     0,   161,     0,     0,    65,     0,    66,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     160,   159,     0,    83,   160,   159,   159,   112,   107,   117,
+     159,   159,     0,     0,     0,   124,     0,     0,     8,     0,
+       0,     0,   106,     0,     0,     0,     0,     0,     0,     0,
+       0,     4,     0,     0,    10,   170,   169,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   173,     0,   146,   145,
+     149,   171,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   149,
+       0,     0,     0,     0,     0,     0,   126,     0,    68,    69,
+       0,     0,     0,     0,     0,     0,   147,     0,     0,     0,
+       0,     0,     0,     0,     0,   160,    82,     0,   110,   111,
+     108,   109,   114,   113,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   161,   162,   163,     0,
+       0,   152,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   172,    12,    62,    38,    64,    37,     0,    25,
+      24,    61,    59,    60,    58,    30,    33,    31,     0,    29,
+      28,    63,    57,    54,     0,    53,    34,    14,    13,   165,
+     164,   166,     0,     0,    15,    27,    26,    17,    16,    50,
+      45,   127,    47,   127,    49,   127,    42,     0,   127,    43,
+     127,    90,    91,    55,   143,     0,    67,     0,    71,    72,
+       0,    74,    75,     0,     0,   148,    21,    23,    22,    20,
+      19,    18,    84,    88,    85,     0,    80,    81,   118,     0,
+       0,   115,   116,   100,     0,     0,   102,   105,   104,     0,
+       0,    99,    98,    35,     0,     5,     6,     7,   151,   142,
+     140,   135,     0,     0,     0,   183,   182,   181,     0,     0,
+     174,   175,   176,   177,   178,     0,     0,     0,   155,   156,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    70,
+       0,     0,     0,   125,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   157,   153,   179,   180,   131,
+      36,    32,     0,    44,    46,    48,    41,    39,    40,    92,
+      93,    56,    73,    76,     0,    77,    78,    89,    86,     0,
+     119,     0,   122,   123,   121,   101,   103,     0,     0,     0,
+       0,     0,    52,     0,   138,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   158,    79,    87,   120,    97,    96,
+     144,    95,    94
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,     1,    39,   229,    40,    97,    62,    63,    64,    65,
+      66,    67,    68,    69,   276,    70,    71,    91,   427,    72,
+     103,    73,    74,    75,   159,    77,   113,   154,   283,   156,
+     157
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -176
+static const yytype_int16 yypact[] =
+{
+    -176,   464,  -176,   -63,   560,   637,    97,    97,   -24,   -24,
+      97,   556,   317,   618,    12,    12,    12,    12,   -27,    47,
+     -47,   -29,   725,   725,   -47,   -26,   -26,   -43,   -17,    97,
+     -17,   -23,   -24,   658,   -26,    97,    51,   -11,  -176,  -176,
+      -2,  -176,   556,   556,  -176,  -176,  -176,  -176,    -1,     2,
+      11,  -176,  -176,  -176,    24,  -176,  -176,    91,  -176,    26,
+     716,   556,    57,    65,  -176,    85,  -176,  -176,    92,    98,
+     104,   110,   119,   134,  -176,   155,   160,  -176,    69,   162,
+     165,   170,   172,   176,   556,   179,   180,   182,   183,   185,
+     556,   187,  -176,     2,    91,   736,   326,  -176,   196,  -176,
+      52,     6,   197,   198,   202,   203,   215,   216,   217,   222,
+    -176,   223,   235,  -176,    73,   -47,   -47,  -176,  -176,  -176,
+     -47,   -47,   239,    79,   178,  -176,   240,   246,  -176,    97,
+     247,   248,  -176,   252,   253,   255,   262,   263,   266,   267,
+     268,  -176,   556,   556,  -176,  -176,  -176,   556,   556,   556,
+     556,   193,   556,   556,   166,     9,  -176,   278,  -176,  -176,
+      69,  -176,   607,    97,    97,   109,    20,   683,    61,    97,
+      27,    97,    97,   340,   637,    97,    97,    97,    97,  -176,
+      97,    97,   -24,    97,   -24,   556,   166,   326,  -176,  -176,
+     199,   152,   742,   762,   153,   283,  -176,   696,    12,    12,
+      12,    12,    12,    12,    12,    97,  -176,    97,  -176,  -176,
+    -176,  -176,  -176,  -176,   382,     4,   556,   -26,   725,   -24,
+      72,   -17,    97,    97,    97,   725,    97,   556,    97,   527,
+     436,   567,   274,   276,   277,   279,   154,  -176,  -176,     4,
+      97,  -176,   556,   556,   556,   353,   339,   556,   556,   556,
+     556,   556,  -176,  -176,  -176,  -176,  -176,  -176,   284,  -176,
+    -176,  -176,  -176,  -176,  -176,  -176,  -176,  -176,   295,  -176,
+    -176,  -176,  -176,  -176,   303,  -176,  -176,  -176,  -176,  -176,
+    -176,  -176,   304,   308,  -176,  -176,  -176,  -176,  -176,  -176,
+    -176,   305,  -176,   316,  -176,   323,  -176,   325,   333,  -176,
+     334,   335,   336,  -176,   343,   342,  -176,   326,  -176,  -176,
+     326,  -176,  -176,   139,   344,  -176,  -176,  -176,  -176,  -176,
+    -176,  -176,  -176,   345,   348,   349,  -176,  -176,  -176,   354,
+     355,  -176,  -176,  -176,   356,   357,  -176,  -176,  -176,   360,
+     373,  -176,  -176,  -176,   374,  -176,  -176,  -176,  -176,  -176,
+    -176,  -176,   327,   377,   379,   298,   612,   506,   556,   556,
+     125,   125,  -176,  -176,  -176,   405,   410,   556,  -176,  -176,
+      97,    97,    97,    97,    97,    97,    -8,    -8,   556,  -176,
+     385,   388,   782,  -176,    -8,    12,    12,   -26,   381,    97,
+     -17,   382,   382,    97,   429,  -176,  -176,   498,   498,  -176,
+    -176,  -176,   390,  -176,  -176,  -176,  -176,  -176,  -176,  -176,
+    -176,  -176,  -176,  -176,   326,  -176,  -176,  -176,  -176,   393,
+     462,   712,  -176,  -176,  -176,  -176,  -176,   398,   399,   416,
+     419,   426,  -176,   451,  -176,   454,    12,   556,   328,    97,
+      97,   556,    97,    97,  -176,  -176,  -176,  -176,  -176,  -176,
+    -176,  -176,  -176
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -176,  -176,   306,  -176,  -176,   -88,    -5,   -73,  -176,  -154,
+    -176,  -176,  -137,  -158,  -176,    67,    39,  -175,   141,   -15,
+     149,   113,   167,    80,    32,   200,   124,   -83,   299,    35,
+      70
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
+static const yytype_uint16 yytable[] =
+{
+      79,    82,    83,    85,    87,    89,   120,   188,   255,   267,
+     303,   186,    41,   111,   115,   195,    46,   240,    48,    46,
+      46,    48,    48,   191,   131,   256,   133,   135,   137,   110,
+     140,   271,   128,    45,    42,    43,    76,    81,    93,    78,
+      78,   279,   280,   281,    99,   105,    92,   100,    78,   110,
+      60,    98,    84,    84,   129,    84,    47,   123,   123,    50,
+     129,    45,    44,   143,    47,   138,    93,    50,    78,    46,
+      46,    48,    48,   144,   196,   274,   147,   145,   146,   148,
+     102,   106,   107,   108,   109,    80,   116,   241,   149,   254,
+      46,    47,    48,   104,    50,   160,   161,   151,    58,   152,
+     153,   150,    45,    90,   308,   311,    61,    93,   130,   208,
+     132,   134,    54,    55,   305,    56,    46,    47,    48,   179,
+      50,    86,    88,   114,   141,   142,    84,   189,   193,   194,
+     190,   112,   117,   162,   121,   249,   250,   251,   126,   127,
+      46,   163,    48,   118,   119,   136,   173,   139,   125,   129,
+      45,    84,    46,   352,    48,    93,   215,   253,   261,   262,
+     263,   164,   152,   153,   273,   275,   277,   278,   165,   284,
+     287,   288,   289,   290,   166,   292,   294,   296,   299,   301,
+     167,   209,   232,   233,   234,   235,   168,   237,   238,   216,
+     279,   280,   281,   314,   260,   169,    46,    78,    48,   270,
+     236,   257,    78,   411,   264,   266,   286,   272,   401,    78,
+     170,   400,   230,   231,   333,   382,   194,   338,   339,   340,
+     304,   342,   122,   124,   309,   312,   155,   190,   313,   318,
+     306,   171,    78,   265,   380,   206,   172,   381,   174,   210,
+     211,   175,   259,   239,   212,   213,   176,   269,   177,   329,
+     332,   330,   178,    78,   285,   180,   181,   341,   182,   183,
+      78,   184,   343,   185,   316,   319,   320,   321,   322,   323,
+     324,   325,   192,   197,   198,   258,   194,   317,   199,   200,
+     268,   242,   243,   244,   245,   246,   247,   248,   249,   250,
+     251,   201,   202,   203,   415,   297,   155,   302,   204,   205,
+     336,   337,   243,   244,   245,   246,   247,   248,   249,   250,
+     251,   207,   355,   356,   357,   214,   217,   360,   361,   362,
+     363,   364,   218,   219,   220,    42,    43,   328,   221,   222,
+     331,   223,   334,   335,    42,    43,    42,    43,   224,   225,
+     282,   435,   226,   227,   228,   291,   359,   293,   295,   298,
+     300,   315,   348,    44,   349,   350,   252,   351,    45,   358,
+     365,   282,    44,    93,    44,   403,   404,   405,   406,   407,
+     408,   366,   326,   422,   327,    52,    53,   279,   280,   281,
+     367,   370,   368,    46,   425,    48,   369,    94,   432,    58,
+      42,    43,   371,    95,    96,   344,   315,    61,    58,   372,
+      58,   373,   402,    90,   394,    90,    61,   354,    61,   374,
+     375,   376,   377,    92,   416,   409,   410,   190,    44,   378,
+     379,   384,   383,   417,   385,   386,   429,   429,   397,   398,
+     387,   388,   389,   390,   448,   449,   391,   451,   452,   242,
+     243,   244,   245,   246,   247,   248,   249,   250,   251,   392,
+     393,   399,   418,   419,    58,   395,   160,   396,    51,    90,
+     421,    84,    61,   412,     2,     3,   413,   433,   434,   436,
+     426,   437,   447,   146,   439,   440,   450,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,   441,    19,    20,   442,    21,    22,    23,    24,
+     420,   424,   443,   446,   428,   431,   247,   248,   249,   250,
+     251,   346,   245,   246,   247,   248,   249,   250,   251,    25,
+      26,    27,    28,    29,    30,    31,    32,    33,     3,   444,
+      34,    35,   445,   430,    36,   345,    37,   423,   353,    38,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,     0,    19,    20,     0,    21,
+      22,    23,    24,     0,    42,    43,     0,     0,    42,    43,
+     242,   243,   244,   245,   246,   247,   248,   249,   250,   251,
+       0,     0,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,     0,    44,    34,    35,     0,    44,    36,     0,    37,
+       0,    45,    38,    46,    47,    48,    49,    50,    51,    52,
+      53,    54,    55,     0,    56,    42,    43,   244,   245,   246,
+     247,   248,   249,   250,   251,     0,    42,    43,    58,     0,
+      57,     0,    58,    90,     0,     0,    61,    59,     0,    60,
+      61,     0,   347,    44,     0,    42,    43,     0,    45,     0,
+      46,     0,    48,    49,    44,     0,    52,    53,    54,    55,
+       0,    56,    47,     0,     0,    50,    42,    43,     0,     0,
+       0,     0,     0,    44,     0,     0,     0,    57,     0,    58,
+      46,     0,    48,     0,    59,     0,    84,    61,    57,     0,
+      58,    42,    43,     0,    44,    59,     0,   101,    61,     0,
+       0,    46,     0,    48,    42,    43,     0,    57,     0,    58,
+       0,     0,     0,     0,    59,     0,     0,    61,     0,    44,
+      42,   438,     0,     0,    42,    43,     0,     0,    57,     0,
+      58,    51,    44,    42,    43,    90,     0,     0,    61,     0,
+      47,     0,     0,    50,    42,    43,     0,     0,    44,     0,
+      42,    43,    44,    57,     0,    58,     0,     0,     0,     0,
+      59,    44,    84,    61,     0,     0,    57,     0,    58,     0,
+      42,    43,    44,    59,     0,     0,    61,     0,    44,     0,
+     196,   158,    57,     0,    58,   158,    57,     0,    58,    90,
+      42,    43,    61,    90,     0,    57,    61,    58,    44,     0,
+       0,     0,    90,     0,     0,    61,    94,     0,    58,     0,
+       0,     0,    94,   187,    58,     0,    61,     0,    44,   307,
+       0,     0,    61,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    94,     0,    58,     0,     0,     0,     0,   310,
+       0,     0,    61,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    94,     0,    58,     0,     0,     0,     0,   414,
+       0,     0,    61
+};
+
+static const yytype_int16 yycheck[] =
+{
+       5,     6,     7,     8,     9,    10,    21,    95,   162,   167,
+     185,    94,    75,    18,    19,     9,    43,     8,    45,    43,
+      43,    45,    45,    96,    29,   162,    31,    32,    33,    76,
+      35,   168,    75,    41,     8,     9,     4,     5,    46,     4,
+       5,    37,    38,    39,    12,    13,    11,    12,    13,    76,
+      79,    12,    79,    79,    77,    79,    44,    22,    23,    47,
+      77,    41,    36,    74,    44,    33,    46,    47,    33,    43,
+      43,    45,    45,    75,    68,    48,    77,    42,    43,    77,
+      13,    14,    15,    16,    17,     5,    19,    78,    77,   162,
+      43,    44,    45,    13,    47,    60,    61,     6,    72,     8,
+       9,    77,    41,    77,   192,   193,    80,    46,    28,   114,
+      30,    31,    51,    52,   187,    54,    43,    44,    45,    84,
+      47,     8,     9,    76,    73,    74,    79,    95,    76,    77,
+      95,    18,    19,    76,    21,    10,    11,    12,    25,    26,
+      43,    76,    45,    19,    20,    32,    77,    34,    24,    77,
+      41,    79,    43,   236,    45,    46,    77,   162,   163,   164,
+     165,    76,     8,     9,   169,   170,   171,   172,    76,   174,
+     175,   176,   177,   178,    76,   180,   181,   182,   183,   184,
+      76,   114,   147,   148,   149,   150,    76,   152,   153,    11,
+      37,    38,    39,    40,   162,    76,    43,   162,    45,   167,
+       7,   162,   167,   378,   165,   166,   174,   168,   366,   174,
+      76,   365,   142,   143,   219,    76,    77,   222,   223,   224,
+     185,   226,    22,    23,   192,   193,    59,   192,   193,   197,
+      78,    76,   197,   166,   307,   111,    76,   310,    76,   115,
+     116,    76,   162,    77,   120,   121,    76,   167,    76,   214,
+     218,   216,    76,   218,   174,    76,    76,   225,    76,    76,
+     225,    76,   227,    76,   197,   198,   199,   200,   201,   202,
+     203,   204,    76,    76,    76,   162,    77,   197,    76,    76,
+     167,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    76,    76,    76,   382,   182,   129,   184,    76,    76,
+     220,   221,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    76,   242,   243,   244,    76,    76,   247,   248,   249,
+     250,   251,    76,    76,    76,     8,     9,   214,    76,    76,
+     217,    76,   219,   220,     8,     9,     8,     9,    76,    76,
+     173,   414,    76,    76,    76,   178,     7,   180,   181,   182,
+     183,    68,    78,    36,    78,    78,    78,    78,    41,     6,
+      76,   194,    36,    46,    36,   370,   371,   372,   373,   374,
+     375,    76,   205,   388,   207,    49,    50,    37,    38,    39,
+      77,    76,    78,    43,   389,    45,    78,    70,   393,    72,
+       8,     9,    76,    76,    77,   228,    68,    80,    72,    76,
+      72,    76,   367,    77,    77,    77,    80,   240,    80,    76,
+      76,    76,    76,   378,   382,   376,   377,   382,    36,    76,
+      78,    76,    78,   384,    76,    76,   391,   392,   358,   359,
+      76,    76,    76,    76,   439,   440,    76,   442,   443,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    76,
+      76,    46,   385,   386,    72,    78,   421,    78,    48,    77,
+      79,    79,    80,    78,     0,     1,    78,    38,    78,    76,
+     390,     9,   437,   438,    76,    76,   441,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
+      26,    27,    76,    29,    30,    76,    32,    33,    34,    35,
+     387,   388,    76,   436,   391,   392,     8,     9,    10,    11,
+      12,    75,     6,     7,     8,     9,    10,    11,    12,    55,
+      56,    57,    58,    59,    60,    61,    62,    63,     1,    78,
+      66,    67,    78,   392,    70,   229,    72,   388,   239,    75,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    -1,    29,    30,    -1,    32,
+      33,    34,    35,    -1,     8,     9,    -1,    -1,     8,     9,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      -1,    -1,    55,    56,    57,    58,    59,    60,    61,    62,
+      63,    -1,    36,    66,    67,    -1,    36,    70,    -1,    72,
+      -1,    41,    75,    43,    44,    45,    46,    47,    48,    49,
+      50,    51,    52,    -1,    54,     8,     9,     5,     6,     7,
+       8,     9,    10,    11,    12,    -1,     8,     9,    72,    -1,
+      70,    -1,    72,    77,    -1,    -1,    80,    77,    -1,    79,
+      80,    -1,    75,    36,    -1,     8,     9,    -1,    41,    -1,
+      43,    -1,    45,    46,    36,    -1,    49,    50,    51,    52,
+      -1,    54,    44,    -1,    -1,    47,     8,     9,    -1,    -1,
+      -1,    -1,    -1,    36,    -1,    -1,    -1,    70,    -1,    72,
+      43,    -1,    45,    -1,    77,    -1,    79,    80,    70,    -1,
+      72,     8,     9,    -1,    36,    77,    -1,    79,    80,    -1,
+      -1,    43,    -1,    45,     8,     9,    -1,    70,    -1,    72,
+      -1,    -1,    -1,    -1,    77,    -1,    -1,    80,    -1,    36,
+       8,     9,    -1,    -1,     8,     9,    -1,    -1,    70,    -1,
+      72,    48,    36,     8,     9,    77,    -1,    -1,    80,    -1,
+      44,    -1,    -1,    47,     8,     9,    -1,    -1,    36,    -1,
+       8,     9,    36,    70,    -1,    72,    -1,    -1,    -1,    -1,
+      77,    36,    79,    80,    -1,    -1,    70,    -1,    72,    -1,
+       8,     9,    36,    77,    -1,    -1,    80,    -1,    36,    -1,
+      68,    69,    70,    -1,    72,    69,    70,    -1,    72,    77,
+       8,     9,    80,    77,    -1,    70,    80,    72,    36,    -1,
+      -1,    -1,    77,    -1,    -1,    80,    70,    -1,    72,    -1,
+      -1,    -1,    70,    77,    72,    -1,    80,    -1,    36,    77,
+      -1,    -1,    80,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    70,    -1,    72,    -1,    -1,    -1,    -1,    77,
+      -1,    -1,    80,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    70,    -1,    72,    -1,    -1,    -1,    -1,    77,
+      -1,    -1,    80
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,    82,     0,     1,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    29,
+      30,    32,    33,    34,    35,    55,    56,    57,    58,    59,
+      60,    61,    62,    63,    66,    67,    70,    72,    75,    83,
+      85,    75,     8,     9,    36,    41,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    54,    70,    72,    77,
+      79,    80,    87,    88,    89,    90,    91,    92,    93,    94,
+      96,    97,   100,   102,   103,   104,   105,   106,   110,    87,
+     104,   105,    87,    87,    79,    87,   102,    87,   102,    87,
+      77,    98,   110,    46,    70,    76,    77,    86,    97,   105,
+     110,    79,    96,   101,   104,   105,    96,    96,    96,    96,
+      76,    87,   102,   107,    76,    87,    96,   102,   107,   107,
+     100,   102,   106,   110,   106,   107,   102,   102,    75,    77,
+     104,    87,   104,    87,   104,    87,   102,    87,   105,   102,
+      87,    73,    74,    74,    75,   110,   110,    77,    77,    77,
+      77,     6,     8,     9,   108,   103,   110,   111,    69,   105,
+     110,   110,    76,    76,    76,    76,    76,    76,    76,    76,
+      76,    76,    76,    77,    76,    76,    76,    76,    76,   110,
+      76,    76,    76,    76,    76,    76,   108,    77,    86,   105,
+     110,    88,    76,    76,    77,     9,    68,    76,    76,    76,
+      76,    76,    76,    76,    76,    76,   107,    76,    87,    96,
+     107,   107,   107,   107,    76,    77,    11,    76,    76,    76,
+      76,    76,    76,    76,    76,    76,    76,    76,    76,    84,
+     111,   111,   110,   110,   110,   110,     7,   110,   110,    77,
+       8,    78,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    78,    87,    88,    90,    93,    97,   102,   104,
+     105,    87,    87,    87,    97,    96,    97,    94,   102,   104,
+     105,    93,    97,    87,    48,    87,    95,    87,    87,    37,
+      38,    39,   103,   109,    87,   104,   105,    87,    87,    87,
+      87,   103,    87,   103,    87,   103,    87,   102,   103,    87,
+     103,    87,   102,    98,   110,    88,    78,    77,    86,   105,
+      77,    86,   105,   110,    40,    68,    96,   104,   105,    96,
+      96,    96,    96,    96,    96,    96,   103,   103,   102,   110,
+     110,   102,   105,    87,   102,   102,   104,   104,    87,    87,
+      87,   105,    87,   110,   103,    83,    75,    75,    78,    78,
+      78,    78,   108,   109,   103,   111,   111,   111,     6,     7,
+     111,   111,   111,   111,   111,    76,    76,    77,    78,    78,
+      76,    76,    76,    76,    76,    76,    76,    76,    76,    78,
+      88,    88,    76,    78,    76,    76,    76,    76,    76,    76,
+      76,    76,    76,    76,    77,    78,    78,   111,   111,    46,
+      90,    94,   110,    87,    87,    87,    87,    87,    87,    97,
+      97,    98,    78,    78,    77,    86,   105,    97,    96,    96,
+     102,    79,   100,   101,   102,    87,   104,    99,   102,   110,
+      99,   102,    87,    38,    78,    88,    76,     9,     9,    76,
+      76,    76,    76,    76,    78,    78,    96,   110,    87,    87,
+     110,    87,    87
+};
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                (-2)
+#define YYEOF          0
+
+#define YYACCEPT       goto yyacceptlab
+#define YYABORT                goto yyabortlab
+#define YYERROR                goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL         goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                 \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK (1);                                          \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;                                                 \
+    }                                                          \
+while (YYID (0))
+
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (YYID (N))                                                    \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+             (Loc).first_line, (Loc).first_column,     \
+             (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                       \
+do {                                           \
+  if (yydebug)                                 \
+    YYFPRINTF Args;                            \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                   \
+do {                                                                     \
+  if (yydebug)                                                           \
+    {                                                                    \
+      YYFPRINTF (stderr, "%s ", Title);                                          \
+      yy_symbol_print (stderr,                                           \
+                 Type, Value); \
+      YYFPRINTF (stderr, "\n");                                                  \
+    }                                                                    \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+       break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                           \
+do {                                                           \
+  if (yydebug)                                                 \
+    yy_stack_print ((Bottom), (Top));                          \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+            yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+                      &(yyvsp[(yyi + 1) - (yynrhs)])
+                                      );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)         \
+do {                                   \
+  if (yydebug)                         \
+    yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef        YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+       switch (*++yyp)
+         {
+         case '\'':
+         case ',':
+           goto do_not_strip_quotes;
+
+         case '\\':
+           if (*++yyp != '\\')
+             goto do_not_strip_quotes;
+           /* Fall through.  */
+         default:
+           if (yyres)
+             yyres[yyn] = *yyp;
+           yyn++;
+           break;
+
+         case '"':
+           if (yyres)
+             yyres[yyn] = '\0';
+           return yyn;
+         }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+        constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+                   + sizeof yyexpecting - 1
+                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                      * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+        YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+         {
+           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+             {
+               yycount = 1;
+               yysize = yysize0;
+               yyformat[sizeof yyunexpected - 1] = '\0';
+               break;
+             }
+           yyarg[yycount++] = yytname[yyx];
+           yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+           yysize_overflow |= (yysize1 < yysize);
+           yysize = yysize1;
+           yyfmt = yystpcpy (yyfmt, yyprefix);
+           yyprefix = yyor;
+         }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+       return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+       {
+         /* Avoid sprintf, as that infringes on the user's name space.
+            Don't have undefined behavior even if the translation
+            produced a string with the wrong number of "%s"s.  */
+         char *yyp = yyresult;
+         int yyi = 0;
+         while ((*yyp = *yyf) != '\0')
+           {
+             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+               {
+                 yyp += yytnamerr (yyp, yyarg[yyi++]);
+                 yyf += 2;
+               }
+             else
+               {
+                 yyp++;
+                 yyf++;
+               }
+           }
+       }
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+\f
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+       break;
+    }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;            /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+       /* Give user a chance to reallocate the stack.  Use copies of
+          these so that the &'s don't force the real ones into
+          memory.  */
+       YYSTYPE *yyvs1 = yyvs;
+       yytype_int16 *yyss1 = yyss;
+
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  This used to be a
+          conditional around just the two extra args, but that might
+          be undefined if yyoverflow is a macro.  */
+       yyoverflow (YY_("memory exhausted"),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+
+                   &yystacksize);
+
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+       goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+       yystacksize = YYMAXDEPTH;
+
+      {
+       yytype_int16 *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyexhaustedlab;
+       YYSTACK_RELOCATE (yyss);
+       YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+       YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 4:
+#line 71 "a.y"
+    {
+               (yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
+               if((yyvsp[(1) - (2)].sym)->type == LLAB && (yyvsp[(1) - (2)].sym)->value != pc)
+                       yyerror("redeclaration of %s", (yyvsp[(1) - (2)].sym)->labelname);
+               (yyvsp[(1) - (2)].sym)->type = LLAB;
+               (yyvsp[(1) - (2)].sym)->value = pc;
+       }
+    break;
+
+  case 6:
+#line 80 "a.y"
+    {
+               (yyvsp[(1) - (4)].sym)->type = LVAR;
+               (yyvsp[(1) - (4)].sym)->value = (yyvsp[(3) - (4)].lval);
+       }
+    break;
+
+  case 7:
+#line 85 "a.y"
+    {
+               if((yyvsp[(1) - (4)].sym)->value != (yyvsp[(3) - (4)].lval))
+                       yyerror("redeclaration of %s", (yyvsp[(1) - (4)].sym)->name);
+               (yyvsp[(1) - (4)].sym)->value = (yyvsp[(3) - (4)].lval);
+       }
+    break;
+
+  case 8:
+#line 91 "a.y"
+    {
+               nosched = (yyvsp[(1) - (2)].lval);
+       }
+    break;
+
+  case 12:
+#line 103 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 13:
+#line 107 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 14:
+#line 111 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 15:
+#line 115 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 16:
+#line 119 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 17:
+#line 123 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 18:
+#line 130 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 19:
+#line 134 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 20:
+#line 138 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 21:
+#line 142 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 22:
+#line 146 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 23:
+#line 150 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 24:
+#line 157 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 25:
+#line 161 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 26:
+#line 165 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 27:
+#line 169 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 28:
+#line 176 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 29:
+#line 180 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 30:
+#line 187 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 31:
+#line 191 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 32:
+#line 195 "a.y"
+    {
+               outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), NREG, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 33:
+#line 199 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 34:
+#line 203 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 35:
+#line 207 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), (yyvsp[(4) - (4)].lval), &nullgen);
+       }
+    break;
+
+  case 36:
+#line 214 "a.y"
+    {
+               outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), NREG, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 37:
+#line 218 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 38:
+#line 222 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 39:
+#line 232 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 40:
+#line 236 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 41:
+#line 240 "a.y"
+    {
+               outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), NREG, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 42:
+#line 244 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 43:
+#line 248 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 44:
+#line 252 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 45:
+#line 256 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 46:
+#line 260 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 47:
+#line 264 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 48:
+#line 268 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 49:
+#line 272 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 50:
+#line 276 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 51:
+#line 280 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr), NREG, &(yyvsp[(2) - (2)].addr));
+       }
+    break;
+
+  case 52:
+#line 287 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 53:
+#line 294 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 54:
+#line 298 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 55:
+#line 305 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), (yyvsp[(4) - (4)].addr).reg, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 56:
+#line 309 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 57:
+#line 317 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 58:
+#line 321 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 59:
+#line 325 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 60:
+#line 329 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 61:
+#line 333 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 62:
+#line 337 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 63:
+#line 341 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 64:
+#line 345 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 65:
+#line 354 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &nullgen, NREG, &(yyvsp[(2) - (2)].addr));
+       }
+    break;
+
+  case 66:
+#line 358 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &nullgen, NREG, &(yyvsp[(2) - (2)].addr));
+       }
+    break;
+
+  case 67:
+#line 362 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &nullgen, NREG, &(yyvsp[(3) - (4)].addr));
+       }
+    break;
+
+  case 68:
+#line 366 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
+       }
+    break;
+
+  case 69:
+#line 370 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
+       }
+    break;
+
+  case 70:
+#line 374 "a.y"
+    {
+               outcode((yyvsp[(1) - (5)].lval), &nullgen, NREG, &(yyvsp[(4) - (5)].addr));
+       }
+    break;
+
+  case 71:
+#line 378 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 72:
+#line 382 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 73:
+#line 386 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), NREG, &(yyvsp[(5) - (6)].addr));
+       }
+    break;
+
+  case 74:
+#line 390 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &nullgen, (yyvsp[(2) - (4)].lval), &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 75:
+#line 394 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &nullgen, (yyvsp[(2) - (4)].lval), &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 76:
+#line 398 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &nullgen, (yyvsp[(2) - (6)].lval), &(yyvsp[(5) - (6)].addr));
+       }
+    break;
+
+  case 77:
+#line 402 "a.y"
+    {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = (yyvsp[(2) - (6)].lval);
+               outcode((yyvsp[(1) - (6)].lval), &g, (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 78:
+#line 410 "a.y"
+    {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = (yyvsp[(2) - (6)].lval);
+               outcode((yyvsp[(1) - (6)].lval), &g, (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 79:
+#line 418 "a.y"
+    {
+               Addr g;
+               g = nullgen;
+               g.type = D_CONST;
+               g.offset = (yyvsp[(2) - (8)].lval);
+               outcode((yyvsp[(1) - (8)].lval), &g, (yyvsp[(4) - (8)].lval), &(yyvsp[(7) - (8)].addr));
+       }
+    break;
+
+  case 80:
+#line 429 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), (yyvsp[(4) - (4)].lval), &nullgen);
+       }
+    break;
+
+  case 81:
+#line 433 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), (yyvsp[(4) - (4)].lval), &nullgen);
+       }
+    break;
+
+  case 82:
+#line 437 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), NREG, &nullgen);
+       }
+    break;
+
+  case 83:
+#line 441 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &nullgen, NREG, &nullgen);
+       }
+    break;
+
+  case 84:
+#line 448 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 85:
+#line 452 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 86:
+#line 456 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].addr).reg, &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 87:
+#line 460 "a.y"
+    {
+               outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
+       }
+    break;
+
+  case 88:
+#line 464 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 89:
+#line 468 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(4) - (6)].addr));
+       }
+    break;
+
+  case 90:
+#line 475 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 91:
+#line 479 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 92:
+#line 483 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(4) - (6)].addr));
+       }
+    break;
+
+  case 93:
+#line 487 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(4) - (6)].addr));
+       }
+    break;
+
+  case 94:
+#line 494 "a.y"
+    {
+               outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
+       }
+    break;
+
+  case 95:
+#line 498 "a.y"
+    {
+               outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
+       }
+    break;
+
+  case 96:
+#line 502 "a.y"
+    {
+               outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
+       }
+    break;
+
+  case 97:
+#line 506 "a.y"
+    {
+               outgcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].addr).reg, &(yyvsp[(6) - (8)].addr), &(yyvsp[(8) - (8)].addr));
+       }
+    break;
+
+  case 98:
+#line 513 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 99:
+#line 517 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 100:
+#line 525 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 101:
+#line 529 "a.y"
+    {
+               outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), NREG, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 102:
+#line 533 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 103:
+#line 537 "a.y"
+    {
+               outgcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), NREG, &(yyvsp[(4) - (6)].addr), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 104:
+#line 541 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 105:
+#line 545 "a.y"
+    {
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 106:
+#line 549 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr), NREG, &nullgen);
+       }
+    break;
+
+  case 107:
+#line 556 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &nullgen, NREG, &nullgen);
+       }
+    break;
+
+  case 108:
+#line 560 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), NREG, &nullgen);
+       }
+    break;
+
+  case 109:
+#line 564 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), NREG, &nullgen);
+       }
+    break;
+
+  case 110:
+#line 568 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
+       }
+    break;
+
+  case 111:
+#line 572 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
+       }
+    break;
+
+  case 112:
+#line 576 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr), NREG, &nullgen);
+       }
+    break;
+
+  case 113:
+#line 583 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), NREG, &nullgen);
+       }
+    break;
+
+  case 114:
+#line 587 "a.y"
+    {
+               outcode((yyvsp[(1) - (3)].lval), &(yyvsp[(2) - (3)].addr), NREG, &nullgen);
+       }
+    break;
+
+  case 115:
+#line 594 "a.y"
+    {
+               if((yyvsp[(2) - (4)].addr).type != D_CONST || (yyvsp[(4) - (4)].addr).type != D_CONST)
+                       yyerror("arguments to PCDATA must be integer constants");
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 116:
+#line 603 "a.y"
+    {
+               if((yyvsp[(2) - (4)].addr).type != D_CONST)
+                       yyerror("index for FUNCDATA must be integer constant");
+               if((yyvsp[(4) - (4)].addr).type != D_EXTERN && (yyvsp[(4) - (4)].addr).type != D_STATIC && (yyvsp[(4) - (4)].addr).type != D_OREG)
+                       yyerror("value for FUNCDATA must be symbol reference");
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 117:
+#line 614 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &nullgen, NREG, &nullgen);
+       }
+    break;
+
+  case 118:
+#line 621 "a.y"
+    {
+               settext((yyvsp[(2) - (4)].addr).sym);
+               outcode((yyvsp[(1) - (4)].lval), &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+       }
+    break;
+
+  case 119:
+#line 626 "a.y"
+    {
+               settext((yyvsp[(2) - (6)].addr).sym);
+               (yyvsp[(6) - (6)].addr).offset &= 0xffffffffull;
+               (yyvsp[(6) - (6)].addr).offset |= (vlong)ArgsSizeUnknown << 32;
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 120:
+#line 633 "a.y"
+    {
+               settext((yyvsp[(2) - (8)].addr).sym);
+               (yyvsp[(6) - (8)].addr).offset &= 0xffffffffull;
+               (yyvsp[(6) - (8)].addr).offset |= ((yyvsp[(8) - (8)].lval) & 0xffffffffull) << 32;
+               outcode((yyvsp[(1) - (8)].lval), &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].lval), &(yyvsp[(6) - (8)].addr));
+       }
+    break;
+
+  case 121:
+#line 643 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 122:
+#line 647 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 123:
+#line 651 "a.y"
+    {
+               outcode((yyvsp[(1) - (6)].lval), &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
+       }
+    break;
+
+  case 124:
+#line 658 "a.y"
+    {
+               outcode((yyvsp[(1) - (2)].lval), &nullgen, NREG, &nullgen);
+       }
+    break;
+
+  case 125:
+#line 664 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_BRANCH;
+               (yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
+       }
+    break;
+
+  case 126:
+#line 670 "a.y"
+    {
+               (yyvsp[(1) - (2)].sym) = labellookup((yyvsp[(1) - (2)].sym));
+               (yyval.addr) = nullgen;
+               if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
+                       yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
+               (yyval.addr).type = D_BRANCH;
+               (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
+       }
+    break;
+
+  case 127:
+#line 681 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_REG;
+               (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
+       }
+    break;
+
+  case 130:
+#line 693 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_SPR;
+               (yyval.addr).offset = (yyvsp[(1) - (1)].lval);
+       }
+    break;
+
+  case 131:
+#line 701 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_CREG;
+               (yyval.addr).reg = NREG;        /* whole register */
+       }
+    break;
+
+  case 132:
+#line 709 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_SPR;
+               (yyval.addr).offset = (yyvsp[(1) - (1)].lval);
+       }
+    break;
+
+  case 133:
+#line 717 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_MSR;
+       }
+    break;
+
+  case 134:
+#line 724 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_SPR;
+               (yyval.addr).offset = (yyvsp[(1) - (1)].lval);
+       }
+    break;
+
+  case 135:
+#line 730 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = (yyvsp[(1) - (4)].lval);
+               (yyval.addr).offset = (yyvsp[(3) - (4)].lval);
+       }
+    break;
+
+  case 137:
+#line 739 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_FPSCR;
+               (yyval.addr).reg = NREG;
+       }
+    break;
+
+  case 138:
+#line 747 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_FPSCR;
+               (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
+       }
+    break;
+
+  case 139:
+#line 755 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_FREG;
+               (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
+       }
+    break;
+
+  case 140:
+#line 761 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_FREG;
+               (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
+       }
+    break;
+
+  case 141:
+#line 769 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_CREG;
+               (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
+       }
+    break;
+
+  case 142:
+#line 775 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_CREG;
+               (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
+       }
+    break;
+
+  case 143:
+#line 783 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_REG;
+               (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
+       }
+    break;
+
+  case 144:
+#line 791 "a.y"
+    {
+               int mb, me;
+               uint32 v;
+
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_CONST;
+               mb = (yyvsp[(1) - (3)].lval);
+               me = (yyvsp[(3) - (3)].lval);
+               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))));
+               (yyval.addr).offset = v;
+       }
+    break;
+
+  case 145:
+#line 812 "a.y"
+    {
+               (yyval.addr) = (yyvsp[(2) - (2)].addr);
+               (yyval.addr).type = D_CONST;
+       }
+    break;
+
+  case 146:
+#line 817 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_SCONST;
+               memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
+       }
+    break;
+
+  case 147:
+#line 825 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_FCONST;
+               (yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
+       }
+    break;
+
+  case 148:
+#line 831 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_FCONST;
+               (yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
+       }
+    break;
+
+  case 149:
+#line 838 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_CONST;
+               (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
+       }
+    break;
+
+  case 151:
+#line 847 "a.y"
+    {
+               if((yyval.lval) < 0 || (yyval.lval) >= NREG)
+                       print("register value out of range\n");
+               (yyval.lval) = (yyvsp[(3) - (4)].lval);
+       }
+    break;
+
+  case 152:
+#line 855 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_OREG;
+               (yyval.addr).reg = (yyvsp[(2) - (3)].lval);
+               (yyval.addr).offset = 0;
+       }
+    break;
+
+  case 153:
+#line 862 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_OREG;
+               (yyval.addr).reg = (yyvsp[(2) - (5)].lval);
+               (yyval.addr).scale = (yyvsp[(4) - (5)].lval);
+               (yyval.addr).offset = 0;
+       }
+    break;
+
+  case 155:
+#line 873 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_OREG;
+               (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
+               (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
+       }
+    break;
+
+  case 156:
+#line 882 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_OREG;
+               (yyval.addr).name = (yyvsp[(3) - (4)].lval);
+               (yyval.addr).sym = nil;
+               (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
+       }
+    break;
+
+  case 157:
+#line 890 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_OREG;
+               (yyval.addr).name = (yyvsp[(4) - (5)].lval);
+               (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
+               (yyval.addr).offset = (yyvsp[(2) - (5)].lval);
+       }
+    break;
+
+  case 158:
+#line 898 "a.y"
+    {
+               (yyval.addr) = nullgen;
+               (yyval.addr).type = D_OREG;
+               (yyval.addr).name = D_STATIC;
+               (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 0);
+               (yyval.addr).offset = (yyvsp[(4) - (7)].lval);
+       }
+    break;
+
+  case 161:
+#line 910 "a.y"
+    {
+               (yyval.lval) = 0;
+       }
+    break;
+
+  case 162:
+#line 914 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(2) - (2)].lval);
+       }
+    break;
+
+  case 163:
+#line 918 "a.y"
+    {
+               (yyval.lval) = -(yyvsp[(2) - (2)].lval);
+       }
+    break;
+
+  case 168:
+#line 930 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
+       }
+    break;
+
+  case 169:
+#line 934 "a.y"
+    {
+               (yyval.lval) = -(yyvsp[(2) - (2)].lval);
+       }
+    break;
+
+  case 170:
+#line 938 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(2) - (2)].lval);
+       }
+    break;
+
+  case 171:
+#line 942 "a.y"
+    {
+               (yyval.lval) = ~(yyvsp[(2) - (2)].lval);
+       }
+    break;
+
+  case 172:
+#line 946 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(2) - (3)].lval);
+       }
+    break;
+
+  case 174:
+#line 953 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
+       }
+    break;
+
+  case 175:
+#line 957 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
+       }
+    break;
+
+  case 176:
+#line 961 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
+       }
+    break;
+
+  case 177:
+#line 965 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
+       }
+    break;
+
+  case 178:
+#line 969 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
+       }
+    break;
+
+  case 179:
+#line 973 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
+       }
+    break;
+
+  case 180:
+#line 977 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
+       }
+    break;
+
+  case 181:
+#line 981 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
+       }
+    break;
+
+  case 182:
+#line 985 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
+       }
+    break;
+
+  case 183:
+#line 989 "a.y"
+    {
+               (yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
+       }
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 3185 "y.tab.c"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+         {
+           YYSIZE_T yyalloc = 2 * yysize;
+           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+             yyalloc = YYSTACK_ALLOC_MAXIMUM;
+           if (yymsg != yymsgbuf)
+             YYSTACK_FREE (yymsg);
+           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+           if (yymsg)
+             yymsg_alloc = yyalloc;
+           else
+             {
+               yymsg = yymsgbuf;
+               yymsg_alloc = sizeof yymsgbuf;
+             }
+         }
+
+       if (0 < yysize && yysize <= yymsg_alloc)
+         {
+           (void) yysyntax_error (yymsg, yystate, yychar);
+           yyerror (yymsg);
+         }
+       else
+         {
+           yyerror (YY_("syntax error"));
+           if (yysize != 0)
+             goto yyexhaustedlab;
+         }
+      }
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+        error, discard it.  */
+
+      if (yychar <= YYEOF)
+       {
+         /* Return failure if at end of input.  */
+         if (yychar == YYEOF)
+           YYABORT;
+       }
+      else
+       {
+         yydestruct ("Error: discarding",
+                     yytoken, &yylval);
+         yychar = YYEMPTY;
+       }
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+       {
+         yyn += YYTERROR;
+         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+           {
+             yyn = yytable[yyn];
+             if (0 < yyn)
+               break;
+           }
+       }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+       YYABORT;
+
+
+      yydestruct ("Error: popping",
+                 yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                 yystos[*yyssp], yyvsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
diff --git a/src/cmd/9a/y.tab.h b/src/cmd/9a/y.tab.h
new file mode 100644 (file)
index 0000000..e6b93a2
--- /dev/null
@@ -0,0 +1,188 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     LMOVW = 258,
+     LMOVB = 259,
+     LABS = 260,
+     LLOGW = 261,
+     LSHW = 262,
+     LADDW = 263,
+     LCMP = 264,
+     LCROP = 265,
+     LBRA = 266,
+     LFMOV = 267,
+     LFCONV = 268,
+     LFCMP = 269,
+     LFADD = 270,
+     LFMA = 271,
+     LTRAP = 272,
+     LXORW = 273,
+     LNOP = 274,
+     LEND = 275,
+     LRETT = 276,
+     LWORD = 277,
+     LTEXT = 278,
+     LDATA = 279,
+     LRETRN = 280,
+     LCONST = 281,
+     LSP = 282,
+     LSB = 283,
+     LFP = 284,
+     LPC = 285,
+     LCREG = 286,
+     LFLUSH = 287,
+     LREG = 288,
+     LFREG = 289,
+     LR = 290,
+     LCR = 291,
+     LF = 292,
+     LFPSCR = 293,
+     LLR = 294,
+     LCTR = 295,
+     LSPR = 296,
+     LSPREG = 297,
+     LSEG = 298,
+     LMSR = 299,
+     LPCDAT = 300,
+     LFUNCDAT = 301,
+     LSCHED = 302,
+     LXLD = 303,
+     LXST = 304,
+     LXOP = 305,
+     LXMV = 306,
+     LRLWM = 307,
+     LMOVMW = 308,
+     LMOVEM = 309,
+     LMOVFL = 310,
+     LMTFSB = 311,
+     LMA = 312,
+     LFCONST = 313,
+     LSCONST = 314,
+     LNAME = 315,
+     LLAB = 316,
+     LVAR = 317
+   };
+#endif
+/* Tokens.  */
+#define LMOVW 258
+#define LMOVB 259
+#define LABS 260
+#define LLOGW 261
+#define LSHW 262
+#define LADDW 263
+#define LCMP 264
+#define LCROP 265
+#define LBRA 266
+#define LFMOV 267
+#define LFCONV 268
+#define LFCMP 269
+#define LFADD 270
+#define LFMA 271
+#define LTRAP 272
+#define LXORW 273
+#define LNOP 274
+#define LEND 275
+#define LRETT 276
+#define LWORD 277
+#define LTEXT 278
+#define LDATA 279
+#define LRETRN 280
+#define LCONST 281
+#define LSP 282
+#define LSB 283
+#define LFP 284
+#define LPC 285
+#define LCREG 286
+#define LFLUSH 287
+#define LREG 288
+#define LFREG 289
+#define LR 290
+#define LCR 291
+#define LF 292
+#define LFPSCR 293
+#define LLR 294
+#define LCTR 295
+#define LSPR 296
+#define LSPREG 297
+#define LSEG 298
+#define LMSR 299
+#define LPCDAT 300
+#define LFUNCDAT 301
+#define LSCHED 302
+#define LXLD 303
+#define LXST 304
+#define LXOP 305
+#define LXMV 306
+#define LRLWM 307
+#define LMOVMW 308
+#define LMOVEM 309
+#define LMOVFL 310
+#define LMTFSB 311
+#define LMA 312
+#define LFCONST 313
+#define LSCONST 314
+#define LNAME 315
+#define LLAB 316
+#define LVAR 317
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 38 "a.y"
+{
+       Sym     *sym;
+       vlong   lval;
+       double  dval;
+       char    sval[8];
+       Addr    addr;
+}
+/* Line 1529 of yacc.c.  */
+#line 181 "y.tab.h"
+       YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
diff --git a/src/cmd/9c/Makefile b/src/cmd/9c/Makefile
new file mode 100644 (file)
index 0000000..3f528d7
--- /dev/null
@@ -0,0 +1,5 @@
+# Copyright 2012 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include ../../Make.dist
diff --git a/src/cmd/9c/Notes b/src/cmd/9c/Notes
new file mode 100644 (file)
index 0000000..92dd9de
--- /dev/null
@@ -0,0 +1,14 @@
+-      effect of register expansion on 32-bit shifts and masks etc
+9c
+-      multab
+-      floating-point conversions
+-      conversions of constants
+-      nodtype for loads
+-      sign-extension instruction (32-64) when in register?
+-      double indexing
+-      SLW (eg, in cat)
+-      scheduling
+
+9l
+-      D_QCONST, DWORD
+-      maskgen
diff --git a/src/cmd/9c/cgen.c b/src/cmd/9c/cgen.c
new file mode 100644 (file)
index 0000000..bd1f7b2
--- /dev/null
@@ -0,0 +1,1147 @@
+// cmd/9c/cgen.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.
+
+#include "gc.h"
+#include "../../runtime/funcdata.h"
+
+void
+cgen(Node *n, Node *nn)
+{
+       Node *l, *r;
+       Prog *p1;
+       Node nod, nod1, nod2, nod3, nod4;
+       int o;
+       int32 v, curs;
+
+       if(debug['g']) {
+               prtree(nn, "cgen lhs");
+               prtree(n, "cgen");
+       }
+       if(n == Z || n->type == T)
+               return;
+       if(typesu[n->type->etype] && (n->op != OFUNC || nn != Z)) {
+               sugen(n, nn, n->type->width);
+               return;
+       }
+       l = n->left;
+       r = n->right;
+       o = n->op;
+       if(n->addable >= INDEXED) {
+               if(nn == Z) {
+                       switch(o) {
+                       default:
+                               nullwarn(Z, Z);
+                               break;
+                       case OINDEX:
+                               nullwarn(l, r);
+                               break;
+                       }
+                       return;
+               }
+               gmove(n, nn);
+               return;
+       }
+       curs = cursafe;
+
+       if(n->complex >= FNX)
+       if(l->complex >= FNX)
+       if(r != Z && r->complex >= FNX)
+       switch(o) {
+       default:
+               regret(&nod, r, 0, 0);
+               cgen(r, &nod);
+
+               regsalloc(&nod1, r);
+               gopcode(OAS, &nod, Z, &nod1);
+
+               regfree(&nod);
+               nod = *n;
+               nod.right = &nod1;
+               cgen(&nod, nn);
+               return;
+
+       case OFUNC:
+       case OCOMMA:
+       case OANDAND:
+       case OOROR:
+       case OCOND:
+       case ODOT:
+               break;
+       }
+
+       switch(o) {
+       default:
+               diag(n, "unknown op in cgen: %O", o);
+               break;
+
+       case OAS:
+               if(l->op == OBIT)
+                       goto bitas;
+               if(l->addable >= INDEXED) {
+                       if(nn != Z || r->addable < INDEXED) {
+                               regalloc(&nod, r, nn);
+                               cgen(r, &nod);
+                               gmove(&nod, l);
+                               regfree(&nod);
+                       } else
+                               gmove(r, l);
+                       break;
+               }
+               if(l->complex >= r->complex) {
+                       reglcgen(&nod1, l, Z);
+                       if(r->addable >= INDEXED) {
+                               gmove(r, &nod1);
+                               if(nn != Z)
+                                       gmove(r, nn);
+                               regfree(&nod1);
+                               break;
+                       }
+                       regalloc(&nod, r, nn);
+                       cgen(r, &nod);
+               } else {
+                       regalloc(&nod, r, nn);
+                       cgen(r, &nod);
+                       reglcgen(&nod1, l, Z);
+               }
+               gmove(&nod, &nod1);
+               regfree(&nod);
+               regfree(&nod1);
+               break;
+
+       bitas:
+               n = l->left;
+               regalloc(&nod, r, nn);
+               if(l->complex >= r->complex) {
+                       reglcgen(&nod1, n, Z);
+                       cgen(r, &nod);
+               } else {
+                       cgen(r, &nod);
+                       reglcgen(&nod1, n, Z);
+               }
+               regalloc(&nod2, n, Z);
+               gopcode(OAS, &nod1, Z, &nod2);
+               bitstore(l, &nod, &nod1, &nod2, nn);
+               break;
+
+       case OBIT:
+               if(nn == Z) {
+                       nullwarn(l, Z);
+                       break;
+               }
+               bitload(n, &nod, Z, Z, nn);
+               gopcode(OAS, &nod, Z, nn);
+               regfree(&nod);
+               break;
+
+       case OXOR:
+               if(nn != Z)
+               if(r->op == OCONST && r->vconst == -1){
+                       cgen(l, nn);
+                       gopcode(OCOM, nn, Z, nn);
+                       break;
+               }
+
+       case OADD:
+       case OSUB:
+       case OAND:
+       case OOR:
+       case OLSHR:
+       case OASHL:
+       case OASHR:
+               /*
+                * immediate operands
+                */
+               if(nn != Z &&
+                  r->op == OCONST &&
+                  !typefd[n->type->etype] &&
+                  immconst(r)) {
+                       cgen(l, nn);
+                       if(r->vconst == 0)
+                       if(o != OAND)
+                               break;
+                       if(nn != Z)
+                               gopcode(o, r, Z, nn);
+                       break;
+               }
+
+       case OMUL:
+       case OLMUL:
+       case OLDIV:
+       case OLMOD:
+       case ODIV:
+       case OMOD:
+               if(nn == Z) {
+                       nullwarn(l, r);
+                       break;
+               }
+               if(o == OMUL || o == OLMUL) {
+                       if(mulcon(n, nn))
+                               break;
+                       if(debug['M'])
+                               print("%L multiply\n", n->lineno);
+               }
+               if(l->complex >= r->complex) {
+                       regalloc(&nod, l, nn);
+                       cgen(l, &nod);
+                       regalloc(&nod1, l, Z);          /* note: l used for type, so shifts work! */
+                       cgen(r, &nod1);
+                       gopcode(o, &nod1, Z, &nod);
+               } else {
+                       regalloc(&nod, l, nn);          /* note: l used for type, so shifts work! */
+                       cgen(r, &nod);
+                       regalloc(&nod1, l, Z);
+                       cgen(l, &nod1);
+                       gopcode(o, &nod, &nod1, &nod);
+               }
+               gopcode(OAS, &nod, Z, nn);
+               regfree(&nod);
+               regfree(&nod1);
+               break;
+
+       case OASLSHR:
+       case OASASHL:
+       case OASASHR:
+       case OASAND:
+       case OASADD:
+       case OASSUB:
+       case OASXOR:
+       case OASOR:
+               if(l->op == OBIT)
+                       goto asbitop;
+               if(r->op == OCONST &&
+                  !typefd[n->type->etype] &&
+                  immconst(r)) {
+                       if(l->addable < INDEXED)
+                               reglcgen(&nod2, l, Z);
+                       else
+                               nod2 = *l;
+                       regalloc(&nod, l, nn);          /* note: l used for type, so shifts work! */
+                       gopcode(OAS, &nod2, Z, &nod);
+                       gopcode(o, r, Z, &nod);
+                       gopcode(OAS, &nod, Z, &nod2);
+       
+                       regfree(&nod);
+                       if(l->addable < INDEXED)
+                               regfree(&nod2);
+                       break;
+               }
+
+       case OASLMUL:
+       case OASLDIV:
+       case OASLMOD:
+       case OASMUL:
+       case OASDIV:
+       case OASMOD:
+               if(l->op == OBIT)
+                       goto asbitop;
+               if(l->complex >= r->complex) {
+                       if(l->addable < INDEXED)
+                               reglcgen(&nod2, l, Z);
+                       else
+                               nod2 = *l;
+                       regalloc(&nod, n, nn);
+                       cgen(r, &nod);
+               } else {
+                       regalloc(&nod, n, nn);
+                       cgen(r, &nod);
+                       if(l->addable < INDEXED)
+                               reglcgen(&nod2, l, Z);
+                       else
+                               nod2 = *l;
+               }
+               regalloc(&nod1, n, Z);
+               gopcode(OAS, &nod2, Z, &nod1);
+               if(nod1.type->etype != nod.type->etype){
+                       regalloc(&nod3, &nod, Z);
+                       gmove(&nod1, &nod3);
+                       regfree(&nod1);
+                       nod1 = nod3;
+               }
+               gopcode(o, &nod, &nod1, &nod);
+               gmove(&nod, &nod2);
+               if(nn != Z)
+                       gmove(&nod, nn);
+               regfree(&nod);
+               regfree(&nod1);
+               if(l->addable < INDEXED)
+                       regfree(&nod2);
+               break;
+
+       asbitop:
+               regalloc(&nod4, n, nn);
+               regalloc(&nod3, r, Z);
+               if(l->complex >= r->complex) {
+                       bitload(l, &nod, &nod1, &nod2, &nod4);
+                       cgen(r, &nod3);
+               } else {
+                       cgen(r, &nod3);
+                       bitload(l, &nod, &nod1, &nod2, &nod4);
+               }
+               gmove(&nod, &nod4);
+               gopcode(n->op, &nod3, Z, &nod4);
+               regfree(&nod3);
+               gmove(&nod4, &nod);
+               regfree(&nod4);
+               bitstore(l, &nod, &nod1, &nod2, nn);
+               break;
+
+       case OADDR:
+               if(nn == Z) {
+                       nullwarn(l, Z);
+                       break;
+               }
+               lcgen(l, nn);
+               break;
+
+       case OFUNC:
+               if(l->complex >= FNX) {
+                       if(l->op != OIND)
+                               diag(n, "bad function call");
+
+                       regret(&nod, l->left, 0, 0);
+                       cgen(l->left, &nod);
+                       regsalloc(&nod1, l->left);
+                       gopcode(OAS, &nod, Z, &nod1);
+                       regfree(&nod);
+
+                       nod = *n;
+                       nod.left = &nod2;
+                       nod2 = *l;
+                       nod2.left = &nod1;
+                       nod2.complex = 1;
+                       cgen(&nod, nn);
+
+                       return;
+               }
+               if(REGARG >= 0)
+                       o = reg[REGARG];
+               gargs(r, &nod, &nod1);
+               if(l->addable < INDEXED) {
+                       reglcgen(&nod, l, Z);
+                       gopcode(OFUNC, Z, Z, &nod);
+                       regfree(&nod);
+               } else
+                       gopcode(OFUNC, Z, Z, l);
+               if(REGARG>=0)
+                       if(o != reg[REGARG])
+                               reg[REGARG]--;
+               regret(&nod, n, l->type, 1); // update maxarg if nothing else
+               if(nn != Z)
+                       gopcode(OAS, &nod, Z, nn);
+               if(nod.op == OREGISTER)
+                       regfree(&nod);
+               break;
+
+       case OIND:
+               if(nn == Z) {
+                       cgen(l, nn);
+                       break;
+               }
+               regialloc(&nod, n, nn);
+               r = l;
+               while(r->op == OADD)
+                       r = r->right;
+               if(sconst(r)) {
+                       v = r->vconst;
+                       r->vconst = 0;
+                       cgen(l, &nod);
+                       nod.xoffset += v;
+                       r->vconst = v;
+               } else
+                       cgen(l, &nod);
+               regind(&nod, n);
+               gopcode(OAS, &nod, Z, nn);
+               regfree(&nod);
+               break;
+
+       case OEQ:
+       case ONE:
+       case OLE:
+       case OLT:
+       case OGE:
+       case OGT:
+       case OLO:
+       case OLS:
+       case OHI:
+       case OHS:
+               if(nn == Z) {
+                       nullwarn(l, r);
+                       break;
+               }
+               boolgen(n, 1, nn);
+               break;
+
+       case OANDAND:
+       case OOROR:
+               boolgen(n, 1, nn);
+               if(nn == Z)
+                       patch(p, pc);
+               break;
+
+       case ONOT:
+               if(nn == Z) {
+                       nullwarn(l, Z);
+                       break;
+               }
+               boolgen(n, 1, nn);
+               break;
+
+       case OCOMMA:
+               cgen(l, Z);
+               cgen(r, nn);
+               break;
+
+       case OCAST:
+               if(nn == Z) {
+                       nullwarn(l, Z);
+                       break;
+               }
+               /*
+                * convert from types l->n->nn
+                */
+               if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
+                       /* both null, gen l->nn */
+                       cgen(l, nn);
+                       break;
+               }
+               regalloc(&nod, l, nn);
+               cgen(l, &nod);
+               regalloc(&nod1, n, &nod);
+               gopcode(OAS, &nod, Z, &nod1);
+               gopcode(OAS, &nod1, Z, nn);
+               regfree(&nod1);
+               regfree(&nod);
+               break;
+
+       case ODOT:
+               sugen(l, nodrat, l->type->width);
+               if(nn != Z) {
+                       warn(n, "non-interruptable temporary");
+                       nod = *nodrat;
+                       if(!r || r->op != OCONST) {
+                               diag(n, "DOT and no offset");
+                               break;
+                       }
+                       nod.xoffset += (int32)r->vconst;
+                       nod.type = n->type;
+                       cgen(&nod, nn);
+               }
+               break;
+
+       case OCOND:
+               bcgen(l, 1);
+               p1 = p;
+               cgen(r->left, nn);
+               gbranch(OGOTO);
+               patch(p1, pc);
+               p1 = p;
+               cgen(r->right, nn);
+               patch(p1, pc);
+               break;
+
+       case OPOSTINC:
+       case OPOSTDEC:
+               v = 1;
+               if(l->type->etype == TIND)
+                       v = l->type->link->width;
+               if(o == OPOSTDEC)
+                       v = -v;
+               if(l->op == OBIT)
+                       goto bitinc;
+               if(nn == Z)
+                       goto pre;
+
+               if(l->addable < INDEXED)
+                       reglcgen(&nod2, l, Z);
+               else
+                       nod2 = *l;
+
+               regalloc(&nod, l, nn);
+               gopcode(OAS, &nod2, Z, &nod);
+               regalloc(&nod1, l, Z);
+               if(typefd[l->type->etype]) {
+                       regalloc(&nod3, l, Z);
+                       if(v < 0) {
+                               gopcode(OAS, nodfconst(-v), Z, &nod3);
+                               gopcode(OSUB, &nod3, &nod, &nod1);
+                       } else {
+                               gopcode(OAS, nodfconst(v), Z, &nod3);
+                               gopcode(OADD, &nod3, &nod, &nod1);
+                       }
+                       regfree(&nod3);
+               } else
+                       gopcode(OADD, nodconst(v), &nod, &nod1);
+               gopcode(OAS, &nod1, Z, &nod2);
+
+               regfree(&nod);
+               regfree(&nod1);
+               if(l->addable < INDEXED)
+                       regfree(&nod2);
+               break;
+
+       case OPREINC:
+       case OPREDEC:
+               v = 1;
+               if(l->type->etype == TIND)
+                       v = l->type->link->width;
+               if(o == OPREDEC)
+                       v = -v;
+               if(l->op == OBIT)
+                       goto bitinc;
+
+       pre:
+               if(l->addable < INDEXED)
+                       reglcgen(&nod2, l, Z);
+               else
+                       nod2 = *l;
+
+               regalloc(&nod, l, nn);
+               gopcode(OAS, &nod2, Z, &nod);
+               if(typefd[l->type->etype]) {
+                       regalloc(&nod3, l, Z);
+                       if(v < 0) {
+                               gopcode(OAS, nodfconst(-v), Z, &nod3);
+                               gopcode(OSUB, &nod3, Z, &nod);
+                       } else {
+                               gopcode(OAS, nodfconst(v), Z, &nod3);
+                               gopcode(OADD, &nod3, Z, &nod);
+                       }
+                       regfree(&nod3);
+               } else
+                       gopcode(OADD, nodconst(v), Z, &nod);
+               gopcode(OAS, &nod, Z, &nod2);
+               if(nn && l->op == ONAME)        /* in x=++i, emit USED(i) */
+                       gins(ANOP, l, Z);
+
+               regfree(&nod);
+               if(l->addable < INDEXED)
+                       regfree(&nod2);
+               break;
+
+       bitinc:
+               if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
+                       bitload(l, &nod, &nod1, &nod2, Z);
+                       gopcode(OAS, &nod, Z, nn);
+                       gopcode(OADD, nodconst(v), Z, &nod);
+                       bitstore(l, &nod, &nod1, &nod2, Z);
+                       break;
+               }
+               bitload(l, &nod, &nod1, &nod2, nn);
+               gopcode(OADD, nodconst(v), Z, &nod);
+               bitstore(l, &nod, &nod1, &nod2, nn);
+               break;
+       }
+       cursafe = curs;
+}
+
+void
+reglcgen(Node *t, Node *n, Node *nn)
+{
+       Node *r;
+       int32 v;
+
+       regialloc(t, n, nn);
+       if(n->op == OIND) {
+               r = n->left;
+               while(r->op == OADD)
+                       r = r->right;
+               if(sconst(r)) {
+                       v = r->vconst;
+                       r->vconst = 0;
+                       lcgen(n, t);
+                       t->xoffset += v;
+                       r->vconst = v;
+                       regind(t, n);
+                       return;
+               }
+       }
+       lcgen(n, t);
+       regind(t, n);
+}
+
+void
+lcgen(Node *n, Node *nn)
+{
+       Prog *p1;
+       Node nod;
+
+       if(debug['g']) {
+               prtree(nn, "lcgen lhs");
+               prtree(n, "lcgen");
+       }
+       if(n == Z || n->type == T)
+               return;
+       if(nn == Z) {
+               nn = &nod;
+               regalloc(&nod, n, Z);
+       }
+       switch(n->op) {
+       default:
+               if(n->addable < INDEXED) {
+                       diag(n, "unknown op in lcgen: %O", n->op);
+                       break;
+               }
+               nod = *n;
+               nod.op = OADDR;
+               nod.left = n;
+               nod.right = Z;
+               nod.type = types[TIND];
+               gopcode(OAS, &nod, Z, nn);
+               break;
+
+       case OCOMMA:
+               cgen(n->left, n->left);
+               lcgen(n->right, nn);
+               break;
+
+       case OIND:
+               cgen(n->left, nn);
+               break;
+
+       case OCOND:
+               bcgen(n->left, 1);
+               p1 = p;
+               lcgen(n->right->left, nn);
+               gbranch(OGOTO);
+               patch(p1, pc);
+               p1 = p;
+               lcgen(n->right->right, nn);
+               patch(p1, pc);
+               break;
+       }
+}
+
+void
+bcgen(Node *n, int true)
+{
+
+       if(n->type == T)
+               gbranch(OGOTO);
+       else
+               boolgen(n, true, Z);
+}
+
+void
+boolgen(Node *n, int true, Node *nn)
+{
+       int o;
+       Prog *p1, *p2;
+       Node *l, *r, nod, nod1;
+       int32 curs;
+
+       if(debug['g']) {
+               prtree(nn, "boolgen lhs");
+               prtree(n, "boolgen");
+       }
+       curs = cursafe;
+       l = n->left;
+       r = n->right;
+       switch(n->op) {
+
+       default:
+               if(n->op == OCONST) {
+                       o = vconst(n);
+                       if(!true)
+                               o = !o;
+                       gbranch(OGOTO);
+                       if(o) {
+                               p1 = p;
+                               gbranch(OGOTO);
+                               patch(p1, pc);
+                       }
+                       goto com;
+               }
+               regalloc(&nod, n, nn);
+               cgen(n, &nod);
+               o = ONE;
+               if(true)
+                       o = comrel[relindex(o)];
+               if(typefd[n->type->etype]) {
+                       nodreg(&nod1, n, NREG+FREGZERO);
+                       gopcode(o, &nod, Z, &nod1);
+               } else
+                       gopcode(o, &nod, Z, nodconst(0));
+               regfree(&nod);
+               goto com;
+
+       case OCOMMA:
+               cgen(l, Z);
+               boolgen(r, true, nn);
+               break;
+
+       case ONOT:
+               boolgen(l, !true, nn);
+               break;
+
+       case OCOND:
+               bcgen(l, 1);
+               p1 = p;
+               bcgen(r->left, true);
+               p2 = p;
+               gbranch(OGOTO);
+               patch(p1, pc);
+               p1 = p;
+               bcgen(r->right, !true);
+               patch(p2, pc);
+               p2 = p;
+               gbranch(OGOTO);
+               patch(p1, pc);
+               patch(p2, pc);
+               goto com;
+
+       case OANDAND:
+               if(!true)
+                       goto caseor;
+
+       caseand:
+               bcgen(l, true);
+               p1 = p;
+               bcgen(r, !true);
+               p2 = p;
+               patch(p1, pc);
+               gbranch(OGOTO);
+               patch(p2, pc);
+               goto com;
+
+       case OOROR:
+               if(!true)
+                       goto caseand;
+
+       caseor:
+               bcgen(l, !true);
+               p1 = p;
+               bcgen(r, !true);
+               p2 = p;
+               gbranch(OGOTO);
+               patch(p1, pc);
+               patch(p2, pc);
+               goto com;
+
+       case OEQ:
+       case ONE:
+       case OLE:
+       case OLT:
+       case OGE:
+       case OGT:
+       case OHI:
+       case OHS:
+       case OLO:
+       case OLS:
+               o = n->op;
+               if(true)
+                       o = comrel[relindex(o)];
+               if(l->complex >= FNX && r->complex >= FNX) {
+                       regret(&nod, r, 0, 0);
+                       cgen(r, &nod);
+                       regsalloc(&nod1, r);
+                       gopcode(OAS, &nod, Z, &nod1);
+                       regfree(&nod);
+                       nod = *n;
+                       nod.right = &nod1;
+                       boolgen(&nod, true, nn);
+                       break;
+               }
+               if(sconst(r)) {
+                       regalloc(&nod, l, nn);
+                       cgen(l, &nod);
+                       gopcode(o, &nod, Z, r);
+                       regfree(&nod);
+                       goto com;
+               }
+               if(l->complex >= r->complex) {
+                       regalloc(&nod1, l, nn);
+                       cgen(l, &nod1);
+                       regalloc(&nod, r, Z);
+                       cgen(r, &nod);
+               } else {
+                       regalloc(&nod, r, nn);
+                       cgen(r, &nod);
+                       regalloc(&nod1, l, Z);
+                       cgen(l, &nod1);
+               }
+               gopcode(o, &nod1, Z, &nod);
+               regfree(&nod);
+               regfree(&nod1);
+
+       com:
+               if(nn != Z) {
+                       p1 = p;
+                       gopcode(OAS, nodconst(1L), Z, nn);
+                       gbranch(OGOTO);
+                       p2 = p;
+                       patch(p1, pc);
+                       gopcode(OAS, nodconst(0L), Z, nn);
+                       patch(p2, pc);
+               }
+               break;
+       }
+       cursafe = curs;
+}
+
+void
+sugen(Node *n, Node *nn, int32 w)
+{
+       Prog *p1;
+       Node nod0, nod1, nod2, nod3, nod4, *l, *r;
+       Type *t;
+       int32 pc1;
+       int i, m, c;
+
+       if(n == Z || n->type == T)
+               return;
+       if(debug['g']) {
+               prtree(nn, "sugen lhs");
+               prtree(n, "sugen");
+       }
+       if(nn == nodrat)
+               if(w > nrathole)
+                       nrathole = w;
+       switch(n->op) {
+       case OIND:
+               if(nn == Z) {
+                       nullwarn(n->left, Z);
+                       break;
+               }
+
+       default:
+               goto copy;
+
+       case OCONST:
+               if(n->type && typev[n->type->etype]) {
+                       if(nn == Z) {
+                               nullwarn(n->left, Z);
+                               break;
+                       }
+
+                       t = nn->type;
+                       nn->type = types[TLONG];
+                       reglcgen(&nod1, nn, Z);
+                       nn->type = t;
+
+                       if(align(0, types[TCHAR], Aarg1, nil))  /* isbigendian */
+                               gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
+                       else
+                               gopcode(OAS, nod32const(n->vconst), Z, &nod1);
+                       nod1.xoffset += SZ_LONG;
+                       if(align(0, types[TCHAR], Aarg1, nil))  /* isbigendian */
+                               gopcode(OAS, nod32const(n->vconst), Z, &nod1);
+                       else
+                               gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
+
+                       regfree(&nod1);
+                       break;
+               }
+               goto copy;
+
+       case ODOT:
+               l = n->left;
+               sugen(l, nodrat, l->type->width);
+               if(nn != Z) {
+                       warn(n, "non-interruptable temporary");
+                       nod1 = *nodrat;
+                       r = n->right;
+                       if(!r || r->op != OCONST) {
+                               diag(n, "DOT and no offset");
+                               break;
+                       }
+                       nod1.xoffset += (int32)r->vconst;
+                       nod1.type = n->type;
+                       sugen(&nod1, nn, w);
+               }
+               break;
+
+       case OSTRUCT:
+               /*
+                * rewrite so lhs has no side effects
+                */
+               if(nn != Z && side(nn)) {
+                       nod1 = *n;
+                       nod1.type = typ(TIND, n->type);
+                       regalloc(&nod2, &nod1, Z);
+                       lcgen(nn, &nod2);
+                       regsalloc(&nod0, &nod1);
+                       gopcode(OAS, &nod2, Z, &nod0);
+                       regfree(&nod2);
+
+                       nod1 = *n;
+                       nod1.op = OIND;
+                       nod1.left = &nod0;
+                       nod1.right = Z;
+                       nod1.complex = 1;
+
+                       sugen(n, &nod1, w);
+                       return;
+               }
+
+               r = n->left;
+               for(t = n->type->link; t != T; t = t->down) {
+                       l = r;
+                       if(r->op == OLIST) {
+                               l = r->left;
+                               r = r->right;
+                       }
+                       if(nn == Z) {
+                               cgen(l, nn);
+                               continue;
+                       }
+                       /*
+                        * hand craft *(&nn + o) = l
+                        */
+                       nod0 = znode;
+                       nod0.op = OAS;
+                       nod0.type = t;
+                       nod0.left = &nod1;
+                       nod0.right = l;
+
+                       nod1 = znode;
+                       nod1.op = OIND;
+                       nod1.type = t;
+                       nod1.left = &nod2;
+
+                       nod2 = znode;
+                       nod2.op = OADD;
+                       nod2.type = typ(TIND, t);
+                       nod2.left = &nod3;
+                       nod2.right = &nod4;
+
+                       nod3 = znode;
+                       nod3.op = OADDR;
+                       nod3.type = nod2.type;
+                       nod3.left = nn;
+
+                       nod4 = znode;
+                       nod4.op = OCONST;
+                       nod4.type = nod2.type;
+                       nod4.vconst = t->offset;
+
+                       ccom(&nod0);
+                       acom(&nod0);
+                       xcom(&nod0);
+                       nod0.addable = 0;
+
+                       /* prtree(&nod0, "hand craft"); /* */
+                       cgen(&nod0, Z);
+               }
+               break;
+
+       case OAS:
+               if(nn == Z) {
+                       if(n->addable < INDEXED)
+                               sugen(n->right, n->left, w);
+                       break;
+               }
+               /* BOTCH -- functions can clobber rathole */
+               sugen(n->right, nodrat, w);
+               warn(n, "non-interruptable temporary");
+               sugen(nodrat, n->left, w);
+               sugen(nodrat, nn, w);
+               break;
+
+       case OFUNC:
+               if(!hasdotdotdot(n->left->type)) {
+                       cgen(n, Z);
+                       if(nn != Z) {
+                               curarg -= n->type->width;
+                               regret(&nod1, n, n->left->type, 1);
+                               if(nn->complex >= FNX) {
+                                       regsalloc(&nod2, n);
+                                       cgen(&nod1, &nod2);
+                                       nod1 = nod2;
+                               }
+                               cgen(&nod1, nn);
+                       }
+                       break;
+               }
+               if(nn == Z) {
+                       sugen(n, nodrat, w);
+                       break;
+               }
+               if(nn->op != OIND) {
+                       nn = new1(OADDR, nn, Z);
+                       nn->type = types[TIND];
+                       nn->addable = 0;
+               } else
+                       nn = nn->left;
+               n = new(OFUNC, n->left, new(OLIST, nn, n->right));
+               n->type = types[TVOID];
+               n->left->type = types[TVOID];
+               cgen(n, Z);
+               break;
+
+       case OCOND:
+               bcgen(n->left, 1);
+               p1 = p;
+               sugen(n->right->left, nn, w);
+               gbranch(OGOTO);
+               patch(p1, pc);
+               p1 = p;
+               sugen(n->right->right, nn, w);
+               patch(p1, pc);
+               break;
+
+       case OCOMMA:
+               cgen(n->left, Z);
+               sugen(n->right, nn, w);
+               break;
+       }
+       return;
+
+copy:
+       if(nn == Z)
+               return;
+       if(n->complex >= FNX && nn->complex >= FNX) {
+               t = nn->type;
+               nn->type = types[TLONG];
+               regialloc(&nod1, nn, Z);
+               lcgen(nn, &nod1);
+               regsalloc(&nod2, nn);
+               nn->type = t;
+
+               gopcode(OAS, &nod1, Z, &nod2);
+               regfree(&nod1);
+
+               nod2.type = typ(TIND, t);
+
+               nod1 = nod2;
+               nod1.op = OIND;
+               nod1.left = &nod2;
+               nod1.right = Z;
+               nod1.complex = 1;
+               nod1.type = t;
+
+               sugen(n, &nod1, w);
+               return;
+       }
+
+       if(n->complex > nn->complex) {
+               t = n->type;
+               n->type = types[TLONG];
+               reglcgen(&nod1, n, Z);
+               n->type = t;
+
+               t = nn->type;
+               nn->type = types[TLONG];
+               reglcgen(&nod2, nn, Z);
+               nn->type = t;
+       } else {
+               t = nn->type;
+               nn->type = types[TLONG];
+               reglcgen(&nod2, nn, Z);
+               nn->type = t;
+
+               t = n->type;
+               n->type = types[TLONG];
+               reglcgen(&nod1, n, Z);
+               n->type = t;
+       }
+
+       w /= SZ_LONG;
+       if(w <= 5) {
+               layout(&nod1, &nod2, w, 0, Z);
+               goto out;
+       }
+
+       /*
+        * minimize space for unrolling loop
+        * 3,4,5 times. (6 or more is never minimum)
+        * if small structure, try 2 also.
+        */
+       c = 0; /* set */
+       m = 100;
+       i = 3;
+       if(w <= 15)
+               i = 2;
+       for(; i<=5; i++)
+               if(i + w%i <= m) {
+                       c = i;
+                       m = c + w%c;
+               }
+
+       regalloc(&nod3, &regnode, Z);
+       layout(&nod1, &nod2, w%c, w/c, &nod3);
+       
+       pc1 = pc;
+       layout(&nod1, &nod2, c, 0, Z);
+
+       gopcode(OSUB, nodconst(1L), Z, &nod3);
+       nod1.op = OREGISTER;
+       gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
+       nod2.op = OREGISTER;
+       gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
+       
+       gopcode(OGT, &nod3, Z, nodconst(0));
+       patch(p, pc1);
+
+       regfree(&nod3);
+out:
+       regfree(&nod1);
+       regfree(&nod2);
+}
+
+void
+layout(Node *f, Node *t, int c, int cv, Node *cn)
+{
+       Node t1, t2;
+
+       while(c > 3) {
+               layout(f, t, 2, 0, Z);
+               c -= 2;
+       }
+
+       regalloc(&t1, &regnode, Z);
+       regalloc(&t2, &regnode, Z);
+       if(c > 0) {
+               gopcode(OAS, f, Z, &t1);
+               f->xoffset += SZ_LONG;
+       }
+       if(cn != Z)
+               gopcode(OAS, nodconst(cv), Z, cn);
+       if(c > 1) {
+               gopcode(OAS, f, Z, &t2);
+               f->xoffset += SZ_LONG;
+       }
+       if(c > 0) {
+               gopcode(OAS, &t1, Z, t);
+               t->xoffset += SZ_LONG;
+       }
+       if(c > 2) {
+               gopcode(OAS, f, Z, &t1);
+               f->xoffset += SZ_LONG;
+       }
+       if(c > 1) {
+               gopcode(OAS, &t2, Z, t);
+               t->xoffset += SZ_LONG;
+       }
+       if(c > 2) {
+               gopcode(OAS, &t1, Z, t);
+               t->xoffset += SZ_LONG;
+       }
+       regfree(&t1);
+       regfree(&t2);
+}
diff --git a/src/cmd/9c/doc.go b/src/cmd/9c/doc.go
new file mode 100644 (file)
index 0000000..6c9b476
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+
+9c is a version of the Plan 9 C compiler.  The original is documented at
+
+       http://plan9.bell-labs.com/magic/man2html/1/8c
+
+Its target architecture is the Power64, referred to by these tools as
+power64 (big endian) or power64le (little endian).
+
+*/
+package main
diff --git a/src/cmd/9c/gc.h b/src/cmd/9c/gc.h
new file mode 100644 (file)
index 0000000..fbe5099
--- /dev/null
@@ -0,0 +1,350 @@
+// cmd/9c/gc.h from Vita Nuova.
+//
+//     Copyright Â© 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright Â© 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright Â© 1997-1999 Vita Nuova Limited
+//     Portions Copyright Â© 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright Â© 2004,2006 Bruce Ellis
+//     Portions Copyright Â© 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright Â© 2000-2008 Lucent Technologies Inc. and others
+//     Portions Copyright Â© 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include       <u.h>
+#include       "../cc/cc.h"
+#include       "../9l/9.out.h"
+
+/*
+ * 9c/powerpc64
+ */
+#define        SZ_CHAR         1
+#define        SZ_SHORT        2
+#define        SZ_INT          4
+#define        SZ_LONG         4
+#define        SZ_IND          8
+#define        SZ_FLOAT        4
+#define        SZ_VLONG        8
+#define        SZ_DOUBLE       8
+#define        FNX             100
+
+typedef        struct  Case    Case;
+typedef        struct  C1      C1;
+typedef        struct  Multab  Multab;
+typedef        struct  Hintab  Hintab;
+typedef        struct  Reg     Reg;
+typedef        struct  Rgn     Rgn;
+
+#define        A       ((Adr*)0)
+
+#define        INDEXED 9
+#define        P       ((Prog*)0)
+
+struct Case
+{
+       Case*   link;
+       vlong   val;
+       int32   label;
+       char    def;
+       char isv;
+};
+#define        C       ((Case*)0)
+
+struct C1
+{
+       vlong   val;
+       int32   label;
+};
+
+struct Multab
+{
+       int32   val;
+       char    code[20];
+};
+
+struct Hintab
+{
+       ushort  val;
+       char    hint[10];
+};
+
+struct Reg
+{
+       int32   pc;
+       int32   rpo;            /* reverse post ordering */
+
+       Bits    set;
+       Bits    use1;
+       Bits    use2;
+
+       Bits    refbehind;
+       Bits    refahead;
+       Bits    calbehind;
+       Bits    calahead;
+       Bits    regdiff;
+       Bits    act;
+
+       int32   regu;
+       int32   loop;           /* could be shorter */
+
+       union
+       {
+               Reg*    log5;
+               int32   active;
+       };
+       Reg*    p1;
+       Reg*    p2;
+       Reg*    p2link;
+       Reg*    s1;
+       Reg*    s2;
+       Reg*    link;
+       Prog*   prog;
+};
+#define        R       ((Reg*)0)
+
+#define        NRGN    600
+struct Rgn
+{
+       Reg*    enter;
+       short   cost;
+       short   varno;
+       short   regno;
+};
+
+EXTERN int32   breakpc;
+EXTERN int32   nbreak;
+EXTERN Case*   cases;
+EXTERN Node    constnode;
+EXTERN Node    fconstnode;
+EXTERN Node    vconstnode;
+EXTERN int32   continpc;
+EXTERN int32   curarg;
+EXTERN int32   cursafe;
+EXTERN Prog*   lastp;
+extern int     hintabsize;
+EXTERN int32   maxargsafe;
+EXTERN Multab  multab[20];
+EXTERN int     mnstring;
+EXTERN Node*   nodrat;
+EXTERN Node*   nodret;
+EXTERN Node*   nodsafe;
+EXTERN int32   nrathole;
+EXTERN int32   nstring;
+EXTERN Prog*   p;
+EXTERN int32   pc;
+EXTERN Node    regnode;
+EXTERN Node    qregnode;
+EXTERN char    string[NSNAME];
+EXTERN Sym*    symrathole;
+EXTERN Node    znode;
+EXTERN Prog    zprog;
+EXTERN int     reg[NREG+NREG];
+EXTERN int32   exregoffset;
+EXTERN int32   exfregoffset;
+EXTERN uchar   typechlpv[NTYPE];
+
+#define        BLOAD(r)        band(bnot(r->refbehind), r->refahead)
+#define        BSTORE(r)       band(bnot(r->calbehind), r->calahead)
+#define        LOAD(r)         (~r->refbehind.b[z] & r->refahead.b[z])
+#define        STORE(r)        (~r->calbehind.b[z] & r->calahead.b[z])
+
+#define        bset(a,n)       ((a).b[(n)/32]&(1L<<(n)%32))
+
+#define        CLOAD   5
+#define        CREF    5
+#define        CINF    1000
+#define        LOOP    3
+
+EXTERN Rgn     region[NRGN];
+EXTERN Rgn*    rgp;
+EXTERN int     nregion;
+EXTERN int     nvar;
+
+EXTERN Bits    externs;
+EXTERN Bits    params;
+EXTERN Bits    consts;
+EXTERN Bits    addrs;
+
+EXTERN int32   regbits;
+EXTERN int32   exregbits;
+
+EXTERN int     change;
+EXTERN int     suppress;
+
+EXTERN Reg*    firstr;
+EXTERN Reg*    lastr;
+EXTERN Reg     zreg;
+EXTERN Reg*    freer;
+EXTERN Var     var[NVAR];
+EXTERN int32*  idom;
+EXTERN Reg**   rpo2r;
+EXTERN int32   maxnr;
+
+#define        R0ISZERO        (debug['0']==0)
+
+extern char*   anames[];
+extern Hintab  hintab[];
+
+/*
+ * sgen.c
+ */
+void   codgen(Node*, Node*);
+void   gen(Node*);
+void   usedset(Node*, int);
+void   noretval(int);
+void   xcom(Node*);
+int    bcomplex(Node*, Node*);
+Prog*  gtext(Sym*, int32);
+vlong  argsize(int);
+
+/*
+ * cgen.c
+ */
+void   cgen(Node*, Node*);
+void   reglcgen(Node*, Node*, Node*);
+void   lcgen(Node*, Node*);
+void   bcgen(Node*, int);
+void   boolgen(Node*, int, Node*);
+void   sugen(Node*, Node*, int32);
+void   layout(Node*, Node*, int, int, Node*);
+
+/*
+ * txt.c
+ */
+void   ginit(void);
+void   gclean(void);
+void   nextpc(void);
+void   gargs(Node*, Node*, Node*);
+void   garg1(Node*, Node*, Node*, int, Node**);
+Node*  nodconst(int32);
+Node*  nod32const(vlong);
+Node*  nodfconst(double);
+Node*  nodgconst(vlong v, Type *t);
+void   nodreg(Node*, Node*, int);
+void   regret(Node*, Node*, Type*, int);
+void   regalloc(Node*, Node*, Node*);
+void   regfree(Node*);
+void   regialloc(Node*, Node*, Node*);
+void   regsalloc(Node*, Node*);
+void   regaalloc1(Node*, Node*);
+void   regaalloc(Node*, Node*);
+void   regind(Node*, Node*);
+void   gprep(Node*, Node*);
+void   raddr(Node*, Prog*);
+void   naddr(Node*, Addr*);
+void   gmove(Node*, Node*);
+void   gins(int a, Node*, Node*);
+void   gopcode(int, Node*, Node*, Node*);
+int    samaddr(Node*, Node*);
+void   gbranch(int);
+int    immconst(Node*);
+void   patch(Prog*, int32);
+int    sconst(Node*);
+int    sval(int32);
+int    uconst(Node*);
+void   gpseudo(int, Sym*, Node*);
+void   gprefetch(Node*);
+void   gpcdata(int, int);
+
+/*
+ * swt.c
+ */
+int    swcmp(const void*, const void*);
+void   doswit(Node*);
+void   swit1(C1*, int, int32, Node*);
+void   swit2(C1*, int, int32, Node*, Node*);
+void   newcase(void);
+void   bitload(Node*, Node*, Node*, Node*, Node*);
+void   bitstore(Node*, Node*, Node*, Node*, Node*);
+int32  outstring(char*, int32);
+int    mulcon(Node*, Node*);
+Multab*        mulcon0(Node*, int32);
+int    mulcon1(Node*, int32, Node*);
+void   nullwarn(Node*, Node*);
+void   sextern(Sym*, Node*, int32, int32);
+void   gextern(Sym*, Node*, int32, int32);
+void   outcode(void);
+
+/*
+ * list
+ */
+void   listinit(void);
+int    Pconv(Fmt*);
+int    Aconv(Fmt*);
+int    Dconv(Fmt*);
+int    Sconv(Fmt*);
+int    Nconv(Fmt*);
+int    Bconv(Fmt*);
+
+/*
+ * reg.c
+ */
+Reg*   rega(void);
+int    rcmp(const void*, const void*);
+void   regopt(Prog*);
+void   addmove(Reg*, int, int, int);
+Bits   mkvar(Addr*, int);
+void   prop(Reg*, Bits, Bits);
+void   loopit(Reg*, int32);
+void   synch(Reg*, Bits);
+uint32 allreg(uint32, Rgn*);
+void   paint1(Reg*, int);
+uint32 paint2(Reg*, int);
+void   paint3(Reg*, int, int32, int);
+void   addreg(Addr*, int);
+
+/*
+ * peep.c
+ */
+void   peep(void);
+void   excise(Reg*);
+Reg*   uniqp(Reg*);
+Reg*   uniqs(Reg*);
+int    regtyp(Addr*);
+int    regzer(Addr*);
+int    anyvar(Addr*);
+int    subprop(Reg*);
+int    copyprop(Reg*);
+int    copy1(Addr*, Addr*, Reg*, int);
+int    copyu(Prog*, Addr*, Addr*);
+
+int    copyas(Addr*, Addr*);
+int    copyau(Addr*, Addr*);
+int    copyau1(Prog*, Addr*);
+int    copysub(Addr*, Addr*, Addr*, int);
+int    copysub1(Prog*, Addr*, Addr*, int);
+
+int32  RtoB(int);
+int32  FtoB(int);
+int    BtoR(int32);
+int    BtoF(int32);
+
+/*
+ * com64.c
+ */
+int    com64(Node*);
+void   com64init(void);
+void   bool64(Node*);
+
+#pragma        varargck        type    "A"     int
+#pragma        varargck        type    "B"     Bits
+#pragma        varargck        type    "D"     Addr*
+#pragma        varargck        type    "N"     Addr*
+#pragma        varargck        type    "P"     Prog*
+#pragma        varargck        type    "S"     char*
diff --git a/src/cmd/9c/list.c b/src/cmd/9c/list.c
new file mode 100644 (file)
index 0000000..5cfc442
--- /dev/null
@@ -0,0 +1,37 @@
+// cmd/9c/list.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.
+
+#define EXTERN
+#include "gc.h"
+
+void
+listinit(void)
+{
+       listinit9();
+}
diff --git a/src/cmd/9c/machcap.c b/src/cmd/9c/machcap.c
new file mode 100644 (file)
index 0000000..af44bc8
--- /dev/null
@@ -0,0 +1,105 @@
+// cmd/9c/machcap.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.
+
+#include "gc.h"
+
+int
+machcap(Node *n)
+{
+
+       if(n == Z)
+               return 1;       /* test */
+
+       switch(n->op) {
+       case OMUL:
+       case OLMUL:
+       case OASMUL:
+       case OASLMUL:
+               if(typechlv[n->type->etype])
+                       return 1;
+               break;
+
+       case OADD:
+       case OAND:
+       case OOR:
+       case OSUB:
+       case OXOR:
+       case OASHL:
+       case OLSHR:
+       case OASHR:
+               if(typechlv[n->left->type->etype])
+                       return 1;
+               break;
+
+       case OCAST:
+               return 1;
+
+       case OCOND:
+       case OCOMMA:
+       case OLIST:
+       case OANDAND:
+       case OOROR:
+       case ONOT:
+               return 1;
+
+       case OASADD:
+       case OASSUB:
+       case OASAND:
+       case OASOR:
+       case OASXOR:
+               return 1;
+
+       case OASASHL:
+       case OASASHR:
+       case OASLSHR:
+               return 1;
+
+       case OPOSTINC:
+       case OPOSTDEC:
+       case OPREINC:
+       case OPREDEC:
+               return 1;
+
+       case OEQ:
+       case ONE:
+       case OLE:
+       case OGT:
+       case OLT:
+       case OGE:
+       case OHI:
+       case OHS:
+       case OLO:
+       case OLS:
+               return 1;
+       case ONEG:
+       case OCOM:
+               break;
+       }
+       return 0;
+}
diff --git a/src/cmd/9c/mul.c b/src/cmd/9c/mul.c
new file mode 100644 (file)
index 0000000..353376f
--- /dev/null
@@ -0,0 +1,638 @@
+// cmd/9c/mul.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.
+
+#include "gc.h"
+
+/*
+ * code sequences for multiply by constant.
+ * [a-l][0-3]
+ *     lsl     $(A-'a'),r0,r1
+ * [+][0-7]
+ *     add     r0,r1,r2
+ * [-][0-7]
+ *     sub     r0,r1,r2
+ */
+
+static int     multabp;
+static int32   mulval;
+static char*   mulcp;
+static int32   valmax;
+static int     shmax;
+
+static int     docode(char *hp, char *cp, int r0, int r1);
+static int     gen1(int len);
+static int     gen2(int len, int32 r1);
+static int     gen3(int len, int32 r0, int32 r1, int flag);
+enum
+{
+       SR1     = 1<<0,         /* r1 has been shifted */
+       SR0     = 1<<1,         /* r0 has been shifted */
+       UR1     = 1<<2,         /* r1 has not been used */
+       UR0     = 1<<3,         /* r0 has not been used */
+};
+
+Multab*
+mulcon0(Node *n, int32 v)
+{
+       int a1, a2, g;
+       Multab *m, *m1;
+       char hint[10];
+
+       if(v < 0)
+               v = -v;
+
+       /*
+        * look in cache
+        */
+       m = multab;
+       for(g=0; g<nelem(multab); g++) {
+               if(m->val == v) {
+                       if(m->code[0] == 0)
+                               return 0;
+                       return m;
+               }
+               m++;
+       }
+
+       /*
+        * select a spot in cache to overwrite
+        */
+       multabp++;
+       if(multabp < 0 || multabp >= nelem(multab))
+               multabp = 0;
+       m = multab+multabp;
+       m->val = v;
+       mulval = v;
+
+       /*
+        * look in execption hint table
+        */
+       a1 = 0;
+       a2 = hintabsize;
+       for(;;) {
+               if(a1 >= a2)
+                       goto no;
+               g = (a2 + a1)/2;
+               if(v < hintab[g].val) {
+                       a2 = g;
+                       continue;
+               }
+               if(v > hintab[g].val) {
+                       a1 = g+1;
+                       continue;
+               }
+               break;
+       }
+
+       if(docode(hintab[g].hint, m->code, 1, 0))
+               return m;
+       print("%L: multiply table failure %ld\n", n->lineno, v);
+       m->code[0] = 0;
+       return 0;
+
+no:
+       /*
+        * try to search
+        */
+       hint[0] = 0;
+       for(g=1; g<=6; g++) {
+               if(g >= 6 && v >= 65535)
+                       break;
+               mulcp = hint+g;
+               *mulcp = 0;
+               if(gen1(g)) {
+                       if(docode(hint, m->code, 1, 0))
+                               return m;
+                       print("%L: multiply table failure (g=%d h=%s) %ld\n",
+                               n->lineno, g, hint, v);
+                       break;
+               }
+       }
+
+       /*
+        * try a recur followed by a shift
+        */
+       g = 0;
+       while(!(v & 1)) {
+               g++;
+               v >>= 1;
+       }
+       if(g) {
+               m1 = mulcon0(n, v);
+               if(m1) {
+                       strcpy(m->code, m1->code);
+                       sprint(strchr(m->code, 0), "%c0", g+'a');
+                       return m;
+               }
+       }
+       m->code[0] = 0;
+       return 0;
+}
+
+static int
+docode(char *hp, char *cp, int r0, int r1)
+{
+       int c, i;
+
+       c = *hp++;
+       *cp = c;
+       cp += 2;
+       switch(c) {
+       default:
+               c -= 'a';
+               if(c < 1 || c >= 30)
+                       break;
+               for(i=0; i<4; i++) {
+                       switch(i) {
+                       case 0:
+                               if(docode(hp, cp, r0<<c, r1))
+                                       goto out;
+                               break;
+                       case 1:
+                               if(docode(hp, cp, r1<<c, r1))
+                                       goto out;
+                               break;
+                       case 2:
+                               if(docode(hp, cp, r0, r0<<c))
+                                       goto out;
+                               break;
+                       case 3:
+                               if(docode(hp, cp, r0, r1<<c))
+                                       goto out;
+                               break;
+                       }
+               }
+               break;
+
+       case '+':
+               for(i=0; i<8; i++) {
+                       cp[-1] = i+'0';
+                       switch(i) {
+                       case 1:
+                               if(docode(hp, cp, r0+r1, r1))
+                                       goto out;
+                               break;
+                       case 5:
+                               if(docode(hp, cp, r0, r0+r1))
+                                       goto out;
+                               break;
+                       }
+               }
+               break;
+
+       case '-':
+               for(i=0; i<8; i++) {
+                       cp[-1] = i+'0';
+                       switch(i) {
+                       case 1:
+                               if(docode(hp, cp, r0-r1, r1))
+                                       goto out;
+                               break;
+                       case 2:
+                               if(docode(hp, cp, r1-r0, r1))
+                                       goto out;
+                               break;
+                       case 5:
+                               if(docode(hp, cp, r0, r0-r1))
+                                       goto out;
+                               break;
+                       case 6:
+                               if(docode(hp, cp, r0, r1-r0))
+                                       goto out;
+                               break;
+                       }
+               }
+               break;
+
+       case 0:
+               if(r0 == mulval)
+                       return 1;
+       }
+       return 0;
+
+out:
+       cp[-1] = i+'0';
+       return 1;
+}
+
+static int
+gen1(int len)
+{
+       int i;
+
+       for(shmax=1; shmax<30; shmax++) {
+               valmax = 1<<shmax;
+               if(valmax >= mulval)
+                       break;
+       }
+       if(mulval == 1)
+               return 1;
+
+       len--;
+       for(i=1; i<=shmax; i++)
+               if(gen2(len, 1<<i)) {
+                       *--mulcp = 'a'+i;
+                       return 1;
+               }
+       return 0;
+}
+
+static int
+gen2(int len, int32 r1)
+{
+       int i;
+
+       if(len <= 0) {
+               if(r1 == mulval)
+                       return 1;
+               return 0;
+       }
+
+       len--;
+       if(len == 0)
+               goto calcr0;
+
+       if(gen3(len, r1, r1+1, UR1)) {
+               i = '+';
+               goto out;
+       }
+       if(gen3(len, r1-1, r1, UR0)) {
+               i = '-';
+               goto out;
+       }
+       if(gen3(len, 1, r1+1, UR1)) {
+               i = '+';
+               goto out;
+       }
+       if(gen3(len, 1, r1-1, UR1)) {
+               i = '-';
+               goto out;
+       }
+
+       return 0;
+
+calcr0:
+       if(mulval == r1+1) {
+               i = '+';
+               goto out;
+       }
+       if(mulval == r1-1) {
+               i = '-';
+               goto out;
+       }
+       return 0;
+
+out:
+       *--mulcp = i;
+       return 1;
+}
+
+static int
+gen3(int len, int32 r0, int32 r1, int flag)
+{
+       int i, f1, f2;
+       int32 x;
+
+       if(r0 <= 0 ||
+          r0 >= r1 ||
+          r1 > valmax)
+               return 0;
+
+       len--;
+       if(len == 0)
+               goto calcr0;
+
+       if(!(flag & UR1)) {
+               f1 = UR1|SR1;
+               for(i=1; i<=shmax; i++) {
+                       x = r0<<i;
+                       if(x > valmax)
+                               break;
+                       if(gen3(len, r0, x, f1)) {
+                               i += 'a';
+                               goto out;
+                       }
+               }
+       }
+
+       if(!(flag & UR0)) {
+               f1 = UR1|SR1;
+               for(i=1; i<=shmax; i++) {
+                       x = r1<<i;
+                       if(x > valmax)
+                               break;
+                       if(gen3(len, r1, x, f1)) {
+                               i += 'a';
+                               goto out;
+                       }
+               }
+       }
+
+       if(!(flag & SR1)) {
+               f1 = UR1|SR1|(flag&UR0);
+               for(i=1; i<=shmax; i++) {
+                       x = r1<<i;
+                       if(x > valmax)
+                               break;
+                       if(gen3(len, r0, x, f1)) {
+                               i += 'a';
+                               goto out;
+                       }
+               }
+       }
+
+       if(!(flag & SR0)) {
+               f1 = UR0|SR0|(flag&(SR1|UR1));
+
+               f2 = UR1|SR1;
+               if(flag & UR1)
+                       f2 |= UR0;
+               if(flag & SR1)
+                       f2 |= SR0;
+
+               for(i=1; i<=shmax; i++) {
+                       x = r0<<i;
+                       if(x > valmax)
+                               break;
+                       if(x > r1) {
+                               if(gen3(len, r1, x, f2)) {
+                                       i += 'a';
+                                       goto out;
+                               }
+                       } else
+                               if(gen3(len, x, r1, f1)) {
+                                       i += 'a';
+                                       goto out;
+                               }
+               }
+       }
+
+       x = r1+r0;
+       if(gen3(len, r0, x, UR1)) {
+               i = '+';
+               goto out;
+       }
+
+       if(gen3(len, r1, x, UR1)) {
+               i = '+';
+               goto out;
+       }
+
+       x = r1-r0;
+       if(gen3(len, x, r1, UR0)) {
+               i = '-';
+               goto out;
+       }
+
+       if(x > r0) {
+               if(gen3(len, r0, x, UR1)) {
+                       i = '-';
+                       goto out;
+               }
+       } else
+               if(gen3(len, x, r0, UR0)) {
+                       i = '-';
+                       goto out;
+               }
+
+       return 0;
+
+calcr0:
+       f1 = flag & (UR0|UR1);
+       if(f1 == UR1) {
+               for(i=1; i<=shmax; i++) {
+                       x = r1<<i;
+                       if(x >= mulval) {
+                               if(x == mulval) {
+                                       i += 'a';
+                                       goto out;
+                               }
+                               break;
+                       }
+               }
+       }
+
+       if(mulval == r1+r0) {
+               i = '+';
+               goto out;
+       }
+       if(mulval == r1-r0) {
+               i = '-';
+               goto out;
+       }
+
+       return 0;
+
+out:
+       *--mulcp = i;
+       return 1;
+}
+
+/*
+ * hint table has numbers that
+ * the search algorithm fails on.
+ * <1000:
+ *     all numbers
+ * <5000:
+ *     Ã· by 5
+ * <10000:
+ *     Ã· by 50
+ * <65536:
+ *     Ã· by 250
+ */
+Hintab hintab[] =
+{
+       683,    "b++d+e+",
+       687,    "b+e++e-",
+       691,    "b++d+e+",
+       731,    "b++d+e+",
+       811,    "b++d+i+",
+       821,    "b++e+e+",
+       843,    "b+d++e+",
+       851,    "b+f-+e-",
+       853,    "b++e+e+",
+       877,    "c++++g-",
+       933,    "b+c++g-",
+       981,    "c-+e-d+",
+       1375,   "b+c+b+h-",
+       1675,   "d+b++h+",
+       2425,   "c++f-e+",
+       2675,   "c+d++f-",
+       2750,   "b+d-b+h-",
+       2775,   "c-+g-e-",
+       3125,   "b++e+g+",
+       3275,   "b+c+g+e+",
+       3350,   "c++++i+",
+       3475,   "c-+e-f-",
+       3525,   "c-+d+g-",
+       3625,   "c-+e-j+",
+       3675,   "b+d+d+e+",
+       3725,   "b+d-+h+",
+       3925,   "b+d+f-d-",
+       4275,   "b+g++e+",
+       4325,   "b+h-+d+",
+       4425,   "b+b+g-j-",
+       4525,   "b+d-d+f+",
+       4675,   "c++d-g+",
+       4775,   "b+d+b+g-",
+       4825,   "c+c-+i-",
+       4850,   "c++++i-",
+       4925,   "b++e-g-",
+       4975,   "c+f++e-",
+       5500,   "b+g-c+d+",
+       6700,   "d+b++i+",
+       9700,   "d++++j-",
+       11000,  "b+f-c-h-",
+       11750,  "b+d+g+j-",
+       12500,  "b+c+e-k+",
+       13250,  "b+d+e-f+",
+       13750,  "b+h-c-d+",
+       14250,  "b+g-c+e-",
+       14500,  "c+f+j-d-",
+       14750,  "d-g--f+",
+       16750,  "b+e-d-n+",
+       17750,  "c+h-b+e+",
+       18250,  "d+b+h-d+",
+       18750,  "b+g-++f+",
+       19250,  "b+e+b+h+",
+       19750,  "b++h--f-",
+       20250,  "b+e-l-c+",
+       20750,  "c++bi+e-",
+       21250,  "b+i+l+c+",
+       22000,  "b+e+d-g-",
+       22250,  "b+d-h+k-",
+       22750,  "b+d-e-g+",
+       23250,  "b+c+h+e-",
+       23500,  "b+g-c-g-",
+       23750,  "b+g-b+h-",
+       24250,  "c++g+m-",
+       24750,  "b+e+e+j-",
+       25000,  "b++dh+g+",
+       25250,  "b+e+d-g-",
+       25750,  "b+e+b+j+",
+       26250,  "b+h+c+e+",
+       26500,  "b+h+c+g+",
+       26750,  "b+d+e+g-",
+       27250,  "b+e+e+f+",
+       27500,  "c-i-c-d+",
+       27750,  "b+bd++j+",
+       28250,  "d-d-++i-",
+       28500,  "c+c-h-e-",
+       29000,  "b+g-d-f+",
+       29500,  "c+h+++e-",
+       29750,  "b+g+f-c+",
+       30250,  "b+f-g-c+",
+       33500,  "c-f-d-n+",
+       33750,  "b+d-b+j-",
+       34250,  "c+e+++i+",
+       35250,  "e+b+d+k+",
+       35500,  "c+e+d-g-",
+       35750,  "c+i-++e+",
+       36250,  "b+bh-d+e+",
+       36500,  "c+c-h-e-",
+       36750,  "d+e--i+",
+       37250,  "b+g+g+b+",
+       37500,  "b+h-b+f+",
+       37750,  "c+be++j-",
+       38500,  "b+e+b+i+",
+       38750,  "d+i-b+d+",
+       39250,  "b+g-l-+d+",
+       39500,  "b+g-c+g-",
+       39750,  "b+bh-c+f-",
+       40250,  "b+bf+d+g-",
+       40500,  "b+g-c+g+",
+       40750,  "c+b+i-e+",
+       41250,  "d++bf+h+",
+       41500,  "b+j+c+d-",
+       41750,  "c+f+b+h-",
+       42500,  "c+h++g+",
+       42750,  "b+g+d-f-",
+       43250,  "b+l-e+d-",
+       43750,  "c+bd+h+f-",
+       44000,  "b+f+g-d-",
+       44250,  "b+d-g--f+",
+       44500,  "c+e+c+h+",
+       44750,  "b+e+d-h-",
+       45250,  "b++g+j-g+",
+       45500,  "c+d+e-g+",
+       45750,  "b+d-h-e-",
+       46250,  "c+bd++j+",
+       46500,  "b+d-c-j-",
+       46750,  "e-e-b+g-",
+       47000,  "b+c+d-j-",
+       47250,  "b+e+e-g-",
+       47500,  "b+g-c-h-",
+       47750,  "b+f-c+h-",
+       48250,  "d--h+n-",
+       48500,  "b+c-g+m-",
+       48750,  "b+e+e-g+",
+       49500,  "c-f+e+j-",
+       49750,  "c+c+g++f-",
+       50000,  "b+e+e+k+",
+       50250,  "b++i++g+",
+       50500,  "c+g+f-i+",
+       50750,  "b+e+d+k-",
+       51500,  "b+i+c-f+",
+       51750,  "b+bd+g-e-",
+       52250,  "b+d+g-j+",
+       52500,  "c+c+f+g+",
+       52750,  "b+c+e+i+",
+       53000,  "b+i+c+g+",
+       53500,  "c+g+g-n+",
+       53750,  "b+j+d-c+",
+       54250,  "b+d-g-j-",
+       54500,  "c-f+e+f+",
+       54750,  "b+f-+c+g+",
+       55000,  "b+g-d-g-",
+       55250,  "b+e+e+g+",
+       55500,  "b+cd++j+",
+       55750,  "b+bh-d-f-",
+       56250,  "c+d-b+j-",
+       56500,  "c+d+c+i+",
+       56750,  "b+e+d++h-",
+       57000,  "b+d+g-f+",
+       57250,  "b+f-m+d-",
+       57750,  "b+i+c+e-",
+       58000,  "b+e+d+h+",
+       58250,  "c+b+g+g+",
+       58750,  "d-e-j--e+",
+       59000,  "d-i-+e+",
+       59250,  "e--h-m+",
+       59500,  "c+c-h+f-",
+       59750,  "b+bh-e+i-",
+       60250,  "b+bh-e-e-",
+       60500,  "c+c-g-g-",
+       60750,  "b+e-l-e-",
+       61250,  "b+g-g-c+",
+       61750,  "b+g-c+g+",
+       62250,  "f--+c-i-",
+       62750,  "e+f--+g+",
+       64750,  "b+f+d+p-",
+};
+int    hintabsize      = nelem(hintab);
diff --git a/src/cmd/9c/peep.c b/src/cmd/9c/peep.c
new file mode 100644 (file)
index 0000000..2e8e2ad
--- /dev/null
@@ -0,0 +1,1076 @@
+// cmd/9c/peep.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.
+
+#include "gc.h"
+
+/*
+static Reg*
+rnops(Reg *r)
+{
+       Prog *p;
+       Reg *r1;
+
+       if(r != R)
+       for(;;){
+               p = r->prog;
+               if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
+                       break;
+               r1 = uniqs(r);
+               if(r1 == R)
+                       break;
+               r = r1;
+       }
+       return r;
+}
+*/
+
+void
+peep(void)
+{
+       Reg *r, *r1, *r2;
+       Prog *p, *p1;
+       int t;
+/*
+ * complete R structure
+ */
+       t = 0;
+       for(r=firstr; r!=R; r=r1) {
+               r1 = r->link;
+               if(r1 == R)
+                       break;
+               p = r->prog->link;
+               while(p != r1->prog)
+               switch(p->as) {
+               default:
+                       r2 = rega();
+                       r->link = r2;
+                       r2->link = r1;
+
+                       r2->prog = p;
+                       r2->p1 = r;
+                       r->s1 = r2;
+                       r2->s1 = r1;
+                       r1->p1 = r2;
+
+                       r = r2;
+                       t++;
+
+               case ADATA:
+               case AGLOBL:
+               case ANAME:
+               case ASIGNAME:
+                       p = p->link;
+               }
+       }
+
+loop1:
+       t = 0;
+       for(r=firstr; r!=R; r=r->link) {
+               p = r->prog;
+               if(p->as == AMOVW || p->as == AMOVD || p->as == AFMOVS || p->as == AFMOVD)
+               if(regtyp(&p->to)) {
+                       if(regtyp(&p->from))
+                       if(p->from.type == p->to.type) {
+                               if(copyprop(r)) {
+                                       excise(r);
+                                       t++;
+                               } else
+                               if(subprop(r) && copyprop(r)) {
+                                       excise(r);
+                                       t++;
+                               }
+                       }
+                       if(regzer(&p->from))
+                       if(p->to.type == D_REG) {
+                               p->from.type = D_REG;
+                               p->from.reg = REGZERO;
+                               if(copyprop(r)) {
+                                       excise(r);
+                                       t++;
+                               } else
+                               if(subprop(r) && copyprop(r)) {
+                                       excise(r);
+                                       t++;
+                               }
+                       }
+               }
+       }
+       if(t)
+               goto loop1;
+       /*
+        * look for MOVB x,R; MOVB R,R
+        */
+       for(r=firstr; r!=R; r=r->link) {
+               p = r->prog;
+               switch(p->as) {
+               default:
+                       continue;
+               case AMOVH:
+               case AMOVHZ:
+               case AMOVB:
+               case AMOVBZ:
+               case AMOVW:
+               case AMOVWZ:
+                       if(p->to.type != D_REG)
+                               continue;
+                       break;
+               }
+               r1 = r->link;
+               if(r1 == R)
+                       continue;
+               p1 = r1->prog;
+               if(p1->as != p->as)
+                       continue;
+               if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
+                       continue;
+               if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
+                       continue;
+               excise(r1);
+       }
+
+       if(debug['D'] > 1)
+               return; /* allow following code improvement to be suppressed */
+
+       /*
+        * look for OP x,y,R; CMP R, $0 -> OPCC x,y,R
+        * when OP can set condition codes correctly
+        */
+       for(r=firstr; r!=R; r=r->link) {
+               p = r->prog;
+               switch(p->as) {
+               case ACMP:
+               case ACMPW:             /* always safe? */
+                       if(!regzer(&p->to))
+                               continue;
+                       r1 = r->s1;
+                       if(r1 == R)
+                               continue;
+                       switch(r1->prog->as) {
+                       default:
+                               continue;
+                       case ABCL:
+                       case ABC:
+                               /* the conditions can be complex and these are currently little used */
+                               continue;
+                       case ABEQ:
+                       case ABGE:
+                       case ABGT:
+                       case ABLE:
+                       case ABLT:
+                       case ABNE:
+                       case ABVC:
+                       case ABVS:
+                               break;
+                       }
+                       r1 = r;
+                       do
+                               r1 = uniqp(r1);
+                       while (r1 != R && r1->prog->as == ANOP);
+                       if(r1 == R)
+                               continue;
+                       p1 = r1->prog;
+                       if(p1->to.type != D_REG || p1->to.reg != p->from.reg)
+                               continue;
+                       switch(p1->as) {
+                       case ASUB:
+                       case AADD:
+                       case AXOR:
+                       case AOR:
+                               /* irregular instructions */
+                               if(p1->from.type == D_CONST)
+                                       continue;
+                               break;
+                       }
+                       switch(p1->as) {
+                       default:
+                               continue;
+                       case AMOVW:
+                       case AMOVD:
+                               if(p1->from.type != D_REG)
+                                       continue;
+                               continue;
+                       case AANDCC:
+                       case AANDNCC:
+                       case AORCC:
+                       case AORNCC:
+                       case AXORCC:
+                       case ASUBCC:
+                       case ASUBECC:
+                       case ASUBMECC:
+                       case ASUBZECC:
+                       case AADDCC:
+                       case AADDCCC:
+                       case AADDECC:
+                       case AADDMECC:
+                       case AADDZECC:
+                       case ARLWMICC:
+                       case ARLWNMCC:
+                               t = p1->as;
+                               break;
+                       /* don't deal with floating point instructions for now */
+/*
+                       case AFABS:     t = AFABSCC; break;
+                       case AFADD:     t = AFADDCC; break;
+                       case AFADDS:    t = AFADDSCC; break;
+                       case AFCTIW:    t = AFCTIWCC; break;
+                       case AFCTIWZ:   t = AFCTIWZCC; break;
+                       case AFDIV:     t = AFDIVCC; break;
+                       case AFDIVS:    t = AFDIVSCC; break;
+                       case AFMADD:    t = AFMADDCC; break;
+                       case AFMADDS:   t = AFMADDSCC; break;
+                       case AFMOVD:    t = AFMOVDCC; break;
+                       case AFMSUB:    t = AFMSUBCC; break;
+                       case AFMSUBS:   t = AFMSUBSCC; break;
+                       case AFMUL:     t = AFMULCC; break;
+                       case AFMULS:    t = AFMULSCC; break;
+                       case AFNABS:    t = AFNABSCC; break;
+                       case AFNEG:     t = AFNEGCC; break;
+                       case AFNMADD:   t = AFNMADDCC; break;
+                       case AFNMADDS:  t = AFNMADDSCC; break;
+                       case AFNMSUB:   t = AFNMSUBCC; break;
+                       case AFNMSUBS:  t = AFNMSUBSCC; break;
+                       case AFRSP:     t = AFRSPCC; break;
+                       case AFSUB:     t = AFSUBCC; break;
+                       case AFSUBS:    t = AFSUBSCC; break;
+                       case ACNTLZW:   t = ACNTLZWCC; break;
+                       case AMTFSB0:   t = AMTFSB0CC; break;
+                       case AMTFSB1:   t = AMTFSB1CC; break;
+*/
+                       case AADD:      t = AADDCC; break;
+                       case AADDV:     t = AADDVCC; break;
+                       case AADDC:     t = AADDCCC; break;
+                       case AADDCV:    t = AADDCVCC; break;
+                       case AADDME:    t = AADDMECC; break;
+                       case AADDMEV:   t = AADDMEVCC; break;
+                       case AADDE:     t = AADDECC; break;
+                       case AADDEV:    t = AADDEVCC; break;
+                       case AADDZE:    t = AADDZECC; break;
+                       case AADDZEV:   t = AADDZEVCC; break;
+                       case AAND:      t = AANDCC; break;
+                       case AANDN:     t = AANDNCC; break;
+                       case ADIVW:     t = ADIVWCC; break;
+                       case ADIVWV:    t = ADIVWVCC; break;
+                       case ADIVWU:    t = ADIVWUCC; break;
+                       case ADIVWUV:   t = ADIVWUVCC; break;
+                       case ADIVD:     t = ADIVDCC; break;
+                       case ADIVDV:    t = ADIVDVCC; break;
+                       case ADIVDU:    t = ADIVDUCC; break;
+                       case ADIVDUV:   t = ADIVDUVCC; break;
+                       case AEQV:      t = AEQVCC; break;
+                       case AEXTSB:    t = AEXTSBCC; break;
+                       case AEXTSH:    t = AEXTSHCC; break;
+                       case AEXTSW:    t = AEXTSWCC; break;
+                       case AMULHW:    t = AMULHWCC; break;
+                       case AMULHWU:   t = AMULHWUCC; break;
+                       case AMULLW:    t = AMULLWCC; break;
+                       case AMULLWV:   t = AMULLWVCC; break;
+                       case AMULHD:    t = AMULHDCC; break;
+                       case AMULHDU:   t = AMULHDUCC; break;
+                       case AMULLD:    t = AMULLDCC; break;
+                       case AMULLDV:   t = AMULLDVCC; break;
+                       case ANAND:     t = ANANDCC; break;
+                       case ANEG:      t = ANEGCC; break;
+                       case ANEGV:     t = ANEGVCC; break;
+                       case ANOR:      t = ANORCC; break;
+                       case AOR:       t = AORCC; break;
+                       case AORN:      t = AORNCC; break;
+                       case AREM:      t = AREMCC; break;
+                       case AREMV:     t = AREMVCC; break;
+                       case AREMU:     t = AREMUCC; break;
+                       case AREMUV:    t = AREMUVCC; break;
+                       case AREMD:     t = AREMDCC; break;
+                       case AREMDV:    t = AREMDVCC; break;
+                       case AREMDU:    t = AREMDUCC; break;
+                       case AREMDUV:   t = AREMDUVCC; break;
+                       case ARLWMI:    t = ARLWMICC; break;
+                       case ARLWNM:    t = ARLWNMCC; break;
+                       case ASLW:      t = ASLWCC; break;
+                       case ASRAW:     t = ASRAWCC; break;
+                       case ASRW:      t = ASRWCC; break;
+                       case ASLD:      t = ASLDCC; break;
+                       case ASRAD:     t = ASRADCC; break;
+                       case ASRD:      t = ASRDCC; break;
+                       case ASUB:      t = ASUBCC; break;
+                       case ASUBV:     t = ASUBVCC; break;
+                       case ASUBC:     t = ASUBCCC; break;
+                       case ASUBCV:    t = ASUBCVCC; break;
+                       case ASUBME:    t = ASUBMECC; break;
+                       case ASUBMEV:   t = ASUBMEVCC; break;
+                       case ASUBE:     t = ASUBECC; break;
+                       case ASUBEV:    t = ASUBEVCC; break;
+                       case ASUBZE:    t = ASUBZECC; break;
+                       case ASUBZEV:   t = ASUBZEVCC; break;
+                       case AXOR:      t = AXORCC; break;
+                               break;
+                       }
+                       if(debug['D'])
+                               print("cmp %P; %P -> ", p1, p);
+                       p1->as = t;
+                       if(debug['D'])
+                               print("%P\n", p1);
+                       excise(r);
+                       continue;
+               }
+       }
+}
+
+void
+excise(Reg *r)
+{
+       Prog *p;
+
+       p = r->prog;
+       p->as = ANOP;
+       p->from = zprog.from;
+       p->from3 = zprog.from3;
+       p->to = zprog.to;
+       p->reg = zprog.reg; /**/
+}
+
+Reg*
+uniqp(Reg *r)
+{
+       Reg *r1;
+
+       r1 = r->p1;
+       if(r1 == R) {
+               r1 = r->p2;
+               if(r1 == R || r1->p2link != R)
+                       return R;
+       } else
+               if(r->p2 != R)
+                       return R;
+       return r1;
+}
+
+Reg*
+uniqs(Reg *r)
+{
+       Reg *r1;
+
+       r1 = r->s1;
+       if(r1 == R) {
+               r1 = r->s2;
+               if(r1 == R)
+                       return R;
+       } else
+               if(r->s2 != R)
+                       return R;
+       return r1;
+}
+
+/*
+ * if the system forces R0 to be zero,
+ * convert references to $0 to references to R0.
+ */
+int
+regzer(Addr *a)
+{
+       if(R0ISZERO) {
+               if(a->type == D_CONST)
+                       if(a->sym == nil)
+                               if(a->offset == 0)
+                                       return 1;
+               if(a->type == D_REG)
+                       if(a->reg == REGZERO)
+                               return 1;
+       }
+       return 0;
+}
+
+int
+regtyp(Addr *a)
+{
+
+       if(a->type == D_REG) {
+               if(!R0ISZERO || a->reg != REGZERO)
+                       return 1;
+               return 0;
+       }
+       if(a->type == D_FREG)
+               return 1;
+       return 0;
+}
+
+/*
+ * the idea is to substitute
+ * one register for another
+ * from one MOV to another
+ *     MOV     a, R0
+ *     ADD     b, R0   / no use of R1
+ *     MOV     R0, R1
+ * would be converted to
+ *     MOV     a, R1
+ *     ADD     b, R1
+ *     MOV     R1, R0
+ * hopefully, then the former or latter MOV
+ * will be eliminated by copy propagation.
+ */
+int
+subprop(Reg *r0)
+{
+       Prog *p;
+       Addr *v1, *v2;
+       Reg *r;
+       int t;
+
+       p = r0->prog;
+       v1 = &p->from;
+       if(!regtyp(v1))
+               return 0;
+       v2 = &p->to;
+       if(!regtyp(v2))
+               return 0;
+       for(r=uniqp(r0); r!=R; r=uniqp(r)) {
+               if(uniqs(r) == R)
+                       break;
+               p = r->prog;
+               switch(p->as) {
+               case ABL:
+                       return 0;
+
+               case AADD:
+               case AADDC:
+               case AADDCC:
+               case AADDE:
+               case AADDECC:
+               case ASUB:
+               case ASUBCC:
+               case ASUBC:
+               case ASUBCCC:
+               case ASUBE:
+               case ASUBECC:
+               case ASLW:
+               case ASRW:
+               case ASRWCC:
+               case ASRAW:
+               case ASRAWCC:
+               case ASLD:
+               case ASRD:
+               case ASRAD:
+               case AOR:
+               case AORCC:
+               case AORN:
+               case AORNCC:
+               case AAND:
+               case AANDCC:
+               case AANDN:
+               case AANDNCC:
+               case ANAND:
+               case ANANDCC:
+               case ANOR:
+               case ANORCC:
+               case AXOR:
+               case AXORCC:
+               case AMULHW:
+               case AMULHWU:
+               case AMULLW:
+               case AMULLD:
+               case ADIVW:
+               case ADIVWU:
+               case ADIVD:
+               case ADIVDU:
+               case AREM:
+               case AREMU:
+               case AREMD:
+               case AREMDU:
+               case ARLWNM:
+               case ARLWNMCC:
+
+               case AFADD:
+               case AFADDS:
+               case AFSUB:
+               case AFSUBS:
+               case AFMUL:
+               case AFMULS:
+               case AFDIV:
+               case AFDIVS:
+                       if(p->to.type == v1->type)
+                       if(p->to.reg == v1->reg) {
+                               if(p->reg == NREG)
+                                       p->reg = p->to.reg;
+                               goto gotit;
+                       }
+                       break;
+
+               case AADDME:
+               case AADDMECC:
+               case AADDZE:
+               case AADDZECC:
+               case ASUBME:
+               case ASUBMECC:
+               case ASUBZE:
+               case ASUBZECC:
+               case ANEG:
+               case ANEGCC:
+               case AFNEG:
+               case AFNEGCC:
+               case AFMOVS:
+               case AFMOVD:
+               case AMOVW:
+               case AMOVD:
+                       if(p->to.type == v1->type)
+                       if(p->to.reg == v1->reg)
+                               goto gotit;
+                       break;
+               }
+               if(copyau(&p->from, v2) ||
+                  copyau1(p, v2) ||
+                  copyau(&p->to, v2))
+                       break;
+               if(copysub(&p->from, v1, v2, 0) ||
+                  copysub1(p, v1, v2, 0) ||
+                  copysub(&p->to, v1, v2, 0))
+                       break;
+       }
+       return 0;
+
+gotit:
+       copysub(&p->to, v1, v2, 1);
+       if(debug['P']) {
+               print("gotit: %D->%D\n%P", v1, v2, r->prog);
+               if(p->from.type == v2->type)
+                       print(" excise");
+               print("\n");
+       }
+       for(r=uniqs(r); r!=r0; r=uniqs(r)) {
+               p = r->prog;
+               copysub(&p->from, v1, v2, 1);
+               copysub1(p, v1, v2, 1);
+               copysub(&p->to, v1, v2, 1);
+               if(debug['P'])
+                       print("%P\n", r->prog);
+       }
+       t = v1->reg;
+       v1->reg = v2->reg;
+       v2->reg = t;
+       if(debug['P'])
+               print("%P last\n", r->prog);
+       return 1;
+}
+
+/*
+ * The idea is to remove redundant copies.
+ *     v1->v2  F=0
+ *     (use v2 s/v2/v1/)*
+ *     set v1  F=1
+ *     use v2  return fail
+ *     -----------------
+ *     v1->v2  F=0
+ *     (use v2 s/v2/v1/)*
+ *     set v1  F=1
+ *     set v2  return success
+ */
+int
+copyprop(Reg *r0)
+{
+       Prog *p;
+       Addr *v1, *v2;
+       Reg *r;
+
+       p = r0->prog;
+       v1 = &p->from;
+       v2 = &p->to;
+       if(copyas(v1, v2))
+               return 1;
+       for(r=firstr; r!=R; r=r->link)
+               r->active = 0;
+       return copy1(v1, v2, r0->s1, 0);
+}
+
+int
+copy1(Addr *v1, Addr *v2, Reg *r, int f)
+{
+       int t;
+       Prog *p;
+
+       if(r->active) {
+               if(debug['P'])
+                       print("act set; return 1\n");
+               return 1;
+       }
+       r->active = 1;
+       if(debug['P'])
+               print("copy %D->%D f=%d\n", v1, v2, f);
+       for(; r != R; r = r->s1) {
+               p = r->prog;
+               if(debug['P'])
+                       print("%P", p);
+               if(!f && uniqp(r) == R) {
+                       f = 1;
+                       if(debug['P'])
+                               print("; merge; f=%d", f);
+               }
+               t = copyu(p, v2, nil);
+               switch(t) {
+               case 2: /* rar, cant split */
+                       if(debug['P'])
+                               print("; %Drar; return 0\n", v2);
+                       return 0;
+
+               case 3: /* set */
+                       if(debug['P'])
+                               print("; %Dset; return 1\n", v2);
+                       return 1;
+
+               case 1: /* used, substitute */
+               case 4: /* use and set */
+                       if(f) {
+                               if(!debug['P'])
+                                       return 0;
+                               if(t == 4)
+                                       print("; %Dused+set and f=%d; return 0\n", v2, f);
+                               else
+                                       print("; %Dused and f=%d; return 0\n", v2, f);
+                               return 0;
+                       }
+                       if(copyu(p, v2, v1)) {
+                               if(debug['P'])
+                                       print("; sub fail; return 0\n");
+                               return 0;
+                       }
+                       if(debug['P'])
+                               print("; sub%D/%D", v2, v1);
+                       if(t == 4) {
+                               if(debug['P'])
+                                       print("; %Dused+set; return 1\n", v2);
+                               return 1;
+                       }
+                       break;
+               }
+               if(!f) {
+                       t = copyu(p, v1, nil);
+                       if(!f && (t == 2 || t == 3 || t == 4)) {
+                               f = 1;
+                               if(debug['P'])
+                                       print("; %Dset and !f; f=%d", v1, f);
+                       }
+               }
+               if(debug['P'])
+                       print("\n");
+               if(r->s2)
+                       if(!copy1(v1, v2, r->s2, f))
+                               return 0;
+       }
+       return 1;
+}
+
+/*
+ * return
+ * 1 if v only used (and substitute),
+ * 2 if read-alter-rewrite
+ * 3 if set
+ * 4 if set and used
+ * 0 otherwise (not touched)
+ */
+int
+copyu(Prog *p, Addr *v, Addr *s)
+{
+
+       switch(p->as) {
+
+       default:
+               if(debug['P'])
+                       print(" (\?\?\?)");
+               return 2;
+
+
+       case ANOP:      /* read, write */
+       case AMOVH:
+       case AMOVHZ:
+       case AMOVB:
+       case AMOVBZ:
+       case AMOVW:
+       case AMOVWZ:
+       case AMOVD:
+
+       case ANEG:
+       case ANEGCC:
+       case AADDME:
+       case AADDMECC:
+       case AADDZE:
+       case AADDZECC:
+       case ASUBME:
+       case ASUBMECC:
+       case ASUBZE:
+       case ASUBZECC:
+
+       case AFCTIW:
+       case AFCTIWZ:
+       case AFMOVS:
+       case AFMOVD:
+       case AFRSP:
+       case AFNEG:
+       case AFNEGCC:
+               if(s != nil) {
+                       if(copysub(&p->from, v, s, 1))
+                               return 1;
+                       if(!copyas(&p->to, v))
+                               if(copysub(&p->to, v, s, 1))
+                                       return 1;
+                       return 0;
+               }
+               if(copyas(&p->to, v)) {
+                       if(copyau(&p->from, v))
+                               return 4;
+                       return 3;
+               }
+               if(copyau(&p->from, v))
+                       return 1;
+               if(copyau(&p->to, v))
+                       return 1;
+               return 0;
+
+       case ARLWMI:    /* read read rar */
+       case ARLWMICC:
+               if(copyas(&p->to, v))
+                       return 2;
+               /* fall through */
+
+       case AADD:      /* read read write */
+       case AADDC:
+       case AADDE:
+       case ASUB:
+       case ASLW:
+       case ASRW:
+       case ASRAW:
+       case ASLD:
+       case ASRD:
+       case ASRAD:
+       case AOR:
+       case AORCC:
+       case AORN:
+       case AORNCC:
+       case AAND:
+       case AANDCC:
+       case AANDN:
+       case AANDNCC:
+       case ANAND:
+       case ANANDCC:
+       case ANOR:
+       case ANORCC:
+       case AXOR:
+       case AMULHW:
+       case AMULHWU:
+       case AMULLW:
+       case AMULLD:
+       case ADIVW:
+       case ADIVD:
+       case ADIVWU:
+       case ADIVDU:
+       case AREM:
+       case AREMU:
+       case AREMD:
+       case AREMDU:
+       case ARLWNM:
+       case ARLWNMCC:
+
+       case AFADDS:
+       case AFADD:
+       case AFSUBS:
+       case AFSUB:
+       case AFMULS:
+       case AFMUL:
+       case AFDIVS:
+       case AFDIV:
+               if(s != nil) {
+                       if(copysub(&p->from, v, s, 1))
+                               return 1;
+                       if(copysub1(p, v, s, 1))
+                               return 1;
+                       if(!copyas(&p->to, v))
+                               if(copysub(&p->to, v, s, 1))
+                                       return 1;
+                       return 0;
+               }
+               if(copyas(&p->to, v)) {
+                       if(p->reg == NREG)
+                               p->reg = p->to.reg;
+                       if(copyau(&p->from, v))
+                               return 4;
+                       if(copyau1(p, v))
+                               return 4;
+                       return 3;
+               }
+               if(copyau(&p->from, v))
+                       return 1;
+               if(copyau1(p, v))
+                       return 1;
+               if(copyau(&p->to, v))
+                       return 1;
+               return 0;
+
+       case ABEQ:
+       case ABGT:
+       case ABGE:
+       case ABLT:
+       case ABLE:
+       case ABNE:
+       case ABVC:
+       case ABVS:
+               break;
+
+       case ACMP:      /* read read */
+       case ACMPU:
+       case ACMPW:
+       case ACMPWU:
+       case AFCMPO:
+       case AFCMPU:
+               if(s != nil) {
+                       if(copysub(&p->from, v, s, 1))
+                               return 1;
+                       return copysub(&p->to, v, s, 1);
+               }
+               if(copyau(&p->from, v))
+                       return 1;
+               if(copyau(&p->to, v))
+                       return 1;
+               break;
+
+       case ABR:       /* funny */
+               if(s != nil) {
+                       if(copysub(&p->to, v, s, 1))
+                               return 1;
+                       return 0;
+               }
+               if(copyau(&p->to, v))
+                       return 1;
+               return 0;
+
+       case ARETURN:   /* funny */
+               if(v->type == D_REG)
+                       if(v->reg == REGRET)
+                               return 2;
+               if(v->type == D_FREG)
+                       if(v->reg == FREGRET)
+                               return 2;
+
+       case ABL:       /* funny */
+               if(v->type == D_REG) {
+                       if(v->reg <= REGEXT && v->reg > exregoffset)
+                               return 2;
+                       if(v->reg == REGARG)
+                               return 2;
+               }
+               if(v->type == D_FREG) {
+                       if(v->reg <= FREGEXT && v->reg > exfregoffset)
+                               return 2;
+               }
+
+               if(s != nil) {
+                       if(copysub(&p->to, v, s, 1))
+                               return 1;
+                       return 0;
+               }
+               if(copyau(&p->to, v))
+                       return 4;
+               return 3;
+
+       case ATEXT:     /* funny */
+               if(v->type == D_REG)
+                       if(v->reg == REGARG)
+                               return 3;
+               return 0;
+       }
+       return 0;
+}
+
+int
+a2type(Prog *p)
+{
+
+       switch(p->as) {
+       case AADD:
+       case AADDC:
+       case AADDCC:
+       case AADDCCC:
+       case AADDE:
+       case AADDECC:
+       case AADDME:
+       case AADDMECC:
+       case AADDZE:
+       case AADDZECC:
+       case ASUB:
+       case ASUBC:
+       case ASUBCC:
+       case ASUBCCC:
+       case ASUBE:
+       case ASUBECC:
+       case ASUBME:
+       case ASUBMECC:
+       case ASUBZE:
+       case ASUBZECC:
+       case ASLW:
+       case ASLWCC:
+       case ASRW:
+       case ASRWCC:
+       case ASRAW:
+       case ASRAWCC:
+       case ASLD:
+       case ASLDCC:
+       case ASRD:
+       case ASRDCC:
+       case ASRAD:
+       case ASRADCC:
+       case AOR:
+       case AORCC:
+       case AORN:
+       case AORNCC:
+       case AAND:
+       case AANDCC:
+       case AANDN:
+       case AANDNCC:
+       case AXOR:
+       case AXORCC:
+       case ANEG:
+       case ANEGCC:
+       case AMULHW:
+       case AMULHWU:
+       case AMULLW:
+       case AMULLWCC:
+       case ADIVW:
+       case ADIVWCC:
+       case ADIVWU:
+       case ADIVWUCC:
+       case AREM:
+       case AREMCC:
+       case AREMU:
+       case AREMUCC:
+       case AMULLD:
+       case AMULLDCC:
+       case ADIVD:
+       case ADIVDCC:
+       case ADIVDU:
+       case ADIVDUCC:
+       case AREMD:
+       case AREMDCC:
+       case AREMDU:
+       case AREMDUCC:
+       case ANAND:
+       case ANANDCC:
+       case ANOR:
+       case ANORCC:
+       case ARLWMI:
+       case ARLWMICC:
+       case ARLWNM:
+       case ARLWNMCC:
+               return D_REG;
+
+       case AFADDS:
+       case AFADDSCC:
+       case AFADD:
+       case AFADDCC:
+       case AFSUBS:
+       case AFSUBSCC:
+       case AFSUB:
+       case AFSUBCC:
+       case AFMULS:
+       case AFMULSCC:
+       case AFMUL:
+       case AFMULCC:
+       case AFDIVS:
+       case AFDIVSCC:
+       case AFDIV:
+       case AFDIVCC:
+       case AFNEG:
+       case AFNEGCC:
+               return D_FREG;
+       }
+       return D_NONE;
+}
+
+/*
+ * direct reference,
+ * could be set/use depending on
+ * semantics
+ */
+int
+copyas(Addr *a, Addr *v)
+{
+
+       if(regtyp(v))
+               if(a->type == v->type)
+               if(a->reg == v->reg)
+                       return 1;
+       return 0;
+}
+
+/*
+ * either direct or indirect
+ */
+int
+copyau(Addr *a, Addr *v)
+{
+
+       if(copyas(a, v))
+               return 1;
+       if(v->type == D_REG)
+               if(a->type == D_OREG)
+                       if(v->reg == a->reg)
+                               return 1;
+       return 0;
+}
+
+int
+copyau1(Prog *p, Addr *v)
+{
+
+       if(regtyp(v))
+               if(p->from.type == v->type || p->to.type == v->type)
+               if(p->reg == v->reg) {
+                       if(a2type(p) != v->type)
+                               print("botch a2type %P\n", p);
+                       return 1;
+               }
+       return 0;
+}
+
+/*
+ * substitute s for v in a
+ * return failure to substitute
+ */
+int
+copysub(Addr *a, Addr *v, Addr *s, int f)
+{
+
+       if(f)
+       if(copyau(a, v))
+               a->reg = s->reg;
+       return 0;
+}
+
+int
+copysub1(Prog *p1, Addr *v, Addr *s, int f)
+{
+
+       if(f)
+       if(copyau1(p1, v))
+               p1->reg = s->reg;
+       return 0;
+}
diff --git a/src/cmd/9c/reg.c b/src/cmd/9c/reg.c
new file mode 100644 (file)
index 0000000..81a7c7f
--- /dev/null
@@ -0,0 +1,1163 @@
+// cmd/9c/reg.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.
+
+#include "gc.h"
+
+Reg*
+rega(void)
+{
+       Reg *r;
+
+       r = freer;
+       if(r == R) {
+               r = alloc(sizeof(*r));
+       } else
+               freer = r->link;
+
+       *r = zreg;
+       return r;
+}
+
+int
+rcmp(const void *a1, const void *a2)
+{
+       const Rgn *p1, *p2;
+       int c1, c2;
+
+       p1 = a1;
+       p2 = a2;
+       c1 = p2->cost;
+       c2 = p1->cost;
+       if(c1 -= c2)
+               return c1;
+       return p2->varno - p1->varno;
+}
+
+void
+regopt(Prog *p)
+{
+       Reg *r, *r1, *r2;
+       Prog *p1;
+       int i, z;
+       int32 initpc, val, npc;
+       uint32 vreg;
+       Bits bit;
+       struct
+       {
+               int32   m;
+               int32   c;
+               Reg*    p;
+       } log5[6], *lp;
+
+       firstr = R;
+       lastr = R;
+       nvar = 0;
+       regbits = 0;
+       for(z=0; z<BITS; z++) {
+               externs.b[z] = 0;
+               params.b[z] = 0;
+               consts.b[z] = 0;
+               addrs.b[z] = 0;
+       }
+
+       /*
+        * pass 1
+        * build aux data structure
+        * allocate pcs
+        * find use and set of variables
+        */
+       val = 5L * 5L * 5L * 5L * 5L;
+       lp = log5;
+       for(i=0; i<5; i++) {
+               lp->m = val;
+               lp->c = 0;
+               lp->p = R;
+               val /= 5L;
+               lp++;
+       }
+       val = 0;
+       for(; p != P; p = p->link) {
+               switch(p->as) {
+               case ADATA:
+               case AGLOBL:
+               case ANAME:
+               case ASIGNAME:
+               case AFUNCDATA:
+                       continue;
+               }
+               r = rega();
+               if(firstr == R) {
+                       firstr = r;
+                       lastr = r;
+               } else {
+                       lastr->link = r;
+                       r->p1 = lastr;
+                       lastr->s1 = r;
+                       lastr = r;
+               }
+               r->prog = p;
+               r->pc = val;
+               val++;
+
+               lp = log5;
+               for(i=0; i<5; i++) {
+                       lp->c--;
+                       if(lp->c <= 0) {
+                               lp->c = lp->m;
+                               if(lp->p != R)
+                                       lp->p->log5 = r;
+                               lp->p = r;
+                               (lp+1)->c = 0;
+                               break;
+                       }
+                       lp++;
+               }
+
+               r1 = r->p1;
+               if(r1 != R)
+               switch(r1->prog->as) {
+               case ARETURN:
+               case ABR:
+               case ARFI:
+               case ARFCI:
+               case ARFID:
+                       r->p1 = R;
+                       r1->s1 = R;
+               }
+
+               /*
+                * left side always read
+                */
+               bit = mkvar(&p->from, p->as==AMOVW || p->as == AMOVWZ || p->as == AMOVD);
+               for(z=0; z<BITS; z++)
+                       r->use1.b[z] |= bit.b[z];
+
+               /*
+                * right side depends on opcode
+                */
+               bit = mkvar(&p->to, 0);
+               if(bany(&bit))
+               switch(p->as) {
+               default:
+                       diag(Z, "reg: unknown asop: %A", p->as);
+                       break;
+
+               /*
+                * right side write
+                */
+               case ANOP:
+               case AMOVB:
+               case AMOVBU:
+               case AMOVBZ:
+               case AMOVBZU:
+               case AMOVH:
+               case AMOVHBR:
+               case AMOVWBR:
+               case AMOVHU:
+               case AMOVHZ:
+               case AMOVHZU:
+               case AMOVW:
+               case AMOVWU:
+               case AMOVWZ:
+               case AMOVWZU:
+               case AMOVD:
+               case AMOVDU:
+               case AFMOVD:
+               case AFMOVDCC:
+               case AFMOVDU:
+               case AFMOVS:
+               case AFMOVSU:
+               case AFRSP:
+                       for(z=0; z<BITS; z++)
+                               r->set.b[z] |= bit.b[z];
+                       break;
+
+               /*
+                * funny
+                */
+               case ABL:
+                       for(z=0; z<BITS; z++)
+                               addrs.b[z] |= bit.b[z];
+                       break;
+               }
+       }
+       if(firstr == R)
+               return;
+       initpc = pc - val;
+       npc = val;
+
+       /*
+        * pass 2
+        * turn branch references to pointers
+        * build back pointers
+        */
+       for(r = firstr; r != R; r = r->link) {
+               p = r->prog;
+               if(p->to.type == D_BRANCH) {
+                       val = p->to.offset - initpc;
+                       r1 = firstr;
+                       while(r1 != R) {
+                               r2 = r1->log5;
+                               if(r2 != R && val >= r2->pc) {
+                                       r1 = r2;
+                                       continue;
+                               }
+                               if(r1->pc == val)
+                                       break;
+                               r1 = r1->link;
+                       }
+                       if(r1 == R) {
+                               nearln = p->lineno;
+                               diag(Z, "ref not found\n%P", p);
+                               continue;
+                       }
+                       if(r1 == r) {
+                               nearln = p->lineno;
+                               diag(Z, "ref to self\n%P", p);
+                               continue;
+                       }
+                       r->s2 = r1;
+                       r->p2link = r1->p2;
+                       r1->p2 = r;
+               }
+       }
+       if(debug['R']) {
+               p = firstr->prog;
+               print("\n%L %D\n", p->lineno, &p->from);
+       }
+
+       /*
+        * pass 2.5
+        * find looping structure
+        */
+       for(r = firstr; r != R; r = r->link)
+               r->active = 0;
+       change = 0;
+       loopit(firstr, npc);
+       if(debug['R'] && debug['v']) {
+               print("\nlooping structure:\n");
+               for(r = firstr; r != R; r = r->link) {
+                       print("%ld:%P", r->loop, r->prog);
+                       for(z=0; z<BITS; z++)
+                               bit.b[z] = r->use1.b[z] |
+                                       r->use2.b[z] | r->set.b[z];
+                       if(bany(&bit)) {
+                               print("\t");
+                               if(bany(&r->use1))
+                                       print(" u1=%B", r->use1);
+                               if(bany(&r->use2))
+                                       print(" u2=%B", r->use2);
+                               if(bany(&r->set))
+                                       print(" st=%B", r->set);
+                       }
+                       print("\n");
+               }
+       }
+
+       /*
+        * pass 3
+        * iterate propagating usage
+        *      back until flow graph is complete
+        */
+loop1:
+       change = 0;
+       for(r = firstr; r != R; r = r->link)
+               r->active = 0;
+       for(r = firstr; r != R; r = r->link)
+               if(r->prog->as == ARETURN)
+                       prop(r, zbits, zbits);
+loop11:
+       /* pick up unreachable code */
+       i = 0;
+       for(r = firstr; r != R; r = r1) {
+               r1 = r->link;
+               if(r1 && r1->active && !r->active) {
+                       prop(r, zbits, zbits);
+                       i = 1;
+               }
+       }
+       if(i)
+               goto loop11;
+       if(change)
+               goto loop1;
+
+
+       /*
+        * pass 4
+        * iterate propagating register/variable synchrony
+        *      forward until graph is complete
+        */
+loop2:
+       change = 0;
+       for(r = firstr; r != R; r = r->link)
+               r->active = 0;
+       synch(firstr, zbits);
+       if(change)
+               goto loop2;
+
+
+       /*
+        * pass 5
+        * isolate regions
+        * calculate costs (paint1)
+        */
+       r = firstr;
+       if(r) {
+               for(z=0; z<BITS; z++)
+                       bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
+                         ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
+               if(bany(&bit)) {
+                       nearln = r->prog->lineno;
+                       warn(Z, "used and not set: %B", bit);
+                       if(debug['R'] && !debug['w'])
+                               print("used and not set: %B\n", bit);
+               }
+       }
+       if(debug['R'] && debug['v'])
+               print("\nprop structure:\n");
+       for(r = firstr; r != R; r = r->link)
+               r->act = zbits;
+       rgp = region;
+       nregion = 0;
+       for(r = firstr; r != R; r = r->link) {
+               if(debug['R'] && debug['v'])
+                       print("%P\n     set = %B; rah = %B; cal = %B\n",
+                               r->prog, r->set, r->refahead, r->calahead);
+               for(z=0; z<BITS; z++)
+                       bit.b[z] = r->set.b[z] &
+                         ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
+               if(bany(&bit)) {
+                       nearln = r->prog->lineno;
+                       warn(Z, "set and not used: %B", bit);
+                       if(debug['R'])
+                               print("set an not used: %B\n", bit);
+                       excise(r);
+               }
+               for(z=0; z<BITS; z++)
+                       bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
+               while(bany(&bit)) {
+                       i = bnum(bit);
+                       rgp->enter = r;
+                       rgp->varno = i;
+                       change = 0;
+                       if(debug['R'] && debug['v'])
+                               print("\n");
+                       paint1(r, i);
+                       bit.b[i/32] &= ~(1L<<(i%32));
+                       if(change <= 0) {
+                               if(debug['R'])
+                                       print("%L$%d: %B\n",
+                                               r->prog->lineno, change, blsh(i));
+                               continue;
+                       }
+                       rgp->cost = change;
+                       nregion++;
+                       if(nregion >= NRGN)
+                               fatal(Z, "too many regions");
+                       rgp++;
+               }
+       }
+       qsort(region, nregion, sizeof(region[0]), rcmp);
+
+       /*
+        * pass 6
+        * determine used registers (paint2)
+        * replace code (paint3)
+        */
+       rgp = region;
+       for(i=0; i<nregion; i++) {
+               bit = blsh(rgp->varno);
+               vreg = paint2(rgp->enter, rgp->varno);
+               vreg = allreg(vreg, rgp);
+               if(debug['R']) {
+                       if(rgp->regno >= NREG)
+                               print("%L$%d F%d: %B\n",
+                                       rgp->enter->prog->lineno,
+                                       rgp->cost,
+                                       rgp->regno-NREG,
+                                       bit);
+                       else
+                               print("%L$%d R%d: %B\n",
+                                       rgp->enter->prog->lineno,
+                                       rgp->cost,
+                                       rgp->regno,
+                                       bit);
+               }
+               if(rgp->regno != 0)
+                       paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
+               rgp++;
+       }
+       /*
+        * pass 7
+        * peep-hole on basic block
+        */
+       if(!debug['R'] || debug['P'])
+               peep();
+
+       /*
+        * pass 8
+        * recalculate pc
+        */
+       val = initpc;
+       for(r = firstr; r != R; r = r1) {
+               r->pc = val;
+               p = r->prog;
+               p1 = P;
+               r1 = r->link;
+               if(r1 != R)
+                       p1 = r1->prog;
+               for(; p != p1; p = p->link) {
+                       switch(p->as) {
+                       default:
+                               val++;
+                               break;
+
+                       case ANOP:
+                       case ADATA:
+                       case AGLOBL:
+                       case ANAME:
+                       case ASIGNAME:
+                       case AFUNCDATA:
+                               break;
+                       }
+               }
+       }
+       pc = val;
+
+       /*
+        * fix up branches
+        */
+       if(debug['R'])
+               if(bany(&addrs))
+                       print("addrs: %B\n", addrs);
+
+       r1 = 0; /* set */
+       for(r = firstr; r != R; r = r->link) {
+               p = r->prog;
+               if(p->to.type == D_BRANCH) {
+                       p->to.offset = r->s2->pc;
+                       p->to.u.branch = r->s2->prog;
+               }
+               r1 = r;
+       }
+
+       /*
+        * last pass
+        * eliminate nops
+        * free aux structures
+        */
+       for(p = firstr->prog; p != P; p = p->link){
+               while(p->link && p->link->as == ANOP)
+                       p->link = p->link->link;
+       }
+       if(r1 != R) {
+               r1->link = freer;
+               freer = firstr;
+       }
+}
+
+/*
+ * add mov b,rn
+ * just after r
+ */
+void
+addmove(Reg *r, int bn, int rn, int f)
+{
+       Prog *p, *p1;
+       Addr *a;
+       Var *v;
+
+       p1 = alloc(sizeof(*p1));
+       *p1 = zprog;
+       p = r->prog;
+
+       p1->link = p->link;
+       p->link = p1;
+       p1->lineno = p->lineno;
+
+       v = var + bn;
+
+       a = &p1->to;
+       a->sym = v->sym;
+       a->name = v->name;
+       a->offset = v->offset;
+       a->etype = v->etype;
+       a->type = D_OREG;
+       if(a->etype == TARRAY || a->sym == nil)
+               a->type = D_CONST;
+
+       p1->as = AMOVW;
+       if(v->etype == TCHAR || v->etype == TUCHAR)
+               p1->as = AMOVB;
+       if(v->etype == TSHORT || v->etype == TUSHORT)
+               p1->as = AMOVH;
+       if(v->etype == TVLONG || v->etype == TUVLONG || v->etype == TIND)
+               p1->as = AMOVD;
+       if(v->etype == TFLOAT)
+               p1->as = AFMOVS;
+       if(v->etype == TDOUBLE)
+               p1->as = AFMOVD;
+
+       p1->from.type = D_REG;
+       p1->from.reg = rn;
+       if(rn >= NREG) {
+               p1->from.type = D_FREG;
+               p1->from.reg = rn-NREG;
+       }
+       if(!f) {
+               p1->from = *a;
+               *a = zprog.from;
+               a->type = D_REG;
+               a->reg = rn;
+               if(rn >= NREG) {
+                       a->type = D_FREG;
+                       a->reg = rn-NREG;
+               }
+               if(v->etype == TUCHAR)
+                       p1->as = AMOVBZ;
+               if(v->etype == TUSHORT)
+                       p1->as = AMOVHZ;
+               if(v->etype == TUINT || v->etype == TULONG)
+                       p1->as = AMOVWZ;
+       }
+       if(debug['R'])
+               print("%P\t.a%P\n", p, p1);
+}
+
+Bits
+mkvar(Addr *a, int docon)
+{
+       Var *v;
+       int i, t, n, et, z;
+       int64 o;
+       Bits bit;
+       LSym *s;
+
+       t = a->type;
+       if(t == D_REG && a->reg != NREG)
+               regbits |= RtoB(a->reg);
+       if(t == D_FREG && a->reg != NREG)
+               regbits |= FtoB(a->reg);
+       s = a->sym;
+       o = a->offset;
+       et = a->etype;
+       if(s == nil) {
+               if(t != D_CONST || !docon || a->reg != NREG)
+                       goto none;
+               et = TLONG;
+       }
+       if(t == D_CONST) {
+               if(s == nil && sval(o))
+                       goto none;
+       }
+       n = a->name;
+       v = var;
+       for(i=0; i<nvar; i++) {
+               if(s == v->sym)
+               if(n == v->name)
+               if(o == v->offset)
+                       goto out;
+               v++;
+       }
+       if(s)
+               if(s->name[0] == '.')
+                       goto none;
+       if(nvar >= NVAR)
+               fatal(Z, "variable not optimized: %s", s->name);
+       i = nvar;
+       nvar++;
+       v = &var[i];
+       v->sym = s;
+       v->offset = o;
+       v->etype = et;
+       v->name = n;
+       if(debug['R'])
+               print("bit=%2d et=%2d %D\n", i, et, a);
+out:
+       bit = blsh(i);
+       if(n == D_EXTERN || n == D_STATIC)
+               for(z=0; z<BITS; z++)
+                       externs.b[z] |= bit.b[z];
+       if(n == D_PARAM)
+               for(z=0; z<BITS; z++)
+                       params.b[z] |= bit.b[z];
+       if(v->etype != et || !(typechlpfd[et] || typev[et]))    /* funny punning */
+               for(z=0; z<BITS; z++)
+                       addrs.b[z] |= bit.b[z];
+       if(t == D_CONST) {
+               if((int32)o != o)
+                       v->etype = TVLONG;
+               if(s == nil) {
+                       for(z=0; z<BITS; z++)
+                               consts.b[z] |= bit.b[z];
+                       return bit;
+               }
+               if(et != TARRAY)
+                       for(z=0; z<BITS; z++)
+                               addrs.b[z] |= bit.b[z];
+               for(z=0; z<BITS; z++)
+                       params.b[z] |= bit.b[z];
+               return bit;
+       }
+       if(t == D_OREG)
+               return bit;
+
+none:
+       return zbits;
+}
+
+void
+prop(Reg *r, Bits ref, Bits cal)
+{
+       Reg *r1, *r2;
+       int z;
+
+       for(r1 = r; r1 != R; r1 = r1->p1) {
+               for(z=0; z<BITS; z++) {
+                       ref.b[z] |= r1->refahead.b[z];
+                       if(ref.b[z] != r1->refahead.b[z]) {
+                               r1->refahead.b[z] = ref.b[z];
+                               change++;
+                       }
+                       cal.b[z] |= r1->calahead.b[z];
+                       if(cal.b[z] != r1->calahead.b[z]) {
+                               r1->calahead.b[z] = cal.b[z];
+                               change++;
+                       }
+               }
+               switch(r1->prog->as) {
+               case ABL:
+                       for(z=0; z<BITS; z++) {
+                               cal.b[z] |= ref.b[z] | externs.b[z];
+                               ref.b[z] = 0;
+                       }
+                       break;
+
+               case ATEXT:
+                       for(z=0; z<BITS; z++) {
+                               cal.b[z] = 0;
+                               ref.b[z] = 0;
+                       }
+                       break;
+
+               case ARETURN:
+                       for(z=0; z<BITS; z++) {
+                               cal.b[z] = externs.b[z];
+                               ref.b[z] = 0;
+                       }
+               }
+               for(z=0; z<BITS; z++) {
+                       ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
+                               r1->use1.b[z] | r1->use2.b[z];
+                       cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
+                       r1->refbehind.b[z] = ref.b[z];
+                       r1->calbehind.b[z] = cal.b[z];
+               }
+               if(r1->active)
+                       break;
+               r1->active = 1;
+       }
+       for(; r != r1; r = r->p1)
+               for(r2 = r->p2; r2 != R; r2 = r2->p2link)
+                       prop(r2, r->refbehind, r->calbehind);
+}
+
+/*
+ * find looping structure
+ *
+ * 1) find reverse postordering
+ * 2) find approximate dominators,
+ *     the actual dominators if the flow graph is reducible
+ *     otherwise, dominators plus some other non-dominators.
+ *     See Matthew S. Hecht and Jeffrey D. Ullman,
+ *     "Analysis of a Simple Algorithm for Global Data Flow Problems",
+ *     Conf.  Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
+ *     Oct. 1-3, 1973, pp.  207-217.
+ * 3) find all nodes with a predecessor dominated by the current node.
+ *     such a node is a loop head.
+ *     recursively, all preds with a greater rpo number are in the loop
+ */
+int32
+postorder(Reg *r, Reg **rpo2r, int32 n)
+{
+       Reg *r1;
+
+       r->rpo = 1;
+       r1 = r->s1;
+       if(r1 && !r1->rpo)
+               n = postorder(r1, rpo2r, n);
+       r1 = r->s2;
+       if(r1 && !r1->rpo)
+               n = postorder(r1, rpo2r, n);
+       rpo2r[n] = r;
+       n++;
+       return n;
+}
+
+int32
+rpolca(int32 *idom, int32 rpo1, int32 rpo2)
+{
+       int32 t;
+
+       if(rpo1 == -1)
+               return rpo2;
+       while(rpo1 != rpo2){
+               if(rpo1 > rpo2){
+                       t = rpo2;
+                       rpo2 = rpo1;
+                       rpo1 = t;
+               }
+               while(rpo1 < rpo2){
+                       t = idom[rpo2];
+                       if(t >= rpo2)
+                               fatal(Z, "bad idom");
+                       rpo2 = t;
+               }
+       }
+       return rpo1;
+}
+
+int
+doms(int32 *idom, int32 r, int32 s)
+{
+       while(s > r)
+               s = idom[s];
+       return s == r;
+}
+
+int
+loophead(int32 *idom, Reg *r)
+{
+       int32 src;
+
+       src = r->rpo;
+       if(r->p1 != R && doms(idom, src, r->p1->rpo))
+               return 1;
+       for(r = r->p2; r != R; r = r->p2link)
+               if(doms(idom, src, r->rpo))
+                       return 1;
+       return 0;
+}
+
+void
+loopmark(Reg **rpo2r, int32 head, Reg *r)
+{
+       if(r->rpo < head || r->active == head)
+               return;
+       r->active = head;
+       r->loop += LOOP;
+       if(r->p1 != R)
+               loopmark(rpo2r, head, r->p1);
+       for(r = r->p2; r != R; r = r->p2link)
+               loopmark(rpo2r, head, r);
+}
+
+void
+loopit(Reg *r, int32 nr)
+{
+       Reg *r1;
+       int32 i, d, me;
+
+       if(nr > maxnr) {
+               rpo2r = alloc(nr * sizeof(Reg*));
+               idom = alloc(nr * sizeof(int32));
+               maxnr = nr;
+       }
+
+       d = postorder(r, rpo2r, 0);
+       if(d > nr)
+               fatal(Z, "too many reg nodes");
+       nr = d;
+       for(i = 0; i < nr / 2; i++){
+               r1 = rpo2r[i];
+               rpo2r[i] = rpo2r[nr - 1 - i];
+               rpo2r[nr - 1 - i] = r1;
+       }
+       for(i = 0; i < nr; i++)
+               rpo2r[i]->rpo = i;
+
+       idom[0] = 0;
+       for(i = 0; i < nr; i++){
+               r1 = rpo2r[i];
+               me = r1->rpo;
+               d = -1;
+               if(r1->p1 != R && r1->p1->rpo < me)
+                       d = r1->p1->rpo;
+               for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
+                       if(r1->rpo < me)
+                               d = rpolca(idom, d, r1->rpo);
+               idom[i] = d;
+       }
+
+       for(i = 0; i < nr; i++){
+               r1 = rpo2r[i];
+               r1->loop++;
+               if(r1->p2 != R && loophead(idom, r1))
+                       loopmark(rpo2r, i, r1);
+       }
+}
+
+void
+synch(Reg *r, Bits dif)
+{
+       Reg *r1;
+       int z;
+
+       for(r1 = r; r1 != R; r1 = r1->s1) {
+               for(z=0; z<BITS; z++) {
+                       dif.b[z] = (dif.b[z] &
+                               ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
+                                       r1->set.b[z] | r1->regdiff.b[z];
+                       if(dif.b[z] != r1->regdiff.b[z]) {
+                               r1->regdiff.b[z] = dif.b[z];
+                               change++;
+                       }
+               }
+               if(r1->active)
+                       break;
+               r1->active = 1;
+               for(z=0; z<BITS; z++)
+                       dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
+               if(r1->s2 != R)
+                       synch(r1->s2, dif);
+       }
+}
+
+uint32
+allreg(uint32 b, Rgn *r)
+{
+       Var *v;
+       int i;
+
+       v = var + r->varno;
+       r->regno = 0;
+       switch(v->etype) {
+
+       default:
+               diag(Z, "unknown etype %d/%d", bitno(b), v->etype);
+               break;
+
+       case TCHAR:
+       case TUCHAR:
+       case TSHORT:
+       case TUSHORT:
+       case TINT:
+       case TUINT:
+       case TLONG:
+       case TULONG:
+       case TIND:
+       case TVLONG:
+       case TUVLONG:
+       case TARRAY:
+               i = BtoR(~b);
+               if(i && r->cost > 0) {
+                       r->regno = i;
+                       return RtoB(i);
+               }
+               break;
+
+       case TDOUBLE:
+       case TFLOAT:
+               i = BtoF(~b);
+               if(i && r->cost > 0) {
+                       r->regno = i+NREG;
+                       return FtoB(i);
+               }
+               break;
+       }
+       return 0;
+}
+
+void
+paint1(Reg *r, int bn)
+{
+       Reg *r1;
+       Prog *p;
+       int z;
+       uint32 bb;
+
+       z = bn/32;
+       bb = 1L<<(bn%32);
+       if(r->act.b[z] & bb)
+               return;
+       for(;;) {
+               if(!(r->refbehind.b[z] & bb))
+                       break;
+               r1 = r->p1;
+               if(r1 == R)
+                       break;
+               if(!(r1->refahead.b[z] & bb))
+                       break;
+               if(r1->act.b[z] & bb)
+                       break;
+               r = r1;
+       }
+
+       if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
+               change -= CLOAD * r->loop;
+               if(debug['R'] && debug['v'])
+                       print("%ld%P\tld %B $%d\n", r->loop,
+                               r->prog, blsh(bn), change);
+       }
+       for(;;) {
+               r->act.b[z] |= bb;
+               p = r->prog;
+
+               if(r->use1.b[z] & bb) {
+                       change += CREF * r->loop;
+                       if(p->to.type == D_FREG && (p->as == AMOVW || p->as == AMOVD))
+                               change = -CINF;         /* cant go Rreg to Freg */
+                       if(debug['R'] && debug['v'])
+                               print("%ld%P\tu1 %B $%d\n", r->loop,
+                                       p, blsh(bn), change);
+               }
+
+               if((r->use2.b[z]|r->set.b[z]) & bb) {
+                       change += CREF * r->loop;
+                       if(p->from.type == D_FREG && (p->as == AMOVW || p->as == AMOVD))
+                               change = -CINF;         /* cant go Rreg to Freg */
+                       if(debug['R'] && debug['v'])
+                               print("%ld%P\tu2 %B $%d\n", r->loop,
+                                       p, blsh(bn), change);
+               }
+
+               if(STORE(r) & r->regdiff.b[z] & bb) {
+                       change -= CLOAD * r->loop;
+                       if(debug['R'] && debug['v'])
+                               print("%ld%P\tst %B $%d\n", r->loop,
+                                       p, blsh(bn), change);
+               }
+
+               if(r->refbehind.b[z] & bb)
+                       for(r1 = r->p2; r1 != R; r1 = r1->p2link)
+                               if(r1->refahead.b[z] & bb)
+                                       paint1(r1, bn);
+
+               if(!(r->refahead.b[z] & bb))
+                       break;
+               r1 = r->s2;
+               if(r1 != R)
+                       if(r1->refbehind.b[z] & bb)
+                               paint1(r1, bn);
+               r = r->s1;
+               if(r == R)
+                       break;
+               if(r->act.b[z] & bb)
+                       break;
+               if(!(r->refbehind.b[z] & bb))
+                       break;
+       }
+}
+
+uint32
+paint2(Reg *r, int bn)
+{
+       Reg *r1;
+       int z;
+       uint32 bb, vreg;
+
+       z = bn/32;
+       bb = 1L << (bn%32);
+       vreg = regbits;
+       if(!(r->act.b[z] & bb))
+               return vreg;
+       for(;;) {
+               if(!(r->refbehind.b[z] & bb))
+                       break;
+               r1 = r->p1;
+               if(r1 == R)
+                       break;
+               if(!(r1->refahead.b[z] & bb))
+                       break;
+               if(!(r1->act.b[z] & bb))
+                       break;
+               r = r1;
+       }
+       for(;;) {
+               r->act.b[z] &= ~bb;
+
+               vreg |= r->regu;
+
+               if(r->refbehind.b[z] & bb)
+                       for(r1 = r->p2; r1 != R; r1 = r1->p2link)
+                               if(r1->refahead.b[z] & bb)
+                                       vreg |= paint2(r1, bn);
+
+               if(!(r->refahead.b[z] & bb))
+                       break;
+               r1 = r->s2;
+               if(r1 != R)
+                       if(r1->refbehind.b[z] & bb)
+                               vreg |= paint2(r1, bn);
+               r = r->s1;
+               if(r == R)
+                       break;
+               if(!(r->act.b[z] & bb))
+                       break;
+               if(!(r->refbehind.b[z] & bb))
+                       break;
+       }
+       return vreg;
+}
+
+void
+paint3(Reg *r, int bn, int32 rb, int rn)
+{
+       Reg *r1;
+       Prog *p;
+       int z;
+       uint32 bb;
+
+       z = bn/32;
+       bb = 1L << (bn%32);
+       if(r->act.b[z] & bb)
+               return;
+       for(;;) {
+               if(!(r->refbehind.b[z] & bb))
+                       break;
+               r1 = r->p1;
+               if(r1 == R)
+                       break;
+               if(!(r1->refahead.b[z] & bb))
+                       break;
+               if(r1->act.b[z] & bb)
+                       break;
+               r = r1;
+       }
+
+       if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
+               addmove(r, bn, rn, 0);
+       for(;;) {
+               r->act.b[z] |= bb;
+               p = r->prog;
+
+               if(r->use1.b[z] & bb) {
+                       if(debug['R'])
+                               print("%P", p);
+                       addreg(&p->from, rn);
+                       if(debug['R'])
+                               print("\t.c%P\n", p);
+               }
+               if((r->use2.b[z]|r->set.b[z]) & bb) {
+                       if(debug['R'])
+                               print("%P", p);
+                       addreg(&p->to, rn);
+                       if(debug['R'])
+                               print("\t.c%P\n", p);
+               }
+
+               if(STORE(r) & r->regdiff.b[z] & bb)
+                       addmove(r, bn, rn, 1);
+               r->regu |= rb;
+
+               if(r->refbehind.b[z] & bb)
+                       for(r1 = r->p2; r1 != R; r1 = r1->p2link)
+                               if(r1->refahead.b[z] & bb)
+                                       paint3(r1, bn, rb, rn);
+
+               if(!(r->refahead.b[z] & bb))
+                       break;
+               r1 = r->s2;
+               if(r1 != R)
+                       if(r1->refbehind.b[z] & bb)
+                               paint3(r1, bn, rb, rn);
+               r = r->s1;
+               if(r == R)
+                       break;
+               if(r->act.b[z] & bb)
+                       break;
+               if(!(r->refbehind.b[z] & bb))
+                       break;
+       }
+}
+
+void
+addreg(Addr *a, int rn)
+{
+
+       a->sym = 0;
+       a->name = D_NONE;
+       a->type = D_REG;
+       a->reg = rn;
+       if(rn >= NREG) {
+               a->type = D_FREG;
+               a->reg = rn-NREG;
+       }
+}
+
+/*
+ * track register variables including external registers:
+ *     bit     reg
+ *     0       R7
+ *     1       R8
+ *     ...     ...
+ *     21      R28
+ */
+int32
+RtoB(int r)
+{
+
+       if(r >= REGMIN && r <= REGMAX)
+               return 1L << (r-REGMIN);
+       return 0;
+}
+
+int
+BtoR(int32 b)
+{
+       b &= 0x001fffffL;
+       if(b == 0)
+               return 0;
+       return bitno(b) + REGMIN;
+}
+
+/*
+ *     bit     reg
+ *     22      F17
+ *     23      F18
+ *     ...     ...
+ *     31      F26
+ */
+int32
+FtoB(int f)
+{
+       if(f < FREGMIN || f > FREGEXT)
+               return 0;
+       return 1L << (f - FREGMIN + 22);
+}
+
+int
+BtoF(int32 b)
+{
+
+       b &= 0xffc00000L;
+       if(b == 0)
+               return 0;
+       return bitno(b) - 22 + FREGMIN;
+}
diff --git a/src/cmd/9c/sgen.c b/src/cmd/9c/sgen.c
new file mode 100644 (file)
index 0000000..b03c172
--- /dev/null
@@ -0,0 +1,291 @@
+// cmd/9c/sgen.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.
+
+#include "gc.h"
+
+Prog*
+gtext(Sym *s, int32 stkoff)
+{
+       vlong v;
+
+       v = ((uvlong)argsize(1) << 32) | (stkoff & 0xffffffff);
+       if((textflag & NOSPLIT) && stkoff >= 128)
+               yyerror("stack frame too large for NOSPLIT function");
+
+       gpseudo(ATEXT, s, nodgconst(v, types[TVLONG]));
+       return p;
+}
+
+
+void
+noretval(int n)
+{
+
+       if(n & 1) {
+               gins(ANOP, Z, Z);
+               p->to.type = D_REG;
+               p->to.reg = REGRET;
+       }
+       if(n & 2) {
+               gins(ANOP, Z, Z);
+               p->to.type = D_FREG;
+               p->to.reg = FREGRET;
+       }
+}
+
+/*
+ *     calculate addressability as follows
+ *             CONST ==> 20            $value
+ *             NAME ==> 10             name
+ *             REGISTER ==> 11         register
+ *             INDREG ==> 12           *[(reg)+offset]
+ *             &10 ==> 2               $name
+ *             ADD(2, 20) ==> 2        $name+offset
+ *             ADD(3, 20) ==> 3        $(reg)+offset
+ *             &12 ==> 3               $(reg)+offset
+ *             *11 ==> 11              ??
+ *             *2 ==> 10               name
+ *             *3 ==> 12               *(reg)+offset
+ *     calculate complexity (number of registers)
+ */
+void
+xcom(Node *n)
+{
+       Node *l, *r;
+       int v;
+
+       if(n == Z)
+               return;
+       l = n->left;
+       r = n->right;
+       n->addable = 0;
+       n->complex = 0;
+       switch(n->op) {
+       case OCONST:
+               n->addable = 20;
+               return;
+
+       case OREGISTER:
+               n->addable = 11;
+               return;
+
+       case OINDREG:
+               n->addable = 12;
+               return;
+
+       case ONAME:
+               n->addable = 10;
+               return;
+
+       case OADDR:
+               xcom(l);
+               if(l->addable == 10)
+                       n->addable = 2;
+               if(l->addable == 12)
+                       n->addable = 3;
+               break;
+
+       case OIND:
+               xcom(l);
+               if(l->addable == 11)
+                       n->addable = 12;
+               if(l->addable == 3)
+                       n->addable = 12;
+               if(l->addable == 2)
+                       n->addable = 10;
+               break;
+
+       case OADD:
+               xcom(l);
+               xcom(r);
+               if(l->addable == 20) {
+                       if(r->addable == 2)
+                               n->addable = 2;
+                       if(r->addable == 3)
+                               n->addable = 3;
+               }
+               if(r->addable == 20) {
+                       if(l->addable == 2)
+                               n->addable = 2;
+                       if(l->addable == 3)
+                               n->addable = 3;
+               }
+               break;
+
+       case OASMUL:
+       case OASLMUL:
+               xcom(l);
+               xcom(r);
+               v = vlog(r);
+               if(v >= 0) {
+                       n->op = OASASHL;
+                       r->vconst = v;
+                       r->type = types[TINT];
+               }
+               break;
+
+       case OMUL:
+       case OLMUL:
+               xcom(l);
+               xcom(r);
+               v = vlog(r);
+               if(v >= 0) {
+                       n->op = OASHL;
+                       r->vconst = v;
+                       r->type = types[TINT];
+               }
+               v = vlog(l);
+               if(v >= 0) {
+                       n->op = OASHL;
+                       n->left = r;
+                       n->right = l;
+                       r = l;
+                       l = n->left;
+                       r->vconst = v;
+                       r->type = types[TINT];
+                       simplifyshift(n);
+               }
+               break;
+
+       case OASLDIV:
+               xcom(l);
+               xcom(r);
+               v = vlog(r);
+               if(v >= 0) {
+                       n->op = OASLSHR;
+                       r->vconst = v;
+                       r->type = types[TINT];
+               }
+               break;
+
+       case OLDIV:
+               xcom(l);
+               xcom(r);
+               v = vlog(r);
+               if(v >= 0) {
+                       n->op = OLSHR;
+                       r->vconst = v;
+                       r->type = types[TINT];
+                       simplifyshift(n);
+               }
+               break;
+
+       case OASLMOD:
+               xcom(l);
+               xcom(r);
+               v = vlog(r);
+               if(v >= 0) {
+                       n->op = OASAND;
+                       r->vconst--;
+               }
+               break;
+
+       case OLMOD:
+               xcom(l);
+               xcom(r);
+               v = vlog(r);
+               if(v >= 0) {
+                       n->op = OAND;
+                       r->vconst--;
+               }
+               break;
+
+       case OLSHR:
+       case OASHL:
+       case OASHR:
+               xcom(l);
+               xcom(r);
+               simplifyshift(n);
+               break;
+
+       default:
+               if(l != Z)
+                       xcom(l);
+               if(r != Z)
+                       xcom(r);
+               break;
+       }
+       if(n->addable >= 10)
+               return;
+       if(l != Z)
+               n->complex = l->complex;
+       if(r != Z) {
+               if(r->complex == n->complex)
+                       n->complex = r->complex+1;
+               else
+               if(r->complex > n->complex)
+                       n->complex = r->complex;
+       }
+       if(n->complex == 0)
+               n->complex++;
+
+//     if(com64(n))
+//             return;
+
+       switch(n->op) {
+
+       case OFUNC:
+               n->complex = FNX;
+               break;
+
+       case OEQ:
+       case ONE:
+       case OLE:
+       case OLT:
+       case OGE:
+       case OGT:
+       case OHI:
+       case OHS:
+       case OLO:
+       case OLS:
+               /*
+                * immediate operators, make const on right
+                */
+               if(l->op == OCONST) {
+                       n->left = r;
+                       n->right = l;
+                       n->op = invrel[relindex(n->op)];
+               }
+               break;
+
+       case OADD:
+       case OXOR:
+       case OAND:
+       case OOR:
+               /*
+                * immediate operators, make const on right
+                */
+               if(l->op == OCONST) {
+                       n->left = r;
+                       n->right = l;
+               }
+               break;
+       }
+}
+
diff --git a/src/cmd/9c/swt.c b/src/cmd/9c/swt.c
new file mode 100644 (file)
index 0000000..a63db60
--- /dev/null
@@ -0,0 +1,407 @@
+// cmd/9c/swt.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.
+
+#include "gc.h"
+
+void
+swit1(C1 *q, int nc, int32 def, Node *n)
+{
+       Node tn, nod;
+
+       regalloc(&nod, n, Z);
+       /* always signed */
+       if(typev[n->type->etype])
+               nod.type = types[TVLONG];
+       else
+               nod.type = types[TLONG];
+       cgen(n, &nod);
+       regalloc(&tn, &regnode, Z);
+       swit2(q, nc, def, &nod, &tn);
+       regfree(&tn);
+       regfree(&nod);
+}
+
+void
+swit2(C1 *q, int nc, int32 def, Node *n, Node *tn)
+{
+       C1 *r;
+       int i;
+       Prog *sp;
+
+       if(nc < 5) {
+               for(i=0; i<nc; i++) {
+                       if(sval(q->val)) {
+                               gopcode(OEQ, n, Z, nodconst(q->val));
+                       } else {
+                               gopcode(OSUB, nodconst(q->val), n, tn);
+                               gopcode(OEQ, tn, Z, nodconst(0));
+                       }
+                       patch(p, q->label);
+                       q++;
+               }
+               gbranch(OGOTO);
+               patch(p, def);
+               return;
+       }
+       i = nc / 2;
+       r = q+i;
+       if(sval(r->val)) {
+               gopcode(OGT, n, Z, nodconst(r->val));
+               sp = p;
+       } else {
+               gopcode(OSUB, nodconst(r->val), n, tn);
+               gopcode(OGT, tn, Z, nodconst(0));
+               sp = p;
+       }
+       gbranch(OGOTO);
+       p->as = ABEQ;
+       patch(p, r->label);
+       swit2(q, i, def, n, tn);
+
+       patch(sp, pc);
+       swit2(r+1, nc-i-1, def, n, tn);
+}
+
+void
+bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
+{
+       int sh;
+       int32 v;
+       Node *l;
+
+       /*
+        * n1 gets adjusted/masked value
+        * n2 gets address of cell
+        * n3 gets contents of cell
+        */
+       l = b->left;
+       if(n2 != Z) {
+               regalloc(n1, l, nn);
+               reglcgen(n2, l, Z);
+               regalloc(n3, l, Z);
+               gopcode(OAS, n2, Z, n3);
+               gopcode(OAS, n3, Z, n1);
+       } else {
+               regalloc(n1, l, nn);
+               cgen(l, n1);
+       }
+       if(b->type->shift == 0 && typeu[b->type->etype]) {
+               v = ~0 + (1L << b->type->nbits);
+               gopcode(OAND, nodconst(v), Z, n1);
+       } else {
+               sh = 32 - b->type->shift - b->type->nbits;
+               if(sh > 0)
+                       gopcode(OASHL, nodconst(sh), Z, n1);
+               sh += b->type->shift;
+               if(sh > 0)
+                       if(typeu[b->type->etype])
+                               gopcode(OLSHR, nodconst(sh), Z, n1);
+                       else
+                               gopcode(OASHR, nodconst(sh), Z, n1);
+       }
+}
+
+void
+bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
+{
+       int32 v;
+       Node nod, *l;
+       int sh;
+
+       /*
+        * n1 has adjusted/masked value
+        * n2 has address of cell
+        * n3 has contents of cell
+        */
+       l = b->left;
+       regalloc(&nod, l, Z);
+       v = ~0 + (1L << b->type->nbits);
+       gopcode(OAND, nodconst(v), Z, n1);
+       gopcode(OAS, n1, Z, &nod);
+       if(nn != Z)
+               gopcode(OAS, n1, Z, nn);
+       sh = b->type->shift;
+       if(sh > 0)
+               gopcode(OASHL, nodconst(sh), Z, &nod);
+       v <<= sh;
+       gopcode(OAND, nodconst(~v), Z, n3);
+       gopcode(OOR, n3, Z, &nod);
+       gopcode(OAS, &nod, Z, n2);
+
+       regfree(&nod);
+       regfree(n1);
+       regfree(n2);
+       regfree(n3);
+}
+
+int32
+outstring(char *s, int32 n)
+{
+       int32 r;
+
+       if(suppress)
+               return nstring;
+       r = nstring;
+       while(n) {
+               string[mnstring] = *s++;
+               mnstring++;
+               nstring++;
+               if(mnstring >= NSNAME) {
+                       gpseudo(ADATA, symstring, nodconst(0L));
+                       p->from.offset += nstring - NSNAME;
+                       p->reg = NSNAME;
+                       p->to.type = D_SCONST;
+                       memmove(p->to.u.sval, string, NSNAME);
+                       mnstring = 0;
+               }
+               n--;
+       }
+       return r;
+}
+
+int
+mulcon(Node *n, Node *nn)
+{
+       Node *l, *r, nod1, nod2;
+       Multab *m;
+       int32 v;
+       int o;
+       char code[sizeof(m->code)+2], *p;
+
+       if(typefd[n->type->etype])
+               return 0;
+       l = n->left;
+       r = n->right;
+       if(l->op == OCONST) {
+               l = r;
+               r = n->left;
+       }
+       if(r->op != OCONST)
+               return 0;
+       v = convvtox(r->vconst, n->type->etype);
+       if(v != r->vconst) {
+               if(debug['M'])
+                       print("%L multiply conv: %lld\n", n->lineno, r->vconst);
+               return 0;
+       }
+       m = mulcon0(n, v);
+       if(!m) {
+               if(debug['M'])
+                       print("%L multiply table: %lld\n", n->lineno, r->vconst);
+               return 0;
+       }
+
+       memmove(code, m->code, sizeof(m->code));
+       code[sizeof(m->code)] = 0;
+
+       p = code;
+       if(p[1] == 'i')
+               p += 2;
+       regalloc(&nod1, n, nn);
+       cgen(l, &nod1);
+       if(v < 0)
+               gopcode(ONEG, &nod1, Z, &nod1);
+       regalloc(&nod2, n, Z);
+
+loop:
+       switch(*p) {
+       case 0:
+               regfree(&nod2);
+               gopcode(OAS, &nod1, Z, nn);
+               regfree(&nod1);
+               return 1;
+       case '+':
+               o = OADD;
+               goto addsub;
+       case '-':
+               o = OSUB;
+       addsub: /* number is r,n,l */
+               v = p[1] - '0';
+               r = &nod1;
+               if(v&4)
+                       r = &nod2;
+               n = &nod1;
+               if(v&2)
+                       n = &nod2;
+               l = &nod1;
+               if(v&1)
+                       l = &nod2;
+               gopcode(o, l, n, r);
+               break;
+       default: /* op is shiftcount, number is r,l */
+               v = p[1] - '0';
+               r = &nod1;
+               if(v&2)
+                       r = &nod2;
+               l = &nod1;
+               if(v&1)
+                       l = &nod2;
+               v = *p - 'a';
+               if(v < 0 || v >= 32) {
+                       diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
+                       break;
+               }
+               gopcode(OASHL, nodconst(v), l, r);
+               break;
+       }
+       p += 2;
+       goto loop;
+}
+
+void
+sextern(Sym *s, Node *a, int32 o, int32 w)
+{
+       int32 e, lw;
+
+       for(e=0; e<w; e+=NSNAME) {
+               lw = NSNAME;
+               if(w-e < lw)
+                       lw = w-e;
+               gpseudo(ADATA, s, nodconst(0));
+               p->from.offset += o+e;
+               p->reg = lw;
+               p->to.type = D_SCONST;
+               memmove(p->to.u.sval, a->cstring+e, lw);
+       }
+}
+
+void
+gextern(Sym *s, Node *a, int32 o, int32 w)
+{
+       gpseudo(ADATA, s, a);
+       p->from.offset += o;
+       p->reg = w;
+       if(p->to.type == D_OREG)
+               p->to.type = D_CONST;
+}
+
+void
+outcode(void)
+{
+       Bprint(&outbuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
+       if(pragcgobuf.to > pragcgobuf.start) {
+               Bprint(&outbuf, "\n");
+               Bprint(&outbuf, "$$  // exports\n\n");
+               Bprint(&outbuf, "$$  // local types\n\n");
+               Bprint(&outbuf, "$$  // cgo\n");
+               Bprint(&outbuf, "%s", fmtstrflush(&pragcgobuf));
+               Bprint(&outbuf, "\n$$\n\n");
+       }
+       Bprint(&outbuf, "!\n");
+
+       writeobj(ctxt, &outbuf);
+       lastp = nil;
+}
+
+int32
+align(int32 i, Type *t, int op, int32 *maxalign)
+{
+       int32 o;
+       Type *v;
+       int w, packw;
+
+       o = i;
+       w = 1;
+       packw = 0;
+       switch(op) {
+       default:
+               diag(Z, "unknown align opcode %d", op);
+               break;
+
+       case Asu2:      /* padding at end of a struct */
+               w = *maxalign;
+               if(w < 1)
+                       w = 1;
+               if(packflg)
+                       packw = packflg;
+               break;
+
+       case Ael1:      /* initial allign of struct element */
+               for(v=t; v->etype==TARRAY; v=v->link)
+                       ;
+               if(v->etype == TSTRUCT || v->etype == TUNION)
+                       w = v->align;
+               else
+                       w = ewidth[v->etype];
+               if(w < 1 || w > SZ_VLONG)
+                       fatal(Z, "align");
+               if(packflg)
+                       packw = packflg;
+               break;
+
+       case Ael2:      /* width of a struct element */
+               o += t->width;
+               break;
+
+       case Aarg0:     /* initial passbyptr argument in arg list */
+               if(typesu[t->etype]) {
+                       o = align(o, types[TIND], Aarg1, nil);
+                       o = align(o, types[TIND], Aarg2, nil);
+               }
+               break;
+
+       case Aarg1:     /* initial align of parameter */
+               w = ewidth[t->etype];
+               if(w <= 0 || w >= SZ_VLONG) {
+                       w = SZ_VLONG;
+                       break;
+               }
+               w = 1;
+               break;
+
+       case Aarg2:     /* width of a parameter */
+               o += t->width;
+               w = t->width;
+               if(w > SZ_VLONG)
+                       w = SZ_VLONG;
+               break;
+
+       case Aaut3:     /* total align of automatic */
+               o = align(o, t, Ael1, nil);
+               o = align(o, t, Ael2, nil);
+               break;
+       }
+       if(packw != 0 && xround(o, w) != xround(o, packw))
+               diag(Z, "#pragma pack changes offset of %T", t);
+       o = xround(o, w);
+       if(maxalign && *maxalign < w)
+               *maxalign = w;
+       if(debug['A'])
+               print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
+       return o;
+}
+
+int32
+maxround(int32 max, int32 v)
+{
+       v = xround(v, SZ_VLONG);
+       if(v > max)
+               return v;
+       return max;
+}
diff --git a/src/cmd/9c/txt.c b/src/cmd/9c/txt.c
new file mode 100644 (file)
index 0000000..e46aba8
--- /dev/null
@@ -0,0 +1,1537 @@
+// cmd/9c/txt.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.
+
+#include "gc.h"
+
+static int     resvreg[nelem(reg)];
+
+#define        isv(et) ((et) == TVLONG || (et) == TUVLONG || (et) == TIND)
+
+int thechar = '9';
+char *thestring = "power64";
+
+LinkArch       *thelinkarch;
+
+void
+linkarchinit(void)
+{
+       thestring = getgoarch();
+       if(strcmp(thestring, "power64le") == 0)
+               thelinkarch = &linkpower64le;
+       else
+               thelinkarch = &linkpower64;
+}
+
+
+void
+ginit(void)
+{
+       Type *t;
+
+       dodefine("_64BITREG");
+       dodefine("_64BIT");
+       exregoffset = REGEXT;
+       exfregoffset = FREGEXT;
+       listinit();
+       nstring = 0;
+       mnstring = 0;
+       nrathole = 0;
+       pc = 0;
+       breakpc = -1;
+       continpc = -1;
+       cases = C;
+       lastp = P;
+       tfield = types[TLONG];
+
+       typeword = typechlvp;
+       typecmplx = typesu;
+       /* TO DO */
+       memmove(typechlpv, typechlp, sizeof(typechlpv));
+       typechlpv[TVLONG] = 1;
+       typechlpv[TUVLONG] = 1;
+
+       zprog.link = P;
+       zprog.as = AGOK;
+       zprog.reg = NREG;
+       zprog.from.type = D_NONE;
+       zprog.from.name = D_NONE;
+       zprog.from.reg = NREG;
+       zprog.from3 = zprog.from;
+       zprog.to = zprog.from;
+
+       regnode.op = OREGISTER;
+       regnode.class = CEXREG;
+       regnode.reg = 0;
+       regnode.complex = 0;
+       regnode.addable = 11;
+       regnode.type = types[TLONG];
+
+       qregnode = regnode;
+       qregnode.type = types[TVLONG];
+
+       constnode.op = OCONST;
+       constnode.class = CXXX;
+       constnode.complex = 0;
+       constnode.addable = 20;
+       constnode.type = types[TLONG];
+
+       vconstnode = constnode;
+       vconstnode.type = types[TVLONG];
+
+       fconstnode.op = OCONST;
+       fconstnode.class = CXXX;
+       fconstnode.complex = 0;
+       fconstnode.addable = 20;
+       fconstnode.type = types[TDOUBLE];
+
+       nodsafe = new(ONAME, Z, Z);
+       nodsafe->sym = slookup(".safe");
+       nodsafe->type = types[TINT];
+       nodsafe->etype = types[TINT]->etype;
+       nodsafe->class = CAUTO;
+       complex(nodsafe);
+
+       t = typ(TARRAY, types[TCHAR]);
+       symrathole = slookup(".rathole");
+       symrathole->class = CGLOBL;
+       symrathole->type = t;
+
+       nodrat = new(ONAME, Z, Z);
+       nodrat->sym = symrathole;
+       nodrat->type = types[TIND];
+       nodrat->etype = TVOID;
+       nodrat->class = CGLOBL;
+       complex(nodrat);
+       nodrat->type = t;
+
+       nodret = new(ONAME, Z, Z);
+       nodret->sym = slookup(".ret");
+       nodret->type = types[TIND];
+       nodret->etype = TIND;
+       nodret->class = CPARAM;
+       nodret = new(OIND, nodret, Z);
+       complex(nodret);
+
+       com64init();
+
+       memset(reg, 0, sizeof(reg));
+       reg[REGZERO] = 1;       /* don't use */
+       reg[REGTMP] = 1;
+       reg[FREGCVI+NREG] = 1;
+       reg[FREGZERO+NREG] = 1;
+       reg[FREGHALF+NREG] = 1;
+       reg[FREGONE+NREG] = 1;
+       reg[FREGTWO+NREG] = 1;
+       memmove(resvreg, reg, sizeof(reg));
+}
+
+void
+gclean(void)
+{
+       int i;
+       Sym *s;
+
+       for(i=0; i<NREG; i++)
+               if(reg[i] && !resvreg[i])
+                       diag(Z, "reg %d left allocated", i);
+       for(i=NREG; i<NREG+NREG; i++)
+               if(reg[i] && !resvreg[i])
+                       diag(Z, "freg %d left allocated", i-NREG);
+       while(mnstring)
+               outstring("", 1L);
+       symstring->type->width = nstring;
+       symrathole->type->width = nrathole;
+       for(i=0; i<NHASH; i++)
+       for(s = hash[i]; s != S; s = s->link) {
+               if(s->type == T)
+                       continue;
+               if(s->type->width == 0)
+                       continue;
+               if(s->class != CGLOBL && s->class != CSTATIC)
+                       continue;
+               if(s->type == types[TENUM])
+                       continue;
+               gpseudo(AGLOBL, s, nodconst(s->type->width));
+       }
+       nextpc();
+       p->as = AEND;
+       outcode();
+}
+
+void
+nextpc(void)
+{
+       Plist *pl;
+
+       p = alloc(sizeof(*p));
+       *p = zprog;
+       p->lineno = nearln;
+       p->pc = pc;
+       pc++;
+       if(lastp == P) {
+               pl = linknewplist(ctxt);
+               pl->firstpc = p;
+       } else
+               lastp->link = p;
+       lastp = p;
+}
+
+void
+gargs(Node *n, Node *tn1, Node *tn2)
+{
+       int32 regs;
+       Node fnxargs[20], *fnxp;
+
+       regs = cursafe;
+
+       fnxp = fnxargs;
+       garg1(n, tn1, tn2, 0, &fnxp);   /* compile fns to temps */
+
+       curarg = 0;
+       fnxp = fnxargs;
+       garg1(n, tn1, tn2, 1, &fnxp);   /* compile normal args and temps */
+
+       cursafe = regs;
+}
+
+void
+garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
+{
+       Node nod;
+
+       if(n == Z)
+               return;
+       if(n->op == OLIST) {
+               garg1(n->left, tn1, tn2, f, fnxp);
+               garg1(n->right, tn1, tn2, f, fnxp);
+               return;
+       }
+       if(f == 0) {
+               if(n->complex >= FNX) {
+                       regsalloc(*fnxp, n);
+                       nod = znode;
+                       nod.op = OAS;
+                       nod.left = *fnxp;
+                       nod.right = n;
+                       nod.type = n->type;
+                       cgen(&nod, Z);
+                       (*fnxp)++;
+               }
+               return;
+       }
+       if(typesu[n->type->etype]) {
+               regaalloc(tn2, n);
+               if(n->complex >= FNX) {
+                       sugen(*fnxp, tn2, n->type->width);
+                       (*fnxp)++;
+               } else
+                       sugen(n, tn2, n->type->width);
+               return;
+       }
+       if(REGARG>=0 && curarg == 0 && typechlpv[n->type->etype]) {
+               regaalloc1(tn1, n);
+               if(n->complex >= FNX) {
+                       cgen(*fnxp, tn1);
+                       (*fnxp)++;
+               } else
+                       cgen(n, tn1);
+               return;
+       }
+       if(vconst(n) == 0) {
+               regaalloc(tn2, n);
+               gopcode(OAS, n, Z, tn2);
+               return;
+       }
+       regalloc(tn1, n, Z);
+       if(n->complex >= FNX) {
+               cgen(*fnxp, tn1);
+               (*fnxp)++;
+       } else
+               cgen(n, tn1);
+       regaalloc(tn2, n);
+       gopcode(OAS, tn1, Z, tn2);
+       regfree(tn1);
+}
+
+Node*
+nod32const(vlong v)
+{
+       constnode.vconst = v & MASK(32);
+       return &constnode;
+}
+
+Node*
+nodgconst(vlong v, Type *t)
+{
+       if(!typev[t->etype])
+               return nodconst((int32)v);
+       vconstnode.vconst = v;
+       return &vconstnode;
+}
+
+Node*
+nodconst(int32 v)
+{
+       constnode.vconst = v;
+       return &constnode;
+}
+
+Node*
+nodfconst(double d)
+{
+       fconstnode.fconst = d;
+       return &fconstnode;
+}
+
+void
+nodreg(Node *n, Node *nn, int reg)
+{
+       *n = qregnode;
+       n->reg = reg;
+       n->type = nn->type;
+       n->lineno = nn->lineno;
+}
+
+void
+regret(Node *n, Node *nn, Type *t, int mode)
+{
+       int r;
+       
+       if(mode == 0 || hasdotdotdot(t) || nn->type->width == 0) {
+               r = REGRET;
+               if(typefd[nn->type->etype])
+                       r = FREGRET+NREG;
+               nodreg(n, nn, r);
+               reg[r]++;
+               return;
+       }
+       
+       if(mode == 1) {
+               // fetch returned value after call.
+               // already called gargs, so curarg is set.
+               curarg = (curarg+7) & ~7;
+               regaalloc(n, nn);
+               return;
+       }
+
+       if(mode == 2) {
+               // store value to be returned.
+               // must compute arg offset.
+               if(t->etype != TFUNC)
+                       fatal(Z, "bad regret func %T", t);
+               *n = *nn;
+               n->op = ONAME;
+               n->class = CPARAM;
+               n->sym = slookup(".ret");
+               n->complex = nodret->complex;
+               n->addable = 20;
+               n->xoffset = argsize(0);
+               return;
+       }
+       
+       fatal(Z, "bad regret"); 
+}
+
+void
+regalloc(Node *n, Node *tn, Node *o)
+{
+       int i, j;
+       static int lasti;
+
+       switch(tn->type->etype) {
+       case TCHAR:
+       case TUCHAR:
+       case TSHORT:
+       case TUSHORT:
+       case TINT:
+       case TUINT:
+       case TLONG:
+       case TULONG:
+       case TVLONG:
+       case TUVLONG:
+       case TIND:
+               if(o != Z && o->op == OREGISTER) {
+                       i = o->reg;
+                       if(i > 0 && i < NREG)
+                               goto out;
+               }
+               j = lasti + REGRET+1;
+               for(i=REGRET+1; i<NREG; i++) {
+                       if(j >= NREG)
+                               j = REGRET+1;
+                       if(reg[j] == 0) {
+                               i = j;
+                               goto out;
+                       }
+                       j++;
+               }
+               diag(tn, "out of fixed registers");
+               goto err;
+
+       case TFLOAT:
+       case TDOUBLE:
+               if(o != Z && o->op == OREGISTER) {
+                       i = o->reg;
+                       if(i >= NREG && i < NREG+NREG)
+                               goto out;
+               }
+               j = lasti + NREG;
+               for(i=NREG; i<NREG+NREG; i++) {
+                       if(j >= NREG+NREG)
+                               j = NREG;
+                       if(reg[j] == 0) {
+                               i = j;
+                               goto out;
+                       }
+                       j++;
+               }
+               diag(tn, "out of float registers");
+               goto err;
+       }
+       diag(tn, "unknown type in regalloc: %T", tn->type);
+err:
+       i = 0;
+out:
+       if(i)
+               reg[i]++;
+       lasti++;
+       if(lasti >= 5)
+               lasti = 0;
+       nodreg(n, tn, i);
+}
+
+void
+regialloc(Node *n, Node *tn, Node *o)
+{
+       Node nod;
+
+       nod = *tn;
+       nod.type = types[TIND];
+       regalloc(n, &nod, o);
+}
+
+void
+regfree(Node *n)
+{
+       int i;
+
+       i = 0;
+       if(n->op != OREGISTER && n->op != OINDREG)
+               goto err;
+       i = n->reg;
+       if(i < 0 || i >= sizeof(reg))
+               goto err;
+       if(reg[i] <= 0)
+               goto err;
+       reg[i]--;
+       return;
+err:
+       diag(n, "error in regfree: %d", i);
+}
+
+void
+regsalloc(Node *n, Node *nn)
+{
+       cursafe = align(cursafe, nn->type, Aaut3, nil);
+       maxargsafe = maxround(maxargsafe, cursafe+curarg);
+       *n = *nodsafe;
+       n->xoffset = -(stkoff + cursafe);
+       n->type = nn->type;
+       n->etype = nn->type->etype;
+       n->lineno = nn->lineno;
+}
+
+void
+regaalloc1(Node *n, Node *nn)
+{
+       if(REGARG < 0)
+               return;
+       nodreg(n, nn, REGARG);
+       reg[REGARG]++;
+       curarg = align(curarg, nn->type, Aarg1, nil);
+       curarg = align(curarg, nn->type, Aarg2, nil);
+       maxargsafe = maxround(maxargsafe, cursafe+curarg);
+}
+
+void
+regaalloc(Node *n, Node *nn)
+{
+       curarg = align(curarg, nn->type, Aarg1, nil);
+       *n = *nn;
+       n->op = OINDREG;
+       n->reg = REGSP;
+       n->xoffset = curarg + SZ_VLONG;
+       n->complex = 0;
+       n->addable = 20;
+       curarg = align(curarg, nn->type, Aarg2, nil);
+       maxargsafe = maxround(maxargsafe, cursafe+curarg);
+}
+
+void
+regind(Node *n, Node *nn)
+{
+
+       if(n->op != OREGISTER) {
+               diag(n, "regind not OREGISTER");
+               return;
+       }
+       n->op = OINDREG;
+       n->type = nn->type;
+}
+
+void
+raddr(Node *n, Prog *p)
+{
+       Addr a;
+
+       naddr(n, &a);
+       if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
+               a.type = D_REG;
+               a.reg = REGZERO;
+       }
+       if(a.type != D_REG && a.type != D_FREG) {
+               if(n)
+                       diag(n, "bad in raddr: %O", n->op);
+               else
+                       diag(n, "bad in raddr: <null>");
+               p->reg = NREG;
+       } else
+               p->reg = a.reg;
+}
+
+void
+naddr(Node *n, Addr *a)
+{
+       int32 v;
+
+       a->type = D_NONE;
+       if(n == Z)
+               return;
+       switch(n->op) {
+       default:
+       bad:
+               prtree(n, "naddr");
+               diag(n, "%L: !bad in naddr: %O", n->lineno, n->op);
+               break;
+
+       case OREGISTER:
+               a->type = D_REG;
+               a->sym = nil;
+               a->reg = n->reg;
+               if(a->reg >= NREG) {
+                       a->type = D_FREG;
+                       a->reg -= NREG;
+               }
+               break;
+
+       case OIND:
+               naddr(n->left, a);
+               if(a->type == D_REG) {
+                       a->type = D_OREG;
+                       break;
+               }
+               if(a->type == D_CONST) {
+                       a->type = D_OREG;
+                       break;
+               }
+               goto bad;
+
+       case OINDREG:
+               a->type = D_OREG;
+               a->sym = nil;
+               a->offset = n->xoffset;
+               a->reg = n->reg;
+               break;
+
+       case ONAME:
+               a->etype = n->etype;
+               a->type = D_OREG;
+               a->name = D_STATIC;
+               a->sym = linksym(n->sym);
+               a->offset = n->xoffset;
+               if(n->class == CSTATIC)
+                       break;
+               if(n->class == CEXTERN || n->class == CGLOBL) {
+                       a->name = D_EXTERN;
+                       break;
+               }
+               if(n->class == CAUTO) {
+                       a->name = D_AUTO;
+                       break;
+               }
+               if(n->class == CPARAM) {
+                       a->name = D_PARAM;
+                       break;
+               }
+               goto bad;
+
+       case OCONST:
+               a->sym = nil;
+               a->reg = NREG;
+               if(typefd[n->type->etype]) {
+                       a->type = D_FCONST;
+                       a->u.dval = n->fconst;
+               } else {
+                       a->type = D_CONST;
+                       a->offset = n->vconst;
+               }
+               break;
+
+       case OADDR:
+               naddr(n->left, a);
+               if(a->type == D_OREG) {
+                       a->type = D_CONST;
+                       break;
+               }
+               goto bad;
+
+       case OADD:
+               if(n->left->op == OCONST) {
+                       naddr(n->left, a);
+                       v = a->offset;
+                       naddr(n->right, a);
+               } else {
+                       naddr(n->right, a);
+                       v = a->offset;
+                       naddr(n->left, a);
+               }
+               a->offset += v;
+               break;
+
+       }
+}
+
+void
+fop(int as, int f1, int f2, Node *t)
+{
+       Node nod1, nod2, nod3;
+
+       nodreg(&nod1, t, NREG+f1);
+       nodreg(&nod2, t, NREG+f2);
+       regalloc(&nod3, t, t);
+       gopcode(as, &nod1, &nod2, &nod3);
+       gmove(&nod3, t);
+       regfree(&nod3);
+}
+
+void
+gmove(Node *f, Node *t)
+{
+       int ft, tt, a;
+       Node nod, fxc0, fxc1, fxc2, fxrat;
+       Prog *p1;
+       double d;
+
+       ft = f->type->etype;
+       tt = t->type->etype;
+
+       if(ft == TDOUBLE && f->op == OCONST) {
+               d = f->fconst;
+               if(d == 0.0) {
+                       a = FREGZERO;
+                       goto ffreg;
+               }
+               if(d == 0.5) {
+                       a = FREGHALF;
+                       goto ffreg;
+               }
+               if(d == 1.0) {
+                       a = FREGONE;
+                       goto ffreg;
+               }
+               if(d == 2.0) {
+                       a = FREGTWO;
+                       goto ffreg;
+               }
+               if(d == -.5) {
+                       fop(OSUB, FREGHALF, FREGZERO, t);
+                       return;
+               }
+               if(d == -1.0) {
+                       fop(OSUB, FREGONE, FREGZERO, t);
+                       return;
+               }
+               if(d == -2.0) {
+                       fop(OSUB, FREGTWO, FREGZERO, t);
+                       return;
+               }
+               if(d == 1.5) {
+                       fop(OADD, FREGONE, FREGHALF, t);
+                       return;
+               }
+               if(d == 2.5) {
+                       fop(OADD, FREGTWO, FREGHALF, t);
+                       return;
+               }
+               if(d == 3.0) {
+                       fop(OADD, FREGTWO, FREGONE, t);
+                       return;
+               }
+       }
+       if(ft == TFLOAT && f->op == OCONST) {
+               d = f->fconst;
+               if(d == 0) {
+                       a = FREGZERO;
+               ffreg:
+                       nodreg(&nod, f, NREG+a);
+                       gmove(&nod, t);
+                       return;
+               }
+       }
+       /*
+        * a load --
+        * put it into a register then
+        * worry what to do with it.
+        */
+       if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
+               switch(ft) {
+               default:
+                       if(ewidth[ft] == 4){
+                               if(typeu[ft])
+                                       a = AMOVWZ;
+                               else
+                                       a = AMOVW;
+                       }else
+                               a = AMOVD;
+                       break;
+               case TINT:
+                       a = AMOVW;
+                       break;
+               case TUINT:
+                       a = AMOVWZ;
+                       break;
+               case TFLOAT:
+                       a = AFMOVS;
+                       break;
+               case TDOUBLE:
+                       a = AFMOVD;
+                       break;
+               case TCHAR:
+                       a = AMOVB;
+                       break;
+               case TUCHAR:
+                       a = AMOVBZ;
+                       break;
+               case TSHORT:
+                       a = AMOVH;
+                       break;
+               case TUSHORT:
+                       a = AMOVHZ;
+                       break;
+               }
+               regalloc(&nod, f, t);
+               gins(a, f, &nod);
+               gmove(&nod, t);
+               regfree(&nod);
+               return;
+       }
+
+       /*
+        * a store --
+        * put it into a register then
+        * store it.
+        */
+       if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
+               switch(tt) {
+               default:
+                       if(ewidth[tt] == 4)
+                               a = AMOVW;
+                       else
+                               a = AMOVD;
+                       break;
+               case TINT:
+                       a = AMOVW;
+                       break;
+               case TUINT:
+                       a = AMOVWZ;
+                       break;
+               case TUCHAR:
+                       a = AMOVBZ;
+                       break;
+               case TCHAR:
+                       a = AMOVB;
+                       break;
+               case TUSHORT:
+                       a = AMOVHZ;
+                       break;
+               case TSHORT:
+                       a = AMOVH;
+                       break;
+               case TFLOAT:
+                       a = AFMOVS;
+                       break;
+               case TDOUBLE:
+                       a = AFMOVD;
+                       break;
+               }
+               if(!typefd[ft] && vconst(f) == 0) {
+                       gins(a, f, t);
+                       return;
+               }
+               if(ft == tt)
+                       regalloc(&nod, t, f);
+               else
+                       regalloc(&nod, t, Z);
+               gmove(f, &nod);
+               gins(a, &nod, t);
+               regfree(&nod);
+               return;
+       }
+
+       /*
+        * type x type cross table
+        */
+       a = AGOK;
+       switch(ft) {
+       case TDOUBLE:
+       case TFLOAT:
+               switch(tt) {
+               case TDOUBLE:
+                       a = AFMOVD;
+                       if(ft == TFLOAT)
+                               a = AFMOVS;     /* AFMOVSD */
+                       break;
+               case TFLOAT:
+                       a = AFRSP;
+                       if(ft == TFLOAT)
+                               a = AFMOVS;
+                       break;
+               case TINT:
+               case TUINT:
+               case TLONG:
+               case TULONG:
+               case TIND:
+               case TSHORT:
+               case TUSHORT:
+               case TCHAR:
+               case TUCHAR:
+                       /* BUG: not right for unsigned int32 */
+                       regalloc(&nod, f, Z);   /* should be type float */
+                       regsalloc(&fxrat, f);
+                       gins(AFCTIWZ, f, &nod);
+                       gins(AFMOVD, &nod, &fxrat);
+                       regfree(&nod);
+                       fxrat.type = nodrat->type;
+                       fxrat.etype = nodrat->etype;
+                       fxrat.xoffset += 4;
+                       gins(AMOVW, &fxrat, t); /* TO DO */
+                       gmove(t, t);
+                       return;
+               case TVLONG:
+               case TUVLONG:
+                       /* BUG: not right for unsigned int32 */
+                       regalloc(&nod, f, Z);   /* should be type float */
+                       regsalloc(&fxrat, f);
+                       gins(AFCTIDZ, f, &nod);
+                       gins(AFMOVD, &nod, &fxrat);
+                       regfree(&nod);
+                       fxrat.type = nodrat->type;
+                       fxrat.etype = nodrat->etype;
+                       gins(AMOVD, &fxrat, t);
+                       gmove(t, t);
+                       return;
+               }
+               break;
+       case TINT:
+       case TUINT:
+       case TLONG:
+       case TULONG:
+               switch(tt) {
+               case TDOUBLE:
+               case TFLOAT:
+                       goto fxtofl;
+               case TINT:
+               case TUINT:
+               case TLONG:
+               case TULONG:
+               case TSHORT:
+               case TUSHORT:
+               case TCHAR:
+               case TUCHAR:
+                       if(typeu[tt])
+                               a = AMOVWZ;
+                       else
+                               a = AMOVW;
+                       break;
+               case TVLONG:
+               case TUVLONG:
+               case TIND:
+                       a = AMOVD;
+                       break;
+               }
+               break;
+       case TVLONG:
+       case TUVLONG:
+       case TIND:
+               switch(tt) {
+               case TDOUBLE:
+               case TFLOAT:
+                       goto fxtofl;
+               case TINT:
+               case TUINT:
+               case TLONG:
+               case TULONG:
+               case TVLONG:
+               case TUVLONG:
+               case TIND:
+               case TSHORT:
+               case TUSHORT:
+               case TCHAR:
+               case TUCHAR:
+                       a = AMOVD;      /* TO DO: conversion done? */
+                       break;
+               }
+               break;
+       case TSHORT:
+               switch(tt) {
+               case TDOUBLE:
+               case TFLOAT:
+                       goto fxtofl;
+               case TINT:
+               case TUINT:
+               case TLONG:
+               case TULONG:
+               case TVLONG:
+               case TUVLONG:
+               case TIND:
+                       a = AMOVH;
+                       break;
+               case TSHORT:
+               case TUSHORT:
+               case TCHAR:
+               case TUCHAR:
+                       a = AMOVD;
+                       break;
+               }
+               break;
+       case TUSHORT:
+               switch(tt) {
+               case TDOUBLE:
+               case TFLOAT:
+                       goto fxtofl;
+               case TINT:
+               case TUINT:
+               case TLONG:
+               case TULONG:
+               case TVLONG:
+               case TUVLONG:
+               case TIND:
+                       a = AMOVHZ;
+                       break;
+               case TSHORT:
+               case TUSHORT:
+               case TCHAR:
+               case TUCHAR:
+                       a = AMOVD;
+                       break;
+               }
+               break;
+       case TCHAR:
+               switch(tt) {
+               case TDOUBLE:
+               case TFLOAT:
+                       goto fxtofl;
+               case TINT:
+               case TUINT:
+               case TLONG:
+               case TULONG:
+               case TVLONG:
+               case TUVLONG:
+               case TIND:
+               case TSHORT:
+               case TUSHORT:
+                       a = AMOVB;
+                       break;
+               case TCHAR:
+               case TUCHAR:
+                       a = AMOVD;
+                       break;
+               }
+               break;
+       case TUCHAR:
+               switch(tt) {
+               case TDOUBLE:
+               case TFLOAT:
+               fxtofl:
+                       /*
+                        * rat[0] = 0x43300000; rat[1] = f^0x80000000;
+                        * t = *(double*)rat - FREGCVI;
+                        * is-unsigned(t) => if(t<0) t += 2^32;
+                        * could be streamlined for int-to-float
+                        */
+                       regalloc(&fxc0, f, Z);
+                       regalloc(&fxc2, f, Z);
+                       regsalloc(&fxrat, t);   /* should be type float */
+                       gins(AMOVW, nodconst(0x43300000L), &fxc0);
+                       gins(AMOVW, f, &fxc2);
+                       gins(AXOR, nodconst(0x80000000L), &fxc2);
+                       if(ctxt->arch->endian == BigEndian) {
+                               gins(AMOVW, &fxc0, &fxrat);
+                               fxc1 = fxrat;
+                               fxc1.type = nodrat->type;
+                               fxc1.etype = nodrat->etype;
+                               fxc1.xoffset += SZ_LONG;
+                               gins(AMOVW, &fxc2, &fxc1);
+                       } else {
+                               gins(AMOVW, &fxc2, &fxrat);
+                               fxc1 = fxrat;
+                               fxc1.type = nodrat->type;
+                               fxc1.etype = nodrat->etype;
+                               fxc1.xoffset += SZ_LONG;
+                               gins(AMOVW, &fxc0, &fxc1);
+                       }
+                       regfree(&fxc2);
+                       regfree(&fxc0);
+                       regalloc(&nod, t, t);   /* should be type float */
+                       gins(AFMOVD, &fxrat, &nod);
+                       nodreg(&fxc1, t, NREG+FREGCVI);
+                       gins(AFSUB, &fxc1, &nod);
+                       a = AFMOVD;
+                       if(tt == TFLOAT)
+                               a = AFRSP;
+                       gins(a, &nod, t);
+                       regfree(&nod);
+                       if(ft == TULONG) {
+                               regalloc(&nod, t, Z);
+                               if(tt == TFLOAT) {
+                                       gins(AFCMPU, t, Z);
+                                       p->to.type = D_FREG;
+                                       p->to.reg = FREGZERO;
+                                       gins(ABGE, Z, Z);
+                                       p1 = p;
+                                       gins(AFMOVS, nodfconst(4294967296.), &nod);
+                                       gins(AFADDS, &nod, t);
+                               } else {
+                                       gins(AFCMPU, t, Z);
+                                       p->to.type = D_FREG;
+                                       p->to.reg = FREGZERO;
+                                       gins(ABGE, Z, Z);
+                                       p1 = p;
+                                       gins(AFMOVD, nodfconst(4294967296.), &nod);
+                                       gins(AFADD, &nod, t);
+                               }
+                               patch(p1, pc);
+                               regfree(&nod);
+                       }
+                       return;
+               case TINT:
+               case TUINT:
+               case TLONG:
+               case TULONG:
+               case TVLONG:
+               case TUVLONG:
+               case TIND:
+               case TSHORT:
+               case TUSHORT:
+                       a = AMOVBZ;
+                       break;
+               case TCHAR:
+               case TUCHAR:
+                       a = AMOVD;
+                       break;
+               }
+               break;
+       }
+       if(a == AGOK)
+               diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
+       if(a == AMOVD || (a == AMOVW || a == AMOVWZ) && ewidth[ft] == ewidth[tt] || a == AFMOVS || a == AFMOVD)
+       if(samaddr(f, t))
+               return;
+       gins(a, f, t);
+}
+
+void
+gins(int a, Node *f, Node *t)
+{
+
+       nextpc();
+       p->as = a;
+       if(f != Z)
+               naddr(f, &p->from);
+       if(t != Z)
+               naddr(t, &p->to);
+       if(debug['g'])
+               print("%P\n", p);
+}
+
+void
+gopcode(int o, Node *f1, Node *f2, Node *t)
+{
+       int a, et;
+       Addr ta;
+       int uns;
+
+       uns = 0;
+       et = TLONG;
+       if(f1 != Z && f1->type != T) {
+               if(f1->op == OCONST && t != Z && t->type != T)
+                       et = t->type->etype;
+               else
+                       et = f1->type->etype;
+       }
+       a = AGOK;
+       switch(o) {
+       case OAS:
+               gmove(f1, t);
+               return;
+
+       case OASADD:
+       case OADD:
+               a = AADD;
+               if(et == TFLOAT)
+                       a = AFADDS;
+               else
+               if(et == TDOUBLE)
+                       a = AFADD;
+               break;
+
+       case OASSUB:
+       case OSUB:
+               a = ASUB;
+               if(et == TFLOAT)
+                       a = AFSUBS;
+               else
+               if(et == TDOUBLE)
+                       a = AFSUB;
+               break;
+
+       case OASOR:
+       case OOR:
+               a = AOR;
+               break;
+
+       case OASAND:
+       case OAND:
+               a = AAND;
+               if(f1->op == OCONST)
+                       a = AANDCC;
+               break;
+
+       case OASXOR:
+       case OXOR:
+               a = AXOR;
+               break;
+
+       case OASLSHR:
+       case OLSHR:
+               a = ASRW;
+               if(isv(et))
+                       a = ASRD;
+               break;
+
+       case OASASHR:
+       case OASHR:
+               a = ASRAW;
+               if(isv(et))
+                       a = ASRAD;
+               break;
+
+       case OASASHL:
+       case OASHL:
+               a = ASLW;
+               if(isv(et))
+                       a = ASLD;
+               break;
+
+       case OFUNC:
+               a = ABL;
+               break;
+
+       case OASLMUL:
+       case OLMUL:
+       case OASMUL:
+       case OMUL:
+               if(et == TFLOAT) {
+                       a = AFMULS;
+                       break;
+               } else
+               if(et == TDOUBLE) {
+                       a = AFMUL;
+                       break;
+               }
+               a = AMULLW;
+               if(isv(et))
+                       a = AMULLD;
+               break;
+
+       case OASDIV:
+       case ODIV:
+               if(et == TFLOAT) {
+                       a = AFDIVS;
+                       break;
+               } else
+               if(et == TDOUBLE) {
+                       a = AFDIV;
+                       break;
+               } else
+               a = ADIVW;
+               if(isv(et))
+                       a = ADIVD;
+               break;
+
+       case OASMOD:
+       case OMOD:
+               a = AREM;
+               if(isv(et))
+                       a = AREMD;
+               break;
+
+       case OASLMOD:
+       case OLMOD:
+               a = AREMU;
+               if(isv(et))
+                       a = AREMDU;
+               break;
+
+       case OASLDIV:
+       case OLDIV:
+               a = ADIVWU;
+               if(isv(et))
+                       a = ADIVDU;
+               break;
+
+       case OCOM:
+               a = ANOR;
+               break;
+
+       case ONEG:
+               a = ANEG;
+               if(et == TFLOAT || et == TDOUBLE)
+                       a = AFNEG;
+               break;
+
+       case OEQ:
+               a = ABEQ;
+               goto cmp;
+
+       case ONE:
+               a = ABNE;
+               goto cmp;
+
+       case OLT:
+               a = ABLT;
+               goto cmp;
+
+       case OLE:
+               a = ABLE;
+               goto cmp;
+
+       case OGE:
+               a = ABGE;
+               goto cmp;
+
+       case OGT:
+               a = ABGT;
+               goto cmp;
+
+       case OLO:
+               a = ABLT;
+               goto cmpu;
+
+       case OLS:
+               a = ABLE;
+               goto cmpu;
+
+       case OHS:
+               a = ABGE;
+               goto cmpu;
+
+       case OHI:
+               a = ABGT;
+               goto cmpu;
+
+       cmpu:
+               uns = 1;
+       cmp:
+               nextpc();
+               switch(et){
+               case TINT:
+               case TLONG:
+                       p->as = ACMPW;
+                       break;
+               case TUINT:
+               case TULONG:
+                       p->as = ACMPWU;
+                       break;
+               case TFLOAT:
+               case TDOUBLE:
+                       p->as = AFCMPU;
+                       break;
+               default:
+                       p->as = uns? ACMPU: ACMP;
+                       break;
+               }
+               if(f1 != Z)
+                       naddr(f1, &p->from);
+               if(t != Z)
+                       naddr(t, &p->to);
+               if(f1 == Z || t == Z || f2 != Z)
+                       diag(Z, "bad cmp in gopcode %O", o);
+               if(debug['g'])
+                       print("%P\n", p);
+               f1 = Z;
+               f2 = Z;
+               t = Z;
+               break;
+       }
+       if(a == AGOK)
+               diag(Z, "bad in gopcode %O", o);
+       nextpc();
+       p->as = a;
+       if(f1 != Z)
+               naddr(f1, &p->from);
+       if(f2 != Z) {
+               naddr(f2, &ta);
+               p->reg = ta.reg;
+               if(ta.type == D_CONST && ta.offset == 0) {
+                       if(R0ISZERO)
+                               p->reg = REGZERO;
+                       else
+                               diag(Z, "REGZERO in gopcode %O", o);
+               }
+       }
+       if(t != Z)
+               naddr(t, &p->to);
+       if(debug['g'])
+               print("%P\n", p);
+}
+
+int
+samaddr(Node *f, Node *t)
+{
+       return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg;
+}
+
+void
+gbranch(int o)
+{
+       int a;
+
+       a = AGOK;
+       switch(o) {
+       case ORETURN:
+               a = ARETURN;
+               break;
+       case OGOTO:
+               a = ABR;
+               break;
+       }
+       nextpc();
+       if(a == AGOK) {
+               diag(Z, "bad in gbranch %O",  o);
+               nextpc();
+       }
+       p->as = a;
+}
+
+void
+patch(Prog *op, int32 pc)
+{
+
+       op->to.offset = pc;
+       op->to.type = D_BRANCH;
+}
+
+void
+gpseudo(int a, Sym *s, Node *n)
+{
+
+       nextpc();
+       p->as = a;
+       p->from.type = D_OREG;
+       p->from.sym = linksym(s);
+
+       switch(a) {
+       case ATEXT:
+               p->reg = textflag;
+               textflag = 0;
+               break;
+       case AGLOBL:
+               p->reg = s->dataflag;
+               break;
+       }
+
+       p->from.name = D_EXTERN;
+       if(s->class == CSTATIC)
+               p->from.name = D_STATIC;
+       naddr(n, &p->to);
+       if(a == ADATA || a == AGLOBL)
+               pc--;
+}
+
+int
+sval(int32 v)
+{
+
+       if(v >= -(1<<15) && v < (1<<15))
+               return 1;
+       return 0;
+}
+
+void
+gpcdata(int index, int value)
+{
+       Node n1;
+
+       n1 = *nodconst(index);
+       gins(APCDATA, &n1, nodconst(value));
+}
+
+void
+gprefetch(Node *n)
+{
+       // TODO(minux)
+       USED(n);
+       /*
+       Node n1;
+
+       regalloc(&n1, n, Z);
+       gmove(n, &n1);
+       n1.op = OINDREG;
+       gins(ADCBT, &n1, Z);
+       regfree(&n1);
+       */
+}
+
+
+int
+sconst(Node *n)
+{
+       vlong vv;
+
+       if(n->op == OCONST) {
+               if(!typefd[n->type->etype]) {
+                       vv = n->vconst;
+                       if(vv >= -(((vlong)1)<<15) && vv < (((vlong)1)<<15))
+                               return 1;
+               }
+       }
+       return 0;
+}
+
+int
+uconst(Node *n)
+{
+       vlong vv;
+
+       if(n->op == OCONST) {
+               if(!typefd[n->type->etype]) {
+                       vv = n->vconst;
+                       if(vv >= 0 && vv < (((vlong)1)<<16))
+                               return 1;
+               }
+       }
+       return 0;
+}
+
+int
+immconst(Node *n)
+{
+       vlong v;
+
+       if(n->op != OCONST || typefd[n->type->etype])
+               return 0;
+       v = n->vconst;
+       if((v & 0xFFFF) == 0)
+               v >>= 16;
+       if(v >= 0 && v < ((vlong)1<<16))
+               return 1;
+       if(v >= -((vlong)1<<15) && v <= ((vlong)1<<15))
+               return 1;
+       return 0;
+}
+
+int32
+exreg(Type *t)
+{
+       int32 o;
+
+       if(typechlpv[t->etype]) {
+               if(exregoffset <= 3)
+                       return 0;
+               o = exregoffset;
+               exregoffset--;
+               return o;
+       }
+       if(typefd[t->etype]) {
+               if(exfregoffset <= 16)
+                       return 0;
+               o = exfregoffset + NREG;
+               exfregoffset--;
+               return o;
+       }
+       return 0;
+}
+
+schar  ewidth[NTYPE] =
+{
+       -1,             /* [TXXX] */
+       SZ_CHAR,        /* [TCHAR] */
+       SZ_CHAR,        /* [TUCHAR] */
+       SZ_SHORT,       /* [TSHORT] */
+       SZ_SHORT,       /* [TUSHORT] */
+       SZ_INT,         /* [TINT] */
+       SZ_INT,         /* [TUINT] */
+       SZ_LONG,        /* [TLONG] */
+       SZ_LONG,        /* [TULONG] */
+       SZ_VLONG,       /* [TVLONG] */
+       SZ_VLONG,       /* [TUVLONG] */
+       SZ_FLOAT,       /* [TFLOAT] */
+       SZ_DOUBLE,      /* [TDOUBLE] */
+       SZ_IND,         /* [TIND] */
+       0,              /* [TFUNC] */
+       -1,             /* [TARRAY] */
+       0,              /* [TVOID] */
+       -1,             /* [TSTRUCT] */
+       -1,             /* [TUNION] */
+       SZ_INT,         /* [TENUM] */
+};
+int32  ncast[NTYPE] =
+{
+       0,                              /* [TXXX] */
+       BCHAR|BUCHAR,                   /* [TCHAR] */
+       BCHAR|BUCHAR,                   /* [TUCHAR] */
+       BSHORT|BUSHORT,                 /* [TSHORT] */
+       BSHORT|BUSHORT,                 /* [TUSHORT] */
+       BINT|BUINT|BLONG|BULONG,        /* [TINT] */
+       BINT|BUINT|BLONG|BULONG,        /* [TUINT] */
+       BINT|BUINT|BLONG|BULONG,        /* [TLONG] */
+       BINT|BUINT|BLONG|BULONG,        /* [TULONG] */
+       BVLONG|BUVLONG|BIND,                    /* [TVLONG] */
+       BVLONG|BUVLONG|BIND,                    /* [TUVLONG] */
+       BFLOAT,                         /* [TFLOAT] */
+       BDOUBLE,                        /* [TDOUBLE] */
+       BVLONG|BUVLONG|BIND,            /* [TIND] */
+       0,                              /* [TFUNC] */
+       0,                              /* [TARRAY] */
+       0,                              /* [TVOID] */
+       BSTRUCT,                        /* [TSTRUCT] */
+       BUNION,                         /* [TUNION] */
+       0,                              /* [TENUM] */
+};
diff --git a/src/cmd/9g/cgen.c b/src/cmd/9g/cgen.c
new file mode 100644 (file)
index 0000000..e389360
--- /dev/null
@@ -0,0 +1,1763 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+
+/*
+ * generate:
+ *     res = n;
+ * simplifies and calls gmove.
+ */
+void
+cgen(Node *n, Node *res)
+{
+       Node *nl, *nr, *r;
+       Node n1, n2;
+       int a, f;
+       Prog *p1, *p2, *p3;
+       Addr addr;
+
+//print("cgen %N(%d) -> %N(%d)\n", n, n->addable, res, res->addable);
+       if(debug['g']) {
+               dump("\ncgen-n", n);
+               dump("cgen-res", res);
+       }
+       if(n == N || n->type == T)
+               goto ret;
+
+       if(res == N || res->type == T)
+               fatal("cgen: res nil");
+
+       while(n->op == OCONVNOP)
+               n = n->left;
+
+       switch(n->op) {
+       case OSLICE:
+       case OSLICEARR:
+       case OSLICESTR:
+       case OSLICE3:
+       case OSLICE3ARR:
+               if (res->op != ONAME || !res->addable) {
+                       tempname(&n1, n->type);
+                       cgen_slice(n, &n1);
+                       cgen(&n1, res);
+               } else
+                       cgen_slice(n, res);
+               goto ret;
+       case OEFACE:
+               if (res->op != ONAME || !res->addable) {
+                       tempname(&n1, n->type);
+                       cgen_eface(n, &n1);
+                       cgen(&n1, res);
+               } else
+                       cgen_eface(n, res);
+               goto ret;
+       }
+
+       if(n->ullman >= UINF) {
+               if(n->op == OINDREG)
+                       fatal("cgen: this is going to misscompile");
+               if(res->ullman >= UINF) {
+                       tempname(&n1, n->type);
+                       cgen(n, &n1);
+                       cgen(&n1, res);
+                       goto ret;
+               }
+       }
+
+       if(isfat(n->type)) {
+               if(n->type->width < 0)
+                       fatal("forgot to compute width for %T", n->type);
+               sgen(n, res, n->type->width);
+               goto ret;
+       }
+
+       if(!res->addable) {
+               if(n->ullman > res->ullman) {
+                       regalloc(&n1, n->type, res);
+                       cgen(n, &n1);
+                       if(n1.ullman > res->ullman) {
+                               dump("n1", &n1);
+                               dump("res", res);
+                               fatal("loop in cgen");
+                       }
+                       cgen(&n1, res);
+                       regfree(&n1);
+                       goto ret;
+               }
+
+               if(res->ullman >= UINF)
+                       goto gen;
+
+               if(complexop(n, res)) {
+                       complexgen(n, res);
+                       goto ret;
+               }
+
+               f = 1;  // gen thru register
+               switch(n->op) {
+               case OLITERAL:
+                       if(smallintconst(n))
+                               f = 0;
+                       break;
+               case OREGISTER:
+                       f = 0;
+                       break;
+               }
+
+               if(!iscomplex[n->type->etype]) {
+                       a = optoas(OAS, res->type);
+                       if(sudoaddable(a, res, &addr)) {
+                               if(f) {
+                                       regalloc(&n2, res->type, N);
+                                       cgen(n, &n2);
+                                       p1 = gins(a, &n2, N);
+                                       regfree(&n2);
+                               } else
+                                       p1 = gins(a, n, N);
+                               p1->to = addr;
+                               if(debug['g'])
+                                       print("%P [ignore previous line]\n", p1);
+                               sudoclean();
+                               goto ret;
+                       }
+               }
+
+       gen:
+               igen(res, &n1, N);
+               cgen(n, &n1);
+               regfree(&n1);
+               goto ret;
+       }
+
+       // update addressability for string, slice
+       // can't do in walk because n->left->addable
+       // changes if n->left is an escaping local variable.
+       switch(n->op) {
+       case OSPTR:
+       case OLEN:
+               if(isslice(n->left->type) || istype(n->left->type, TSTRING))
+                       n->addable = n->left->addable;
+               break;
+       case OCAP:
+               if(isslice(n->left->type))
+                       n->addable = n->left->addable;
+               break;
+       case OITAB:
+               n->addable = n->left->addable;
+               break;
+       }
+
+       if(complexop(n, res)) {
+               complexgen(n, res);
+               goto ret;
+       }
+
+       // if both are addressable, move
+       if(n->addable) {
+               if(n->op == OREGISTER || res->op == OREGISTER) {
+                       gmove(n, res);
+               } else {
+                       regalloc(&n1, n->type, N);
+                       gmove(n, &n1);
+                       cgen(&n1, res);
+                       regfree(&n1);
+               }
+               goto ret;
+       }
+
+       nl = n->left;
+       nr = n->right;
+
+       if(nl != N && nl->ullman >= UINF)
+       if(nr != N && nr->ullman >= UINF) {
+               tempname(&n1, nl->type);
+               cgen(nl, &n1);
+               n2 = *n;
+               n2.left = &n1;
+               cgen(&n2, res);
+               goto ret;
+       }
+
+       if(!iscomplex[n->type->etype]) {
+               a = optoas(OAS, n->type);
+               if(sudoaddable(a, n, &addr)) {
+                       if(res->op == OREGISTER) {
+                               p1 = gins(a, N, res);
+                               p1->from = addr;
+                       } else {
+                               regalloc(&n2, n->type, N);
+                               p1 = gins(a, N, &n2);
+                               p1->from = addr;
+                               gins(a, &n2, res);
+                               regfree(&n2);
+                       }
+                       sudoclean();
+                       goto ret;
+               }
+       }
+
+       // TODO(minux): we shouldn't reverse FP comparisons, but then we need to synthesize
+       // OGE, OLE, and ONE ourselves.
+       // if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype]) goto flt;
+
+       switch(n->op) {
+       default:
+               dump("cgen", n);
+               fatal("cgen: unknown op %+hN", n);
+               break;
+
+       // these call bgen to get a bool value
+       case OOROR:
+       case OANDAND:
+       case OEQ:
+       case ONE:
+       case OLT:
+       case OLE:
+       case OGE:
+       case OGT:
+       case ONOT:
+               p1 = gbranch(ABR, T, 0);
+               p2 = pc;
+               gmove(nodbool(1), res);
+               p3 = gbranch(ABR, T, 0);
+               patch(p1, pc);
+               bgen(n, 1, 0, p2);
+               gmove(nodbool(0), res);
+               patch(p3, pc);
+               goto ret;
+
+       case OPLUS:
+               cgen(nl, res);
+               goto ret;
+
+       // unary
+       case OCOM:
+               a = optoas(OXOR, nl->type);
+               regalloc(&n1, nl->type, N);
+               cgen(nl, &n1);
+               nodconst(&n2, nl->type, -1);
+               gins(a, &n2, &n1);
+               gmove(&n1, res);
+               regfree(&n1);
+               goto ret;
+
+       case OMINUS:
+               if(isfloat[nl->type->etype]) {
+                       nr = nodintconst(-1);
+                       convlit(&nr, n->type);
+                       a = optoas(OMUL, nl->type);
+                       goto sbop;
+               }
+               a = optoas(n->op, nl->type);
+               goto uop;
+
+       // symmetric binary
+       case OAND:
+       case OOR:
+       case OXOR:
+       case OADD:
+       case OMUL:
+               a = optoas(n->op, nl->type);
+               goto sbop;
+
+       // asymmetric binary
+       case OSUB:
+               a = optoas(n->op, nl->type);
+               goto abop;
+
+       case OHMUL:
+               cgen_hmul(nl, nr, res);
+               break;
+
+       case OCONV:
+               if(n->type->width > nl->type->width) {
+                       // If loading from memory, do conversion during load,
+                       // so as to avoid use of 8-bit register in, say, int(*byteptr).
+                       switch(nl->op) {
+                       case ODOT:
+                       case ODOTPTR:
+                       case OINDEX:
+                       case OIND:
+                       case ONAME:
+                               igen(nl, &n1, res);
+                               regalloc(&n2, n->type, res);
+                               gmove(&n1, &n2);
+                               gmove(&n2, res);
+                               regfree(&n2);
+                               regfree(&n1);
+                               goto ret;
+                       }
+               }
+
+               regalloc(&n1, nl->type, res);
+               regalloc(&n2, n->type, &n1);
+               cgen(nl, &n1);
+
+               // if we do the conversion n1 -> n2 here
+               // reusing the register, then gmove won't
+               // have to allocate its own register.
+               gmove(&n1, &n2);
+               gmove(&n2, res);
+               regfree(&n2);
+               regfree(&n1);
+               break;
+
+       case ODOT:
+       case ODOTPTR:
+       case OINDEX:
+       case OIND:
+       case ONAME:     // PHEAP or PPARAMREF var
+               igen(n, &n1, res);
+               gmove(&n1, res);
+               regfree(&n1);
+               break;
+       
+       case OITAB:
+               // interface table is first word of interface value
+               igen(nl, &n1, res);
+               n1.type = n->type;
+               gmove(&n1, res);
+               regfree(&n1);
+               break;
+
+       case OSPTR:
+               // pointer is the first word of string or slice.
+               if(isconst(nl, CTSTR)) {
+                       regalloc(&n1, types[tptr], res);
+                       p1 = gins(AMOVD, N, &n1);
+                       datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       break;
+               }
+               igen(nl, &n1, res);
+               n1.type = n->type;
+               gmove(&n1, res);
+               regfree(&n1);
+               break;
+
+       case OLEN:
+               if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
+                       // map and chan have len in the first int-sized word.
+                       // a zero pointer means zero length
+                       regalloc(&n1, types[tptr], res);
+                       cgen(nl, &n1);
+
+                       nodconst(&n2, types[tptr], 0);
+                       gins(optoas(OCMP, types[tptr]), &n1, &n2);
+                       p1 = gbranch(optoas(OEQ, types[tptr]), T, 0);
+
+                       n2 = n1;
+                       n2.op = OINDREG;
+                       n2.type = types[simtype[TINT]];
+                       gmove(&n2, &n1);
+
+                       patch(p1, pc);
+
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       break;
+               }
+               if(istype(nl->type, TSTRING) || isslice(nl->type)) {
+                       // both slice and string have len one pointer into the struct.
+                       // a zero pointer means zero length
+                       igen(nl, &n1, res);
+                       n1.type = types[simtype[TUINT]];
+                       n1.xoffset += Array_nel;
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       break;
+               }
+               fatal("cgen: OLEN: unknown type %lT", nl->type);
+               break;
+
+       case OCAP:
+               if(istype(nl->type, TCHAN)) {
+                       // chan has cap in the second int-sized word.
+                       // a zero pointer means zero length
+                       regalloc(&n1, types[tptr], res);
+                       cgen(nl, &n1);
+
+                       nodconst(&n2, types[tptr], 0);
+                       gins(optoas(OCMP, types[tptr]), &n1, &n2);
+                       p1 = gbranch(optoas(OEQ, types[tptr]), T, 0);
+
+                       n2 = n1;
+                       n2.op = OINDREG;
+                       n2.xoffset = widthint;
+                       n2.type = types[simtype[TINT]];
+                       gmove(&n2, &n1);
+
+                       patch(p1, pc);
+
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       break;
+               }
+               if(isslice(nl->type)) {
+                       igen(nl, &n1, res);
+                       n1.type = types[simtype[TUINT]];
+                       n1.xoffset += Array_cap;
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       break;
+               }
+               fatal("cgen: OCAP: unknown type %lT", nl->type);
+               break;
+
+       case OADDR:
+               if(n->bounded) // let race detector avoid nil checks
+                       disable_checknil++;
+               agen(nl, res);
+               if(n->bounded)
+                       disable_checknil--;
+               break;
+
+       case OCALLMETH:
+               cgen_callmeth(n, 0);
+               cgen_callret(n, res);
+               break;
+
+       case OCALLINTER:
+               cgen_callinter(n, res, 0);
+               cgen_callret(n, res);
+               break;
+
+       case OCALLFUNC:
+               cgen_call(n, 0);
+               cgen_callret(n, res);
+               break;
+
+       case OMOD:
+       case ODIV:
+               if(isfloat[n->type->etype]) {
+                       a = optoas(n->op, nl->type);
+                       goto abop;
+               }
+
+               if(nl->ullman >= nr->ullman) {
+                       regalloc(&n1, nl->type, res);
+                       cgen(nl, &n1);
+                       cgen_div(n->op, &n1, nr, res);
+                       regfree(&n1);
+               } else {
+                       if(!smallintconst(nr)) {
+                               regalloc(&n2, nr->type, res);
+                               cgen(nr, &n2);
+                       } else {
+                               n2 = *nr;
+                       }
+                       cgen_div(n->op, nl, &n2, res);
+                       if(n2.op != OLITERAL)
+                               regfree(&n2);
+               }
+               break;
+
+       case OLSH:
+       case ORSH:
+       case OLROT:
+               cgen_shift(n->op, n->bounded, nl, nr, res);
+               break;
+       }
+       goto ret;
+
+sbop:  // symmetric binary
+       /*
+        * put simplest on right - we'll generate into left
+        * and then adjust it using the computation of right.
+        * constants and variables have the same ullman
+        * count, so look for constants specially.
+        *
+        * an integer constant we can use as an immediate
+        * is simpler than a variable - we can use the immediate
+        * in the adjustment instruction directly - so it goes
+        * on the right.
+        *
+        * other constants, like big integers or floating point
+        * constants, require a mov into a register, so those
+        * might as well go on the left, so we can reuse that
+        * register for the computation.
+        */
+       if(nl->ullman < nr->ullman ||
+          (nl->ullman == nr->ullman &&
+           (smallintconst(nl) || (nr->op == OLITERAL && !smallintconst(nr))))) {
+               r = nl;
+               nl = nr;
+               nr = r;
+       }
+
+abop:  // asymmetric binary
+       if(nl->ullman >= nr->ullman) {
+               regalloc(&n1, nl->type, res);
+               cgen(nl, &n1);
+       /*
+        * This generates smaller code - it avoids a MOV - but it's
+        * easily 10% slower due to not being able to
+        * optimize/manipulate the move.
+        * To see, run: go test -bench . crypto/md5
+        * with and without.
+        *
+               if(sudoaddable(a, nr, &addr)) {
+                       p1 = gins(a, N, &n1);
+                       p1->from = addr;
+                       gmove(&n1, res);
+                       sudoclean();
+                       regfree(&n1);
+                       goto ret;
+               }
+        *
+        */
+               // TODO(minux): enable using constants directly in certain instructions.
+               //if(smallintconst(nr))
+               //      n2 = *nr;
+               //else {
+                       regalloc(&n2, nr->type, N);
+                       cgen(nr, &n2);
+               //}
+       } else {
+               //if(smallintconst(nr))
+               //      n2 = *nr;
+               //else {
+                       regalloc(&n2, nr->type, res);
+                       cgen(nr, &n2);
+               //}
+               regalloc(&n1, nl->type, N);
+               cgen(nl, &n1);
+       }
+       gins(a, &n2, &n1);
+       // Normalize result for types smaller than word.
+       if(n->type->width < widthreg) {
+               switch(n->op) {
+               case OADD:
+               case OSUB:
+               case OMUL:
+               case OLSH:
+                       gins(optoas(OAS, n->type), &n1, &n1);
+                       break;
+               }
+       }
+       gmove(&n1, res);
+       regfree(&n1);
+       if(n2.op != OLITERAL)
+               regfree(&n2);
+       goto ret;
+
+uop:   // unary
+       regalloc(&n1, nl->type, res);
+       cgen(nl, &n1);
+       gins(a, N, &n1);
+       gmove(&n1, res);
+       regfree(&n1);
+       goto ret;
+
+ret:
+       ;
+}
+
+/*
+ * allocate a register (reusing res if possible) and generate
+ *  a = n
+ * The caller must call regfree(a).
+ */
+void
+cgenr(Node *n, Node *a, Node *res)
+{
+       Node n1;
+
+       if(debug['g'])
+               dump("cgenr-n", n);
+
+       if(isfat(n->type))
+               fatal("cgenr on fat node");
+
+       if(n->addable) {
+               regalloc(a, n->type, res);
+               gmove(n, a);
+               return;
+       }
+
+       switch(n->op) {
+       case ONAME:
+       case ODOT:
+       case ODOTPTR:
+       case OINDEX:
+       case OCALLFUNC:
+       case OCALLMETH:
+       case OCALLINTER:
+               igen(n, &n1, res);
+               regalloc(a, types[tptr], &n1);
+               gmove(&n1, a);
+               regfree(&n1);
+               break;
+       default:
+               regalloc(a, n->type, res);
+               cgen(n, a);
+               break;
+       }
+}
+
+/*
+ * allocate a register (reusing res if possible) and generate
+ * a = &n
+ * The caller must call regfree(a).
+ * The generated code checks that the result is not nil.
+ */
+void
+agenr(Node *n, Node *a, Node *res)
+{
+       Node *nl, *nr;
+       Node n1, n2, n3, n4, tmp;
+       Prog *p1, *p2;
+       uint32 w;
+       uint64 v;
+
+       if(debug['g'])
+               dump("agenr-n", n);
+
+       nl = n->left;
+       nr = n->right;
+
+       switch(n->op) {
+       case ODOT:
+       case ODOTPTR:
+       case OCALLFUNC:
+       case OCALLMETH:
+       case OCALLINTER:
+               igen(n, &n1, res);
+               regalloc(a, types[tptr], &n1);
+               agen(&n1, a);
+               regfree(&n1);
+               break;
+
+       case OIND:
+               cgenr(n->left, a, res);
+               cgen_checknil(a);
+               break;
+
+       case OINDEX:
+               p2 = nil;  // to be patched to panicindex.
+               w = n->type->width;
+               //bounded = debug['B'] || n->bounded;
+               if(nr->addable) {
+                       if(!isconst(nr, CTINT))
+                               tempname(&tmp, types[TINT64]);
+                       if(!isconst(nl, CTSTR))
+                               agenr(nl, &n3, res);
+                       if(!isconst(nr, CTINT)) {
+                               cgen(nr, &tmp);
+                               regalloc(&n1, tmp.type, N);
+                               gmove(&tmp, &n1);
+                       }
+               } else if(nl->addable) {
+                       if(!isconst(nr, CTINT)) {
+                               tempname(&tmp, types[TINT64]);
+                               cgen(nr, &tmp);
+                               regalloc(&n1, tmp.type, N);
+                               gmove(&tmp, &n1);
+                       }
+                       if(!isconst(nl, CTSTR)) {
+                               agenr(nl, &n3, res);
+                       }
+               } else {
+                       tempname(&tmp, types[TINT64]);
+                       cgen(nr, &tmp);
+                       nr = &tmp;
+                       if(!isconst(nl, CTSTR))
+                               agenr(nl, &n3, res);
+                       regalloc(&n1, tmp.type, N);
+                       gins(optoas(OAS, tmp.type), &tmp, &n1);
+               }
+
+               // &a is in &n3 (allocated in res)
+               // i is in &n1 (if not constant)
+               // w is width
+
+               // constant index
+               if(isconst(nr, CTINT)) {
+                       if(isconst(nl, CTSTR))
+                               fatal("constant string constant index");
+                       v = mpgetfix(nr->val.u.xval);
+                       if(isslice(nl->type) || nl->type->etype == TSTRING) {
+                               if(!debug['B'] && !n->bounded) {
+                                       n1 = n3;
+                                       n1.op = OINDREG;
+                                       n1.type = types[tptr];
+                                       n1.xoffset = Array_nel;
+                                       regalloc(&n4, n1.type, N);
+                                       gmove(&n1, &n4);
+                                       ginscon2(optoas(OCMP, types[TUINT64]), &n4, v);
+                                       regfree(&n4);
+                                       p1 = gbranch(optoas(OGT, types[TUINT64]), T, +1);
+                                       ginscall(panicindex, 0);
+                                       patch(p1, pc);
+                               }
+
+                               n1 = n3;
+                               n1.op = OINDREG;
+                               n1.type = types[tptr];
+                               n1.xoffset = Array_array;
+                               gmove(&n1, &n3);
+                       }
+
+                       if (v*w != 0) {
+                               ginscon(optoas(OADD, types[tptr]), v*w, &n3);
+                       }
+                       *a = n3;
+                       break;
+               }
+
+               regalloc(&n2, types[TINT64], &n1);                      // i
+               gmove(&n1, &n2);
+               regfree(&n1);
+
+               if(!debug['B'] && !n->bounded) {
+                       // check bounds
+                       if(isconst(nl, CTSTR)) {
+                               nodconst(&n4, types[TUINT64], nl->val.u.sval->len);
+                       } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
+                               n1 = n3;
+                               n1.op = OINDREG;
+                               n1.type = types[tptr];
+                               n1.xoffset = Array_nel;
+                               regalloc(&n4, types[TUINT64], N);
+                               gmove(&n1, &n4);
+                       } else {
+                               if(nl->type->bound < (1<<15)-1)
+                                       nodconst(&n4, types[TUINT64], nl->type->bound);
+                               else {
+                                       regalloc(&n4, types[TUINT64], N);
+                                       p1 = gins(AMOVD, N, &n4);
+                                       p1->from.type = D_CONST;
+                                       p1->from.offset = nl->type->bound;
+                               }
+                       }
+                       gins(optoas(OCMP, types[TUINT64]), &n2, &n4);
+                       if(n4.op == OREGISTER)
+                               regfree(&n4);
+                       p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1);
+                       if(p2)
+                               patch(p2, pc);
+                       ginscall(panicindex, 0);
+                       patch(p1, pc);
+               }
+               
+               if(isconst(nl, CTSTR)) {
+                       regalloc(&n3, types[tptr], res);
+                       p1 = gins(AMOVD, N, &n3);
+                       datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
+                       p1->from.type = D_CONST;
+               } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
+                       n1 = n3;
+                       n1.op = OINDREG;
+                       n1.type = types[tptr];
+                       n1.xoffset = Array_array;
+                       gmove(&n1, &n3);
+               }
+
+               if(w == 0) {
+                       // nothing to do
+               } else if(w == 1) {
+                       /* w already scaled */
+                       gins(optoas(OADD, types[tptr]), &n2, &n3);
+               } /* else if(w == 2 || w == 4 || w == 8) {
+                       // TODO(minux): scale using shift
+               } */ else {
+                       regalloc(&n4, types[TUINT64], N);
+                       nodconst(&n1, types[TUINT64], w);
+                       gmove(&n1, &n4);
+                       gins(optoas(OMUL, types[TUINT64]), &n4, &n2);
+                       gins(optoas(OADD, types[tptr]), &n2, &n3);
+                       regfree(&n4);
+               }
+
+               *a = n3;
+               regfree(&n2);
+               break;
+
+       default:
+               regalloc(a, types[tptr], res);
+               agen(n, a);
+               break;
+       }
+}
+
+static void
+ginsadd(int as, vlong off, Node *dst)
+{
+       Node n1;
+
+       regalloc(&n1, types[tptr], dst);
+       gmove(dst, &n1);
+       ginscon(as, off, &n1);
+       gmove(&n1, dst);
+       regfree(&n1);
+}
+
+/*
+ * generate:
+ *     res = &n;
+ * The generated code checks that the result is not nil.
+ */
+void
+agen(Node *n, Node *res)
+{
+       Node *nl, *nr;
+       Node n1, n2, n3;
+
+       if(debug['g']) {
+               dump("\nagen-res", res);
+               dump("agen-r", n);
+       }
+       if(n == N || n->type == T)
+               return;
+
+       while(n->op == OCONVNOP)
+               n = n->left;
+
+       if(isconst(n, CTNIL) && n->type->width > widthptr) {
+               // Use of a nil interface or nil slice.
+               // Create a temporary we can take the address of and read.
+               // The generated code is just going to panic, so it need not
+               // be terribly efficient. See issue 3670.
+               tempname(&n1, n->type);
+               gvardef(&n1);
+               clearfat(&n1);
+               regalloc(&n2, types[tptr], res);
+               memset(&n3, 0, sizeof n3);
+               n3.op = OADDR;
+               n3.left = &n1;
+               gins(AMOVD, &n3, &n2);
+               gmove(&n2, res);
+               regfree(&n2);
+               goto ret;
+       }
+               
+       if(n->addable) {
+               memset(&n1, 0, sizeof n1);
+               n1.op = OADDR;
+               n1.left = n;
+               regalloc(&n2, types[tptr], res);
+               gins(AMOVD, &n1, &n2);
+               gmove(&n2, res);
+               regfree(&n2);
+               goto ret;
+       }
+
+       nl = n->left;
+       nr = n->right;
+       USED(nr);
+
+       switch(n->op) {
+       default:
+               fatal("agen: unknown op %+hN", n);
+               break;
+
+       case OCALLMETH:
+               // TODO(minux): 5g has this: Release res so that it is available for cgen_call.
+               // Pick it up again after the call for OCALLMETH and OCALLFUNC.
+               cgen_callmeth(n, 0);
+               cgen_aret(n, res);
+               break;
+
+       case OCALLINTER:
+               cgen_callinter(n, res, 0);
+               cgen_aret(n, res);
+               break;
+
+       case OCALLFUNC:
+               cgen_call(n, 0);
+               cgen_aret(n, res);
+               break;
+
+       case OSLICE:
+       case OSLICEARR:
+       case OSLICESTR:
+       case OSLICE3:
+       case OSLICE3ARR:
+               tempname(&n1, n->type);
+               cgen_slice(n, &n1);
+               agen(&n1, res);
+               break;
+
+       case OEFACE:
+               tempname(&n1, n->type);
+               cgen_eface(n, &n1);
+               agen(&n1, res);
+               break;
+
+       case OINDEX:
+               agenr(n, &n1, res);
+               gmove(&n1, res);
+               regfree(&n1);
+               break;
+
+       case ONAME:
+               // should only get here with names in this func.
+               if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
+                       dump("bad agen", n);
+                       fatal("agen: bad ONAME funcdepth %d != %d",
+                               n->funcdepth, funcdepth);
+               }
+
+               // should only get here for heap vars or paramref
+               if(!(n->class & PHEAP) && n->class != PPARAMREF) {
+                       dump("bad agen", n);
+                       fatal("agen: bad ONAME class %#x", n->class);
+               }
+               cgen(n->heapaddr, res);
+               if(n->xoffset != 0) {
+                       ginsadd(optoas(OADD, types[tptr]), n->xoffset, res);
+               }
+               break;
+
+       case OIND:
+               cgen(nl, res);
+               cgen_checknil(res);
+               break;
+
+       case ODOT:
+               agen(nl, res);
+               if(n->xoffset != 0) {
+                       ginsadd(optoas(OADD, types[tptr]), n->xoffset, res);
+               }
+               break;
+
+       case ODOTPTR:
+               cgen(nl, res);
+               cgen_checknil(res);
+               if(n->xoffset != 0) {
+                       ginsadd(optoas(OADD, types[tptr]), n->xoffset, res);
+               }
+               break;
+       }
+
+ret:
+       ;
+}
+
+/*
+ * generate:
+ *     newreg = &n;
+ *     res = newreg
+ *
+ * on exit, a has been changed to be *newreg.
+ * caller must regfree(a).
+ * The generated code checks that the result is not *nil.
+ */
+void
+igen(Node *n, Node *a, Node *res)
+{
+       Type *fp;
+       Iter flist;
+       Node n1;
+
+       if(debug['g']) {
+               dump("\nigen-n", n);
+       }
+       switch(n->op) {
+       case ONAME:
+               if((n->class&PHEAP) || n->class == PPARAMREF)
+                       break;
+               *a = *n;
+               return;
+
+       case OINDREG:
+               // Increase the refcount of the register so that igen's caller
+               // has to call regfree.
+               if(n->val.u.reg != D_R0+REGSP)
+                       reg[n->val.u.reg]++;
+               *a = *n;
+               return;
+
+       case ODOT:
+               igen(n->left, a, res);
+               a->xoffset += n->xoffset;
+               a->type = n->type;
+               fixlargeoffset(a);
+               return;
+
+       case ODOTPTR:
+               cgenr(n->left, a, res);
+               cgen_checknil(a);
+               a->op = OINDREG;
+               a->xoffset += n->xoffset;
+               a->type = n->type;
+               fixlargeoffset(a);
+               return;
+
+       case OCALLFUNC:
+       case OCALLMETH:
+       case OCALLINTER:
+               switch(n->op) {
+               case OCALLFUNC:
+                       cgen_call(n, 0);
+                       break;
+               case OCALLMETH:
+                       cgen_callmeth(n, 0);
+                       break;
+               case OCALLINTER:
+                       cgen_callinter(n, N, 0);
+                       break;
+               }
+               fp = structfirst(&flist, getoutarg(n->left->type));
+               memset(a, 0, sizeof *a);
+               a->op = OINDREG;
+               a->val.u.reg = D_R0+REGSP;
+               a->addable = 1;
+               a->xoffset = fp->width + widthptr; // +widthptr: saved lr at 0(SP)
+               a->type = n->type;
+               return;
+
+       case OINDEX:
+               // Index of fixed-size array by constant can
+               // put the offset in the addressing.
+               // Could do the same for slice except that we need
+               // to use the real index for the bounds checking.
+               if(isfixedarray(n->left->type) ||
+                  (isptr[n->left->type->etype] && isfixedarray(n->left->left->type)))
+               if(isconst(n->right, CTINT)) {
+                       // Compute &a.
+                       if(!isptr[n->left->type->etype])
+                               igen(n->left, a, res);
+                       else {
+                               igen(n->left, &n1, res);
+                               cgen_checknil(&n1);
+                               regalloc(a, types[tptr], res);
+                               gmove(&n1, a);
+                               regfree(&n1);
+                               a->op = OINDREG;
+                       }
+
+                       // Compute &a[i] as &a + i*width.
+                       a->type = n->type;
+                       a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->width;
+                       fixlargeoffset(a);
+                       return;
+               }
+               break;
+       }
+
+       agenr(n, a, res);
+       a->op = OINDREG;
+       a->type = n->type;
+}
+
+/*
+ * generate:
+ *     if(n == true) goto to;
+ */
+void
+bgen(Node *n, int true, int likely, Prog *to)
+{
+       int et, a;
+       Node *nl, *nr, *l, *r;
+       Node n1, n2, tmp;
+       NodeList *ll;
+       Prog *p1, *p2;
+
+       if(debug['g']) {
+               dump("\nbgen", n);
+       }
+
+       if(n == N)
+               n = nodbool(1);
+
+       if(n->ninit != nil)
+               genlist(n->ninit);
+
+       if(n->type == T) {
+               convlit(&n, types[TBOOL]);
+               if(n->type == T)
+                       goto ret;
+       }
+
+       et = n->type->etype;
+       if(et != TBOOL) {
+               yyerror("cgen: bad type %T for %O", n->type, n->op);
+               patch(gins(AEND, N, N), to);
+               goto ret;
+       }
+       nr = N;
+
+       while(n->op == OCONVNOP) {
+               n = n->left;
+               if(n->ninit != nil)
+                       genlist(n->ninit);
+       }
+
+       switch(n->op) {
+       default:
+               regalloc(&n1, n->type, N);
+               cgen(n, &n1);
+               nodconst(&n2, n->type, 0);
+               gins(optoas(OCMP, n->type), &n1, &n2);
+               a = ABNE;
+               if(!true)
+                       a = ABEQ;
+               patch(gbranch(a, n->type, likely), to);
+               regfree(&n1);
+               goto ret;
+
+       case OLITERAL:
+               // need to ask if it is bool?
+               if(!true == !n->val.u.bval)
+                       patch(gbranch(ABR, T, likely), to);
+               goto ret;
+
+       case OANDAND:
+               if(!true)
+                       goto caseor;
+
+       caseand:
+               p1 = gbranch(ABR, T, 0);
+               p2 = gbranch(ABR, T, 0);
+               patch(p1, pc);
+               bgen(n->left, !true, -likely, p2);
+               bgen(n->right, !true, -likely, p2);
+               p1 = gbranch(ABR, T, 0);
+               patch(p1, to);
+               patch(p2, pc);
+               goto ret;
+
+       case OOROR:
+               if(!true)
+                       goto caseand;
+
+       caseor:
+               bgen(n->left, true, likely, to);
+               bgen(n->right, true, likely, to);
+               goto ret;
+
+       case OEQ:
+       case ONE:
+       case OLT:
+       case OGT:
+       case OLE:
+       case OGE:
+               nr = n->right;
+               if(nr == N || nr->type == T)
+                       goto ret;
+
+       case ONOT:      // unary
+               nl = n->left;
+               if(nl == N || nl->type == T)
+                       goto ret;
+               break;
+       }
+
+       switch(n->op) {
+
+       case ONOT:
+               bgen(nl, !true, likely, to);
+               goto ret;
+
+       case OEQ:
+       case ONE:
+       case OLT:
+       case OGT:
+       case OLE:
+       case OGE:
+               a = n->op;
+               if(!true) {
+                       if(isfloat[nr->type->etype]) {
+                               // brcom is not valid on floats when NaN is involved.
+                               p1 = gbranch(ABR, T, 0);
+                               p2 = gbranch(ABR, T, 0);
+                               patch(p1, pc);
+                               ll = n->ninit;   // avoid re-genning ninit
+                               n->ninit = nil;
+                               bgen(n, 1, -likely, p2);
+                               n->ninit = ll;
+                               patch(gbranch(ABR, T, 0), to);
+                               patch(p2, pc);
+                               goto ret;
+                       }
+                       a = brcom(a);
+                       true = !true;
+               }
+
+               // make simplest on right
+               if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) {
+                       a = brrev(a);
+                       r = nl;
+                       nl = nr;
+                       nr = r;
+               }
+
+               if(isslice(nl->type)) {
+                       // front end should only leave cmp to literal nil
+                       if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
+                               yyerror("illegal slice comparison");
+                               break;
+                       }
+                       a = optoas(a, types[tptr]);
+                       igen(nl, &n1, N);
+                       n1.xoffset += Array_array;
+                       n1.type = types[tptr];
+                       nodconst(&tmp, types[tptr], 0);
+                       regalloc(&n2, types[tptr], &n1);
+                       gmove(&n1, &n2);
+                       gins(optoas(OCMP, types[tptr]), &n2, &tmp);
+                       regfree(&n2);
+                       patch(gbranch(a, types[tptr], likely), to);
+                       regfree(&n1);
+                       break;
+               }
+
+               if(isinter(nl->type)) {
+                       // front end should only leave cmp to literal nil
+                       if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
+                               yyerror("illegal interface comparison");
+                               break;
+                       }
+                       a = optoas(a, types[tptr]);
+                       igen(nl, &n1, N);
+                       n1.type = types[tptr];
+                       nodconst(&tmp, types[tptr], 0);
+                       regalloc(&n2, types[tptr], &n1);
+                       gmove(&n1, &n2);
+                       gins(optoas(OCMP, types[tptr]), &n2, &tmp);
+                       regfree(&n2);
+                       patch(gbranch(a, types[tptr], likely), to);
+                       regfree(&n1);
+                       break;
+               }
+               if(iscomplex[nl->type->etype]) {
+                       complexbool(a, nl, nr, true, likely, to);
+                       break;
+               }
+
+               if(nr->ullman >= UINF) {
+                       regalloc(&n1, nl->type, N);
+                       cgen(nl, &n1);
+
+                       tempname(&tmp, nl->type);
+                       gmove(&n1, &tmp);
+                       regfree(&n1);
+
+                       regalloc(&n2, nr->type, N);
+                       cgen(nr, &n2);
+
+                       regalloc(&n1, nl->type, N);
+                       cgen(&tmp, &n1);
+
+                       goto cmp;
+               }
+
+               regalloc(&n1, nl->type, N);
+               cgen(nl, &n1);
+
+               // TODO(minux): cmpi does accept 16-bit signed immediate as p->to.
+               // and cmpli accepts 16-bit unsigned immediate.
+               //if(smallintconst(nr)) {
+               //      gins(optoas(OCMP, nr->type), &n1, nr);
+               //      patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
+               //      regfree(&n1);
+               //      break;
+               //}
+
+               regalloc(&n2, nr->type, N);
+               cgen(nr, &n2);
+       cmp:
+               l = &n1;
+               r = &n2;
+               gins(optoas(OCMP, nr->type), l, r);
+               if(isfloat[nr->type->etype] && (a == OLE || a == OGE)) {
+                       // To get NaN right, must rewrite x <= y into separate x < y or x = y.
+                       switch(a) {
+                       case OLE:
+                               a = OLT;
+                               break;
+                       case OGE:
+                               a = OGT;
+                               break;
+                       }
+                       patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
+                       patch(gbranch(optoas(OEQ, nr->type), nr->type, likely), to);                    
+               } else {
+                       patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
+               }
+               regfree(&n1);
+               regfree(&n2);
+               break;
+       }
+       goto ret;
+
+ret:
+       ;
+}
+
+/*
+ * n is on stack, either local variable
+ * or return value from function call.
+ * return n's offset from SP.
+ */
+int64
+stkof(Node *n)
+{
+       Type *t;
+       Iter flist;
+       int64 off;
+
+       switch(n->op) {
+       case OINDREG:
+               return n->xoffset;
+
+       case ODOT:
+               t = n->left->type;
+               if(isptr[t->etype])
+                       break;
+               off = stkof(n->left);
+               if(off == -1000 || off == 1000)
+                       return off;
+               return off + n->xoffset;
+
+       case OINDEX:
+               t = n->left->type;
+               if(!isfixedarray(t))
+                       break;
+               off = stkof(n->left);
+               if(off == -1000 || off == 1000)
+                       return off;
+               if(isconst(n->right, CTINT))
+                       return off + t->type->width * mpgetfix(n->right->val.u.xval);
+               return 1000;
+               
+       case OCALLMETH:
+       case OCALLINTER:
+       case OCALLFUNC:
+               t = n->left->type;
+               if(isptr[t->etype])
+                       t = t->type;
+
+               t = structfirst(&flist, getoutarg(t));
+               if(t != T)
+                       return t->width + widthptr;     // +widthptr: correct for saved LR
+               break;
+       }
+
+       // botch - probably failing to recognize address
+       // arithmetic on the above. eg INDEX and DOT
+       return -1000;
+}
+
+/*
+ * block copy:
+ *     memmove(&ns, &n, w);
+ */
+void
+sgen(Node *n, Node *ns, int64 w)
+{
+       Node dst, src, tmp, nend;
+       int32 c, odst, osrc;
+       int dir, align, op;
+       Prog *p, *ploop;
+       NodeList *l;
+       Node *res = ns;
+
+       if(debug['g']) {
+               print("\nsgen w=%lld\n", w);
+               dump("r", n);
+               dump("res", ns);
+       }
+
+       if(n->ullman >= UINF && ns->ullman >= UINF)
+               fatal("sgen UINF");
+
+       if(w < 0)
+               fatal("sgen copy %lld", w);
+       
+       // If copying .args, that's all the results, so record definition sites
+       // for them for the liveness analysis.
+       if(ns->op == ONAME && strcmp(ns->sym->name, ".args") == 0)
+               for(l = curfn->dcl; l != nil; l = l->next)
+                       if(l->n->class == PPARAMOUT)
+                               gvardef(l->n);
+
+       // Avoid taking the address for simple enough types.
+       //if(componentgen(n, ns))
+       //      return;
+       
+       if(w == 0) {
+               // evaluate side effects only.
+               regalloc(&dst, types[tptr], N);
+               agen(res, &dst);
+               agen(n, &dst);
+               regfree(&dst);
+               return;
+       }
+
+       // determine alignment.
+       // want to avoid unaligned access, so have to use
+       // smaller operations for less aligned types.
+       // for example moving [4]byte must use 4 MOVB not 1 MOVW.
+       align = n->type->align;
+       switch(align) {
+       default:
+               fatal("sgen: invalid alignment %d for %T", align, n->type);
+       case 1:
+               op = AMOVBU;
+               break;
+       case 2:
+               op = AMOVHU;
+               break;
+       case 4:
+               op = AMOVWZU; // there is no lwau, only lwaux
+               break;
+       case 8:
+               op = AMOVDU;
+               break;
+       }
+       if(w%align)
+               fatal("sgen: unaligned size %lld (align=%d) for %T", w, align, n->type);
+       c = w / align;
+
+       // offset on the stack
+       osrc = stkof(n);
+       odst = stkof(res);
+       if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) {
+               // osrc and odst both on stack, and at least one is in
+               // an unknown position.  Could generate code to test
+               // for forward/backward copy, but instead just copy
+               // to a temporary location first.
+               tempname(&tmp, n->type);
+               sgen(n, &tmp, w);
+               sgen(&tmp, res, w);
+               return;
+       }
+       if(osrc%align != 0 || odst%align != 0)
+               fatal("sgen: unaligned offset src %d or dst %d (align %d)", osrc, odst, align);
+
+       // if we are copying forward on the stack and
+       // the src and dst overlap, then reverse direction
+       dir = align;
+       if(osrc < odst && odst < osrc+w)
+               dir = -dir;
+
+       if(n->ullman >= res->ullman) {
+               agenr(n, &dst, res);    // temporarily use dst
+               regalloc(&src, types[tptr], N);
+               gins(AMOVD, &dst, &src);
+               if(res->op == ONAME)
+                       gvardef(res);
+               agen(res, &dst);
+       } else {
+               if(res->op == ONAME)
+                       gvardef(res);
+               agenr(res, &dst, res);
+               agenr(n, &src, N);
+       }
+
+       regalloc(&tmp, types[tptr], N);
+
+       // set up end marker
+       memset(&nend, 0, sizeof nend);
+
+       // move src and dest to the end of block if necessary
+       if(dir < 0) {
+               if(c >= 4) {
+                       regalloc(&nend, types[tptr], N);
+                       p = gins(AMOVD, &src, &nend);
+               }
+
+               p = gins(AADD, N, &src);
+               p->from.type = D_CONST;
+               p->from.offset = w;
+
+               p = gins(AADD, N, &dst);
+               p->from.type = D_CONST;
+               p->from.offset = w;
+       } else {
+               p = gins(AADD, N, &src);
+               p->from.type = D_CONST;
+               p->from.offset = -dir;
+
+               p = gins(AADD, N, &dst);
+               p->from.type = D_CONST;
+               p->from.offset = -dir;
+
+               if(c >= 4) {
+                       regalloc(&nend, types[tptr], N);
+                       p = gins(AMOVD, &src, &nend);
+                       p->from.type = D_CONST;
+                       p->from.offset = w;
+               }
+       }
+
+
+       // move
+       // TODO: enable duffcopy for larger copies.
+       if(c >= 4) {
+               p = gins(op, &src, &tmp);
+               p->from.type = D_OREG;
+               p->from.offset = dir;
+               ploop = p;
+
+               p = gins(op, &tmp, &dst);
+               p->to.type = D_OREG;
+               p->to.offset = dir;
+
+               p = gins(ACMP, &src, &nend);
+
+               patch(gbranch(ABNE, T, 0), ploop);
+               regfree(&nend);
+       } else {
+               while(c-- > 0) {
+                       p = gins(op, &src, &tmp);
+                       p->from.type = D_OREG;
+                       p->from.offset = dir;
+       
+                       p = gins(op, &tmp, &dst);
+                       p->to.type = D_OREG;
+                       p->to.offset = dir;
+               }
+       }
+
+       regfree(&dst);
+       regfree(&src);
+       regfree(&tmp);
+}
+
+static int
+cadable(Node *n)
+{
+       if(!n->addable) {
+               // dont know how it happens,
+               // but it does
+               return 0;
+       }
+
+       switch(n->op) {
+       case ONAME:
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * copy a composite value by moving its individual components.
+ * Slices, strings and interfaces are supported.
+ * Small structs or arrays with elements of basic type are
+ * also supported.
+ * nr is N when assigning a zero value.
+ * return 1 if can do, 0 if can't.
+ */
+int
+componentgen(Node *nr, Node *nl)
+{
+       Node nodl, nodr;
+       Type *t;
+       int freel, freer;
+       vlong fldcount;
+       vlong loffset, roffset;
+
+       freel = 0;
+       freer = 0;
+
+       switch(nl->type->etype) {
+       default:
+               goto no;
+
+       case TARRAY:
+               t = nl->type;
+
+               // Slices are ok.
+               if(isslice(t))
+                       break;
+               // Small arrays are ok.
+               if(t->bound > 0 && t->bound <= 3 && !isfat(t->type))
+                       break;
+
+               goto no;
+
+       case TSTRUCT:
+               // Small structs with non-fat types are ok.
+               // Zero-sized structs are treated separately elsewhere.
+               fldcount = 0;
+               for(t=nl->type->type; t; t=t->down) {
+                       if(isfat(t->type))
+                               goto no;
+                       if(t->etype != TFIELD)
+                               fatal("componentgen: not a TFIELD: %lT", t);
+                       fldcount++;
+               }
+               if(fldcount == 0 || fldcount > 4)
+                       goto no;
+
+               break;
+
+       case TSTRING:
+       case TINTER:
+               break;
+       }
+
+       nodl = *nl;
+       if(!cadable(nl)) {
+               if(nr == N || !cadable(nr))
+                       goto no;
+               igen(nl, &nodl, N);
+               freel = 1;
+       }
+
+       if(nr != N) {
+               nodr = *nr;
+               if(!cadable(nr)) {
+                       igen(nr, &nodr, N);
+                       freer = 1;
+               }
+       }
+       
+       // nl and nr are 'cadable' which basically means they are names (variables) now.
+       // If they are the same variable, don't generate any code, because the
+       // VARDEF we generate will mark the old value as dead incorrectly.
+       // (And also the assignments are useless.)
+       if(nr != N && nl->op == ONAME && nr->op == ONAME && nl == nr)
+               goto yes;
+
+       switch(nl->type->etype) {
+       case TARRAY:
+               // componentgen for arrays.
+               if(nl->op == ONAME)
+                       gvardef(nl);
+               t = nl->type;
+               if(!isslice(t)) {
+                       nodl.type = t->type;
+                       nodr.type = nodl.type;
+                       for(fldcount=0; fldcount < t->bound; fldcount++) {
+                               if(nr == N)
+                                       clearslim(&nodl);
+                               else
+                                       gmove(&nodr, &nodl);
+                               nodl.xoffset += t->type->width;
+                               nodr.xoffset += t->type->width;
+                       }
+                       goto yes;
+               }
+
+               // componentgen for slices.
+               nodl.xoffset += Array_array;
+               nodl.type = ptrto(nl->type->type);
+
+               if(nr != N) {
+                       nodr.xoffset += Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               nodl.xoffset += Array_nel-Array_array;
+               nodl.type = types[simtype[TUINT]];
+
+               if(nr != N) {
+                       nodr.xoffset += Array_nel-Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               nodl.xoffset += Array_cap-Array_nel;
+               nodl.type = types[simtype[TUINT]];
+
+               if(nr != N) {
+                       nodr.xoffset += Array_cap-Array_nel;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               goto yes;
+
+       case TSTRING:
+               if(nl->op == ONAME)
+                       gvardef(nl);
+               nodl.xoffset += Array_array;
+               nodl.type = ptrto(types[TUINT8]);
+
+               if(nr != N) {
+                       nodr.xoffset += Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               nodl.xoffset += Array_nel-Array_array;
+               nodl.type = types[simtype[TUINT]];
+
+               if(nr != N) {
+                       nodr.xoffset += Array_nel-Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               goto yes;
+
+       case TINTER:
+               if(nl->op == ONAME)
+                       gvardef(nl);
+               nodl.xoffset += Array_array;
+               nodl.type = ptrto(types[TUINT8]);
+
+               if(nr != N) {
+                       nodr.xoffset += Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               nodl.xoffset += Array_nel-Array_array;
+               nodl.type = ptrto(types[TUINT8]);
+
+               if(nr != N) {
+                       nodr.xoffset += Array_nel-Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               goto yes;
+
+       case TSTRUCT:
+               if(nl->op == ONAME)
+                       gvardef(nl);
+               loffset = nodl.xoffset;
+               roffset = nodr.xoffset;
+               // funarg structs may not begin at offset zero.
+               if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type)
+                       loffset -= nl->type->type->width;
+               if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type)
+                       roffset -= nr->type->type->width;
+
+               for(t=nl->type->type; t; t=t->down) {
+                       nodl.xoffset = loffset + t->width;
+                       nodl.type = t->type;
+
+                       if(nr == N)
+                               clearslim(&nodl);
+                       else {
+                               nodr.xoffset = roffset + t->width;
+                               nodr.type = nodl.type;
+                               gmove(&nodr, &nodl);
+                       }
+               }
+               goto yes;
+       }
+
+no:
+       if(freer)
+               regfree(&nodr);
+       if(freel)
+               regfree(&nodl);
+       return 0;
+
+yes:
+       if(freer)
+               regfree(&nodr);
+       if(freel)
+               regfree(&nodl);
+       return 1;
+}
diff --git a/src/cmd/9g/doc.go b/src/cmd/9g/doc.go
new file mode 100644 (file)
index 0000000..200be2e
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+
+9g is the version of the gc compiler for the Power64.
+The $GOARCH for these tools is power64 (big endian) or
+power64le (little endian).
+
+It reads .go files and outputs .9 files. The flags are documented in ../gc/doc.go.
+
+*/
+package main
diff --git a/src/cmd/9g/galign.c b/src/cmd/9g/galign.c
new file mode 100644 (file)
index 0000000..97a5a5d
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+
+int    thechar = '9';
+char*  thestring = "power64";
+LinkArch*      thelinkarch;
+
+void
+linkarchinit(void)
+{
+       thestring = getgoarch();
+       if(strcmp(thestring, "power64le") == 0)
+               thelinkarch = &linkpower64le;
+       else
+               thelinkarch = &linkpower64;
+}
+
+vlong MAXWIDTH = 1LL<<50;
+
+/*
+ * go declares several platform-specific type aliases:
+ * int, uint, float, and uintptr
+ */
+Typedef        typedefs[] =
+{
+       {"int",         TINT,           TINT64},
+       {"uint",                TUINT,          TUINT64},
+       {"uintptr",     TUINTPTR,       TUINT64},
+       {0}
+};
+
+void
+betypeinit(void)
+{
+       widthptr = 8;
+       widthint = 8;
+       widthreg = 8;
+
+       zprog.link = P;
+       zprog.as = AGOK;
+       zprog.reg = NREG;
+       zprog.from.name = D_NONE;
+       zprog.from.type = D_NONE;
+       zprog.from.reg = NREG;
+       zprog.to = zprog.from;
+       zprog.from3 = zprog.from;
+
+       listinit9();
+}
diff --git a/src/cmd/9g/gg.h b/src/cmd/9g/gg.h
new file mode 100644 (file)
index 0000000..703fbd0
--- /dev/null
@@ -0,0 +1,117 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#ifndef        EXTERN
+#define        EXTERN  extern
+#endif
+
+#include "../gc/go.h"
+#include "../9l/9.out.h"
+
+// TODO(minux): Remove when no longer used.
+#define noimpl sysfatal("%s not implemented (%s:%d).", __func__, __FILE__, __LINE__)
+
+#define TEXTFLAG reg
+
+EXTERN int32   dynloc;
+EXTERN uchar   reg[NREG+NFREG];
+EXTERN int32   pcloc;          // instruction counter
+EXTERN Strlit  emptystring;
+EXTERN Prog    zprog;
+EXTERN Node*   newproc;
+EXTERN Node*   deferproc;
+EXTERN Node*   deferreturn;
+EXTERN Node*   panicindex;
+EXTERN Node*   panicslice;
+EXTERN Node*   panicdiv;
+EXTERN Node*   throwreturn;
+extern vlong   unmappedzero;
+
+/*
+ * ggen.c
+ */
+void   compile(Node*);
+void   gen(Node*);
+Node*  lookdot(Node*, Node*, int);
+void   cgen_as(Node*, Node*);
+void   cgen_callmeth(Node*, int);
+void   cgen_callinter(Node*, Node*, int);
+void   cgen_proc(Node*, int);
+void   cgen_callret(Node*, Node*);
+void   cgen_div(int, Node*, Node*, Node*);
+void   cgen_hmul(Node*, Node*, Node*);
+void   cgen_shift(int, int, Node*, Node*, Node*);
+void   cgen_dcl(Node*);
+int    needconvert(Type*, Type*);
+void   genconv(Type*, Type*);
+void   allocparams(void);
+void   checklabels(void);
+void   ginscall(Node*, int);
+int    gen_as_init(Node*);
+
+/*
+ * cgen.c
+ */
+void   agen(Node*, Node*);
+void   agenr(Node*, Node*, Node*);
+void   cgenr(Node*, Node*, Node*);
+void   igen(Node*, Node*, Node*);
+vlong  fieldoffset(Type*, Node*);
+void   sgen(Node*, Node*, int64);
+void   gmove(Node*, Node*);
+Prog*  gins(int, Node*, Node*);
+void   naddr(Node*, Addr*, int);
+void   cgen_aret(Node*, Node*);
+int    componentgen(Node*, Node*);
+
+/*
+ * gsubr.c
+ */
+void   clearp(Prog*);
+Prog*  gbranch(int, Type*, int);
+Prog*  prog(int);
+void   gconv(int, int);
+int    conv2pt(Type*);
+vlong  convvtox(vlong, int);
+void   fnparam(Type*, int, int);
+Prog*  gop(int, Node*, Node*, Node*);
+int    optoas(int, Type*);
+void   ginit(void);
+void   gclean(void);
+void   regalloc(Node*, Type*, Node*);
+void   regfree(Node*);
+Node*  nodarg(Type*, int);
+void   nodreg(Node*, Type*, int);
+void   nodindreg(Node*, Type*, int);
+void   ginscon(int, vlong, Node*);
+void   ginscon2(int, Node*, vlong);
+void   buildtxt(void);
+Plist* newplist(void);
+int    isfat(Type*);
+void   sudoclean(void);
+int    sudoaddable(int, Node*, Addr*);
+void   afunclit(Addr*, Node*);
+void   nodfconst(Node*, Type*, Mpflt*);
+void   gtrack(Sym*);
+void   fixlargeoffset(Node *n);
+
+/*
+ * cplx.c
+ */
+int    complexop(Node*, Node*);
+void   complexmove(Node*, Node*);
+void   complexgen(Node*, Node*);
+
+/*
+ * gobj.c
+ */
+void   datastring(char*, int, Addr*);
+void   datagostring(Strlit*, Addr*);
+
+/*
+ * list.c
+ */
+void   listinit(void);
+
+void   zaddr(Biobuf*, Addr*, int, int);
diff --git a/src/cmd/9g/ggen.c b/src/cmd/9g/ggen.c
new file mode 100644 (file)
index 0000000..c41d8eb
--- /dev/null
@@ -0,0 +1,1034 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#undef EXTERN
+#define        EXTERN
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+#include "opt.h"
+
+static Prog *appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset);
+static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi);
+
+void
+defframe(Prog *ptxt)
+{
+       uint32 frame;
+       Prog *p;
+       vlong hi, lo;
+       NodeList *l;
+       Node *n;
+
+       // fill in argument size
+       ptxt->to.offset = rnd(curfn->type->argwid, widthptr);
+
+       // fill in final stack size
+       ptxt->to.offset <<= 32;
+       frame = rnd(stksize+maxarg, widthreg);
+       ptxt->to.offset |= frame;
+       
+       // insert code to zero ambiguously live variables
+       // so that the garbage collector only sees initialized values
+       // when it looks for pointers.
+       p = ptxt;
+       lo = hi = 0;
+       // iterate through declarations - they are sorted in decreasing xoffset order.
+       for(l=curfn->dcl; l != nil; l = l->next) {
+               n = l->n;
+               if(!n->needzero)
+                       continue;
+               if(n->class != PAUTO)
+                       fatal("needzero class %d", n->class);
+               if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
+                       fatal("var %lN has size %d offset %d", n, (int)n->type->width, (int)n->xoffset);
+
+               if(lo != hi && n->xoffset + n->type->width >= lo - 2*widthreg) {
+                       // merge with range we already have
+                       lo = n->xoffset;
+                       continue;
+               }
+               // zero old range
+               p = zerorange(p, frame, lo, hi);
+
+               // set new range
+               hi = n->xoffset + n->type->width;
+               lo = n->xoffset;
+       }
+       // zero final range
+       zerorange(p, frame, lo, hi);
+}
+
+static Prog*
+zerorange(Prog *p, vlong frame, vlong lo, vlong hi)
+{
+       vlong cnt, i;
+       Prog *p1;
+       Node *f;
+
+       cnt = hi - lo;
+       if(cnt == 0)
+               return p;
+       if(cnt < 4*widthptr) {
+               for(i = 0; i < cnt; i += widthptr)
+                       p = appendpp(p, AMOVD, D_REG, REGZERO, 0, D_OREG, REGSP, 8+frame+lo+i);
+       } else if(cnt <= 128*widthptr) {
+               p = appendpp(p, AADD, D_CONST, NREG, 8+frame+lo-8, D_REG, REGRT1, 0);
+               p->reg = REGSP;
+               p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0);
+               f = sysfunc("duffzero");
+               naddr(f, &p->to, 1);
+               afunclit(&p->to, f);
+               p->to.offset = 4*(128-cnt/widthptr);
+       } else {
+               p = appendpp(p, AMOVD, D_CONST, NREG, 8+frame+lo-8, D_REG, REGTMP, 0);
+               p = appendpp(p, AADD, D_REG, REGTMP, 0, D_REG, REGRT1, 0);
+               p->reg = REGSP;
+               p = appendpp(p, AMOVD, D_CONST, NREG, cnt, D_REG, REGTMP, 0);
+               p = appendpp(p, AADD, D_REG, REGTMP, 0, D_REG, REGRT2, 0);
+               p->reg = REGRT1;
+               p1 = p = appendpp(p, AMOVDU, D_REG, REGZERO, 0, D_OREG, REGRT1, widthptr);
+               p = appendpp(p, ACMP, D_REG, REGRT1, 0, D_REG, REGRT2, 0);
+               p = appendpp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0);
+               patch(p, p1);
+       }
+       return p;
+}
+
+static Prog*
+appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset)
+{
+       Prog *q;
+       q = mal(sizeof(*q));
+       clearp(q);
+       q->as = as;
+       q->lineno = p->lineno;
+       q->from.type = ftype;
+       q->from.reg = freg;
+       q->from.offset = foffset;
+       q->to.type = ttype;
+       q->to.reg = treg;
+       q->to.offset = toffset;
+       q->link = p->link;
+       p->link = q;
+       return q;
+}
+
+// Sweep the prog list to mark any used nodes.
+void
+markautoused(Prog *p)
+{
+       for (; p; p = p->link) {
+               if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
+                       continue;
+
+               if (p->from.node)
+                       p->from.node->used = 1;
+
+               if (p->to.node)
+                       p->to.node->used = 1;
+       }
+}
+
+// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
+void
+fixautoused(Prog *p)
+{
+       Prog **lp;
+
+       for (lp=&p; (p=*lp) != P; ) {
+               if (p->as == ATYPE && p->from.node && p->from.name == D_AUTO && !p->from.node->used) {
+                       *lp = p->link;
+                       continue;
+               }
+               if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !p->to.node->used) {
+                       // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
+                       // VARDEFs are interspersed with other code, and a jump might be using the
+                       // VARDEF as a target. Replace with a no-op instead. A later pass will remove
+                       // the no-ops.
+                       p->to.type = D_NONE;
+                       p->to.node = N;
+                       p->as = ANOP;
+                       continue;
+               }
+               if (p->from.name == D_AUTO && p->from.node)
+                       p->from.offset += p->from.node->stkdelta;
+
+               if (p->to.name == D_AUTO && p->to.node)
+                       p->to.offset += p->to.node->stkdelta;
+
+               lp = &p->link;
+       }
+}
+
+/*
+ * generate: BL reg, f
+ * where both reg and f are registers.
+ * On power, f must be moved to CTR first.
+ */
+static void
+ginsBL(Node *reg, Node *f)
+{
+       Prog *p;
+       p = gins(AMOVD, f, N);
+       p->to.type = D_SPR;
+       p->to.offset = D_CTR;
+       p = gins(ABL, reg, N);
+       p->to.type = D_SPR;
+       p->to.offset = D_CTR;
+}
+
+/*
+ * generate:
+ *     call f
+ *     proc=-1 normal call but no return
+ *     proc=0  normal call
+ *     proc=1  goroutine run in new proc
+ *     proc=2  defer call save away stack
+  *    proc=3  normal call to C pointer (not Go func value)
+ */
+void
+ginscall(Node *f, int proc)
+{
+       Prog *p;
+       Node reg, con, reg2;
+       Node r1;
+
+       if(f->type != T)
+               setmaxarg(f->type);
+
+       switch(proc) {
+       default:
+               fatal("ginscall: bad proc %d", proc);
+               break;
+
+       case 0: // normal call
+       case -1:        // normal call but no return
+               if(f->op == ONAME && f->class == PFUNC) {
+                       if(f == deferreturn) {
+                               // Deferred calls will appear to be returning to
+                               // the CALL deferreturn(SB) that we are about to emit.
+                               // However, the stack trace code will show the line
+                               // of the instruction byte before the return PC. 
+                               // To avoid that being an unrelated instruction,
+                               // insert a Power64 NOP that we will have the right line number.
+                               // Power64 NOP is really or r0, r0, r0; use that description
+                               // because the NOP pseudo-instruction would be removed by
+                               // the linker.
+                               nodreg(&reg, types[TINT], D_R0);
+                               gins(AOR, &reg, &reg);
+                       }
+                       p = gins(ABL, N, f);
+                       afunclit(&p->to, f);
+                       if(proc == -1 || noreturn(p))
+                               gins(AUNDEF, N, N);
+                       break;
+               }
+               nodreg(&reg, types[tptr], D_R0+REGENV);
+               nodreg(&r1, types[tptr], D_R0+3);
+               gmove(f, &reg);
+               reg.op = OINDREG;
+               gmove(&reg, &r1);
+               reg.op = OREGISTER;
+               ginsBL(&reg, &r1);
+               break;
+       
+       case 3: // normal call of c function pointer
+               ginsBL(N, f);
+               break;
+
+       case 1: // call in new proc (go)
+       case 2: // deferred call (defer)
+               nodconst(&con, types[TINT64], argsize(f->type));
+               nodreg(&reg, types[TINT64], D_R0+3);
+               nodreg(&reg2, types[TINT64], D_R0+4);
+               gmove(f, &reg);
+
+               p = gins(ASUB, N, N);
+               p->from.type = D_CONST;
+               p->from.offset = 3 * 8;
+               p->to.type = D_REG;
+               p->to.reg = REGSP;
+
+               gmove(&con, &reg2);
+               p = gins(AMOVW, &reg2, N);
+               p->to.type = D_OREG;
+               p->to.reg = REGSP;
+               p->to.offset = 8;
+
+               p = gins(AMOVD, &reg, N);
+               p->to.type = D_OREG;
+               p->to.reg = REGSP;
+               p->to.offset = 16;
+
+               if(proc == 1)
+                       ginscall(newproc, 0);
+               else {
+                       if(!hasdefer)
+                               fatal("hasdefer=0 but has defer");
+                       ginscall(deferproc, 0);
+               }
+
+               p = gins(AADD, N, N);
+               p->from.type = D_CONST;
+               p->from.offset = 3 * 8;
+               p->to.type = D_REG;
+               p->to.reg = REGSP;
+
+               if(proc == 2) {
+                       nodreg(&reg, types[TINT64], D_R0+3);
+                       p = gins(ACMP, &reg, N);
+                       p->to.type = D_REG;
+                       p->to.reg = D_R0;
+                       p = gbranch(ABEQ, T, +1);
+                       cgen_ret(N);
+                       patch(p, pc);
+               }
+               break;
+       }
+}
+
+/*
+ * n is call to interface method.
+ * generate res = n.
+ */
+void
+cgen_callinter(Node *n, Node *res, int proc)
+{
+       Node *i, *f;
+       Node tmpi, nodi, nodo, nodr, nodsp;
+       Prog *p;
+
+       i = n->left;
+       if(i->op != ODOTINTER)
+               fatal("cgen_callinter: not ODOTINTER %O", i->op);
+
+       f = i->right;           // field
+       if(f->op != ONAME)
+               fatal("cgen_callinter: not ONAME %O", f->op);
+
+       i = i->left;            // interface
+
+       if(!i->addable) {
+               tempname(&tmpi, i->type);
+               cgen(i, &tmpi);
+               i = &tmpi;
+       }
+
+       genlist(n->list);               // assign the args
+
+       // i is now addable, prepare an indirected
+       // register to hold its address.
+       igen(i, &nodi, res);            // REG = &inter
+
+       nodindreg(&nodsp, types[tptr], D_R0+REGSP);
+       nodsp.xoffset = widthptr;
+       nodi.type = types[tptr];
+       nodi.xoffset += widthptr;
+       cgen(&nodi, &nodsp);    // 0(SP) = 8(REG) -- i.data
+
+       regalloc(&nodo, types[tptr], res);
+       nodi.type = types[tptr];
+       nodi.xoffset -= widthptr;
+       cgen(&nodi, &nodo);     // REG = 0(REG) -- i.tab
+       regfree(&nodi);
+
+       regalloc(&nodr, types[tptr], &nodo);
+       if(n->left->xoffset == BADWIDTH)
+               fatal("cgen_callinter: badwidth");
+       cgen_checknil(&nodo); // in case offset is huge
+       nodo.op = OINDREG;
+       nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
+       if(proc == 0) {
+               // plain call: use direct c function pointer - more efficient
+               cgen(&nodo, &nodr);     // REG = 32+offset(REG) -- i.tab->fun[f]
+               proc = 3;
+       } else {
+               // go/defer. generate go func value.
+               p = gins(AMOVD, &nodo, &nodr);  // REG = &(32+offset(REG)) -- i.tab->fun[f]
+               p->from.type = D_CONST;
+       }
+
+       nodr.type = n->left->type;
+       ginscall(&nodr, proc);
+
+       regfree(&nodr);
+       regfree(&nodo);
+}
+
+/*
+ * generate function call;
+ *     proc=0  normal call
+ *     proc=1  goroutine run in new proc
+ *     proc=2  defer call save away stack
+ */
+void
+cgen_call(Node *n, int proc)
+{
+       Type *t;
+       Node nod, afun;
+
+       if(n == N)
+               return;
+
+       if(n->left->ullman >= UINF) {
+               // if name involves a fn call
+               // precompute the address of the fn
+               tempname(&afun, types[tptr]);
+               cgen(n->left, &afun);
+       }
+
+       genlist(n->list);               // assign the args
+       t = n->left->type;
+
+       // call tempname pointer
+       if(n->left->ullman >= UINF) {
+               regalloc(&nod, types[tptr], N);
+               cgen_as(&nod, &afun);
+               nod.type = t;
+               ginscall(&nod, proc);
+               regfree(&nod);
+               return;
+       }
+
+       // call pointer
+       if(n->left->op != ONAME || n->left->class != PFUNC) {
+               regalloc(&nod, types[tptr], N);
+               cgen_as(&nod, n->left);
+               nod.type = t;
+               ginscall(&nod, proc);
+               regfree(&nod);
+               return;
+       }
+
+       // call direct
+       n->left->method = 1;
+       ginscall(n->left, proc);
+}
+
+/*
+ * call to n has already been generated.
+ * generate:
+ *     res = return value from call.
+ */
+void
+cgen_callret(Node *n, Node *res)
+{
+       Node nod;
+       Type *fp, *t;
+       Iter flist;
+
+       t = n->left->type;
+       if(t->etype == TPTR32 || t->etype == TPTR64)
+               t = t->type;
+
+       fp = structfirst(&flist, getoutarg(t));
+       if(fp == T)
+               fatal("cgen_callret: nil");
+
+       memset(&nod, 0, sizeof(nod));
+       nod.op = OINDREG;
+       nod.val.u.reg = D_R0+REGSP;
+       nod.addable = 1;
+
+       nod.xoffset = fp->width + widthptr; // +widthptr: saved LR at 0(R1)
+       nod.type = fp->type;
+       cgen_as(res, &nod);
+}
+
+/*
+ * call to n has already been generated.
+ * generate:
+ *     res = &return value from call.
+ */
+void
+cgen_aret(Node *n, Node *res)
+{
+       Node nod1, nod2;
+       Type *fp, *t;
+       Iter flist;
+
+       t = n->left->type;
+       if(isptr[t->etype])
+               t = t->type;
+
+       fp = structfirst(&flist, getoutarg(t));
+       if(fp == T)
+               fatal("cgen_aret: nil");
+
+       memset(&nod1, 0, sizeof(nod1));
+       nod1.op = OINDREG;
+       nod1.val.u.reg = D_R0 + REGSP;
+       nod1.addable = 1;
+
+       nod1.xoffset = fp->width + widthptr; // +widthptr: saved lr at 0(SP)
+       nod1.type = fp->type;
+
+       if(res->op != OREGISTER) {
+               regalloc(&nod2, types[tptr], res);
+               agen(&nod1, &nod2);
+               gins(AMOVD, &nod2, res);
+               regfree(&nod2);
+       } else
+               agen(&nod1, res);
+}
+
+/*
+ * generate return.
+ * n->left is assignments to return values.
+ */
+void
+cgen_ret(Node *n)
+{
+       Prog *p;
+
+       if(n != N)
+               genlist(n->list);               // copy out args
+       if(hasdefer)
+               ginscall(deferreturn, 0);
+       genlist(curfn->exit);
+       p = gins(ARET, N, N);
+       if(n != N && n->op == ORETJMP) {
+               p->to.name = D_EXTERN;
+               p->to.type = D_CONST;
+               p->to.sym = linksym(n->left->sym);
+       }
+}
+
+void
+cgen_asop(Node *n)
+{
+       USED(n);
+       fatal("cgen_asop"); // no longer used
+}
+
+int
+samereg(Node *a, Node *b)
+{
+       if(a == N || b == N)
+               return 0;
+       if(a->op != OREGISTER)
+               return 0;
+       if(b->op != OREGISTER)
+               return 0;
+       if(a->val.u.reg != b->val.u.reg)
+               return 0;
+       return 1;
+}
+
+/*
+ * generate division.
+ * generates one of:
+ *     res = nl / nr
+ *     res = nl % nr
+ * according to op.
+ */
+void
+dodiv(int op, Node *nl, Node *nr, Node *res)
+{
+       int a, check;
+       Type *t, *t0;
+       Node tl, tr, tl2, tr2, nm1, nz, tm;
+       Prog *p1, *p2;
+
+       // Have to be careful about handling
+       // most negative int divided by -1 correctly.
+       // The hardware will generate undefined result.
+       // Also need to explicitly trap on division on zero,
+       // the hardware will silently generate undefined result.
+       // DIVW will leave unpredicable result in higher 32-bit,
+       // so always use DIVD/DIVDU.
+       t = nl->type;
+       t0 = t;
+       check = 0;
+       if(issigned[t->etype]) {
+               check = 1;
+               if(isconst(nl, CTINT) && mpgetfix(nl->val.u.xval) != -(1ULL<<(t->width*8-1)))
+                       check = 0;
+               else if(isconst(nr, CTINT) && mpgetfix(nr->val.u.xval) != -1)
+                       check = 0;
+       }
+       if(t->width < 8) {
+               if(issigned[t->etype])
+                       t = types[TINT64];
+               else
+                       t = types[TUINT64];
+               check = 0;
+       }
+
+       a = optoas(ODIV, t);
+
+       regalloc(&tl, t0, N);
+       regalloc(&tr, t0, N);
+       if(nl->ullman >= nr->ullman) {
+               cgen(nl, &tl);
+               cgen(nr, &tr);
+       } else {
+               cgen(nr, &tr);
+               cgen(nl, &tl);
+       }
+       if(t != t0) {
+               // Convert
+               tl2 = tl;
+               tr2 = tr;
+               tl.type = t;
+               tr.type = t;
+               gmove(&tl2, &tl);
+               gmove(&tr2, &tr);
+       }
+
+       // Handle divide-by-zero panic.
+       p1 = gins(optoas(OCMP, t), &tr, N);
+       p1->to.type = D_REG;
+       p1->to.reg = REGZERO;
+       p1 = gbranch(optoas(ONE, t), T, +1);
+       if(panicdiv == N)
+               panicdiv = sysfunc("panicdivide");
+       ginscall(panicdiv, -1);
+       patch(p1, pc);
+
+       if(check) {
+               nodconst(&nm1, t, -1);
+               gins(optoas(OCMP, t), &tr, &nm1);
+               p1 = gbranch(optoas(ONE, t), T, +1);
+               if(op == ODIV) {
+                       // a / (-1) is -a.
+                       gins(optoas(OMINUS, t), N, &tl);
+                       gmove(&tl, res);
+               } else {
+                       // a % (-1) is 0.
+                       nodconst(&nz, t, 0);
+                       gmove(&nz, res);
+               }
+               p2 = gbranch(AJMP, T, 0);
+               patch(p1, pc);
+       }
+       p1 = gins(a, &tr, &tl);
+       if(op == ODIV) {
+               regfree(&tr);
+               gmove(&tl, res);
+       } else {
+               // A%B = A-(A/B*B)
+               regalloc(&tm, t, N);
+               // patch div to use the 3 register form
+               // TODO(minux): add gins3?
+               p1->reg = p1->to.reg;
+               p1->to.reg = tm.val.u.reg;
+               gins(optoas(OMUL, t), &tr, &tm);
+               regfree(&tr);
+               gins(optoas(OSUB, t), &tm, &tl);
+               regfree(&tm);
+               gmove(&tl, res);
+       }
+       regfree(&tl);
+       if(check)
+               patch(p2, pc);
+}
+
+/*
+ * generate division according to op, one of:
+ *     res = nl / nr
+ *     res = nl % nr
+ */
+void
+cgen_div(int op, Node *nl, Node *nr, Node *res)
+{
+       Node n1, n2, n3;
+       int w, a;
+       Magic m;
+
+       // TODO(minux): enable division by magic multiply (also need to fix longmod below)
+       //if(nr->op != OLITERAL)
+               goto longdiv;
+       w = nl->type->width*8;
+
+       // Front end handled 32-bit division. We only need to handle 64-bit.
+       // try to do division by multiply by (2^w)/d
+       // see hacker's delight chapter 10
+       switch(simtype[nl->type->etype]) {
+       default:
+               goto longdiv;
+
+       case TUINT64:
+               m.w = w;
+               m.ud = mpgetfix(nr->val.u.xval);
+               umagic(&m);
+               if(m.bad)
+                       break;
+               if(op == OMOD)
+                       goto longmod;
+
+               cgenr(nl, &n1, N);
+               nodconst(&n2, nl->type, m.um);
+               regalloc(&n3, nl->type, res);
+               cgen_hmul(&n1, &n2, &n3);
+
+               if(m.ua) {
+                       // need to add numerator accounting for overflow
+                       gins(optoas(OADD, nl->type), &n1, &n3);
+                       nodconst(&n2, nl->type, 1);
+                       gins(optoas(ORROTC, nl->type), &n2, &n3);
+                       nodconst(&n2, nl->type, m.s-1);
+                       gins(optoas(ORSH, nl->type), &n2, &n3);
+               } else {
+                       nodconst(&n2, nl->type, m.s);
+                       gins(optoas(ORSH, nl->type), &n2, &n3); // shift dx
+               }
+
+               gmove(&n3, res);
+               regfree(&n1);
+               regfree(&n3);
+               return;
+
+       case TINT64:
+               m.w = w;
+               m.sd = mpgetfix(nr->val.u.xval);
+               smagic(&m);
+               if(m.bad)
+                       break;
+               if(op == OMOD)
+                       goto longmod;
+
+               cgenr(nl, &n1, res);
+               nodconst(&n2, nl->type, m.sm);
+               regalloc(&n3, nl->type, N);
+               cgen_hmul(&n1, &n2, &n3);
+
+               if(m.sm < 0) {
+                       // need to add numerator
+                       gins(optoas(OADD, nl->type), &n1, &n3);
+               }
+
+               nodconst(&n2, nl->type, m.s);
+               gins(optoas(ORSH, nl->type), &n2, &n3); // shift n3
+
+               nodconst(&n2, nl->type, w-1);
+               gins(optoas(ORSH, nl->type), &n2, &n1); // -1 iff num is neg
+               gins(optoas(OSUB, nl->type), &n1, &n3); // added
+
+               if(m.sd < 0) {
+                       // this could probably be removed
+                       // by factoring it into the multiplier
+                       gins(optoas(OMINUS, nl->type), N, &n3);
+               }
+
+               gmove(&n3, res);
+               regfree(&n1);
+               regfree(&n3);
+               return;
+       }
+       goto longdiv;
+
+longdiv:
+       // division and mod using (slow) hardware instruction
+       dodiv(op, nl, nr, res);
+       return;
+
+longmod:
+       // mod using formula A%B = A-(A/B*B) but
+       // we know that there is a fast algorithm for A/B
+       regalloc(&n1, nl->type, res);
+       cgen(nl, &n1);
+       regalloc(&n2, nl->type, N);
+       cgen_div(ODIV, &n1, nr, &n2);
+       a = optoas(OMUL, nl->type);
+       if(w == 8) {
+               // use 2-operand 16-bit multiply
+               // because there is no 2-operand 8-bit multiply
+               //a = AIMULW;
+       }
+       if(!smallintconst(nr)) {
+               regalloc(&n3, nl->type, N);
+               cgen(nr, &n3);
+               gins(a, &n3, &n2);
+               regfree(&n3);
+       } else
+               gins(a, nr, &n2);
+       gins(optoas(OSUB, nl->type), &n2, &n1);
+       gmove(&n1, res);
+       regfree(&n1);
+       regfree(&n2);
+}
+
+/*
+ * generate high multiply:
+ *   res = (nl*nr) >> width
+ */
+void
+cgen_hmul(Node *nl, Node *nr, Node *res)
+{
+       int w;
+       Node n1, n2, *tmp;
+       Type *t;
+       Prog *p;
+
+       // largest ullman on left.
+       if(nl->ullman < nr->ullman) {
+               tmp = nl;
+               nl = nr;
+               nr = tmp;
+       }
+       t = nl->type;
+       w = t->width * 8;
+       cgenr(nl, &n1, res);
+       cgenr(nr, &n2, N);
+       switch(simtype[t->etype]) {
+       case TINT8:
+       case TINT16:
+       case TINT32:
+               gins(optoas(OMUL, t), &n2, &n1);
+               p = gins(ASRAD, N, &n1);
+               p->from.type = D_CONST;
+               p->from.offset = w;
+               break;
+       case TUINT8:
+       case TUINT16:
+       case TUINT32:
+               gins(optoas(OMUL, t), &n2, &n1);
+               p = gins(ASRD, N, &n1);
+               p->from.type = D_CONST;
+               p->from.offset = w;
+               break;
+       case TINT64:
+       case TUINT64:
+               if(issigned[t->etype])
+                       p = gins(AMULHD, &n2, &n1);
+               else
+                       p = gins(AMULHDU, &n2, &n1);
+               break;
+       default:
+               fatal("cgen_hmul %T", t);
+               break;
+       }
+       cgen(&n1, res);
+       regfree(&n1);
+       regfree(&n2);
+}
+
+/*
+ * generate shift according to op, one of:
+ *     res = nl << nr
+ *     res = nl >> nr
+ */
+void
+cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
+{
+       Node n1, n2, n3, n4, n5;
+       int a;
+       Prog *p1;
+       uvlong sc;
+       Type *tcount;
+
+       a = optoas(op, nl->type);
+
+       if(nr->op == OLITERAL) {
+               regalloc(&n1, nl->type, res);
+               cgen(nl, &n1);
+               sc = mpgetfix(nr->val.u.xval);
+               if(sc >= nl->type->width*8) {
+                       // large shift gets 2 shifts by width-1
+                       nodconst(&n3, types[TUINT32], nl->type->width*8-1);
+                       gins(a, &n3, &n1);
+                       gins(a, &n3, &n1);
+               } else
+                       gins(a, nr, &n1);
+               gmove(&n1, res);
+               regfree(&n1);
+               goto ret;
+       }
+
+       if(nl->ullman >= UINF) {
+               tempname(&n4, nl->type);
+               cgen(nl, &n4);
+               nl = &n4;
+       }
+       if(nr->ullman >= UINF) {
+               tempname(&n5, nr->type);
+               cgen(nr, &n5);
+               nr = &n5;
+       }
+
+       // Allow either uint32 or uint64 as shift type,
+       // to avoid unnecessary conversion from uint32 to uint64
+       // just to do the comparison.
+       tcount = types[simtype[nr->type->etype]];
+       if(tcount->etype < TUINT32)
+               tcount = types[TUINT32];
+
+       regalloc(&n1, nr->type, N);             // to hold the shift type in CX
+       regalloc(&n3, tcount, &n1);     // to clear high bits of CX
+
+       regalloc(&n2, nl->type, res);
+       if(nl->ullman >= nr->ullman) {
+               cgen(nl, &n2);
+               cgen(nr, &n1);
+               gmove(&n1, &n3);
+       } else {
+               cgen(nr, &n1);
+               gmove(&n1, &n3);
+               cgen(nl, &n2);
+       }
+       regfree(&n3);
+
+       // test and fix up large shifts
+       if(!bounded) {
+               nodconst(&n3, tcount, nl->type->width*8);
+               gins(optoas(OCMP, tcount), &n1, &n3);
+               p1 = gbranch(optoas(OLT, tcount), T, +1);
+               if(op == ORSH && issigned[nl->type->etype]) {
+                       nodconst(&n3, types[TUINT32], nl->type->width*8-1);
+                       gins(a, &n3, &n2);
+               } else {
+                       nodconst(&n3, nl->type, 0);
+                       gmove(&n3, &n2);
+               }
+               patch(p1, pc);
+       }
+
+       gins(a, &n1, &n2);
+
+       gmove(&n2, res);
+
+       regfree(&n1);
+       regfree(&n2);
+
+ret:
+       ;
+}
+
+void
+clearfat(Node *nl)
+{
+       uint64 w, c, q, t;
+       Node dst, end, r0, *f;
+       Prog *p, *pl;
+
+       /* clear a fat object */
+       if(debug['g']) {
+               print("clearfat %N (%T, size: %lld)\n", nl, nl->type, nl->type->width);
+       }
+
+       w = nl->type->width;
+       // Avoid taking the address for simple enough types.
+       //if(componentgen(N, nl))
+       //      return;
+
+       c = w % 8;      // bytes
+       q = w / 8;      // dwords
+
+       if(reg[REGRT1] > 0)
+               fatal("R%d in use during clearfat", REGRT1);
+
+       nodreg(&r0, types[TUINT64], 0); // r0 is always zero
+       nodreg(&dst, types[tptr], D_R0+REGRT1);
+       reg[REGRT1]++;
+       agen(nl, &dst);
+
+       if(q > 128) {
+               p = gins(ASUB, N, &dst);
+               p->from.type = D_CONST;
+               p->from.offset = 8;
+
+               regalloc(&end, types[tptr], N);
+               p = gins(AMOVD, &dst, &end);
+               p->from.type = D_CONST;
+               p->from.offset = q*8;
+
+               p = gins(AMOVDU, &r0, &dst);
+               p->to.type = D_OREG;
+               p->to.offset = 8;
+               pl = p;
+
+               p = gins(ACMP, &dst, &end);
+               patch(gbranch(ABNE, T, 0), pl);
+
+               regfree(&end);
+       } else if(q >= 4) {
+               p = gins(ASUB, N, &dst);
+               p->from.type = D_CONST;
+               p->from.offset = 8;
+               f = sysfunc("duffzero");
+               p = gins(ADUFFZERO, N, f);
+               afunclit(&p->to, f);
+               // 4 and 128 = magic constants: see ../../runtime/asm_power64x.s
+               p->to.offset = 4*(128-q);
+       } else
+       for(t = 0; t < q; t++) {
+               p = gins(AMOVD, &r0, &dst);
+               p->to.type = D_OREG;
+               p->to.offset = 8*t;
+       }
+
+       for(t = 0; t < c; t++) {
+               p = gins(AMOVB, &r0, &dst);
+               p->to.type = D_OREG;
+               p->to.offset = t;
+       }
+       reg[REGRT1]--;
+}
+
+// Called after regopt and peep have run.
+// Expand CHECKNIL pseudo-op into actual nil pointer check.
+void
+expandchecks(Prog *firstp)
+{
+       Prog *p, *p1, *p2;
+
+       for(p = firstp; p != P; p = p->link) {
+               if(debug_checknil && ctxt->debugvlog)
+                       print("expandchecks: %P\n", p);
+               if(p->as != ACHECKNIL)
+                       continue;
+               if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers
+                       warnl(p->lineno, "generated nil check");
+               if(p->from.type != D_REG)
+                       fatal("invalid nil check %P\n", p);
+               /*
+               // check is
+               //      TD $4, R0, arg (R0 is always zero)
+               // eqv. to:
+               //      tdeq r0, arg
+               // NOTE: this needs special runtime support to make SIGTRAP recoverable.
+               reg = p->from.reg;
+               p->as = ATD;
+               p->from = p->to = p->from3 = zprog.from;
+               p->from.type = D_CONST;
+               p->from.offset = 4;
+               p->from.reg = NREG;
+               p->reg = 0;
+               p->to.type = D_REG;
+               p->to.reg = reg;
+               */
+               // check is
+               //      CMP arg, R0
+               //      BNE 2(PC) [likely]
+               //      MOVD R0, 0(R0)
+               p1 = mal(sizeof *p1);
+               p2 = mal(sizeof *p2);
+               clearp(p1);
+               clearp(p2);
+               p1->link = p2;
+               p2->link = p->link;
+               p->link = p1;
+               p1->lineno = p->lineno;
+               p2->lineno = p->lineno;
+               p1->pc = 9999;
+               p2->pc = 9999;
+               p->as = ACMP;
+               p->to.type = D_REG;
+               p->to.reg = REGZERO;
+               p1->as = ABNE;
+               //p1->from.type = D_CONST;
+               //p1->from.offset = 1; // likely
+               p1->to.type = D_BRANCH;
+               p1->to.u.branch = p2->link;
+               // crash by write to memory address 0.
+               p2->as = AMOVD;
+               p2->from.type = D_REG;
+               p2->from.reg = 0;
+               p2->to.type = D_OREG;
+               p2->to.reg = 0;
+               p2->to.offset = 0;
+       }
+}
diff --git a/src/cmd/9g/gobj.c b/src/cmd/9g/gobj.c
new file mode 100644 (file)
index 0000000..fdd7606
--- /dev/null
@@ -0,0 +1,240 @@
+// Derived from Inferno utils/6c/swt.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.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.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+
+int
+dsname(Sym *s, int off, char *t, int n)
+{
+       Prog *p;
+
+       p = gins(ADATA, N, N);
+       p->from.type = D_OREG;
+       p->from.name = D_EXTERN;
+       p->from.offset = off;
+       p->from.reg = NREG;
+       p->from.sym = linksym(s);
+
+       p->reg = n;
+       
+       p->to.type = D_SCONST;
+       p->to.name = D_NONE;
+       p->to.reg = NREG;
+       p->to.offset = 0;
+       memmove(p->to.u.sval, t, n);
+       return off + n;
+}
+
+/*
+ * make a refer to the data s, s+len
+ * emitting DATA if needed.
+ */
+void
+datastring(char *s, int len, Addr *a)
+{
+       Sym *sym;
+       
+       sym = stringsym(s, len);
+       a->type = D_OREG;
+       a->name = D_EXTERN;
+       a->etype = simtype[TINT];
+       a->offset = widthptr+widthint;  // skip header
+       a->reg = NREG;
+       a->sym = linksym(sym);
+       a->node = sym->def;
+}
+
+/*
+ * make a refer to the string sval,
+ * emitting DATA if needed.
+ */
+void
+datagostring(Strlit *sval, Addr *a)
+{
+       Sym *sym;
+
+       sym = stringsym(sval->s, sval->len);
+       a->type = D_OREG;
+       a->name = D_EXTERN;
+       a->sym = linksym(sym);
+       a->reg = NREG;
+       a->node = sym->def;
+       a->offset = 0;  // header
+       a->etype = TINT32;
+}
+
+void
+gdata(Node *nam, Node *nr, int wid)
+{
+       Prog *p;
+
+       if(nr->op == OLITERAL) {
+               switch(nr->val.ctype) {
+               case CTCPLX:
+                       gdatacomplex(nam, nr->val.u.cval);
+                       return;
+               case CTSTR:
+                       gdatastring(nam, nr->val.u.sval);
+                       return;
+               }
+       }
+       p = gins(ADATA, nam, nr);
+       p->reg = wid;
+}
+
+void
+gdatacomplex(Node *nam, Mpcplx *cval)
+{
+       Prog *p;
+       int w;
+
+       w = cplxsubtype(nam->type->etype);
+       w = types[w]->width;
+
+       p = gins(ADATA, nam, N);
+       p->reg = w;
+       p->to.type = D_FCONST;
+       p->to.u.dval = mpgetflt(&cval->real);
+
+       p = gins(ADATA, nam, N);
+       p->reg = w;
+       p->from.offset += w;
+       p->to.type = D_FCONST;
+       p->to.u.dval = mpgetflt(&cval->imag);
+}
+
+void
+gdatastring(Node *nam, Strlit *sval)
+{
+       Prog *p;
+       Node nod1;
+
+       p = gins(ADATA, nam, N);
+       datastring(sval->s, sval->len, &p->to);
+       p->reg = types[tptr]->width;
+       p->to.type = D_CONST;
+       p->to.etype = simtype[tptr];
+
+       nodconst(&nod1, types[TINT], sval->len);
+       p = gins(ADATA, nam, &nod1);
+       p->reg = widthint;
+       p->from.offset += widthptr;
+}
+
+int
+dstringptr(Sym *s, int off, char *str)
+{
+       Prog *p;
+
+       off = rnd(off, widthptr);
+       p = gins(ADATA, N, N);
+       p->from.type = D_OREG;
+       p->from.name = D_EXTERN;
+       p->from.sym = linksym(s);
+       p->from.offset = off;
+       p->reg = widthptr;
+
+       datastring(str, strlen(str)+1, &p->to);
+       p->to.type = D_CONST;
+       p->to.etype = simtype[TINT];
+       off += widthptr;
+
+       return off;
+}
+
+int
+dgostrlitptr(Sym *s, int off, Strlit *lit)
+{
+       Prog *p;
+
+       if(lit == nil)
+               return duintptr(s, off, 0);
+
+       off = rnd(off, widthptr);
+       p = gins(ADATA, N, N);
+       p->from.type = D_OREG;
+       p->from.name = D_EXTERN;
+       p->from.sym = linksym(s);
+       p->from.offset = off;
+       p->reg = widthptr;
+       datagostring(lit, &p->to);
+       p->to.type = D_CONST;
+       p->to.etype = simtype[TINT];
+       off += widthptr;
+
+       return off;
+}
+
+int
+dgostringptr(Sym *s, int off, char *str)
+{
+       int n;
+       Strlit *lit;
+
+       if(str == nil)
+               return duintptr(s, off, 0);
+
+       n = strlen(str);
+       lit = mal(sizeof *lit + n);
+       strcpy(lit->s, str);
+       lit->len = n;
+       return dgostrlitptr(s, off, lit);
+}
+
+int
+dsymptr(Sym *s, int off, Sym *x, int xoff)
+{
+       Prog *p;
+
+       off = rnd(off, widthptr);
+
+       p = gins(ADATA, N, N);
+       p->from.type = D_OREG;
+       p->from.name = D_EXTERN;
+       p->from.sym = linksym(s);
+       p->from.offset = off;
+       p->reg = widthptr;
+       p->to.type = D_CONST;
+       p->to.name = D_EXTERN;
+       p->to.sym = linksym(x);
+       p->to.offset = xoff;
+       off += widthptr;
+
+       return off;
+}
+
+void
+nopout(Prog *p)
+{
+       p->as = ANOP;
+}
+
diff --git a/src/cmd/9g/gsubr.c b/src/cmd/9g/gsubr.c
new file mode 100644 (file)
index 0000000..d8b62b1
--- /dev/null
@@ -0,0 +1,1705 @@
+// Derived from Inferno utils/6c/txt.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.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.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+#include "../../runtime/funcdata.h"
+
+// TODO(rsc): Can make this bigger if we move
+// the text segment up higher in 6l for all GOOS.
+// At the same time, can raise StackBig in ../../runtime/stack.h.
+vlong unmappedzero = 4096;
+
+void
+clearp(Prog *p)
+{
+       *p = zprog;
+       p->as = AEND;
+       p->pc = pcloc;
+       pcloc++;
+}
+
+static int ddumped;
+static Prog *dfirst;
+static Prog *dpc;
+
+/*
+ * generate and return proc with p->as = as,
+ * linked into program. pc is next instruction.
+ */
+Prog*
+prog(int as)
+{
+       Prog *p;
+
+       if(as == ADATA || as == AGLOBL) {
+               if(ddumped)
+                       fatal("already dumped data");
+               if(dpc == nil) {
+                       dpc = mal(sizeof(*dpc));
+                       dfirst = dpc;
+               }
+               p = dpc;
+               dpc = mal(sizeof(*dpc));
+               p->link = dpc;
+               p->reg = 0; // used for flags
+       } else {
+               p = pc;
+               pc = mal(sizeof(*pc));
+               clearp(pc);
+               p->link = pc;
+       }
+
+       if(lineno == 0) {
+               if(debug['K'])
+                       warn("prog: line 0");
+       }
+
+       p->as = as;
+       p->lineno = lineno;
+       return p;
+}
+
+void
+dumpdata(void)
+{
+       ddumped = 1;
+       if(dfirst == nil)
+               return;
+       newplist();
+       *pc = *dfirst;
+       pc = dpc;
+       clearp(pc);
+}
+
+/*
+ * generate a branch.
+ * t is ignored.
+ * likely values are for branch prediction:
+ *     -1 unlikely
+ *     0 no opinion
+ *     +1 likely
+ */
+Prog*
+gbranch(int as, Type *t, int likely)
+{
+       Prog *p;
+       
+       USED(t);
+
+       p = prog(as);
+       p->to.type = D_BRANCH;
+       p->to.u.branch = P;
+       // TODO(minux): Enable this code.
+       // Note: liblink used Bcc CR0, label form, so we need another way
+       // to set likely/unlikely flag. Also note the y bit is not exactly
+       // likely/unlikely bit.
+       if(0 && as != ABR && likely != 0) {
+               p->from.type = D_CONST;
+               p->from.offset = likely > 0;
+       }
+       return p;
+}
+
+/*
+ * patch previous branch to jump to to.
+ */
+void
+patch(Prog *p, Prog *to)
+{
+       if(p->to.type != D_BRANCH)
+               fatal("patch: not a branch");
+       p->to.u.branch = to;
+       p->to.offset = to->pc;
+}
+
+Prog*
+unpatch(Prog *p)
+{
+       Prog *q;
+
+       if(p->to.type != D_BRANCH)
+               fatal("unpatch: not a branch");
+       q = p->to.u.branch;
+       p->to.u.branch = P;
+       p->to.offset = 0;
+       return q;
+}
+
+/*
+ * start a new Prog list.
+ */
+Plist*
+newplist(void)
+{
+       Plist *pl;
+
+       pl = linknewplist(ctxt);
+
+       pc = mal(sizeof(*pc));
+       clearp(pc);
+       pl->firstpc = pc;
+
+       return pl;
+}
+
+void
+gused(Node *n)
+{
+       gins(ANOP, n, N);       // used
+}
+
+Prog*
+gjmp(Prog *to)
+{
+       Prog *p;
+
+       p = gbranch(ABR, T, 0);
+       if(to != P)
+               patch(p, to);
+       return p;
+}
+
+void
+ggloblnod(Node *nam)
+{
+       Prog *p;
+
+       p = gins(AGLOBL, nam, N);
+       p->lineno = nam->lineno;
+       p->from.sym->gotype = linksym(ngotype(nam));
+       p->to.sym = nil;
+       p->to.type = D_CONST;
+       p->to.offset = nam->type->width;
+       if(nam->readonly)
+               p->reg = RODATA;
+       if(nam->type != T && !haspointers(nam->type))
+               p->reg |= NOPTR;
+}
+
+void
+gtrack(Sym *s)
+{
+       Prog *p;
+       
+       p = gins(AUSEFIELD, N, N);
+       p->from.type = D_OREG;
+       p->from.name = D_EXTERN;
+       p->from.sym = linksym(s);
+}
+
+void
+ggloblsym(Sym *s, int32 width, int8 flags)
+{
+       Prog *p;
+
+       p = gins(AGLOBL, N, N);
+       p->from.type = D_OREG;
+       p->from.name = D_EXTERN;
+       p->from.sym = linksym(s);
+       p->to.type = D_CONST;
+       p->to.name = D_NONE;
+       p->to.offset = width;
+       p->reg = flags;
+}
+
+int
+isfat(Type *t)
+{
+       if(t != T)
+       switch(t->etype) {
+       case TSTRUCT:
+       case TARRAY:
+       case TSTRING:
+       case TINTER:    // maybe remove later
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * naddr of func generates code for address of func.
+ * if using opcode that can take address implicitly,
+ * call afunclit to fix up the argument.
+ */
+void
+afunclit(Addr *a, Node *n)
+{
+       if(a->type == D_CONST && a->name == D_EXTERN) {
+               a->type = D_OREG;
+               a->sym = linksym(n->sym);
+       }
+}
+
+static int     resvd[] =
+{
+       REGZERO,
+       REGSP,  // reserved for SP, XXX: not reserved in 9c.
+       30,     // for g
+       REGTMP, // REGTMP
+       FREGCVI+NREG,
+       FREGZERO+NREG,
+       FREGHALF+NREG,
+       FREGONE+NREG,
+       FREGTWO+NREG,
+};
+
+void
+ginit(void)
+{
+       int i;
+
+       for(i=0; i<nelem(reg); i++)
+               reg[i] = 1;
+       for(i=0; i<NREG; i++)
+               reg[i] = 0;
+       for(i=NREG; i<NREG+NREG; i++)
+               reg[i] = 0;
+
+       for(i=0; i<nelem(resvd); i++)
+               reg[resvd[i]]++;
+}
+
+static uintptr regpc[nelem(reg)];
+
+void
+gclean(void)
+{
+       int i;
+
+       for(i=0; i<nelem(resvd); i++)
+               reg[resvd[i]]--;
+
+       for(i=0; i<nelem(reg); i++)
+               if(reg[i])
+                       yyerror("reg %R left allocated, %p\n", i, regpc[i]);
+}
+
+int32
+anyregalloc(void)
+{
+       int i, j;
+
+       for(i=0; i<nelem(reg); i++) {
+               if(reg[i] == 0)
+                       goto ok;
+               for(j=0; j<nelem(resvd); j++)
+                       if(resvd[j] == i)
+                               goto ok;
+               return 1;
+       ok:;
+       }
+       return 0;
+}
+
+/*
+ * allocate register of type t, leave in n.
+ * if o != N, o is desired fixed register.
+ * caller must regfree(n).
+ */
+void
+regalloc(Node *n, Type *t, Node *o)
+{
+       int i, et;
+       int fixfree, fltfree;
+
+       if(t == T)
+               fatal("regalloc: t nil");
+       et = simtype[t->etype];
+
+       if(debug['r']) {
+               fixfree = 0;
+               fltfree = 0;
+               for(i = D_R0; i < D_F0+NREG; i++)
+                       if(reg[i] == 0) {
+                               if(i < D_F0)
+                                       fixfree++;
+                               else
+                                       fltfree++;
+                       }
+               print("regalloc fix %d flt %d free\n", fixfree, fltfree);
+       }
+
+       switch(et) {
+       case TINT8:
+       case TUINT8:
+       case TINT16:
+       case TUINT16:
+       case TINT32:
+       case TUINT32:
+       case TINT64:
+       case TUINT64:
+       case TPTR32:
+       case TPTR64:
+       case TBOOL:
+               if(o != N && o->op == OREGISTER) {
+                       i = o->val.u.reg;
+                       if(i >= D_R0+REGMIN && i <= D_R0+REGMAX)
+                               goto out;
+               }
+               for(i=D_R0+REGMIN; i<=D_R0+REGMAX; i++)
+                       if(reg[i] == 0) {
+                               regpc[i] = (uintptr)getcallerpc(&n);
+                               goto out;
+                       }
+               flusherrors();
+               for(i=D_R0; i<D_R0+NREG; i++)
+                       print("R%d %p\n", i, regpc[i]);
+               fatal("out of fixed registers");
+
+       case TFLOAT32:
+       case TFLOAT64:
+               if(o != N && o->op == OREGISTER) {
+                       i = o->val.u.reg;
+                       if(i >= D_F0+FREGMIN && i <= D_F0+FREGMAX)
+                               goto out;
+               }
+               for(i=D_F0+FREGMIN; i<=D_F0+FREGMAX; i++)
+                       if(reg[i] == 0) {
+                               regpc[i] = (uintptr)getcallerpc(&n);
+                               goto out;
+                       }
+               flusherrors();
+               for(i=D_F0; i<D_F0+NREG; i++)
+                       print("F%d %p\n", i, regpc[i]);
+               fatal("out of floating registers");
+
+       case TCOMPLEX64:
+       case TCOMPLEX128:
+               tempname(n, t);
+               return;
+       }
+       fatal("regalloc: unknown type %T", t);
+       return;
+
+out:
+       reg[i]++;
+       nodreg(n, t, i);
+}
+
+void
+regfree(Node *n)
+{
+       int i;
+
+       if(n->op == ONAME)
+               return;
+       if(n->op != OREGISTER && n->op != OINDREG)
+               fatal("regfree: not a register");
+       i = n->val.u.reg;
+       if(i == D_R0 + REGSP)
+               return;
+       if(i < 0 || i >= nelem(reg))
+               fatal("regfree: reg out of range");
+       if(reg[i] <= 0)
+               fatal("regfree: reg not allocated");
+       reg[i]--;
+       if(reg[i] == 0)
+               regpc[i] = 0;
+}
+
+/*
+ * initialize n to be register r of type t.
+ */
+void
+nodreg(Node *n, Type *t, int r)
+{
+       if(t == T)
+               fatal("nodreg: t nil");
+
+       memset(n, 0, sizeof(*n));
+       n->op = OREGISTER;
+       n->addable = 1;
+       ullmancalc(n);
+       n->val.u.reg = r;
+       n->type = t;
+}
+
+/*
+ * initialize n to be indirect of register r; n is type t.
+ */
+void
+nodindreg(Node *n, Type *t, int r)
+{
+       nodreg(n, t, r);
+       n->op = OINDREG;
+}
+
+Node*
+nodarg(Type *t, int fp)
+{
+       Node *n;
+       NodeList *l;
+       Type *first;
+       Iter savet;
+
+       // entire argument struct, not just one arg
+       if(t->etype == TSTRUCT && t->funarg) {
+               n = nod(ONAME, N, N);
+               n->sym = lookup(".args");
+               n->type = t;
+               first = structfirst(&savet, &t);
+               if(first == nil)
+                       fatal("nodarg: bad struct");
+               if(first->width == BADWIDTH)
+                       fatal("nodarg: offset not computed for %T", t);
+               n->xoffset = first->width;
+               n->addable = 1;
+               goto fp;
+       }
+
+       if(t->etype != TFIELD)
+               fatal("nodarg: not field %T", t);
+       
+       if(fp == 1) {
+               for(l=curfn->dcl; l; l=l->next) {
+                       n = l->n;
+                       if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
+                               return n;
+               }
+       }
+
+       n = nod(ONAME, N, N);
+       n->type = t->type;
+       n->sym = t->sym;
+       
+       if(t->width == BADWIDTH)
+               fatal("nodarg: offset not computed for %T", t);
+       n->xoffset = t->width;
+       n->addable = 1;
+       n->orig = t->nname;
+
+fp:
+       // Rewrite argument named _ to __,
+       // or else the assignment to _ will be
+       // discarded during code generation.
+       if(isblank(n))
+               n->sym = lookup("__");
+
+       switch(fp) {
+       default:
+               fatal("nodarg %T %d", t, fp);
+
+       case 0:         // output arg for calling another function
+               n->op = OINDREG;
+               n->val.u.reg = D_R0+REGSP;
+               n->xoffset += 8;
+               break;
+
+       case 1:         // input arg to current function
+               n->class = PPARAM;
+               break;
+
+       case 2:         // offset output arg
+fatal("shouldn't be used");
+               n->op = OINDREG;
+               n->val.u.reg = D_R0 + REGSP;
+               n->xoffset += types[tptr]->width;
+               break;
+       }
+       n->typecheck = 1;
+       return n;
+}
+
+/*
+ * generate
+ *     as $c, n
+ */
+void
+ginscon(int as, vlong c, Node *n2)
+{
+       Node n1, ntmp;
+
+       nodconst(&n1, types[TINT64], c);
+
+       if(as != AMOVD && (c < -BIG || c > BIG)) {
+               // cannot have more than 16-bit of immediate in ADD, etc.
+               // instead, MOV into register first.
+               regalloc(&ntmp, types[TINT64], N);
+               gins(AMOVD, &n1, &ntmp);
+               gins(as, &ntmp, n2);
+               regfree(&ntmp);
+               return;
+       }
+       gins(as, &n1, n2);
+}
+
+/*
+ * generate
+ *     as n, $c (CMP/CMPU)
+ */
+void
+ginscon2(int as, Node *n2, vlong c)
+{
+       Node n1, ntmp;
+
+       nodconst(&n1, types[TINT64], c);
+
+       switch(as) {
+       default:
+               fatal("ginscon2");
+       case ACMP:
+               if(-BIG <= c && c <= BIG) {
+                       gins(as, n2, &n1);
+                       return;
+               }
+               break;
+       case ACMPU:
+               if(0 <= c && c <= 2*BIG) {
+                       gins(as, n2, &n1);
+                       return;
+               }
+               break;
+       }
+       // MOV n1 into register first
+       regalloc(&ntmp, types[TINT64], N);
+       gins(AMOVD, &n1, &ntmp);
+       gins(as, n2, &ntmp);
+       regfree(&ntmp);
+}
+
+#define        CASE(a,b)       (((a)<<16)|((b)<<0))
+/*c2go int CASE(int, int); */
+
+/*
+ * Is this node a memory operand?
+ */
+int
+ismem(Node *n)
+{
+       switch(n->op) {
+       case OITAB:
+       case OSPTR:
+       case OLEN:
+       case OCAP:
+       case OINDREG:
+       case ONAME:
+       case OPARAM:
+       case OCLOSUREVAR:
+       case OADDR:
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * set up nodes representing 2^63
+ */
+Node bigi;
+Node bigf;
+
+void
+bignodes(void)
+{
+       static int did;
+
+       if(did)
+               return;
+       did = 1;
+
+       nodconst(&bigi, types[TUINT64], 1);
+       mpshiftfix(bigi.val.u.xval, 63);
+
+       bigf = bigi;
+       bigf.type = types[TFLOAT64];
+       bigf.val.ctype = CTFLT;
+       bigf.val.u.fval = mal(sizeof *bigf.val.u.fval);
+       mpmovefixflt(bigf.val.u.fval, bigi.val.u.xval);
+}
+
+/*
+ * generate move:
+ *     t = f
+ * hard part is conversions.
+ */
+void
+gmove(Node *f, Node *t)
+{
+       int a, ft, tt;
+       Type *cvt;
+       Node r1, r2, r3, con;
+       Prog *p1, *p2;
+
+       if(debug['M'])
+               print("gmove %lN -> %lN\n", f, t);
+
+       ft = simsimtype(f->type);
+       tt = simsimtype(t->type);
+       cvt = t->type;
+
+       if(iscomplex[ft] || iscomplex[tt]) {
+               complexmove(f, t);
+               return;
+       }
+
+       // cannot have two memory operands
+       if(ismem(f) && ismem(t))
+               goto hard;
+
+       // convert constant to desired type
+       if(f->op == OLITERAL) {
+               switch(tt) {
+               default:
+                       convconst(&con, t->type, &f->val);
+                       break;
+
+               case TINT32:
+               case TINT16:
+               case TINT8:
+                       convconst(&con, types[TINT64], &f->val);
+                       regalloc(&r1, con.type, t);
+                       gins(AMOVD, &con, &r1);
+                       gmove(&r1, t);
+                       regfree(&r1);
+                       return;
+
+               case TUINT32:
+               case TUINT16:
+               case TUINT8:
+                       convconst(&con, types[TUINT64], &f->val);
+                       regalloc(&r1, con.type, t);
+                       gins(AMOVD, &con, &r1);
+                       gmove(&r1, t);
+                       regfree(&r1);
+                       return;
+               }
+
+               f = &con;
+               ft = tt;        // so big switch will choose a simple mov
+
+               // constants can't move directly to memory.
+               if(ismem(t)) {
+                       goto hard;
+                       // float constants come from memory.
+                       //if(isfloat[tt])
+                       //      goto hard;
+
+                       // 64-bit immediates are also from memory.
+                       //if(isint[tt])
+                       //      goto hard;
+                       //// 64-bit immediates are really 32-bit sign-extended
+                       //// unless moving into a register.
+                       //if(isint[tt]) {
+                       //      if(mpcmpfixfix(con.val.u.xval, minintval[TINT32]) < 0)
+                       //              goto hard;
+                       //      if(mpcmpfixfix(con.val.u.xval, maxintval[TINT32]) > 0)
+                       //              goto hard;
+                       //}
+               }
+       }
+
+       // value -> value copy, only one memory operand.
+       // figure out the instruction to use.
+       // break out of switch for one-instruction gins.
+       // goto rdst for "destination must be register".
+       // goto hard for "convert to cvt type first".
+       // otherwise handle and return.
+
+       switch(CASE(ft, tt)) {
+       default:
+               fatal("gmove %lT -> %lT", f->type, t->type);
+
+       /*
+        * integer copy and truncate
+        */
+       case CASE(TINT8, TINT8):        // same size
+       case CASE(TUINT8, TINT8):
+       case CASE(TINT16, TINT8):       // truncate
+       case CASE(TUINT16, TINT8):
+       case CASE(TINT32, TINT8):
+       case CASE(TUINT32, TINT8):
+       case CASE(TINT64, TINT8):
+       case CASE(TUINT64, TINT8):
+               a = AMOVB;
+               break;
+
+       case CASE(TINT8, TUINT8):       // same size
+       case CASE(TUINT8, TUINT8):
+       case CASE(TINT16, TUINT8):      // truncate
+       case CASE(TUINT16, TUINT8):
+       case CASE(TINT32, TUINT8):
+       case CASE(TUINT32, TUINT8):
+       case CASE(TINT64, TUINT8):
+       case CASE(TUINT64, TUINT8):
+               a = AMOVBZ;
+               break;
+
+       case CASE(TINT16, TINT16):      // same size
+       case CASE(TUINT16, TINT16):
+       case CASE(TINT32, TINT16):      // truncate
+       case CASE(TUINT32, TINT16):
+       case CASE(TINT64, TINT16):
+       case CASE(TUINT64, TINT16):
+               a = AMOVH;
+               break;
+
+       case CASE(TINT16, TUINT16):     // same size
+       case CASE(TUINT16, TUINT16):
+       case CASE(TINT32, TUINT16):     // truncate
+       case CASE(TUINT32, TUINT16):
+       case CASE(TINT64, TUINT16):
+       case CASE(TUINT64, TUINT16):
+               a = AMOVHZ;
+               break;
+
+       case CASE(TINT32, TINT32):      // same size
+       case CASE(TUINT32, TINT32):
+       case CASE(TINT64, TINT32):      // truncate
+       case CASE(TUINT64, TINT32):
+               a = AMOVW;
+               break;
+
+       case CASE(TINT32, TUINT32):     // same size
+       case CASE(TUINT32, TUINT32):
+       case CASE(TINT64, TUINT32):
+       case CASE(TUINT64, TUINT32):
+               a = AMOVWZ;
+               break;
+
+       case CASE(TINT64, TINT64):      // same size
+       case CASE(TINT64, TUINT64):
+       case CASE(TUINT64, TINT64):
+       case CASE(TUINT64, TUINT64):
+               a = AMOVD;
+               break;
+
+       /*
+        * integer up-conversions
+        */
+       case CASE(TINT8, TINT16):       // sign extend int8
+       case CASE(TINT8, TUINT16):
+       case CASE(TINT8, TINT32):
+       case CASE(TINT8, TUINT32):
+       case CASE(TINT8, TINT64):
+       case CASE(TINT8, TUINT64):
+               a = AMOVB;
+               goto rdst;
+
+       case CASE(TUINT8, TINT16):      // zero extend uint8
+       case CASE(TUINT8, TUINT16):
+       case CASE(TUINT8, TINT32):
+       case CASE(TUINT8, TUINT32):
+       case CASE(TUINT8, TINT64):
+       case CASE(TUINT8, TUINT64):
+               a = AMOVBZ;
+               goto rdst;
+
+       case CASE(TINT16, TINT32):      // sign extend int16
+       case CASE(TINT16, TUINT32):
+       case CASE(TINT16, TINT64):
+       case CASE(TINT16, TUINT64):
+               a = AMOVH;
+               goto rdst;
+
+       case CASE(TUINT16, TINT32):     // zero extend uint16
+       case CASE(TUINT16, TUINT32):
+       case CASE(TUINT16, TINT64):
+       case CASE(TUINT16, TUINT64):
+               a = AMOVHZ;
+               goto rdst;
+
+       case CASE(TINT32, TINT64):      // sign extend int32
+       case CASE(TINT32, TUINT64):
+               a = AMOVW;
+               goto rdst;
+
+       case CASE(TUINT32, TINT64):     // zero extend uint32
+       case CASE(TUINT32, TUINT64):
+               a = AMOVWZ;
+               goto rdst;
+
+       /*
+       * float to integer
+       */
+       case CASE(TFLOAT32, TINT32):
+       case CASE(TFLOAT64, TINT32):
+       case CASE(TFLOAT32, TINT64):
+       case CASE(TFLOAT64, TINT64):
+       case CASE(TFLOAT32, TINT16):
+       case CASE(TFLOAT32, TINT8):
+       case CASE(TFLOAT32, TUINT16):
+       case CASE(TFLOAT32, TUINT8):
+       case CASE(TFLOAT64, TINT16):
+       case CASE(TFLOAT64, TINT8):
+       case CASE(TFLOAT64, TUINT16):
+       case CASE(TFLOAT64, TUINT8):
+       case CASE(TFLOAT32, TUINT32):
+       case CASE(TFLOAT64, TUINT32):
+       case CASE(TFLOAT32, TUINT64):
+       case CASE(TFLOAT64, TUINT64):
+               //warn("gmove: convert float to int not implemented: %N -> %N\n", f, t);
+               //return;
+               // algorithm is:
+               //      if small enough, use native float64 -> int64 conversion.
+               //      otherwise, subtract 2^63, convert, and add it back.
+               bignodes();
+               regalloc(&r1, types[ft], f);
+               gmove(f, &r1);
+               if(tt == TUINT64) {
+                       regalloc(&r2, types[TFLOAT64], N);
+                       gmove(&bigf, &r2);
+                       gins(AFCMPU, &r1, &r2);
+                       p1 = gbranch(optoas(OLT, types[TFLOAT64]), T, +1);
+                       gins(AFSUB, &r2, &r1);
+                       patch(p1, pc);
+                       regfree(&r2);
+               }
+               regalloc(&r2, types[TFLOAT64], N);
+               regalloc(&r3, types[TINT64], t);
+               gins(AFCTIDZ, &r1, &r2);
+               p1 = gins(AFMOVD, &r2, N);
+               p1->to.type = D_OREG;
+               p1->to.reg = REGSP;
+               p1->to.offset = -8;
+               p1 = gins(AMOVD, N, &r3);
+               p1->from.type = D_OREG;
+               p1->from.reg = REGSP;
+               p1->from.offset = -8;
+               regfree(&r2);
+               regfree(&r1);
+               if(tt == TUINT64) {
+                       p1 = gbranch(optoas(OLT, types[TFLOAT64]), T, +1); // use CR0 here again
+                       nodreg(&r1, types[TINT64], D_R0+REGTMP);
+                       gins(AMOVD, &bigi, &r1);
+                       gins(AADD, &r1, &r3);
+                       patch(p1, pc);
+               }
+               gmove(&r3, t);
+               regfree(&r3);
+               return;
+
+       /*
+        * integer to float
+        */
+       case CASE(TINT32, TFLOAT32):
+       case CASE(TINT32, TFLOAT64):
+       case CASE(TINT64, TFLOAT32):
+       case CASE(TINT64, TFLOAT64):
+       case CASE(TINT16, TFLOAT32):
+       case CASE(TINT16, TFLOAT64):
+       case CASE(TINT8, TFLOAT32):
+       case CASE(TINT8, TFLOAT64):
+       case CASE(TUINT16, TFLOAT32):
+       case CASE(TUINT16, TFLOAT64):
+       case CASE(TUINT8, TFLOAT32):
+       case CASE(TUINT8, TFLOAT64):
+       case CASE(TUINT32, TFLOAT32):
+       case CASE(TUINT32, TFLOAT64):
+       case CASE(TUINT64, TFLOAT32):
+       case CASE(TUINT64, TFLOAT64):
+               //warn("gmove: convert int to float not implemented: %N -> %N\n", f, t);
+               //return;
+               // algorithm is:
+               //      if small enough, use native int64 -> uint64 conversion.
+               //      otherwise, halve (rounding to odd?), convert, and double.
+               bignodes();
+               regalloc(&r1, types[TINT64], N);
+               gmove(f, &r1);
+               if(ft == TUINT64) {
+                       nodreg(&r2, types[TUINT64], D_R0+REGTMP);
+                       gmove(&bigi, &r2);
+                       gins(ACMPU, &r1, &r2);
+                       p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1);
+                       p2 = gins(ASRD, N, &r1);
+                       p2->from.type = D_CONST;
+                       p2->from.offset = 1;
+                       patch(p1, pc);
+               }
+               regalloc(&r2, types[TFLOAT64], t);
+               p1 = gins(AMOVD, &r1, N);
+               p1->to.type = D_OREG;
+               p1->to.reg = REGSP;
+               p1->to.offset = -8;
+               p1 = gins(AFMOVD, N, &r2);
+               p1->from.type = D_OREG;
+               p1->from.reg = REGSP;
+               p1->from.offset = -8;
+               gins(AFCFID, &r2, &r2);
+               regfree(&r1);
+               if(ft == TUINT64) {
+                       p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1); // use CR0 here again
+                       nodreg(&r1, types[TFLOAT64], D_F0+FREGTWO);
+                       gins(AFMUL, &r1, &r2);
+                       patch(p1, pc);
+               }
+               gmove(&r2, t);
+               regfree(&r2);
+               return;
+
+       /*
+        * float to float
+        */
+       case CASE(TFLOAT32, TFLOAT32):
+               a = AFMOVS;
+               break;
+
+       case CASE(TFLOAT64, TFLOAT64):
+               a = AFMOVD;
+               break;
+
+       case CASE(TFLOAT32, TFLOAT64):
+               a = AFMOVS;
+               goto rdst;
+
+       case CASE(TFLOAT64, TFLOAT32):
+               a = AFRSP;
+               goto rdst;
+       }
+
+       gins(a, f, t);
+       return;
+
+rdst:
+       // requires register destination
+       regalloc(&r1, t->type, t);
+       gins(a, f, &r1);
+       gmove(&r1, t);
+       regfree(&r1);
+       return;
+
+hard:
+       // requires register intermediate
+       regalloc(&r1, cvt, t);
+       gmove(f, &r1);
+       gmove(&r1, t);
+       regfree(&r1);
+       return;
+}
+
+/*
+ * generate one instruction:
+ *     as f, t
+ */
+Prog*
+gins(int as, Node *f, Node *t)
+{
+       //int32 w;
+       Prog *p;
+       Addr af, at;
+
+       memset(&af, 0, sizeof af);
+       memset(&at, 0, sizeof at);
+       if(f != N)
+               naddr(f, &af, 1);
+       if(t != N)
+               naddr(t, &at, 1);
+       p = prog(as);
+       if(f != N)
+               p->from = af;
+       if(t != N)
+               p->to = at;
+       if(as == ATEXT)
+               p->reg = 0;
+       if(debug['g'])
+               print("%P\n", p);
+
+       // TODO(minux): enable these.
+       // right now it fails on MOVD $type."".TypeAssertionError(SB) [width=1], R7 [width=8]
+       /*
+       w = 0;
+       switch(as) {
+       case AMOVB:
+       case AMOVBU:
+       case AMOVBZ:
+       case AMOVBZU:
+               w = 1;
+               break;
+       case AMOVH:
+       case AMOVHU:
+       case AMOVHZ:
+       case AMOVHZU:
+               w = 2;
+               break;
+       case AMOVW:
+       case AMOVWU:
+       case AMOVWZ:
+       case AMOVWZU:
+               w = 4;
+               break;
+       case AMOVD:
+       case AMOVDU:
+               w = 8;
+               break;
+       }
+       if(w != 0 && ((f != N && af.width < w) || (t != N && at.width > w))) {
+               dump("f", f);
+               dump("t", t);
+               fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
+       }
+       */
+
+       return p;
+}
+
+void
+fixlargeoffset(Node *n)
+{
+       Node a;
+
+       if(n == N)
+               return;
+       if(n->op != OINDREG)
+               return;
+       if(n->val.u.reg == D_R0+REGSP) // stack offset cannot be large
+               return;
+       if(n->xoffset != (int32)n->xoffset) {
+               // TODO(minux): offset too large, move into R31 and add to R31 instead.
+               // this is used only in test/fixedbugs/issue6036.go.
+               print("offset too large: %N\n", n);
+               noimpl;
+               a = *n;
+               a.op = OREGISTER;
+               a.type = types[tptr];
+               a.xoffset = 0;
+               cgen_checknil(&a);
+               ginscon(optoas(OADD, types[tptr]), n->xoffset, &a);
+               n->xoffset = 0;
+       }
+}
+
+/*
+ * generate code to compute n;
+ * make a refer to result.
+ */
+void
+naddr(Node *n, Addr *a, int canemitcode)
+{
+       Sym *s;
+
+       a->type = D_NONE;
+       a->name = D_NONE;
+       a->reg = NREG;
+       a->gotype = nil;
+       a->node = N;
+       a->etype = 0;
+       a->width = 0;
+       if(n == N)
+               return;
+
+       if(n->type != T && n->type->etype != TIDEAL) {
+               dowidth(n->type);
+               a->width = n->type->width;
+       }
+
+       switch(n->op) {
+       default:
+               fatal("naddr: bad %O %D", n->op, a);
+               break;
+
+       case ONAME:
+               a->etype = 0;
+               a->width = 0;
+               a->reg = NREG;
+               if(n->type != T) {
+                       a->etype = simtype[n->type->etype];
+                       a->width = n->type->width;
+               }
+               a->offset = n->xoffset;
+               s = n->sym;
+               a->node = n->orig;
+               //if(a->node >= (Node*)&n)
+               //      fatal("stack node");
+               if(s == S)
+                       s = lookup(".noname");
+               if(n->method) {
+                       if(n->type != T)
+                       if(n->type->sym != S)
+                       if(n->type->sym->pkg != nil)
+                               s = pkglookup(s->name, n->type->sym->pkg);
+               }
+
+               a->type = D_OREG;
+               switch(n->class) {
+               default:
+                       fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
+               case PEXTERN:
+                       a->name = D_EXTERN;
+                       break;
+               case PAUTO:
+                       a->name = D_AUTO;
+                       break;
+               case PPARAM:
+               case PPARAMOUT:
+                       a->name = D_PARAM;
+                       break;
+               case PFUNC:
+                       a->name = D_EXTERN;
+                       a->type = D_CONST;
+                       a->width = widthptr;
+                       s = funcsym(s);
+                       break;
+               }
+               a->sym = linksym(s);
+               break;
+
+       case OLITERAL:
+               switch(n->val.ctype) {
+               default:
+                       fatal("naddr: const %lT", n->type);
+                       break;
+               case CTFLT:
+                       a->type = D_FCONST;
+                       a->u.dval = mpgetflt(n->val.u.fval);
+                       break;
+               case CTINT:
+               case CTRUNE:
+                       a->sym = nil;
+                       a->type = D_CONST;
+                       a->offset = mpgetfix(n->val.u.xval);
+                       break;
+               case CTSTR:
+                       datagostring(n->val.u.sval, a);
+                       break;
+               case CTBOOL:
+                       a->sym = nil;
+                       a->type = D_CONST;
+                       a->offset = n->val.u.bval;
+                       break;
+               case CTNIL:
+                       a->sym = nil;
+                       a->type = D_CONST;
+                       a->offset = 0;
+                       break;
+               }
+               break;
+
+       case OREGISTER:
+               if(n->val.u.reg < D_F0) {
+                       a->type = D_REG;
+                       a->reg = n->val.u.reg;
+               } else {
+                       a->type = D_FREG;
+                       a->reg = n->val.u.reg - D_F0;
+               }
+               a->sym = nil;
+               break;
+
+       case OINDREG:
+               a->type = D_OREG;
+               a->reg = n->val.u.reg;
+               a->sym = linksym(n->sym);
+               a->offset = n->xoffset;
+               if(a->offset != (int32)a->offset)
+                       yyerror("offset %lld too large for OINDREG", a->offset);
+               break;
+
+       case OPARAM:
+               // n->left is PHEAP ONAME for stack parameter.
+               // compute address of actual parameter on stack.
+               a->etype = simtype[n->left->type->etype];
+               a->width = n->left->type->width;
+               a->offset = n->xoffset;
+               a->sym = linksym(n->left->sym);
+               a->type = D_OREG;
+               a->name = D_PARAM;
+               a->node = n->left->orig;
+               break;
+
+       case OCLOSUREVAR:
+               if(!curfn->needctxt)
+                       fatal("closurevar without needctxt");
+               a->type = D_OREG;
+               a->reg = REGENV;
+               a->offset = n->xoffset;
+               a->sym = nil;
+               break;
+
+       case OCFUNC:
+               naddr(n->left, a, canemitcode);
+               a->sym = linksym(n->left->sym);
+               break;
+
+       case OITAB:
+               // itable of interface value
+               naddr(n->left, a, canemitcode);
+               a->etype = simtype[tptr];
+               if(a->type == D_CONST && a->offset == 0)
+                       break;  // len(nil)
+               break;
+
+       case OSPTR:
+               // pointer in a string or slice
+               naddr(n->left, a, canemitcode);
+               if(a->type == D_CONST && a->offset == 0)
+                       break;  // ptr(nil)
+               a->etype = simtype[tptr];
+               a->offset += Array_array;
+               a->width = widthptr;
+               break;
+
+       case OLEN:
+               // len of string or slice
+               naddr(n->left, a, canemitcode);
+               a->etype = simtype[TINT];
+               if(a->type == D_CONST && a->offset == 0)
+                       break;  // len(nil)
+               a->offset += Array_nel;
+               break;
+
+       case OCAP:
+               // cap of string or slice
+               naddr(n->left, a, canemitcode);
+               a->etype = simtype[TINT];
+               if(a->type == D_CONST && a->offset == 0)
+                       break;  // cap(nil)
+               a->offset += Array_cap;
+               break;
+
+       case OADDR:
+               naddr(n->left, a, canemitcode);
+               a->etype = tptr;
+               switch(a->type) {
+               case D_OREG:
+                       a->type = D_CONST;
+                       break;
+
+               case D_REG:
+               case D_CONST:
+                       break;
+
+               default:
+                       fatal("naddr: OADDR %d\n", a->type);
+               }
+       }
+}
+
+/*
+ * return Axxx for Oxxx on type t.
+ */
+int
+optoas(int op, Type *t)
+{
+       int a;
+
+       if(t == T)
+               fatal("optoas: t is nil");
+
+       a = AGOK;
+       switch(CASE(op, simtype[t->etype])) {
+       default:
+               fatal("optoas: no entry for op=%O type=%T", op, t);
+               break;
+
+       case CASE(OEQ, TBOOL):
+       case CASE(OEQ, TINT8):
+       case CASE(OEQ, TUINT8):
+       case CASE(OEQ, TINT16):
+       case CASE(OEQ, TUINT16):
+       case CASE(OEQ, TINT32):
+       case CASE(OEQ, TUINT32):
+       case CASE(OEQ, TINT64):
+       case CASE(OEQ, TUINT64):
+       case CASE(OEQ, TPTR32):
+       case CASE(OEQ, TPTR64):
+       case CASE(OEQ, TFLOAT32):
+       case CASE(OEQ, TFLOAT64):
+               a = ABEQ;
+               break;
+
+       case CASE(ONE, TBOOL):
+       case CASE(ONE, TINT8):
+       case CASE(ONE, TUINT8):
+       case CASE(ONE, TINT16):
+       case CASE(ONE, TUINT16):
+       case CASE(ONE, TINT32):
+       case CASE(ONE, TUINT32):
+       case CASE(ONE, TINT64):
+       case CASE(ONE, TUINT64):
+       case CASE(ONE, TPTR32):
+       case CASE(ONE, TPTR64):
+       case CASE(ONE, TFLOAT32):
+       case CASE(ONE, TFLOAT64):
+               a = ABNE;
+               break;
+
+       case CASE(OLT, TINT8):  // ACMP
+       case CASE(OLT, TINT16):
+       case CASE(OLT, TINT32):
+       case CASE(OLT, TINT64):
+       case CASE(OLT, TUINT8): // ACMPU
+       case CASE(OLT, TUINT16):
+       case CASE(OLT, TUINT32):
+       case CASE(OLT, TUINT64):
+       case CASE(OLT, TFLOAT32): // AFCMPU
+       case CASE(OLT, TFLOAT64):
+               a = ABLT;
+               break;
+
+       case CASE(OLE, TINT8):  // ACMP
+       case CASE(OLE, TINT16):
+       case CASE(OLE, TINT32):
+       case CASE(OLE, TINT64):
+       case CASE(OLE, TUINT8): // ACMPU
+       case CASE(OLE, TUINT16):
+       case CASE(OLE, TUINT32):
+       case CASE(OLE, TUINT64):
+       case CASE(OLE, TFLOAT32): // AFCMPU
+       case CASE(OLE, TFLOAT64):
+               a = ABLE;
+               break;
+
+       case CASE(OGT, TINT8):
+       case CASE(OGT, TINT16):
+       case CASE(OGT, TINT32):
+       case CASE(OGT, TINT64):
+       case CASE(OGT, TUINT8):
+       case CASE(OGT, TUINT16):
+       case CASE(OGT, TUINT32):
+       case CASE(OGT, TUINT64):
+       case CASE(OGT, TFLOAT32):
+       case CASE(OGT, TFLOAT64):
+               a = ABGT;
+               break;
+
+       case CASE(OGE, TINT8):
+       case CASE(OGE, TINT16):
+       case CASE(OGE, TINT32):
+       case CASE(OGE, TINT64):
+       case CASE(OGE, TUINT8):
+       case CASE(OGE, TUINT16):
+       case CASE(OGE, TUINT32):
+       case CASE(OGE, TUINT64):
+       case CASE(OGE, TFLOAT32):
+       case CASE(OGE, TFLOAT64):
+               a = ABGE;
+               break;
+
+       case CASE(OCMP, TBOOL):
+       case CASE(OCMP, TINT8):
+       case CASE(OCMP, TINT16):
+       case CASE(OCMP, TINT32):
+       case CASE(OCMP, TPTR32):
+       case CASE(OCMP, TINT64):
+               a = ACMP;
+               break;
+
+       case CASE(OCMP, TUINT8):
+       case CASE(OCMP, TUINT16):
+       case CASE(OCMP, TUINT32):
+       case CASE(OCMP, TUINT64):
+       case CASE(OCMP, TPTR64):
+               a = ACMPU;
+               break;
+
+       case CASE(OCMP, TFLOAT32):
+       case CASE(OCMP, TFLOAT64):
+               a = AFCMPU;
+               break;
+
+       case CASE(OAS, TBOOL):
+       case CASE(OAS, TINT8):
+               a = AMOVB;
+               break;
+
+       case CASE(OAS, TUINT8):
+               a = AMOVBZ;
+               break;
+
+       case CASE(OAS, TINT16):
+               a = AMOVH;
+               break;
+
+       case CASE(OAS, TUINT16):
+               a = AMOVHZ;
+               break;
+
+       case CASE(OAS, TINT32):
+               a = AMOVW;
+               break;
+
+       case CASE(OAS, TUINT32):
+       case CASE(OAS, TPTR32):
+               a = AMOVWZ;
+               break;
+
+       case CASE(OAS, TINT64):
+       case CASE(OAS, TUINT64):
+       case CASE(OAS, TPTR64):
+               a = AMOVD;
+               break;
+
+       case CASE(OAS, TFLOAT32):
+               a = AFMOVS;
+               break;
+
+       case CASE(OAS, TFLOAT64):
+               a = AFMOVD;
+               break;
+
+       case CASE(OADD, TINT8):
+       case CASE(OADD, TUINT8):
+       case CASE(OADD, TINT16):
+       case CASE(OADD, TUINT16):
+       case CASE(OADD, TINT32):
+       case CASE(OADD, TUINT32):
+       case CASE(OADD, TPTR32):
+       case CASE(OADD, TINT64):
+       case CASE(OADD, TUINT64):
+       case CASE(OADD, TPTR64):
+               a = AADD;
+               break;
+
+       case CASE(OADD, TFLOAT32):
+               a = AFADDS;
+               break;
+
+       case CASE(OADD, TFLOAT64):
+               a = AFADD;
+               break;
+
+       case CASE(OSUB, TINT8):
+       case CASE(OSUB, TUINT8):
+       case CASE(OSUB, TINT16):
+       case CASE(OSUB, TUINT16):
+       case CASE(OSUB, TINT32):
+       case CASE(OSUB, TUINT32):
+       case CASE(OSUB, TPTR32):
+       case CASE(OSUB, TINT64):
+       case CASE(OSUB, TUINT64):
+       case CASE(OSUB, TPTR64):
+               a = ASUB;
+               break;
+
+       case CASE(OSUB, TFLOAT32):
+               a = AFSUBS;
+               break;
+
+       case CASE(OSUB, TFLOAT64):
+               a = AFSUB;
+               break;
+
+       case CASE(OMINUS, TINT8):
+       case CASE(OMINUS, TUINT8):
+       case CASE(OMINUS, TINT16):
+       case CASE(OMINUS, TUINT16):
+       case CASE(OMINUS, TINT32):
+       case CASE(OMINUS, TUINT32):
+       case CASE(OMINUS, TPTR32):
+       case CASE(OMINUS, TINT64):
+       case CASE(OMINUS, TUINT64):
+       case CASE(OMINUS, TPTR64):
+               a = ANEG;
+               break;
+
+       case CASE(OAND, TINT8):
+       case CASE(OAND, TUINT8):
+       case CASE(OAND, TINT16):
+       case CASE(OAND, TUINT16):
+       case CASE(OAND, TINT32):
+       case CASE(OAND, TUINT32):
+       case CASE(OAND, TPTR32):
+       case CASE(OAND, TINT64):
+       case CASE(OAND, TUINT64):
+       case CASE(OAND, TPTR64):
+               a = AAND;
+               break;
+
+       case CASE(OOR, TINT8):
+       case CASE(OOR, TUINT8):
+       case CASE(OOR, TINT16):
+       case CASE(OOR, TUINT16):
+       case CASE(OOR, TINT32):
+       case CASE(OOR, TUINT32):
+       case CASE(OOR, TPTR32):
+       case CASE(OOR, TINT64):
+       case CASE(OOR, TUINT64):
+       case CASE(OOR, TPTR64):
+               a = AOR;
+               break;
+
+       case CASE(OXOR, TINT8):
+       case CASE(OXOR, TUINT8):
+       case CASE(OXOR, TINT16):
+       case CASE(OXOR, TUINT16):
+       case CASE(OXOR, TINT32):
+       case CASE(OXOR, TUINT32):
+       case CASE(OXOR, TPTR32):
+       case CASE(OXOR, TINT64):
+       case CASE(OXOR, TUINT64):
+       case CASE(OXOR, TPTR64):
+               a = AXOR;
+               break;
+
+       // TODO(minux): handle rotates
+       //case CASE(OLROT, TINT8):
+       //case CASE(OLROT, TUINT8):
+       //case CASE(OLROT, TINT16):
+       //case CASE(OLROT, TUINT16):
+       //case CASE(OLROT, TINT32):
+       //case CASE(OLROT, TUINT32):
+       //case CASE(OLROT, TPTR32):
+       //case CASE(OLROT, TINT64):
+       //case CASE(OLROT, TUINT64):
+       //case CASE(OLROT, TPTR64):
+       //      a = 0//???; RLDC?
+       //      break;
+
+       case CASE(OLSH, TINT8):
+       case CASE(OLSH, TUINT8):
+       case CASE(OLSH, TINT16):
+       case CASE(OLSH, TUINT16):
+       case CASE(OLSH, TINT32):
+       case CASE(OLSH, TUINT32):
+       case CASE(OLSH, TPTR32):
+       case CASE(OLSH, TINT64):
+       case CASE(OLSH, TUINT64):
+       case CASE(OLSH, TPTR64):
+               a = ASLD;
+               break;
+
+       case CASE(ORSH, TUINT8):
+       case CASE(ORSH, TUINT16):
+       case CASE(ORSH, TUINT32):
+       case CASE(ORSH, TPTR32):
+       case CASE(ORSH, TUINT64):
+       case CASE(ORSH, TPTR64):
+               a = ASRD;
+               break;
+
+       case CASE(ORSH, TINT8):
+       case CASE(ORSH, TINT16):
+       case CASE(ORSH, TINT32):
+       case CASE(ORSH, TINT64):
+               a = ASRAD;
+               break;
+
+       // TODO(minux): handle rotates
+       //case CASE(ORROTC, TINT8):
+       //case CASE(ORROTC, TUINT8):
+       //case CASE(ORROTC, TINT16):
+       //case CASE(ORROTC, TUINT16):
+       //case CASE(ORROTC, TINT32):
+       //case CASE(ORROTC, TUINT32):
+       //case CASE(ORROTC, TINT64):
+       //case CASE(ORROTC, TUINT64):
+       //      a = 0//??? RLDC??
+       //      break;
+
+       case CASE(OHMUL, TINT64):
+               a = AMULHD;
+               break;
+       case CASE(OHMUL, TUINT64):
+       case CASE(OHMUL, TPTR64):
+               a = AMULHDU;
+               break;
+
+       case CASE(OMUL, TINT8):
+       case CASE(OMUL, TINT16):
+       case CASE(OMUL, TINT32):
+       case CASE(OMUL, TINT64):
+               a = AMULLD;
+               break;
+
+       case CASE(OMUL, TUINT8):
+       case CASE(OMUL, TUINT16):
+       case CASE(OMUL, TUINT32):
+       case CASE(OMUL, TPTR32):
+               // don't use word multiply, the high 32-bit are undefined.
+               // fallthrough
+       case CASE(OMUL, TUINT64):
+       case CASE(OMUL, TPTR64):
+               a = AMULLD; // for 64-bit multiplies, signedness doesn't matter.
+               break;
+
+       case CASE(OMUL, TFLOAT32):
+               a = AFMULS;
+               break;
+
+       case CASE(OMUL, TFLOAT64):
+               a = AFMUL;
+               break;
+
+       case CASE(ODIV, TINT8):
+       case CASE(ODIV, TINT16):
+       case CASE(ODIV, TINT32):
+       case CASE(ODIV, TINT64):
+               a = ADIVD;
+               break;
+
+       case CASE(ODIV, TUINT8):
+       case CASE(ODIV, TUINT16):
+       case CASE(ODIV, TUINT32):
+       case CASE(ODIV, TPTR32):
+       case CASE(ODIV, TUINT64):
+       case CASE(ODIV, TPTR64):
+               a = ADIVDU;
+               break;
+
+       case CASE(ODIV, TFLOAT32):
+               a = AFDIVS;
+               break;
+
+       case CASE(ODIV, TFLOAT64):
+               a = AFDIV;
+               break;
+
+       }
+       return a;
+}
+
+enum
+{
+       ODynam          = 1<<0,
+       OAddable        = 1<<1,
+};
+
+int
+xgen(Node *n, Node *a, int o)
+{
+       // TODO(minux)
+       USED(n); USED(a); USED(o);
+       return -1;
+}
+
+void
+sudoclean(void)
+{
+       return;
+}
+
+/*
+ * generate code to compute address of n,
+ * a reference to a (perhaps nested) field inside
+ * an array or struct.
+ * return 0 on failure, 1 on success.
+ * on success, leaves usable address in a.
+ *
+ * caller is responsible for calling sudoclean
+ * after successful sudoaddable,
+ * to release the register used for a.
+ */
+int
+sudoaddable(int as, Node *n, Addr *a)
+{
+       // TODO(minux)
+       USED(as); USED(n); USED(a);
+       return 0;
+}
diff --git a/src/cmd/9g/opt.h b/src/cmd/9g/opt.h
new file mode 100644 (file)
index 0000000..d3cbcb9
--- /dev/null
@@ -0,0 +1,219 @@
+// Derived from Inferno utils/6c/gc.h
+// http://code.google.com/p/inferno-os/source/browse/utils/6c/gc.h
+//
+//     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       "../gc/popt.h"
+
+#define        Z       N
+#define        Adr     Addr
+
+#define        BLOAD(r)        band(bnot(r->refbehind), r->refahead)
+#define        BSTORE(r)       band(bnot(r->calbehind), r->calahead)
+#define        LOAD(r)         (~r->refbehind.b[z] & r->refahead.b[z])
+#define        STORE(r)        (~r->calbehind.b[z] & r->calahead.b[z])
+
+#define        CLOAD   5
+#define        CREF    5
+#define        CINF    1000
+#define        LOOP    3
+
+typedef        struct  Reg     Reg;
+typedef        struct  Rgn     Rgn;
+
+/*c2go
+extern Node *Z;
+enum
+{
+       CLOAD = 5,
+       CREF = 5,
+       CINF = 1000,
+       LOOP = 3,
+};
+
+uint32 BLOAD(Reg*);
+uint32 BSTORE(Reg*);
+uint32 LOAD(Reg*);
+uint32 STORE(Reg*);
+*/
+
+// A Reg is a wrapper around a single Prog (one instruction) that holds
+// register optimization information while the optimizer runs.
+// r->prog is the instruction.
+// r->prog->opt points back to r.
+struct Reg
+{
+       Flow    f;
+
+       Bits    set;            // variables written by this instruction.
+       Bits    use1;           // variables read by prog->from.
+       Bits    use2;           // variables read by prog->to.
+
+       Bits    refbehind;
+       Bits    refahead;
+       Bits    calbehind;
+       Bits    calahead;
+       Bits    regdiff;
+       Bits    act;
+
+       int32   regu;           // register used bitmap
+};
+#define        R       ((Reg*)0)
+/*c2go extern Reg *R; */
+
+#define        NRGN    600
+/*c2go enum { NRGN = 600 }; */
+struct Rgn
+{
+       Reg*    enter;
+       short   cost;
+       short   varno;
+       short   regno;
+};
+
+EXTERN int32   exregoffset;            // not set
+EXTERN int32   exfregoffset;           // not set
+EXTERN Reg     zreg;
+EXTERN Rgn     region[NRGN];
+EXTERN Rgn*    rgp;
+EXTERN int     nregion;
+EXTERN int     nvar;
+EXTERN int32   regbits;
+EXTERN int32   exregbits;
+EXTERN Bits    externs;
+EXTERN Bits    params;
+EXTERN Bits    consts;
+EXTERN Bits    addrs;
+EXTERN Bits    ivar;
+EXTERN Bits    ovar;
+EXTERN int     change;
+EXTERN int32   maxnr;
+
+EXTERN struct
+{
+       int32   ncvtreg;
+       int32   nspill;
+       int32   nreload;
+       int32   ndelmov;
+       int32   nvar;
+       int32   naddr;
+} ostats;
+
+/*
+ * reg.c
+ */
+int    rcmp(const void*, const void*);
+void   regopt(Prog*);
+void   addmove(Reg*, int, int, int);
+Bits   mkvar(Reg*, Adr*);
+void   prop(Reg*, Bits, Bits);
+void   synch(Reg*, Bits);
+uint32 allreg(uint32, Rgn*);
+void   paint1(Reg*, int);
+uint32 paint2(Reg*, int);
+void   paint3(Reg*, int, int32, int);
+void   addreg(Adr*, int);
+void   dumpone(Flow*, int);
+void   dumpit(char*, Flow*, int);
+
+/*
+ * peep.c
+ */
+void   peep(Prog*);
+void   excise(Flow*);
+int    copyu(Prog*, Adr*, Adr*);
+
+uint64 RtoB(int);
+uint64 FtoB(int);
+int    BtoR(uint64);
+int    BtoF(uint64);
+
+/*
+ * prog.c
+ */
+typedef struct ProgInfo ProgInfo;
+struct ProgInfo
+{
+       uint32 flags; // the bits below
+       uint64 reguse; // required registers used by this instruction
+       uint64 regset; // required registers set by this instruction
+       uint64 regindex; // registers used by addressing mode
+};
+
+enum
+{
+       // Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
+       Pseudo = 1<<1,
+       
+       // There's nothing to say about the instruction,
+       // but it's still okay to see.
+       OK = 1<<2,
+
+       // Size of right-side write, or right-side read if no write.
+       SizeB = 1<<3,
+       SizeW = 1<<4,
+       SizeL = 1<<5,
+       SizeQ = 1<<6,
+       SizeF = 1<<7, // float aka float32
+       SizeD = 1<<8, // double aka float64
+
+       // Left side: address taken, read, write.
+       LeftAddr = 1<<9,
+       LeftRead = 1<<10,
+       LeftWrite = 1<<11,
+       
+       // Register in middle; never written.
+       RegRead = 1<<12,
+       CanRegRead = 1<<13,
+       
+       // Right side: address taken, read, write.
+       RightAddr = 1<<14,
+       RightRead = 1<<15,
+       RightWrite = 1<<16,
+
+       PostInc = 1<<17,
+
+       // Instruction kinds
+       Move = 1<<18, // straight move
+       Conv = 1<<19, // size conversion
+       Cjmp = 1<<20, // conditional jump
+       Break = 1<<21, // breaks control flow (no fallthrough)
+       Call = 1<<22, // function call
+       Jump = 1<<23, // jump
+       Skip = 1<<24, // data instruction
+};
+
+void proginfo(ProgInfo*, Prog*);
+
+// To allow use of AJMP, ACALL, ARET in ../gc/popt.c.
+enum
+{
+       AJMP = ABR,
+       ACALL = ABL,
+       ARET = ARETURN,
+};
diff --git a/src/cmd/9g/peep.c b/src/cmd/9g/peep.c
new file mode 100644 (file)
index 0000000..5721d7b
--- /dev/null
@@ -0,0 +1,94 @@
+// Derived from Inferno utils/6c/peep.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6c/peep.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.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+#include "opt.h"
+
+void
+peep(Prog *p)
+{
+       USED(p);
+       // TODO(minux)
+       return;
+}
+
+void
+excise(Flow *r)
+{
+       Prog *p;
+
+       p = r->prog;
+       if(debug['P'] && debug['v'])
+               print("%P ===delete===\n", p);
+       *p = zprog;
+       p->as = ANOP;
+       ostats.ndelmov++;
+}
+
+int
+regtyp(Adr *a)
+{
+       switch(a->type) {
+       default:
+               return 0;
+       case D_REG:
+       case D_FREG:
+               return 1;
+       }
+}
+
+int
+sameaddr(Addr *a, Addr *v)
+{
+       if(a->type != v->type)
+               return 0;
+       if(regtyp(v) && a->reg == v->reg)
+               return 1;
+       if(v->type == D_AUTO || v->type == D_PARAM)
+               if(v->offset == a->offset)
+                       return 1;
+       return 0;
+}
+
+int
+smallindir(Addr *a, Addr *reg)
+{
+       return reg->type == D_REG && a->type == D_OREG &&
+               a->reg == reg->reg &&
+               0 <= a->offset && a->offset < 4096;
+}
+
+int
+stackaddr(Addr *a)
+{
+       return a->type == D_REG && a->reg == REGSP;
+}
diff --git a/src/cmd/9g/prog.c b/src/cmd/9g/prog.c
new file mode 100644 (file)
index 0000000..0a51a53
--- /dev/null
@@ -0,0 +1,138 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+#include "opt.h"
+
+enum {
+       LeftRdwr = LeftRead | LeftWrite,
+       RightRdwr = RightRead | RightWrite,
+};
+
+// This table gives the basic information about instruction
+// generated by the compiler and processed in the optimizer.
+// See opt.h for bit definitions.
+//
+// Instructions not generated need not be listed.
+// As an exception to that rule, we typically write down all the
+// size variants of an operation even if we just use a subset.
+//
+// The table is formatted for 8-space tabs.
+static ProgInfo progtable[ALAST] = {
+       [ATYPE]=        {Pseudo | Skip},
+       [ATEXT]=        {Pseudo},
+       [AFUNCDATA]=    {Pseudo},
+       [APCDATA]=      {Pseudo},
+       [AUNDEF]=       {Break},
+       [AUSEFIELD]=    {OK},
+       [ACHECKNIL]=    {LeftRead},
+       [AVARDEF]=      {Pseudo | RightWrite},
+       [AVARKILL]=     {Pseudo | RightWrite},
+
+       // NOP is an internal no-op that also stands
+       // for USED and SET annotations, not the Power opcode.
+       [ANOP]=         {LeftRead | RightWrite},
+
+       // Integer
+       [AADD]=         {SizeQ | LeftRead | RegRead | RightWrite},
+       [ASUB]=         {SizeQ | LeftRead | RegRead | RightWrite},
+       [ANEG]=         {SizeQ | LeftRead | RegRead | RightWrite},
+       [AAND]=         {SizeQ | LeftRead | RegRead | RightWrite},
+       [AOR]=          {SizeQ | LeftRead | RegRead | RightWrite},
+       [AXOR]=         {SizeQ | LeftRead | RegRead | RightWrite},
+       [AMULLD]=       {SizeQ | LeftRead | RegRead | RightWrite},
+       [AMULLW]=       {SizeL | LeftRead | RegRead | RightWrite},
+       [AMULHD]=       {SizeL | LeftRead | RegRead | RightWrite},
+       [AMULHDU]=      {SizeL | LeftRead | RegRead | RightWrite},
+       [ADIVD]=        {SizeQ | LeftRead | RegRead | RightWrite},
+       [ADIVDU]=       {SizeQ | LeftRead | RegRead | RightWrite},
+       [ASLD]=         {SizeQ | LeftRead | RegRead | RightWrite},
+       [ASRD]=         {SizeQ | LeftRead | RegRead | RightWrite},
+       [ASRAD]=        {SizeQ | LeftRead | RegRead | RightWrite},
+       [ACMP]=         {SizeQ | LeftRead | RightRead},
+       [ACMPU]=        {SizeQ | LeftRead | RightRead},
+       [ATD]=          {SizeQ | RightRead},
+
+       // Floating point.
+       [AFADD]=        {SizeD | LeftRead | RegRead | RightWrite},
+       [AFADDS]=       {SizeF | LeftRead | RegRead | RightWrite},
+       [AFSUB]=        {SizeD | LeftRead | RegRead | RightWrite},
+       [AFSUBS]=       {SizeF | LeftRead | RegRead | RightWrite},
+       [AFMUL]=        {SizeD | LeftRead | RegRead | RightWrite},
+       [AFMULS]=       {SizeF | LeftRead | RegRead | RightWrite},
+       [AFDIV]=        {SizeD | LeftRead | RegRead | RightWrite},
+       [AFDIVS]=       {SizeF | LeftRead | RegRead | RightWrite},
+       [AFCTIDZ]=      {SizeF | LeftRead | RegRead | RightWrite},
+       [AFCFID]=       {SizeF | LeftRead | RegRead | RightWrite},
+       [AFCMPU]=       {SizeD | LeftRead | RightRead},
+       [AFRSP]=        {SizeD | LeftRead | RightWrite | Conv},
+
+       // Moves
+       [AMOVB]=        {SizeB | LeftRead | RightWrite | Move | Conv},
+       [AMOVBU]=       {SizeB | LeftRead | RightWrite | Move | Conv | PostInc},
+       [AMOVBZ]=       {SizeB | LeftRead | RightWrite | Move | Conv},
+       [AMOVH]=        {SizeW | LeftRead | RightWrite | Move | Conv},
+       [AMOVHU]=       {SizeW | LeftRead | RightWrite | Move | Conv | PostInc},
+       [AMOVHZ]=       {SizeW | LeftRead | RightWrite | Move | Conv},
+       [AMOVW]=        {SizeL | LeftRead | RightWrite | Move | Conv},
+       // there is no AMOVWU.
+       [AMOVWZU]=      {SizeL | LeftRead | RightWrite | Move | Conv | PostInc},
+       [AMOVWZ]=       {SizeL | LeftRead | RightWrite | Move | Conv},
+       [AMOVD]=        {SizeQ | LeftRead | RightWrite | Move},
+       [AMOVDU]=       {SizeQ | LeftRead | RightWrite | Move | PostInc},
+       [AFMOVS]=       {SizeF | LeftRead | RightWrite | Move | Conv},
+       [AFMOVD]=       {SizeD | LeftRead | RightWrite | Move},
+
+       // Jumps
+       [ABR]=          {Jump | Break},
+       [ABL]=          {Call},
+       [ABEQ]=         {Cjmp},
+       [ABNE]=         {Cjmp},
+       [ABGE]=         {Cjmp},
+       [ABLT]=         {Cjmp},
+       [ABGT]=         {Cjmp},
+       [ABLE]=         {Cjmp},
+       [ARETURN]=      {Break},
+       // In addtion, duffzero reads R0,R2 and writes R2.  This fact must be
+       // encoded in peep.c (TODO)
+       [ADUFFZERO]=    {Call},
+       // In addtion, duffcopy reads R0,R2,R3 and writes R2,R3.  This fact must be
+       // encoded in peep.c (TODO)
+       [ADUFFCOPY]=    {Call},
+};
+
+void
+proginfo(ProgInfo *info, Prog *p)
+{
+       *info = progtable[p->as];
+       if(info->flags == 0) {
+               *info = progtable[AADD];
+               fatal("proginfo: unknown instruction %P", p);
+       }
+
+       if((info->flags & RegRead) && p->reg == NREG) {
+               info->flags &= ~RegRead;
+               info->flags |= /*CanRegRead |*/ RightRead;
+       }
+
+       if(p->from.type == D_OREG && p->from.reg != NREG) {
+               info->reguse |= RtoB(p->from.reg);
+               if(info->flags & PostInc) {
+                       info->regset |= RtoB(p->from.reg);
+               }
+       }
+       if(p->to.type == D_OREG && p->to.reg != NREG) {
+               info->reguse |= RtoB(p->to.reg);
+               if(info->flags & PostInc) {
+                       info->regset |= RtoB(p->to.reg);
+               }
+       }
+
+       if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
+               info->flags &= ~LeftRead;
+               info->flags |= LeftAddr;
+       }
+}
diff --git a/src/cmd/9g/reg.c b/src/cmd/9g/reg.c
new file mode 100644 (file)
index 0000000..bbebf3f
--- /dev/null
@@ -0,0 +1,161 @@
+// Derived from Inferno utils/6c/reg.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6c/reg.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.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+#include "opt.h"
+
+void
+regopt(Prog *p)
+{
+       USED(p);
+       // TODO(minux)
+       return;
+}
+
+/*
+ * track register variables including external registers:
+ *     bit     reg
+ *     0       R0
+ *     1       R1
+ *     ...     ...
+ *     31      R31
+ *     32+0    F0
+ *     32+1    F1
+ *     ...     ...
+ *     32+31   F31
+ */
+uint64
+RtoB(int r)
+{
+       if(r >= D_R0 && r <= D_R0+31)
+               return 1ULL << (r - D_R0);
+       return 0;
+}
+
+int
+BtoR(uint64 b)
+{
+       b &= 0xffffffff;
+       if(b == 0)
+               return 0;
+       return bitno(b) + D_R0;
+}
+
+uint64
+FtoB(int r)
+{
+       if(r >= D_F0 && r <= D_F0+31)
+               return 1ULL << (32 + r - D_F0);
+       return 0;
+}
+
+int
+BtoF(uint64 b)
+{
+       b >>= 32;
+       if(b == 0)
+               return 0;
+       return bitno(b) + D_F0;
+}
+
+void
+dumpone(Flow *f, int isreg)
+{
+       int z;
+       Bits bit;
+       Reg *r;
+
+       print("%d:%P", f->loop, f->prog);
+       if(isreg) {     
+               r = (Reg*)f;
+               for(z=0; z<BITS; z++)
+                       bit.b[z] =
+                               r->set.b[z] |
+                               r->use1.b[z] |
+                               r->use2.b[z] |
+                               r->refbehind.b[z] |
+                               r->refahead.b[z] |
+                               r->calbehind.b[z] |
+                               r->calahead.b[z] |
+                               r->regdiff.b[z] |
+                               r->act.b[z] |
+                                       0;
+               if(bany(&bit)) {
+                       print("\t");
+                       if(bany(&r->set))
+                               print(" s:%Q", r->set);
+                       if(bany(&r->use1))
+                               print(" u1:%Q", r->use1);
+                       if(bany(&r->use2))
+                               print(" u2:%Q", r->use2);
+                       if(bany(&r->refbehind))
+                               print(" rb:%Q ", r->refbehind);
+                       if(bany(&r->refahead))
+                               print(" ra:%Q ", r->refahead);
+                       if(bany(&r->calbehind))
+                               print(" cb:%Q ", r->calbehind);
+                       if(bany(&r->calahead))
+                               print(" ca:%Q ", r->calahead);
+                       if(bany(&r->regdiff))
+                               print(" d:%Q ", r->regdiff);
+                       if(bany(&r->act))
+                               print(" a:%Q ", r->act);
+               }
+       }
+       print("\n");
+}
+
+
+void
+dumpit(char *str, Flow *r0, int isreg)
+{
+       Flow *r, *r1;
+
+       print("\n%s\n", str);
+       for(r = r0; r != nil; r = r->link) {
+               dumpone(r, isreg);
+               r1 = r->p2;
+               if(r1 != nil) {
+                       print(" pred:");
+                       for(; r1 != nil; r1 = r1->p2link)
+                               print(" %.4ud", (int)r1->prog->pc);
+                       print("\n");
+               }
+//             r1 = r->s1;
+//             if(r1 != R) {
+//                     print(" succ:");
+//                     for(; r1 != R; r1 = r1->s1)
+//                             print(" %.4ud", (int)r1->prog->pc);
+//                     print("\n");
+//             }
+       }
+}
diff --git a/src/cmd/9l/9.out.h b/src/cmd/9l/9.out.h
new file mode 100644 (file)
index 0000000..e494e90
--- /dev/null
@@ -0,0 +1,514 @@
+// cmd/9c/9.out.h 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.
+
+/*
+ * powerpc 64
+ */
+#define        NSNAME  8
+#define        NSYM    50
+#define        NREG    32      /* number of general registers */
+#define        NFREG   32      /* number of floating point registers */
+
+#include "../ld/textflag.h"
+
+enum
+{
+       REGZERO         = 0,    /* set to zero */
+       REGSP           = 1,
+       REGSB           = 2,
+       REGRET          = 3,
+       REGARG          = -1,   /* -1 disables passing the first argument in register */
+       REGRT1          = 3,    /* reserved for runtime, duffzero and duffcopy */
+       REGRT2          = 4,    /* reserved for runtime, duffcopy */
+       REGMIN          = 7,    /* register variables allocated from here to REGMAX */
+       REGENV          = 11,   /* environment for closures */
+       REGMAX          = 27,
+       REGEXT          = 30,   /* external registers allocated from here down */
+       REGG            = 30,   /* G */
+       REGTMP          = 31,   /* used by the linker */
+
+       FREGRET         = 0,
+       FREGMIN         = 17,   /* first register variable */
+       FREGMAX         = 26,   /* last register variable for 9g only */
+       FREGEXT         = 26,   /* first external register */
+       FREGCVI         = 27,   /* floating conversion constant */
+       FREGZERO        = 28,   /* both float and double */
+       FREGHALF        = 29,   /* double */
+       FREGONE         = 30,   /* double */
+       FREGTWO         = 31    /* double */
+/*
+ * GENERAL:
+ *
+ * compiler allocates R3 up as temps
+ * compiler allocates register variables R7-R27
+ * compiler allocates external registers R30 down
+ *
+ * compiler allocates register variables F17-F26
+ * compiler allocates external registers F26 down
+ */
+};
+
+enum {
+       BIG = 32768-8,
+};
+
+enum {
+/* mark flags */
+       LABEL           = 1<<0,
+       LEAF            = 1<<1,
+       FLOAT           = 1<<2,
+       BRANCH          = 1<<3,
+       LOAD            = 1<<4,
+       FCMP            = 1<<5,
+       SYNC            = 1<<6,
+       LIST            = 1<<7,
+       FOLL            = 1<<8,
+       NOSCHED         = 1<<9,
+};
+
+enum
+{
+       C_NONE,
+       C_REG,
+       C_FREG,
+       C_CREG,
+       C_SPR,          /* special processor register */
+       C_ZCON,
+       C_SCON,         /* 16 bit signed */
+       C_UCON,         /* low 16 bits 0 */
+       C_ADDCON,       /* -0x8000 <= v < 0 */
+       C_ANDCON,       /* 0 < v <= 0xFFFF */
+       C_LCON,         /* other 32 */
+       C_DCON,         /* other 64 (could subdivide further) */
+       C_SACON,
+       C_SECON,
+       C_LACON,
+       C_LECON,
+       C_SBRA,
+       C_LBRA,
+       C_SAUTO,
+       C_LAUTO,
+       C_SEXT,
+       C_LEXT,
+       C_ZOREG,
+       C_SOREG,
+       C_LOREG,
+       C_FPSCR,
+       C_MSR,
+       C_XER,
+       C_LR,
+       C_CTR,
+       C_ANY,
+       C_GOK,
+       C_ADDR,
+
+       C_NCLASS,       /* must be the last */
+};
+
+enum   as
+{
+       AXXX,
+       AADD,
+       AADDCC,
+       AADDV,
+       AADDVCC,
+       AADDC,
+       AADDCCC,
+       AADDCV,
+       AADDCVCC,
+       AADDME,
+       AADDMECC,
+       AADDMEVCC,
+       AADDMEV,
+       AADDE,
+       AADDECC,
+       AADDEVCC,
+       AADDEV,
+       AADDZE,
+       AADDZECC,
+       AADDZEVCC,
+       AADDZEV,
+       AAND,
+       AANDCC,
+       AANDN,
+       AANDNCC,
+       ABC,
+       ABCL,
+       ABEQ,
+       ABGE,
+       ABGT,
+       ABL,
+       ABLE,
+       ABLT,
+       ABNE,
+       ABR,
+       ABVC,
+       ABVS,
+       ACMP,
+       ACMPU,
+       ACNTLZW,
+       ACNTLZWCC,
+       ACRAND,
+       ACRANDN,
+       ACREQV,
+       ACRNAND,
+       ACRNOR,
+       ACROR,
+       ACRORN,
+       ACRXOR,
+       ADIVW,
+       ADIVWCC,
+       ADIVWVCC,
+       ADIVWV,
+       ADIVWU,
+       ADIVWUCC,
+       ADIVWUVCC,
+       ADIVWUV,
+       AEQV,
+       AEQVCC,
+       AEXTSB,
+       AEXTSBCC,
+       AEXTSH,
+       AEXTSHCC,
+       AFABS,
+       AFABSCC,
+       AFADD,
+       AFADDCC,
+       AFADDS,
+       AFADDSCC,
+       AFCMPO,
+       AFCMPU,
+       AFCTIW,
+       AFCTIWCC,
+       AFCTIWZ,
+       AFCTIWZCC,
+       AFDIV,
+       AFDIVCC,
+       AFDIVS,
+       AFDIVSCC,
+       AFMADD,
+       AFMADDCC,
+       AFMADDS,
+       AFMADDSCC,
+       AFMOVD,
+       AFMOVDCC,
+       AFMOVDU,
+       AFMOVS,
+       AFMOVSU,
+       AFMSUB,
+       AFMSUBCC,
+       AFMSUBS,
+       AFMSUBSCC,
+       AFMUL,
+       AFMULCC,
+       AFMULS,
+       AFMULSCC,
+       AFNABS,
+       AFNABSCC,
+       AFNEG,
+       AFNEGCC,
+       AFNMADD,
+       AFNMADDCC,
+       AFNMADDS,
+       AFNMADDSCC,
+       AFNMSUB,
+       AFNMSUBCC,
+       AFNMSUBS,
+       AFNMSUBSCC,
+       AFRSP,
+       AFRSPCC,
+       AFSUB,
+       AFSUBCC,
+       AFSUBS,
+       AFSUBSCC,
+       AMOVMW,
+       ALSW,
+       ALWAR,
+       AMOVWBR,
+       AMOVB,
+       AMOVBU,
+       AMOVBZ,
+       AMOVBZU,
+       AMOVH,
+       AMOVHBR,
+       AMOVHU,
+       AMOVHZ,
+       AMOVHZU,
+       AMOVW,
+       AMOVWU,
+       AMOVFL,
+       AMOVCRFS,
+       AMTFSB0,
+       AMTFSB0CC,
+       AMTFSB1,
+       AMTFSB1CC,
+       AMULHW,
+       AMULHWCC,
+       AMULHWU,
+       AMULHWUCC,
+       AMULLW,
+       AMULLWCC,
+       AMULLWVCC,
+       AMULLWV,
+       ANAND,
+       ANANDCC,
+       ANEG,
+       ANEGCC,
+       ANEGVCC,
+       ANEGV,
+       ANOR,
+       ANORCC,
+       AOR,
+       AORCC,
+       AORN,
+       AORNCC,
+       AREM,
+       AREMCC,
+       AREMV,
+       AREMVCC,
+       AREMU,
+       AREMUCC,
+       AREMUV,
+       AREMUVCC,
+       ARFI,
+       ARLWMI,
+       ARLWMICC,
+       ARLWNM,
+       ARLWNMCC,
+       ASLW,
+       ASLWCC,
+       ASRW,
+       ASRAW,
+       ASRAWCC,
+       ASRWCC,
+       ASTSW,
+       ASTWCCC,
+       ASUB,
+       ASUBCC,
+       ASUBVCC,
+       ASUBC,
+       ASUBCCC,
+       ASUBCV,
+       ASUBCVCC,
+       ASUBME,
+       ASUBMECC,
+       ASUBMEVCC,
+       ASUBMEV,
+       ASUBV,
+       ASUBE,
+       ASUBECC,
+       ASUBEV,
+       ASUBEVCC,
+       ASUBZE,
+       ASUBZECC,
+       ASUBZEVCC,
+       ASUBZEV,
+       ASYNC,
+       AXOR,
+       AXORCC,
+
+       ADCBF,
+       ADCBI,
+       ADCBST,
+       ADCBT,
+       ADCBTST,
+       ADCBZ,
+       AECIWX,
+       AECOWX,
+       AEIEIO,
+       AICBI,
+       AISYNC,
+       APTESYNC,
+       ATLBIE,
+       ATLBIEL,
+       ATLBSYNC,
+       ATW,
+
+       ASYSCALL,
+       ADATA,
+       AGLOBL,
+       AGOK,
+       AHISTORY,
+       ANAME,
+       ANOP,
+       ARETURN,
+       ATEXT,
+       AWORD,
+       AEND,
+       ADYNT,
+       AINIT,
+       ASIGNAME,
+
+       ARFCI,
+
+       /* optional on 32-bit */
+       AFRES,
+       AFRESCC,
+       AFRSQRTE,
+       AFRSQRTECC,
+       AFSEL,
+       AFSELCC,
+       AFSQRT,
+       AFSQRTCC,
+       AFSQRTS,
+       AFSQRTSCC,
+
+       /* 64-bit */
+       
+       ACNTLZD,
+       ACNTLZDCC,
+       ACMPW,  /* CMP with L=0 */
+       ACMPWU,
+       ADIVD,
+       ADIVDCC,
+       ADIVDVCC,
+       ADIVDV,
+       ADIVDU,
+       ADIVDUCC,
+       ADIVDUVCC,
+       ADIVDUV,
+       AEXTSW,
+       AEXTSWCC,
+       /* AFCFIW; AFCFIWCC */
+       AFCFID,
+       AFCFIDCC,
+       AFCTID,
+       AFCTIDCC,
+       AFCTIDZ,
+       AFCTIDZCC,
+       ALDAR,
+       AMOVD,
+       AMOVDU,
+       AMOVWZ,
+       AMOVWZU,
+       AMULHD,
+       AMULHDCC,
+       AMULHDU,
+       AMULHDUCC,
+       AMULLD,
+       AMULLDCC,
+       AMULLDVCC,
+       AMULLDV,
+       ARFID,
+       ARLDMI,
+       ARLDMICC,
+       ARLDC,
+       ARLDCCC,
+       ARLDCR,
+       ARLDCRCC,
+       ARLDCL,
+       ARLDCLCC,
+       ASLBIA,
+       ASLBIE,
+       ASLBMFEE,
+       ASLBMFEV,
+       ASLBMTE,
+       ASLD,
+       ASLDCC,
+       ASRD,
+       ASRAD,
+       ASRADCC,
+       ASRDCC,
+       ASTDCCC,
+       ATD,
+
+       /* 64-bit pseudo operation */
+       ADWORD,
+       AREMD,
+       AREMDCC,
+       AREMDV,
+       AREMDVCC,
+       AREMDU,
+       AREMDUCC,
+       AREMDUV,
+       AREMDUVCC,
+
+       /* more 64-bit operations */
+       AHRFID,
+
+       AUNDEF,
+       AUSEFIELD,
+       ATYPE,
+       AFUNCDATA,
+       APCDATA,
+       ACHECKNIL,
+       AVARDEF,
+       AVARKILL,
+       ADUFFCOPY,
+       ADUFFZERO,
+
+       ALAST
+};
+
+/* type/name */
+enum
+{
+       D_GOK   = 0,
+       D_NONE,
+
+/* name */
+       D_EXTERN,
+       D_STATIC,
+       D_AUTO,
+       D_PARAM,
+
+/* type */
+       D_BRANCH,
+       D_OREG,
+       D_CONST,
+       D_FCONST,
+       D_SCONST,
+       D_REG,
+       D_FPSCR,
+       D_MSR,
+       D_FREG,
+       D_CREG,
+       D_SPR,
+       D_OPT,  /* branch/trap option */
+       D_FILE,
+       D_FILE1,
+       D_DCR,  /* device control register */
+       D_DCONST,
+       D_ADDR, // not used, use D_CONST with non-empty sym.
+
+/* reg names for 9g OREGISTER */
+       D_R0 = 0, // type is D_REG
+       D_F0 = D_R0+NREG, // type is D_FREG
+
+/* reg names iff type is D_SPR */
+       D_XER   = 1,
+       D_LR    = 8,
+       D_CTR   = 9
+       /* and many supervisor level registers */
+};
+
+/*
+ * this is the ranlib header
+ */
+#define        SYMDEF  "__.GOSYMDEF"
diff --git a/src/cmd/9l/Makefile b/src/cmd/9l/Makefile
new file mode 100644 (file)
index 0000000..3f528d7
--- /dev/null
@@ -0,0 +1,5 @@
+# Copyright 2012 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include ../../Make.dist
diff --git a/src/cmd/9l/asm.c b/src/cmd/9l/asm.c
new file mode 100644 (file)
index 0000000..b8ca777
--- /dev/null
@@ -0,0 +1,338 @@
+// Inferno utils/5l/asm.c
+// http://code.google.com/p/inferno-os/source/browse/utils/5l/asm.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.
+
+// Writing object files.
+
+#include       "l.h"
+#include       "../ld/lib.h"
+#include       "../ld/elf.h"
+#include       "../ld/dwarf.h"
+
+
+char linuxdynld[] = "/lib64/ld64.so.1";
+char freebsddynld[] = "XXX";
+char openbsddynld[] = "XXX";
+char netbsddynld[] = "XXX";
+char dragonflydynld[] = "XXX";
+char solarisdynld[] = "XXX";
+
+static int
+needlib(char *name)
+{
+       char *p;
+       LSym *s;
+
+       if(*name == '\0')
+               return 0;
+
+       /* reuse hash code in symbol table */
+       p = smprint(".dynlib.%s", name);
+       s = linklookup(ctxt, p, 0);
+       free(p);
+       if(s->type == 0) {
+               s->type = 100;  // avoid SDATA, etc.
+               return 1;
+       }
+       return 0;
+}
+
+int    nelfsym = 1;
+
+// b is the addresses, a is the I-form branch instruction template, peform
+// addition so that the instruction jumps to address (offset) b.
+static int32
+braddoff(int32 a, int32 b)
+{
+       return (((uint32)a) & 0xfc000003U) | (0x03fffffcU & (uint32)((a & 0x3fffffcU) + b));
+}
+
+void
+adddynrela(LSym *rel, LSym *s, Reloc *r)
+{
+       // TODO(minux)
+       USED(rel); USED(s); USED(r);
+}
+
+void
+adddynrel(LSym *s, Reloc *r)
+{
+       LSym *targ;
+
+       // TODO(minux)
+
+       targ = r->sym;
+       ctxt->cursym = s;
+       diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
+}
+
+int
+elfreloc1(Reloc *r, vlong sectoff)
+{
+       USED(r); USED(sectoff);
+       // TODO(minux)
+       return -1;
+}
+
+void
+elfsetupplt(void)
+{
+       // TODO(minux)
+       return;
+}
+
+int
+machoreloc1(Reloc *r, vlong sectoff)
+{
+       USED(r);
+       USED(sectoff);
+
+       return -1;
+}
+
+
+int
+archreloc(Reloc *r, LSym *s, vlong *val)
+{
+       uint32 o1, o2;
+       int32 t;
+
+       if(linkmode == LinkExternal) {
+               // TODO(minux): translate R_ADDRPOWER and R_CALLPOWER into standard ELF relocations.
+               // R_ADDRPOWER corresponds to R_PPC_ADDR16_HA and R_PPC_ADDR16_LO.
+               // R_CALLPOWER corresponds to R_PPC_REL24.
+               return -1;
+       }
+       switch(r->type) {
+       case R_CONST:
+               *val = r->add;
+               return 0;
+       case R_GOTOFF:
+               *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got", 0));
+               return 0;
+       case R_ADDRPOWER:
+               // r->add is two power64 instructions holding an immediate 32-bit constant.
+               // We want to add r->sym's address to that constant.
+               // The encoding of the immediate x<<16 + y,
+               // where x is the low 16 bits of the first instruction and y is the low 16
+               // bits of the second. Both x and y are signed (int16, not uint16).
+               o1 = r->add >> 32;
+               o2 = r->add;
+               t = symaddr(r->sym);
+               if(t < 0) {
+                       ctxt->diag("relocation for %s is too big (>=2G): %lld", s->name, symaddr(r->sym));
+               }
+               t += ((o1 & 0xffff) << 16) + ((int32)o2 << 16 >> 16);
+               if(t & 0x8000)
+                       t += 0x10000;
+               o1 = (o1 & 0xffff0000) | ((t >> 16) & 0xffff);
+               o2 = (o2 & 0xffff0000) | (t & 0xffff);
+               // when laid out, the instruction order must always be o1, o2.
+               if(ctxt->arch->endian == BigEndian)
+                       *val = ((vlong)o1 << 32) | o2;
+               else
+                       *val = ((vlong)o2 << 32) | o1;
+               return 0;
+       case R_CALLPOWER:
+               *val = braddoff((uint32)r->add, (int32)(symaddr(r->sym) - (s->value + r->off)));
+               return 0;
+       }
+       return -1;
+}
+
+void
+adddynsym(Link *ctxt, LSym *s)
+{
+       USED(ctxt); USED(s);
+       // TODO(minux)
+       return;
+}
+
+void
+adddynlib(char *lib)
+{
+       LSym *s;
+       
+       if(!needlib(lib))
+               return;
+       
+       if(iself) {
+               s = linklookup(ctxt, ".dynstr", 0);
+               if(s->size == 0)
+                       addstring(s, "");
+               elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
+       } else {
+               diag("adddynlib: unsupported binary format");
+       }
+}
+
+void
+asmb(void)
+{
+       uint32 symo;
+       Section *sect;
+       LSym *sym;
+       int i;
+
+       if(debug['v'])
+               Bprint(&bso, "%5.2f asmb\n", cputime());
+       Bflush(&bso);
+
+       if(iself)
+               asmbelfsetup();
+
+       sect = segtext.sect;
+       cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
+       codeblk(sect->vaddr, sect->len);
+       for(sect = sect->next; sect != nil; sect = sect->next) {
+               cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
+               datblk(sect->vaddr, sect->len);
+       }
+
+       if(segrodata.filelen > 0) {
+               if(debug['v'])
+                       Bprint(&bso, "%5.2f rodatblk\n", cputime());
+               Bflush(&bso);
+
+               cseek(segrodata.fileoff);
+               datblk(segrodata.vaddr, segrodata.filelen);
+       }
+
+       if(debug['v'])
+               Bprint(&bso, "%5.2f datblk\n", cputime());
+       Bflush(&bso);
+
+       cseek(segdata.fileoff);
+       datblk(segdata.vaddr, segdata.filelen);
+
+       /* output symbol table */
+       symsize = 0;
+       lcsize = 0;
+       symo = 0;
+       if(!debug['s']) {
+               // TODO: rationalize
+               if(debug['v'])
+                       Bprint(&bso, "%5.2f sym\n", cputime());
+               Bflush(&bso);
+               switch(HEADTYPE) {
+               default:
+                       if(iself)
+                               goto ElfSym;
+               case Hplan9:
+                       symo = segdata.fileoff+segdata.filelen;
+                       break;
+               ElfSym:
+                       symo = segdata.fileoff+segdata.filelen;
+                       symo = rnd(symo, INITRND);
+                       break;
+               }
+               cseek(symo);
+               switch(HEADTYPE) {
+               default:
+                       if(iself) {
+                               if(debug['v'])
+                                       Bprint(&bso, "%5.2f elfsym\n", cputime());
+                               asmelfsym();
+                               cflush();
+                               cwrite(elfstrdat, elfstrsize);
+       
+                               if(debug['v'])
+                                       Bprint(&bso, "%5.2f dwarf\n", cputime());
+                               dwarfemitdebugsections();
+                               
+                               if(linkmode == LinkExternal)
+                                       elfemitreloc();
+                       }
+                       break;
+               case Hplan9:
+                       asmplan9sym();
+                       cflush();
+
+                       sym = linklookup(ctxt, "pclntab", 0);
+                       if(sym != nil) {
+                               lcsize = sym->np;
+                               for(i=0; i < lcsize; i++)
+                                       cput(sym->p[i]);
+
+                               cflush();
+                       }
+                       break;
+               }
+       }
+
+       ctxt->cursym = nil;
+       if(debug['v'])
+               Bprint(&bso, "%5.2f header\n", cputime());
+       Bflush(&bso);
+       cseek(0L);
+       switch(HEADTYPE) {
+       default:
+       case Hplan9:    /* plan 9 */
+               LPUT(0x647);                    /* magic */
+               LPUT(segtext.filelen);                  /* sizes */
+               LPUT(segdata.filelen);
+               LPUT(segdata.len - segdata.filelen);
+               LPUT(symsize);                  /* nsyms */
+               LPUT(entryvalue());             /* va of entry */
+               LPUT(0L);
+               LPUT(lcsize);
+               break;
+       case Hlinux:
+       case Hfreebsd:
+       case Hnetbsd:
+       case Hopenbsd:
+       case Hnacl:
+               asmbelf(symo);
+               break;
+       }
+       cflush();
+       if(debug['c']){
+               print("textsize=%ulld\n", segtext.filelen);
+               print("datsize=%ulld\n", segdata.filelen);
+               print("bsssize=%ulld\n", segdata.len - segdata.filelen);
+               print("symsize=%d\n", symsize);
+               print("lcsize=%d\n", lcsize);
+               print("total=%lld\n", segtext.filelen+segdata.len+symsize+lcsize);
+       }
+}
+
+vlong
+rnd(vlong v, int32 r)
+{
+       vlong c;
+
+       if(r <= 0)
+               return v;
+       v += r - 1;
+       c = v % r;
+       if(c < 0)
+               c += r;
+       v -= c;
+       return v;
+}
diff --git a/src/cmd/9l/doc.go b/src/cmd/9l/doc.go
new file mode 100644 (file)
index 0000000..9df5dc6
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+
+9l is the linker for the Power64.
+The $GOARCH for these tools is power64 (big endian) or
+power64le (little endian).
+
+The flags are documented in ../ld/doc.go.
+
+*/
+package main
diff --git a/src/cmd/9l/l.h b/src/cmd/9l/l.h
new file mode 100644 (file)
index 0000000..dda741c
--- /dev/null
@@ -0,0 +1,100 @@
+// cmd/9l/l.h from Vita Nuova.
+//
+//     Copyright Â© 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright Â© 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright Â© 1997-1999 Vita Nuova Limited
+//     Portions Copyright Â© 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright Â© 2004,2006 Bruce Ellis
+//     Portions Copyright Â© 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright Â© 2000-2008 Lucent Technologies Inc. and others
+//     Portions Copyright Â© 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include       <u.h>
+#include       <libc.h>
+#include       <bio.h>
+#include       <link.h>
+#include       "9.out.h"
+
+#ifndef        EXTERN
+#define        EXTERN  extern
+#endif
+
+enum
+{
+       thechar = '9',
+       PtrSize = 8,
+       IntSize = 8,
+       RegSize = 8,
+       MaxAlign = 32,  // max data alignment
+       FuncAlign = 8
+};
+
+#define        P               ((Prog*)0)
+#define        S               ((LSym*)0)
+
+enum
+{
+       FPCHIP          = 1,
+       STRINGSZ        = 200,
+       MAXHIST         = 20,                           /* limit of path elements for history symbols */
+       DATBLK          = 1024,
+       NHASH           = 10007,
+       NHUNK           = 100000,
+       MINSIZ          = 64,
+       NENT            = 100,
+       NSCHED          = 20,
+       MINLC           = 4,
+
+       Roffset = 22,           /* no. bits for offset in relocation address */
+       Rindex  = 10            /* no. bits for index in relocation address */
+};
+
+EXTERN int32   autosize;
+EXTERN LSym*   datap;
+EXTERN int     debug[128];
+EXTERN int32   lcsize;
+EXTERN char    literal[32];
+EXTERN int     nerrors;
+EXTERN vlong   instoffset;
+EXTERN char*   rpath;
+EXTERN vlong   pc;
+EXTERN int32   symsize;
+EXTERN int32   staticgen;
+EXTERN Prog*   lastp;
+EXTERN vlong   textsize;
+
+void   asmb(void);
+void   adddynlib(char *lib);
+void   adddynrel(LSym *s, Reloc *r);
+void   adddynsym(Link *ctxt, LSym *s);
+int    archreloc(Reloc *r, LSym *s, vlong *val);
+void   listinit(void);
+vlong  rnd(vlong, int32);
+
+#define        LPUT(a) (ctxt->arch->endian == BigEndian ? lputb(a):lputl(a))
+#define        WPUT(a) (ctxt->arch->endian == BigEndian ? wputb(a):wputl(a))
+#define        VPUT(a) (ctxt->arch->endian == BigEndian ? vputb(a):vputl(a))
+
+/* Used by ../ld/dwarf.c */
+enum
+{
+       DWARFREGSP = 1
+};
diff --git a/src/cmd/9l/list.c b/src/cmd/9l/list.c
new file mode 100644 (file)
index 0000000..af8dc15
--- /dev/null
@@ -0,0 +1,40 @@
+// Inferno utils/5l/list.h
+// http://code.google.com/p/inferno-os/source/browse/utils/5l/list.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.
+
+// Printing.
+
+#include "l.h"
+#include "../ld/lib.h"
+
+void
+listinit(void)
+{
+       listinit9();
+}
diff --git a/src/cmd/9l/obj.c b/src/cmd/9l/obj.c
new file mode 100644 (file)
index 0000000..badb72a
--- /dev/null
@@ -0,0 +1,108 @@
+// Inferno utils/5l/obj.c
+// http://code.google.com/p/inferno-os/source/browse/utils/5l/obj.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.
+
+// Reading object files.
+
+#include       "l.h"
+#include       "../ld/lib.h"
+#include       "../ld/elf.h"
+#include       "../ld/dwarf.h"
+#include       <ar.h>
+
+char *thestring = "power64";
+LinkArch *thelinkarch;
+
+void
+linkarchinit(void)
+{
+       thestring = getgoarch();
+       if(strcmp(thestring, "power64le") == 0)
+               thelinkarch = &linkpower64le;
+       else
+               thelinkarch = &linkpower64;
+}
+
+void
+archinit(void)
+{
+       // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
+       // Go was built; see ../../make.bash.
+       if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
+               linkmode = LinkInternal;
+
+       switch(HEADTYPE) {
+       default:
+               if(linkmode == LinkAuto)
+                       linkmode = LinkInternal;
+               if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0)
+                       sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE));
+               break;
+       }
+
+       switch(HEADTYPE) {
+       default:
+               diag("unknown -H option");
+               errorexit();
+       case Hplan9:    /* plan 9 */
+               HEADR = 32L;
+               if(INITTEXT == -1)
+                       INITTEXT = 4128;
+               if(INITDAT == -1)
+                       INITDAT = 0;
+               if(INITRND == -1)
+                       INITRND = 4096;
+               break;
+       case Hlinux:    /* power64 elf */
+               debug['d'] = 1; // TODO(minux): dynamic linking is not supported yet.
+               elfinit();
+               HEADR = ELFRESERVE;
+               if(INITTEXT == -1)
+                       INITTEXT = 0x10000 + HEADR;
+               if(INITDAT == -1)
+                       INITDAT = 0;
+               if(INITRND == -1)
+                       INITRND = 0x10000;
+               break;
+       case Hnacl:
+               elfinit();
+               HEADR = 0x10000;
+               funcalign = 16;
+               if(INITTEXT == -1)
+                       INITTEXT = 0x20000;
+               if(INITDAT == -1)
+                       INITDAT = 0;
+               if(INITRND == -1)
+                       INITRND = 0x10000;
+               break;
+       }
+       if(INITDAT != 0 && INITRND != 0)
+               print("warning: -D0x%ux is ignored because of -R0x%ux\n",
+                       INITDAT, INITRND);
+}
index e24db1bc0b4c957ca053b1ee1dc95ca164161845..f586aaa20e670994081be7dfd388ba92b8f3aec5 100644 (file)
@@ -220,6 +220,31 @@ slookup(char *s)
        return lookup();
 }
 
+LSym *thetext;
+
+void
+settext(LSym *s)
+{
+       thetext = s;
+}
+
+Sym*
+labellookup(Sym *s)
+{
+       char *p;
+       Sym *lab;
+       
+       if(thetext == nil) {
+               s->labelname = s->name;
+               return s;
+       }
+       p = smprint("%s.%s", thetext->name, s->name);
+       lab = slookup(p);
+       free(p);
+       lab->labelname = s->name;
+       return lab;
+}
+
 Sym*
 lookup(void)
 {
index db9aae916ca6444df9762b0aee9839f0e6f84cce..54cf0c5e11dd58e83b4cc4229f3f5c738d398c14 100644 (file)
@@ -65,14 +65,14 @@ argsize(int doret)
                }
 //print("      %d %T\n", s, t);
        }
-       if(thechar == '6')
+       if(thechar == '6' || thechar == '9')
                s = (s+7) & ~7;
        else
                s = (s+3) & ~3;
        if(doret && thisfn->link->etype != TVOID) {
                s = align(s, thisfn->link, Aarg1, nil);
                s = align(s, thisfn->link, Aarg2, nil);
-               if(thechar == '6')
+               if(thechar == '6' || thechar == '9')
                        s = (s+7) & ~7;
                else
                        s = (s+3) & ~3;
index 17b0cdd167019cb2fa2f8f7df040755a6247074c..0dc22dcd45013adf34add8e86ae0d819cff7c209 100644 (file)
@@ -130,15 +130,23 @@ func usage() {
 }
 
 var ptrSizeMap = map[string]int64{
-       "386":   4,
-       "amd64": 8,
-       "arm":   4,
+       "386":       4,
+       "amd64":     8,
+       "arm":       4,
+       "ppc64":     8,
+       "ppc64le":   8,
+       "power64":   8,
+       "power64le": 8,
 }
 
 var intSizeMap = map[string]int64{
-       "386":   4,
-       "amd64": 8,
-       "arm":   4,
+       "386":       4,
+       "amd64":     8,
+       "arm":       4,
+       "ppc64":     8,
+       "ppc64le":   8,
+       "power64":   8,
+       "power64le": 8,
 }
 
 var cPrefix string
index 31c4da3817c378b13303e8dc7339e4264a19ef37..8fd2e998a44d4a7990a2b2542f4c8c131dfd4d87 100644 (file)
@@ -39,7 +39,7 @@ static void dopack(char*, char*, char**, int);
 static char *findgoversion(void);
 
 // The known architecture letters.
-static char *gochars = "5668";
+static char *gochars = "566899";
 
 // The known architectures.
 static char *okgoarch[] = {
@@ -48,6 +48,8 @@ static char *okgoarch[] = {
        "amd64",
        "amd64p32",
        "386",
+       "power64",
+       "power64le",
 };
 
 // The known operating systems.
@@ -344,6 +346,7 @@ static char *oldtool[] = {
        "5a", "5c", "5g", "5l",
        "6a", "6c", "6g", "6l",
        "8a", "8c", "8g", "8l",
+       "9a", "9c", "9g", "9l",
        "6cov",
        "6nm",
        "6prof",
@@ -521,6 +524,7 @@ static struct {
                "anames5.c",
                "anames6.c",
                "anames8.c",
+               "anames9.c",
        }},
        {"cmd/cc", {
                "-pgen.c",
@@ -549,6 +553,11 @@ static struct {
                "../cc/pswt.c",
                "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
        }},
+       {"cmd/9c", {
+               "../cc/pgen.c",
+               "../cc/pswt.c",
+               "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
+       }},
        {"cmd/5g", {
                "../gc/cplx.c",
                "../gc/pgen.c",
@@ -573,6 +582,14 @@ static struct {
                "../gc/popt.h",
                "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
        }},
+       {"cmd/9g", {
+               "../gc/cplx.c",
+               "../gc/pgen.c",
+               "../gc/plive.c",
+               "../gc/popt.c",
+               "../gc/popt.h",
+               "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
+       }},
        {"cmd/5l", {
                "../ld/*",
        }},
@@ -582,6 +599,9 @@ static struct {
        {"cmd/8l", {
                "../ld/*",
        }},
+       {"cmd/9l", {
+               "../ld/*",
+       }},
        {"cmd/go", {
                "zdefaultcc.go",
        }},
@@ -618,6 +638,7 @@ static struct {
        {"anames5.c", mkanames},
        {"anames6.c", mkanames},
        {"anames8.c", mkanames},
+       {"anames9.c", mkanames},
        {"zasm_", mkzasm},
        {"zdefaultcc.go", mkzdefaultcc},
        {"zsys_", mkzsys},
@@ -1163,12 +1184,26 @@ shouldbuild(char *file, char *dir)
        
        // Check file name for GOOS or GOARCH.
        name = lastelem(file);
-       for(i=0; i<nelem(okgoos); i++)
-               if(contains(name, okgoos[i]) && !streq(okgoos[i], goos))
+       for(i=0; i<nelem(okgoos); i++) {
+               if(streq(okgoos[i], goos))
+                       continue;
+               p = xstrstr(name, okgoos[i]);
+               if(p == nil)
+                       continue;
+               p += xstrlen(okgoos[i]);
+               if(*p == '.' || *p == '_' || *p == '\0')
                        return 0;
-       for(i=0; i<nelem(okgoarch); i++)
-               if(contains(name, okgoarch[i]) && !streq(okgoarch[i], goarch))
+       }
+       for(i=0; i<nelem(okgoarch); i++) {
+               if(streq(okgoarch[i], goarch))
+                       continue;
+               p = xstrstr(name, okgoarch[i]);
+               if(p == nil)
+                       continue;
+               p += xstrlen(okgoarch[i]);
+               if(*p == '.' || *p == '_' || *p == '\0')
                        return 0;
+       }
 
        // Omit test files.
        if(contains(name, "_test"))
@@ -1367,6 +1402,10 @@ static char *cleantab[] = {
        "cmd/8c",
        "cmd/8g",
        "cmd/8l",
+       "cmd/9a",
+       "cmd/9c",
+       "cmd/9g",
+       "cmd/9l",
        "cmd/cc",
        "cmd/gc",
        "cmd/go",       
index 66adf6857c707fc181eadb8add296b63cd4b0ad7..1c3329758733a18ab591233b1d739d5b9b32fc25 100644 (file)
@@ -63,7 +63,7 @@ gcopnames(char *dir, char *file)
        vfree(&fields);
 }
 
-// mkanames reads [568].out.h and writes anames[568].c
+// mkanames reads [5689].out.h and writes anames[5689].c
 // The format is much the same as the Go opcodes above.
 // it also writes out cnames array for C_* constants.
 void
index bb774e05fcf429a2aabcbe512de470647e82fd74..d22e09955769ab6d4ab0885fdbcc76bf519f8380 100644 (file)
@@ -148,6 +148,13 @@ static struct {
        {"arm", "",
        "#define        LR      R14\n"
        },
+
+       {"power64", "",
+       "#define        g       R30\n"
+       },
+       {"power64le", "",
+       "#define        g       R30\n"
+       },
 };
 
 #define MAXWINCB 2000 /* maximum number of windows callbacks allowed */
index 4a78684b44ad5cd46da1bcecf2214ebeab299767..893ed5cdd2c6d42ab2fd9636466190d0b35278f6 100644 (file)
@@ -708,6 +708,10 @@ main(int argc, char **argv)
                        gohostarch = "386";
                else if(contains(u.machine, "arm"))
                        gohostarch = "arm";
+               else if(contains(u.machine, "ppc64le"))
+                       gohostarch = "power64le";
+               else if(contains(u.machine, "ppc64"))
+                       gohostarch = "power64";
                else
                        fatal("unknown architecture: %s", u.machine);
        }
index 39028e3f88900942567721782c653d6035614d36..259cec85a31531b6bafb04b1348466113b0bb67f 100644 (file)
@@ -471,7 +471,7 @@ allocauto(Prog* ptxt)
                stksize = rnd(stksize, n->type->align);
                if(haspointers(n->type))
                        stkptrsize = stksize;
-               if(thechar == '5')
+               if(thechar == '5' || thechar == '9')
                        stksize = rnd(stksize, widthptr);
                if(stksize >= (1ULL<<31)) {
                        setlineno(curfn);
@@ -528,7 +528,7 @@ cgen_checknil(Node *n)
                dump("checknil", n);
                fatal("bad checknil");
        }
-       if((thechar == '5' && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
+       if(((thechar == '5' || thechar == '9') && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
                regalloc(&reg, types[tptr], n);
                cgen(n, &reg);
                gins(ACHECKNIL, &reg, N);
index 993bb24821d21b59d56ce809ac23d2e9cad49573..6e6db88ef86daac315da0f204de74ea7f8d4cf56 100644 (file)
@@ -847,6 +847,10 @@ nilopt(Prog *firstp)
        Graph *g;
        int ncheck, nkill;
 
+       // TODO(minux): nilopt on power64 throw away seemly random segment of code.
+       if(thechar == '9')
+               return;
+
        g = flowstart(firstp, sizeof(NilFlow));
        if(g == nil)
                return;
index ff9b362083e7892bc920bc02fd142719a618cf52..d4d0f449c3e751e489f58bd5cfdb05ace459f8c3 100644 (file)
@@ -3301,6 +3301,9 @@ walkrotate(Node **np)
        int w, sl, sr, s;
        Node *l, *r;
        Node *n;
+
+       if(thechar == '9')
+               return;
        
        n = *np;
 
@@ -3426,6 +3429,10 @@ walkdiv(Node **np, NodeList **init)
        Type *twide;
        Magic m;
 
+       // TODO(minux)
+       if(thechar == '9')
+               return;
+
        n = *np;
        if(n->right->op != OLITERAL)
                return;
index 61847546a33d5ba95fedb5967283e7068950b377..92c6fb57cea0ac261c37af7178f0bf7f8ae6043e 100644 (file)
@@ -445,11 +445,11 @@ blk(LSym *start, int64 addr, int64 size)
                        continue;
                if(sym->value >= eaddr)
                        break;
+               ctxt->cursym = sym;
                if(sym->value < addr) {
                        diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type);
                        errorexit();
                }
-               ctxt->cursym = sym;
                for(; addr < sym->value; addr++)
                        cput(0);
                p = sym->p;
@@ -463,6 +463,8 @@ blk(LSym *start, int64 addr, int64 size)
                        diag("phase error: addr=%#llx value+size=%#llx", (vlong)addr, (vlong)sym->value+sym->size);
                        errorexit();
                }
+               if(sym->value+sym->size >= eaddr)
+                       break;
        }
 
        for(; addr < eaddr; addr++)
index 5b5833db5dce4910af085f3b3011a680ed93cc38..ad35df7400329c7efa1f96b0d069ee80aaf39796 100644 (file)
@@ -10,8 +10,8 @@ Ld is the portable code for a modified version of the Plan 9 linker.  The origin
 
        http://plan9.bell-labs.com/magic/man2html/1/8l
 
-It reads object files (.5, .6, or .8 files) and writes a binary named for the
-architecture (5.out, 6.out, 8.out) by default (if $GOOS is windows, a .exe suffix
+It reads object files (.5, .6, .8, .9 files) and writes a binary named for the
+architecture (5.out, 6.out, 8.out, 9.out) by default (if $GOOS is windows, a .exe suffix
 will be appended).
 
 Major changes include:
@@ -22,7 +22,7 @@ Original options are listed on the manual page linked above.
 
 Usage:
        go tool 6l [flags] mainObj
-Substitute 6l with 8l or 5l as appropriate.
+Substitute 6l with 5l, 8l or 9l as appropriate.
 
 Options new in this version:
 
index a3ba523253c250386bfbf12e23e8fff3d25ebd5c..fbb5699bdb6489e72a3026d83fd400516f91af5a 100644 (file)
@@ -2189,7 +2189,7 @@ dwarfaddshstrings(LSym *shstrtab)
        elfstrdbg[ElfStrDebugStr]      = addstring(shstrtab, ".debug_str");
        elfstrdbg[ElfStrGDBScripts]    = addstring(shstrtab, ".debug_gdb_scripts");
        if(linkmode == LinkExternal) {
-               if(thechar == '6') {
+               if(thechar == '6' || thechar == '9') {
                        elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
                        elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
                        elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
@@ -2244,7 +2244,7 @@ dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
        ElfShdr *sh;
 
        sh = newElfShdr(elfstrdbg[elfstr]);
-       if(thechar == '6') {
+       if(thechar == '6' || thechar == '9') {
                sh->type = SHT_RELA;
        } else {
                sh->type = SHT_REL;
index 3196961f35c2124ecb6fe162bdbc092632082e99..6ac6b6ee82ee12a944a336d65fce49cfe4276d84 100644 (file)
@@ -45,6 +45,7 @@ elfinit(void)
        switch(thechar) {
        // 64-bit architectures
        case '6':
+       case '9':
                elf64 = 1;
                hdr.phoff = ELF64HDRSIZE;       /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
                hdr.shoff = ELF64HDRSIZE;       /* Will move as we add PHeaders */
@@ -678,7 +679,7 @@ elfdynhash(void)
                elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0));
        }
 
-       if(thechar == '6') {
+       if(thechar == '6' || thechar == '9') {
                sy = linklookup(ctxt, ".rela.plt", 0);
                if(sy->size > 0) {
                        elfwritedynent(s, DT_PLTREL, DT_RELA);
@@ -804,7 +805,7 @@ elfshreloc(Section *sect)
        if(strcmp(sect->name, ".shstrtab") == 0 || strcmp(sect->name, ".tbss") == 0)
                return nil;
 
-       if(thechar == '6') {
+       if(thechar == '6' || thechar == '9') {
                prefix = ".rela";
                typ = SHT_RELA;
        } else {
@@ -931,7 +932,7 @@ doelf(void)
                debug['s'] = 0;
                debug['d'] = 1;
 
-               if(thechar == '6') {
+               if(thechar == '6' || thechar == '9') {
                        addstring(shstrtab, ".rela.text");
                        addstring(shstrtab, ".rela.rodata");
                        addstring(shstrtab, ".rela.typelink");
@@ -954,7 +955,7 @@ doelf(void)
 
        if(flag_shared) {
                addstring(shstrtab, ".init_array");
-               if(thechar == '6')
+               if(thechar == '6' || thechar == '9')
                        addstring(shstrtab, ".rela.init_array");
                else
                        addstring(shstrtab, ".rel.init_array");
@@ -975,7 +976,7 @@ doelf(void)
                addstring(shstrtab, ".dynamic");
                addstring(shstrtab, ".dynsym");
                addstring(shstrtab, ".dynstr");
-               if(thechar == '6') {
+               if(thechar == '6' || thechar == '9') {
                        addstring(shstrtab, ".rela");
                        addstring(shstrtab, ".rela.plt");
                } else {
@@ -990,7 +991,7 @@ doelf(void)
                s = linklookup(ctxt, ".dynsym", 0);
                s->type = SELFROSECT;
                s->reachable = 1;
-               if(thechar == '6')
+               if(thechar == '6' || thechar == '9')
                        s->size += ELF64SYMSIZE;
                else
                        s->size += ELF32SYMSIZE;
@@ -1004,7 +1005,7 @@ doelf(void)
                dynstr = s;
 
                /* relocation table */
-               if(thechar == '6')
+               if(thechar == '6' || thechar == '9')
                        s = linklookup(ctxt, ".rela", 0);
                else
                        s = linklookup(ctxt, ".rel", 0);
@@ -1031,7 +1032,7 @@ doelf(void)
                
                elfsetupplt();
                
-               if(thechar == '6')
+               if(thechar == '6' || thechar == '9')
                        s = linklookup(ctxt, ".rela.plt", 0);
                else
                        s = linklookup(ctxt, ".rel.plt", 0);
@@ -1056,13 +1057,13 @@ doelf(void)
                 */
                elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0));
                elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0));
-               if(thechar == '6')
+               if(thechar == '6' || thechar == '9')
                        elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE);
                else
                        elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
                elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0));
                elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0));
-               if(thechar == '6') {
+               if(thechar == '6' || thechar == '9') {
                        elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0));
                        elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0));
                        elfwritedynent(s, DT_RELAENT, ELF64RELASIZE);
@@ -1148,6 +1149,9 @@ asmbelf(vlong symo)
        case '8':
                eh->machine = EM_386;
                break;
+       case '9':
+               eh->machine = EM_PPC64;
+               break;
        }
 
        startva = INITTEXT - HEADR;
@@ -1488,7 +1492,10 @@ elfobj:
                eh->ident[EI_CLASS] = ELFCLASS64;
        else
                eh->ident[EI_CLASS] = ELFCLASS32;
-       eh->ident[EI_DATA] = ELFDATA2LSB;
+       if(ctxt->arch->endian == BigEndian)
+               eh->ident[EI_DATA] = ELFDATA2MSB;
+       else
+               eh->ident[EI_DATA] = ELFDATA2LSB;
        eh->ident[EI_VERSION] = EV_CURRENT;
 
        if(linkmode == LinkExternal)
index b5d0819493f2a5ffcc89e6bfc2fcffff6aa8c81f..ec8e7c4eaf123fc92110c2d9b129dcc86937fb7d 100644 (file)
@@ -436,6 +436,12 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
                        return;
                }
                break;
+       case '9':
+               if(obj->machine != ElfMachPower64 || hdr->ident[4] != ElfClass64) {
+                       diag("%s: elf object but not power64", pn);
+                       return;
+               }
+               break;
        }
 
        // load section list into memory.
index f889aba8a98db5a033742180a6c6eb1846b51097..64608d226ece43196a831abd54dc6fc295bcfb65 100644 (file)
@@ -594,6 +594,7 @@ hostlink(void)
                argv[argc++] = "-m32";
                break;
        case '6':
+       case '9':
                argv[argc++] = "-m64";
                break;
        case '5':
@@ -1033,7 +1034,7 @@ static LSym *newstack;
 
 enum
 {
-       HasLinkRegister = (thechar == '5'),
+       HasLinkRegister = (thechar == '5' || thechar == '9'),
 };
 
 // TODO: Record enough information in new object files to
@@ -1042,7 +1043,7 @@ enum
 static int
 callsize(void)
 {
-       if(thechar == '5')
+       if(HasLinkRegister)
                return 0;
        return RegSize;
 }
@@ -1052,7 +1053,7 @@ dostkcheck(void)
 {
        Chain ch;
        LSym *s;
-       
+
        morestack = linklookup(ctxt, "runtime.morestack", 0);
        newstack = linklookup(ctxt, "runtime.newstack", 0);
 
@@ -1076,19 +1077,19 @@ dostkcheck(void)
                        continue;
 
                if(s->nosplit) {
-               ctxt->cursym = s;
-               ch.sym = s;
-               stkcheck(&ch, 0);
-       }
+                       ctxt->cursym = s;
+                       ch.sym = s;
+                       stkcheck(&ch, 0);
+               }
        }
        for(s = ctxt->textp; s != nil; s = s->next) {
                if(!s->nosplit) {
-               ctxt->cursym = s;
-               ch.sym = s;
-               stkcheck(&ch, 0);
+                       ctxt->cursym = s;
+                       ch.sym = s;
+                       stkcheck(&ch, 0);
+               }
        }
 }
-}
 
 static int
 stkcheck(Chain *up, int depth)
@@ -1106,7 +1107,7 @@ stkcheck(Chain *up, int depth)
        // function at top of safe zone once.
        if(limit == StackLimit-callsize()) {
                if(s->stkcheck)
-               return 0;
+                       return 0;
                s->stkcheck = 1;
        }
        
@@ -1154,6 +1155,7 @@ stkcheck(Chain *up, int depth)
                        switch(r->type) {
                        case R_CALL:
                        case R_CALLARM:
+                       case R_CALLPOWER:
                                // Direct call.
                                ch.limit = limit - pcsp.value - callsize();
                                ch.sym = r->sym;
@@ -1164,8 +1166,8 @@ stkcheck(Chain *up, int depth)
                                // to StackLimit beyond the frame size.
                                if(strncmp(r->sym->name, "runtime.morestack", 17) == 0) {
                                        limit = StackLimit + s->locals;
-                                       if(thechar == '5')
-                                               limit += 4; // saved LR
+                                       if(HasLinkRegister)
+                                               limit += RegSize;
                                }
                                break;
 
@@ -1184,7 +1186,7 @@ stkcheck(Chain *up, int depth)
                                break;
                        }
                }
-               }
+       }
                
        return 0;
 }
@@ -1213,7 +1215,7 @@ stkprint(Chain *ch, int limit)
                else
                        print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
        } else {
-               stkprint(ch->up, ch->limit + (!HasLinkRegister)*PtrSize);
+               stkprint(ch->up, ch->limit + (!HasLinkRegister)*RegSize);
                if(!HasLinkRegister)
                        print("\t%d\ton entry to %s\n", ch->limit, name);
        }
@@ -1533,7 +1535,7 @@ callgraph(void)
                        r = &s->r[i];
                        if(r->sym == nil)
                                continue;
-                       if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT)
+                       if((r->type == R_CALL || r->type == R_CALLARM || r->type == R_CALLPOWER) && r->sym->type == STEXT)
                                Bprint(&bso, "%s calls %s\n", s->name, r->sym->name);
                }
        }
index fe7e10e466691249f8dee517a7a3ad3c7c5114c2..ffb20b3a55be523549dcf846ba35a0d7867fe746 100644 (file)
@@ -44,6 +44,7 @@ machoinit(void)
        switch(thechar) {
        // 64-bit architectures
        case '6':
+       case '9':
                macho64 = 1;
                break;
 
index 156270c8fabcd57f108486abde69f6604bba2574..c3a72c3cf6eea533d0eacdd4dbc6d94743d76856 100644 (file)
@@ -78,6 +78,7 @@ putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other)
 {
        switch(thechar) {
        case '6':
+       case '9':
                LPUT(off);
                cput(info);
                cput(other);
index cde296c79448275abd58877e6fe4218f2c67da7e..46e9d5735d179cecc5bf65a89b04f4d15bfe83c8 100644 (file)
@@ -1414,6 +1414,184 @@ var rppcStrings = []intName{
 func (i R_PPC) String() string   { return stringName(uint32(i), rppcStrings, false) }
 func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
 
+// Relocation types for PowerPC 64.
+type R_PPC64 int
+
+const (
+       R_PPC64_NONE               R_PPC64 = 0
+       R_PPC64_ADDR32             R_PPC64 = 1
+       R_PPC64_ADDR24             R_PPC64 = 2
+       R_PPC64_ADDR16             R_PPC64 = 3
+       R_PPC64_ADDR16_LO          R_PPC64 = 4
+       R_PPC64_ADDR16_HI          R_PPC64 = 5
+       R_PPC64_ADDR16_HA          R_PPC64 = 6
+       R_PPC64_ADDR14             R_PPC64 = 7
+       R_PPC64_ADDR14_BRTAKEN     R_PPC64 = 8
+       R_PPC64_ADDR14_BRNTAKEN    R_PPC64 = 9
+       R_PPC64_REL24              R_PPC64 = 10
+       R_PPC64_REL14              R_PPC64 = 11
+       R_PPC64_REL14_BRTAKEN      R_PPC64 = 12
+       R_PPC64_REL14_BRNTAKEN     R_PPC64 = 13
+       R_PPC64_GOT16              R_PPC64 = 14
+       R_PPC64_GOT16_LO           R_PPC64 = 15
+       R_PPC64_GOT16_HI           R_PPC64 = 16
+       R_PPC64_GOT16_HA           R_PPC64 = 17
+       R_PPC64_JMP_SLOT           R_PPC64 = 21
+       R_PPC64_REL32              R_PPC64 = 26
+       R_PPC64_ADDR64             R_PPC64 = 38
+       R_PPC64_ADDR16_HIGHER      R_PPC64 = 39
+       R_PPC64_ADDR16_HIGHERA     R_PPC64 = 40
+       R_PPC64_ADDR16_HIGHEST     R_PPC64 = 41
+       R_PPC64_ADDR16_HIGHESTA    R_PPC64 = 42
+       R_PPC64_REL64              R_PPC64 = 44
+       R_PPC64_TOC16              R_PPC64 = 47
+       R_PPC64_TOC16_LO           R_PPC64 = 48
+       R_PPC64_TOC16_HI           R_PPC64 = 49
+       R_PPC64_TOC16_HA           R_PPC64 = 50
+       R_PPC64_TOC                R_PPC64 = 51
+       R_PPC64_ADDR16_DS          R_PPC64 = 56
+       R_PPC64_ADDR16_LO_DS       R_PPC64 = 57
+       R_PPC64_GOT16_DS           R_PPC64 = 58
+       R_PPC64_GOT16_LO_DS        R_PPC64 = 59
+       R_PPC64_TOC16_DS           R_PPC64 = 63
+       R_PPC64_TOC16_LO_DS        R_PPC64 = 64
+       R_PPC64_TLS                R_PPC64 = 67
+       R_PPC64_DTPMOD64           R_PPC64 = 68
+       R_PPC64_TPREL16            R_PPC64 = 69
+       R_PPC64_TPREL16_LO         R_PPC64 = 70
+       R_PPC64_TPREL16_HI         R_PPC64 = 71
+       R_PPC64_TPREL16_HA         R_PPC64 = 72
+       R_PPC64_TPREL64            R_PPC64 = 73
+       R_PPC64_DTPREL16           R_PPC64 = 74
+       R_PPC64_DTPREL16_LO        R_PPC64 = 75
+       R_PPC64_DTPREL16_HI        R_PPC64 = 76
+       R_PPC64_DTPREL16_HA        R_PPC64 = 77
+       R_PPC64_DTPREL64           R_PPC64 = 78
+       R_PPC64_GOT_TLSGD16        R_PPC64 = 79
+       R_PPC64_GOT_TLSGD16_LO     R_PPC64 = 80
+       R_PPC64_GOT_TLSGD16_HI     R_PPC64 = 81
+       R_PPC64_GOT_TLSGD16_HA     R_PPC64 = 82
+       R_PPC64_GOT_TLSLD16        R_PPC64 = 83
+       R_PPC64_GOT_TLSLD16_LO     R_PPC64 = 84
+       R_PPC64_GOT_TLSLD16_HI     R_PPC64 = 85
+       R_PPC64_GOT_TLSLD16_HA     R_PPC64 = 86
+       R_PPC64_GOT_TPREL16_DS     R_PPC64 = 87
+       R_PPC64_GOT_TPREL16_LO_DS  R_PPC64 = 88
+       R_PPC64_GOT_TPREL16_HI     R_PPC64 = 89
+       R_PPC64_GOT_TPREL16_HA     R_PPC64 = 90
+       R_PPC64_GOT_DTPREL16_DS    R_PPC64 = 91
+       R_PPC64_GOT_DTPREL16_LO_DS R_PPC64 = 92
+       R_PPC64_GOT_DTPREL16_HI    R_PPC64 = 93
+       R_PPC64_GOT_DTPREL16_HA    R_PPC64 = 94
+       R_PPC64_TPREL16_DS         R_PPC64 = 95
+       R_PPC64_TPREL16_LO_DS      R_PPC64 = 96
+       R_PPC64_TPREL16_HIGHER     R_PPC64 = 97
+       R_PPC64_TPREL16_HIGHERA    R_PPC64 = 98
+       R_PPC64_TPREL16_HIGHEST    R_PPC64 = 99
+       R_PPC64_TPREL16_HIGHESTA   R_PPC64 = 100
+       R_PPC64_DTPREL16_DS        R_PPC64 = 101
+       R_PPC64_DTPREL16_LO_DS     R_PPC64 = 102
+       R_PPC64_DTPREL16_HIGHER    R_PPC64 = 103
+       R_PPC64_DTPREL16_HIGHERA   R_PPC64 = 104
+       R_PPC64_DTPREL16_HIGHEST   R_PPC64 = 105
+       R_PPC64_DTPREL16_HIGHESTA  R_PPC64 = 106
+       R_PPC64_TLSGD              R_PPC64 = 107
+       R_PPC64_TLSLD              R_PPC64 = 108
+       R_PPC64_REL16              R_PPC64 = 249
+       R_PPC64_REL16_LO           R_PPC64 = 250
+       R_PPC64_REL16_HI           R_PPC64 = 251
+       R_PPC64_REL16_HA           R_PPC64 = 252
+)
+
+var rppc64Strings = []intName{
+       {0, "R_PPC64_NONE"},
+       {1, "R_PPC64_ADDR32"},
+       {2, "R_PPC64_ADDR24"},
+       {3, "R_PPC64_ADDR16"},
+       {4, "R_PPC64_ADDR16_LO"},
+       {5, "R_PPC64_ADDR16_HI"},
+       {6, "R_PPC64_ADDR16_HA"},
+       {7, "R_PPC64_ADDR14"},
+       {8, "R_PPC64_ADDR14_BRTAKEN"},
+       {9, "R_PPC64_ADDR14_BRNTAKEN"},
+       {10, "R_PPC64_REL24"},
+       {11, "R_PPC64_REL14"},
+       {12, "R_PPC64_REL14_BRTAKEN"},
+       {13, "R_PPC64_REL14_BRNTAKEN"},
+       {14, "R_PPC64_GOT16"},
+       {15, "R_PPC64_GOT16_LO"},
+       {16, "R_PPC64_GOT16_HI"},
+       {17, "R_PPC64_GOT16_HA"},
+       {21, "R_PPC64_JMP_SLOT"},
+       {26, "R_PPC64_REL32"},
+       {38, "R_PPC64_ADDR64"},
+       {39, "R_PPC64_ADDR16_HIGHER"},
+       {40, "R_PPC64_ADDR16_HIGHERA"},
+       {41, "R_PPC64_ADDR16_HIGHEST"},
+       {42, "R_PPC64_ADDR16_HIGHESTA"},
+       {44, "R_PPC64_REL64"},
+       {47, "R_PPC64_TOC16"},
+       {48, "R_PPC64_TOC16_LO"},
+       {49, "R_PPC64_TOC16_HI"},
+       {50, "R_PPC64_TOC16_HA"},
+       {51, "R_PPC64_TOC"},
+       {56, "R_PPC64_ADDR16_DS"},
+       {57, "R_PPC64_ADDR16_LO_DS"},
+       {58, "R_PPC64_GOT16_DS"},
+       {59, "R_PPC64_GOT16_LO_DS"},
+       {63, "R_PPC64_TOC16_DS"},
+       {64, "R_PPC64_TOC16_LO_DS"},
+       {67, "R_PPC64_TLS"},
+       {68, "R_PPC64_DTPMOD64"},
+       {69, "R_PPC64_TPREL16"},
+       {70, "R_PPC64_TPREL16_LO"},
+       {71, "R_PPC64_TPREL16_HI"},
+       {72, "R_PPC64_TPREL16_HA"},
+       {73, "R_PPC64_TPREL64"},
+       {74, "R_PPC64_DTPREL16"},
+       {75, "R_PPC64_DTPREL16_LO"},
+       {76, "R_PPC64_DTPREL16_HI"},
+       {77, "R_PPC64_DTPREL16_HA"},
+       {78, "R_PPC64_DTPREL64"},
+       {79, "R_PPC64_GOT_TLSGD16"},
+       {80, "R_PPC64_GOT_TLSGD16_LO"},
+       {81, "R_PPC64_GOT_TLSGD16_HI"},
+       {82, "R_PPC64_GOT_TLSGD16_HA"},
+       {83, "R_PPC64_GOT_TLSLD16"},
+       {84, "R_PPC64_GOT_TLSLD16_LO"},
+       {85, "R_PPC64_GOT_TLSLD16_HI"},
+       {86, "R_PPC64_GOT_TLSLD16_HA"},
+       {87, "R_PPC64_GOT_TPREL16_DS"},
+       {88, "R_PPC64_GOT_TPREL16_LO_DS"},
+       {89, "R_PPC64_GOT_TPREL16_HI"},
+       {90, "R_PPC64_GOT_TPREL16_HA"},
+       {91, "R_PPC64_GOT_DTPREL16_DS"},
+       {92, "R_PPC64_GOT_DTPREL16_LO_DS"},
+       {93, "R_PPC64_GOT_DTPREL16_HI"},
+       {94, "R_PPC64_GOT_DTPREL16_HA"},
+       {95, "R_PPC64_TPREL16_DS"},
+       {96, "R_PPC64_TPREL16_LO_DS"},
+       {97, "R_PPC64_TPREL16_HIGHER"},
+       {98, "R_PPC64_TPREL16_HIGHERA"},
+       {99, "R_PPC64_TPREL16_HIGHEST"},
+       {100, "R_PPC64_TPREL16_HIGHESTA"},
+       {101, "R_PPC64_DTPREL16_DS"},
+       {102, "R_PPC64_DTPREL16_LO_DS"},
+       {103, "R_PPC64_DTPREL16_HIGHER"},
+       {104, "R_PPC64_DTPREL16_HIGHERA"},
+       {105, "R_PPC64_DTPREL16_HIGHEST"},
+       {106, "R_PPC64_DTPREL16_HIGHESTA"},
+       {107, "R_PPC64_TLSGD"},
+       {108, "R_PPC64_TLSLD"},
+       {249, "R_PPC64_REL16"},
+       {250, "R_PPC64_REL16_LO"},
+       {251, "R_PPC64_REL16_HI"},
+       {252, "R_PPC64_REL16_HA"},
+}
+
+func (i R_PPC64) String() string   { return stringName(uint32(i), rppc64Strings, false) }
+func (i R_PPC64) GoString() string { return stringName(uint32(i), rppc64Strings, true) }
+
 // Relocation types for SPARC.
 type R_SPARC int
 
index de8a3a24fe9584a3424daee4dcfb2574f3176443..74d1db306c78868111e5b5d882bc372c9b8f9cc8 100644 (file)
@@ -532,6 +532,9 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {
        if f.Class == ELFCLASS64 && f.Machine == EM_AARCH64 {
                return f.applyRelocationsARM64(dst, rels)
        }
+       if f.Class == ELFCLASS64 && f.Machine == EM_PPC64 {
+               return f.applyRelocationsPPC64(dst, rels)
+       }
 
        return errors.New("not implemented")
 }
@@ -671,6 +674,51 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
        return nil
 }
 
+func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
+       // 24 is the size of Rela64.
+       if len(rels)%24 != 0 {
+               return errors.New("length of relocation section is not a multiple of 24")
+       }
+
+       symbols, _, err := f.getSymbols(SHT_SYMTAB)
+       if err != nil {
+               return err
+       }
+
+       b := bytes.NewReader(rels)
+       var rela Rela64
+
+       for b.Len() > 0 {
+               binary.Read(b, f.ByteOrder, &rela)
+               symNo := rela.Info >> 32
+               t := R_PPC64(rela.Info & 0xffff)
+
+               if symNo == 0 || symNo > uint64(len(symbols)) {
+                       continue
+               }
+               sym := &symbols[symNo-1]
+               if SymType(sym.Info&0xf) != STT_SECTION {
+                       // We don't handle non-section relocations for now.
+                       continue
+               }
+
+               switch t {
+               case R_PPC64_ADDR64:
+                       if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+                               continue
+                       }
+                       f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
+               case R_PPC64_ADDR32:
+                       if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+                               continue
+                       }
+                       f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
+               }
+       }
+
+       return nil
+}
+
 func (f *File) DWARF() (*dwarf.Data, error) {
        // There are many other DWARF sections, but these
        // are the required ones, and the debug/dwarf package
@@ -693,7 +741,7 @@ func (f *File) DWARF() (*dwarf.Data, error) {
        // If there's a relocation table for .debug_info, we have to process it
        // now otherwise the data in .debug_info is invalid for x86-64 objects.
        rela := f.Section(".rela.debug_info")
-       if rela != nil && rela.Type == SHT_RELA && (f.Machine == EM_X86_64 || f.Machine == EM_AARCH64) {
+       if rela != nil && rela.Type == SHT_RELA && (f.Machine == EM_X86_64 || f.Machine == EM_AARCH64 || f.Machine == EM_PPC64) {
                data, err := rela.Data()
                if err != nil {
                        return nil, err
index 5e5ba52f3993a4ee79b84dd5c9e01501c4b8c5d1..d57aaab0ec2630fe7c8420792b2a920bb7e23818 100644 (file)
@@ -266,6 +266,12 @@ var relocationTests = []relocationTest{
                        {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x24)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
                },
        },
+       {
+               "testdata/go-relocation-test-gcc482-ppc64le.obj",
+               []relocationTestEntry{
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector"}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(1)}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c"}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp"}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: uint64(0x24)}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+               },
+       },
        {
                "testdata/go-relocation-test-clang-x86.obj",
                []relocationTestEntry{
diff --git a/src/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj b/src/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj
new file mode 100644 (file)
index 0000000..dad7445
Binary files /dev/null and b/src/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj differ
index 7a51cf3c0607617fb746ae0c3315da5ba128c5d4..ed79df2939f59b749648553c5bbf2990010c6cfb 100644 (file)
@@ -1384,6 +1384,8 @@ func ArchChar(goarch string) (string, error) {
                return "6", nil
        case "arm":
                return "5", nil
+       case "power64", "power64le":
+               return "9", nil
        }
        return "", errors.New("unsupported GOARCH " + goarch)
 }
index 965f873dfb7afeffb509e66ee0fd139b71492196..2ab53bb9ccbdc3813f5dbc854561f2649ca037d5 100644 (file)
@@ -5,4 +5,4 @@
 package build
 
 const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows "
-const goarchList = "386 amd64 amd64p32 arm "
+const goarchList = "386 amd64 amd64p32 arm power64 power64le "
index c3fdcd685c5c74f50bda58032cd19438ff5d134c..1c7f806c605652547314d9404b32ae26e78da275 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build 386 arm
+// +build 386 arm power64 power64le
 
 package crc32
 
diff --git a/src/liblink/asm9.c b/src/liblink/asm9.c
new file mode 100644 (file)
index 0000000..c5a78e5
--- /dev/null
@@ -0,0 +1,2784 @@
+// cmd/9l/optab.c, cmd/9l/asmout.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.
+
+// Instruction layout.
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <link.h>
+#include "../cmd/9l/9.out.h"
+#include "../runtime/stack.h"
+
+enum {
+       FuncAlign = 8,
+};
+
+enum {
+       r0iszero = 1,
+};
+
+typedef        struct  Optab   Optab;
+
+struct Optab
+{
+       short   as;
+       uchar   a1;
+       uchar   a2;
+       uchar   a3;
+       uchar   a4;
+       char    type;
+       char    size;
+       char    param;
+};
+
+static Optab   optab[] = {
+       { ATEXT,        C_LEXT, C_NONE, C_NONE,         C_LCON,          0, 0, 0 },
+       { ATEXT,        C_LEXT, C_REG, C_NONE,  C_LCON,          0, 0, 0 },
+       { ATEXT,        C_LEXT, C_NONE, C_LCON,         C_LCON,          0, 0, 0 },
+       { ATEXT,        C_LEXT, C_REG, C_LCON,  C_LCON,          0, 0, 0 },
+       { ATEXT,        C_ADDR, C_NONE, C_NONE,         C_LCON,          0, 0, 0 },
+       { ATEXT,        C_ADDR, C_REG, C_NONE,  C_LCON,          0, 0, 0 },
+       { ATEXT,        C_ADDR, C_NONE, C_LCON,         C_LCON,          0, 0, 0 },
+       { ATEXT,        C_ADDR, C_REG, C_LCON,  C_LCON,          0, 0, 0 },
+
+       /* move register */
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_REG,           1, 4, 0 },
+       { AMOVB,        C_REG,  C_NONE, C_NONE,         C_REG,          12, 4, 0 },
+       { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_REG,          13, 4, 0 },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_REG,           12, 4, 0 },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_REG,           13, 4, 0 },
+
+       { AADD,         C_REG,  C_REG, C_NONE,  C_REG,           2, 4, 0 },
+       { AADD,         C_REG,  C_NONE, C_NONE,         C_REG,           2, 4, 0 },
+       { AADD,         C_ADDCON,C_REG, C_NONE,         C_REG,           4, 4, 0 },
+       { AADD,         C_ADDCON,C_NONE, C_NONE, C_REG,          4, 4, 0 },
+       { AADD,         C_UCON, C_REG, C_NONE,  C_REG,          20, 4, 0 },
+       { AADD,         C_UCON, C_NONE, C_NONE,         C_REG,          20, 4, 0 },
+       { AADD,         C_LCON, C_REG, C_NONE,  C_REG,          22, 12, 0 },
+       { AADD,         C_LCON, C_NONE, C_NONE,         C_REG,          22, 12, 0 },
+
+       { AADDC,        C_REG,  C_REG, C_NONE,  C_REG,           2, 4, 0 },
+       { AADDC,        C_REG,  C_NONE, C_NONE,         C_REG,           2, 4, 0 },
+       { AADDC,        C_ADDCON,C_REG, C_NONE,         C_REG,           4, 4, 0 },
+       { AADDC,        C_ADDCON,C_NONE, C_NONE, C_REG,          4, 4, 0 },
+       { AADDC,        C_LCON, C_REG, C_NONE,  C_REG,          22, 12, 0 },
+       { AADDC,        C_LCON, C_NONE, C_NONE,         C_REG,          22, 12, 0 },
+
+       { AAND,         C_REG,  C_REG, C_NONE,  C_REG,          6, 4, 0 },      /* logical, no literal */
+       { AAND,         C_REG,  C_NONE, C_NONE,         C_REG,          6, 4, 0 },
+       { AANDCC,       C_REG,  C_REG, C_NONE,  C_REG,          6, 4, 0 },
+       { AANDCC,       C_REG,  C_NONE, C_NONE,         C_REG,          6, 4, 0 },
+
+       { AANDCC,       C_ANDCON,C_NONE, C_NONE, C_REG,         58, 4, 0 },
+       { AANDCC,       C_ANDCON,C_REG, C_NONE,         C_REG,          58, 4, 0 },
+       { AANDCC,       C_UCON, C_NONE, C_NONE,         C_REG,          59, 4, 0 },
+       { AANDCC,       C_UCON, C_REG, C_NONE,  C_REG,          59, 4, 0 },
+       { AANDCC,       C_LCON, C_NONE, C_NONE,         C_REG,          23, 12, 0 },
+       { AANDCC,       C_LCON, C_REG, C_NONE,  C_REG,          23, 12, 0 },
+
+       { AMULLW,       C_REG,  C_REG, C_NONE,  C_REG,           2, 4, 0 },
+       { AMULLW,       C_REG,  C_NONE, C_NONE,         C_REG,           2, 4, 0 },
+       { AMULLW,       C_ADDCON,C_REG, C_NONE,         C_REG,           4, 4, 0 },
+       { AMULLW,       C_ADDCON,C_NONE, C_NONE, C_REG,          4, 4, 0 },
+       { AMULLW,       C_ANDCON,C_REG, C_NONE,         C_REG,           4, 4, 0 },
+       { AMULLW,       C_ANDCON,       C_NONE, C_NONE, C_REG,   4, 4, 0 },
+       { AMULLW,       C_LCON, C_REG,  C_NONE, C_REG,          22, 12, 0},
+       { AMULLW,       C_LCON, C_NONE, C_NONE, C_REG,          22, 12, 0},
+
+       { ASUBC,        C_REG,  C_REG, C_NONE,  C_REG,           10, 4, 0 },
+       { ASUBC,        C_REG,  C_NONE, C_NONE,         C_REG,           10, 4, 0 },
+       { ASUBC,        C_REG,  C_NONE, C_ADDCON,       C_REG,   27, 4, 0 },
+       { ASUBC,        C_REG,  C_NONE, C_LCON, C_REG,          28, 12, 0},
+
+       { AOR,          C_REG,  C_REG, C_NONE,  C_REG,          6, 4, 0 },      /* logical, literal not cc (or/xor) */
+       { AOR,          C_REG,  C_NONE, C_NONE,         C_REG,          6, 4, 0 },
+       { AOR,          C_ANDCON, C_NONE, C_NONE,  C_REG,       58, 4, 0 },
+       { AOR,          C_ANDCON, C_REG, C_NONE,  C_REG,                58, 4, 0 },
+       { AOR,          C_UCON, C_NONE, C_NONE,  C_REG,         59, 4, 0 },
+       { AOR,          C_UCON, C_REG, C_NONE,  C_REG,          59, 4, 0 },
+       { AOR,          C_LCON, C_NONE, C_NONE,         C_REG,          23, 12, 0 },
+       { AOR,          C_LCON, C_REG, C_NONE,  C_REG,          23, 12, 0 },
+
+       { ADIVW,        C_REG,  C_REG, C_NONE,  C_REG,           2, 4, 0 },     /* op r1[,r2],r3 */
+       { ADIVW,        C_REG,  C_NONE, C_NONE,         C_REG,           2, 4, 0 },
+       { ASUB, C_REG,  C_REG, C_NONE,  C_REG,           10, 4, 0 },    /* op r2[,r1],r3 */
+       { ASUB, C_REG,  C_NONE, C_NONE,         C_REG,           10, 4, 0 },
+
+       { ASLW, C_REG,  C_NONE, C_NONE,         C_REG,           6, 4, 0 },
+       { ASLW, C_REG,  C_REG, C_NONE,  C_REG,           6, 4, 0 },
+       { ASLD, C_REG,  C_NONE, C_NONE,         C_REG,           6, 4, 0 },
+       { ASLD, C_REG,  C_REG, C_NONE,  C_REG,           6, 4, 0 },
+       { ASLD, C_SCON, C_REG, C_NONE,  C_REG,          25, 4, 0 },
+       { ASLD, C_SCON, C_NONE, C_NONE, C_REG,          25, 4, 0 },
+       { ASLW, C_SCON, C_REG, C_NONE,  C_REG,          57, 4, 0 },
+       { ASLW, C_SCON, C_NONE, C_NONE,         C_REG,          57, 4, 0 },
+
+       { ASRAW,        C_REG,  C_NONE, C_NONE,         C_REG,           6, 4, 0 },
+       { ASRAW,        C_REG,  C_REG, C_NONE,  C_REG,           6, 4, 0 },
+       { ASRAW,        C_SCON, C_REG, C_NONE,  C_REG,          56, 4, 0 },
+       { ASRAW,        C_SCON, C_NONE, C_NONE,         C_REG,          56, 4, 0 },
+       { ASRAD,        C_REG,  C_NONE, C_NONE,         C_REG,           6, 4, 0 },
+       { ASRAD,        C_REG,  C_REG, C_NONE,  C_REG,           6, 4, 0 },
+       { ASRAD,        C_SCON, C_REG, C_NONE,  C_REG,          56, 4, 0 },
+       { ASRAD,        C_SCON, C_NONE, C_NONE,         C_REG,          56, 4, 0 },
+
+       { ARLWMI,       C_SCON, C_REG, C_LCON,  C_REG,          62, 4, 0 },
+       { ARLWMI,       C_REG,  C_REG, C_LCON,  C_REG,          63, 4, 0 },
+       { ARLDMI,       C_SCON, C_REG, C_LCON,  C_REG,          30, 4, 0 },
+
+       { ARLDC,        C_SCON, C_REG, C_LCON,  C_REG,          29, 4, 0 },
+       { ARLDCL,       C_SCON, C_REG, C_LCON,  C_REG,          29, 4, 0 },
+       { ARLDCL,       C_REG,  C_REG,  C_LCON, C_REG,          14, 4, 0 },
+       { ARLDCL, C_REG,        C_NONE, C_LCON, C_REG,          14, 4, 0 },
+
+       { AFADD,        C_FREG, C_NONE, C_NONE,         C_FREG,          2, 4, 0 },
+       { AFADD,        C_FREG, C_REG, C_NONE,  C_FREG,          2, 4, 0 },
+       { AFABS,        C_FREG, C_NONE, C_NONE,         C_FREG,         33, 4, 0 },
+       { AFABS,        C_NONE, C_NONE, C_NONE,         C_FREG,         33, 4, 0 },
+       { AFMOVD,       C_FREG, C_NONE, C_NONE,         C_FREG,         33, 4, 0 },
+
+       { AFMADD,       C_FREG, C_REG, C_FREG,  C_FREG,          34, 4, 0 },
+       { AFMUL,        C_FREG, C_NONE, C_NONE,         C_FREG,          32, 4, 0 },
+       { AFMUL,        C_FREG, C_REG, C_NONE,  C_FREG,          32, 4, 0 },
+
+       /* store, short offset */
+       { AMOVD,        C_REG,  C_REG, C_NONE,  C_ZOREG,         7, 4, REGZERO },
+       { AMOVW,        C_REG,  C_REG, C_NONE,  C_ZOREG,         7, 4, REGZERO },
+       { AMOVWZ,       C_REG,  C_REG, C_NONE,  C_ZOREG,         7, 4, REGZERO },
+       { AMOVBZ,       C_REG,  C_REG, C_NONE,  C_ZOREG,         7, 4, REGZERO },
+       { AMOVBZU,      C_REG,  C_REG, C_NONE,  C_ZOREG,         7, 4, REGZERO },
+       { AMOVB,        C_REG,  C_REG, C_NONE,  C_ZOREG,         7, 4, REGZERO },
+       { AMOVBU,       C_REG,  C_REG, C_NONE,  C_ZOREG,         7, 4, REGZERO },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_SEXT,          7, 4, REGSB },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_SEXT,          7, 4, REGSB },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_SEXT,          7, 4, REGSB },
+       { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_SEXT,          7, 4, REGSB },
+       { AMOVB,        C_REG,  C_NONE, C_NONE,         C_SEXT,          7, 4, REGSB },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_SAUTO,         7, 4, REGSP },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_SAUTO,         7, 4, REGSP },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_SAUTO,         7, 4, REGSP },
+       { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_SAUTO,         7, 4, REGSP },
+       { AMOVB,        C_REG,  C_NONE, C_NONE,         C_SAUTO,         7, 4, REGSP },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_SOREG,         7, 4, REGZERO },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_SOREG,         7, 4, REGZERO },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_SOREG,         7, 4, REGZERO },
+       { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_SOREG,         7, 4, REGZERO },
+       { AMOVBZU,      C_REG,  C_NONE, C_NONE,         C_SOREG,         7, 4, REGZERO },
+       { AMOVB,        C_REG,  C_NONE, C_NONE,         C_SOREG,         7, 4, REGZERO },
+       { AMOVBU,       C_REG,  C_NONE, C_NONE,         C_SOREG,         7, 4, REGZERO },
+
+       /* load, short offset */
+       { AMOVD,        C_ZOREG,C_REG, C_NONE,  C_REG,           8, 4, REGZERO },
+       { AMOVW,        C_ZOREG,C_REG, C_NONE,  C_REG,           8, 4, REGZERO },
+       { AMOVWZ,       C_ZOREG,C_REG, C_NONE,  C_REG,           8, 4, REGZERO },
+       { AMOVBZ,       C_ZOREG,C_REG, C_NONE,  C_REG,           8, 4, REGZERO },
+       { AMOVBZU,      C_ZOREG,C_REG, C_NONE,  C_REG,           8, 4, REGZERO },
+       { AMOVB,        C_ZOREG,C_REG, C_NONE,  C_REG,          9, 8, REGZERO },
+       { AMOVBU,       C_ZOREG,C_REG, C_NONE,  C_REG,          9, 8, REGZERO },
+       { AMOVD,        C_SEXT, C_NONE, C_NONE,         C_REG,           8, 4, REGSB },
+       { AMOVW,        C_SEXT, C_NONE, C_NONE,         C_REG,           8, 4, REGSB },
+       { AMOVWZ,       C_SEXT, C_NONE, C_NONE,         C_REG,           8, 4, REGSB },
+       { AMOVBZ,       C_SEXT, C_NONE, C_NONE,         C_REG,           8, 4, REGSB },
+       { AMOVB,        C_SEXT, C_NONE, C_NONE,         C_REG,          9, 8, REGSB },
+       { AMOVD,        C_SAUTO,C_NONE, C_NONE,         C_REG,           8, 4, REGSP },
+       { AMOVW,        C_SAUTO,C_NONE, C_NONE,         C_REG,           8, 4, REGSP },
+       { AMOVWZ,       C_SAUTO,C_NONE, C_NONE,         C_REG,           8, 4, REGSP },
+       { AMOVBZ,       C_SAUTO,C_NONE, C_NONE,         C_REG,           8, 4, REGSP },
+       { AMOVB,        C_SAUTO,C_NONE, C_NONE,         C_REG,          9, 8, REGSP },
+       { AMOVD,        C_SOREG,C_NONE, C_NONE,         C_REG,           8, 4, REGZERO },
+       { AMOVW,        C_SOREG,C_NONE, C_NONE,         C_REG,           8, 4, REGZERO },
+       { AMOVWZ,       C_SOREG,C_NONE, C_NONE,         C_REG,           8, 4, REGZERO },
+       { AMOVBZ,       C_SOREG,C_NONE, C_NONE,         C_REG,           8, 4, REGZERO },
+       { AMOVBZU,      C_SOREG,C_NONE, C_NONE,         C_REG,           8, 4, REGZERO },
+       { AMOVB,        C_SOREG,C_NONE, C_NONE,         C_REG,          9, 8, REGZERO },
+       { AMOVBU,       C_SOREG,C_NONE, C_NONE,         C_REG,          9, 8, REGZERO },
+
+       /* store, long offset */
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_LEXT,         35, 8, REGSB },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_LEXT,         35, 8, REGSB },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_LEXT,         35, 8, REGSB },
+       { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_LEXT,         35, 8, REGSB },
+       { AMOVB,        C_REG,  C_NONE, C_NONE,         C_LEXT,         35, 8, REGSB },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_LAUTO,        35, 8, REGSP },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_LAUTO,        35, 8, REGSP },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_LAUTO,        35, 8, REGSP },
+       { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_LAUTO,        35, 8, REGSP },
+       { AMOVB,        C_REG,  C_NONE, C_NONE,         C_LAUTO,        35, 8, REGSP },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
+       { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
+       { AMOVB,        C_REG,  C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_ADDR,         74, 8, 0 },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_ADDR,         74, 8, 0 },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_ADDR,         74, 8, 0 },
+       { AMOVBZ,       C_REG,  C_NONE, C_NONE,         C_ADDR,         74, 8, 0 },
+       { AMOVB,        C_REG,  C_NONE, C_NONE,         C_ADDR,         74, 8, 0 },
+
+       /* load, long offset */
+       { AMOVD,        C_LEXT, C_NONE, C_NONE,         C_REG,          36, 8, REGSB },
+       { AMOVW,        C_LEXT, C_NONE, C_NONE,         C_REG,          36, 8, REGSB },
+       { AMOVWZ,       C_LEXT, C_NONE, C_NONE,         C_REG,          36, 8, REGSB },
+       { AMOVBZ,       C_LEXT, C_NONE, C_NONE,         C_REG,          36, 8, REGSB },
+       { AMOVB,        C_LEXT, C_NONE, C_NONE,         C_REG,          37, 12, REGSB },
+       { AMOVD,        C_LAUTO,C_NONE, C_NONE,         C_REG,          36, 8, REGSP },
+       { AMOVW,        C_LAUTO,C_NONE, C_NONE,         C_REG,          36, 8, REGSP },
+       { AMOVWZ,       C_LAUTO,C_NONE, C_NONE,         C_REG,          36, 8, REGSP },
+       { AMOVBZ,       C_LAUTO,C_NONE, C_NONE,         C_REG,          36, 8, REGSP },
+       { AMOVB,        C_LAUTO,C_NONE, C_NONE,         C_REG,          37, 12, REGSP },
+       { AMOVD,        C_LOREG,C_NONE, C_NONE,         C_REG,          36, 8, REGZERO },
+       { AMOVW,        C_LOREG,C_NONE, C_NONE,         C_REG,          36, 8, REGZERO },
+       { AMOVWZ,       C_LOREG,C_NONE, C_NONE,         C_REG,          36, 8, REGZERO },
+       { AMOVBZ,       C_LOREG,C_NONE, C_NONE,         C_REG,          36, 8, REGZERO },
+       { AMOVB,        C_LOREG,C_NONE, C_NONE,         C_REG,          37, 12, REGZERO },
+       { AMOVD,        C_ADDR, C_NONE, C_NONE,         C_REG,          75, 8, 0 },
+       { AMOVW,        C_ADDR, C_NONE, C_NONE,         C_REG,          75, 8, 0 },
+       { AMOVWZ,       C_ADDR, C_NONE, C_NONE,         C_REG,          75, 8, 0 },
+       { AMOVBZ,       C_ADDR, C_NONE, C_NONE,         C_REG,          75, 8, 0 },
+       { AMOVB,        C_ADDR, C_NONE, C_NONE,         C_REG,          76, 12, 0 },
+
+       /* load constant */
+       { AMOVD,        C_SECON,C_NONE, C_NONE,         C_REG,           3, 4, REGSB },
+       { AMOVD,        C_SACON,C_NONE, C_NONE,         C_REG,           3, 4, REGSP },
+       { AMOVD,        C_LECON,C_NONE, C_NONE,         C_REG,          26, 8, REGSB }, 
+       { AMOVD,        C_LACON,C_NONE, C_NONE,         C_REG,          26, 8, REGSP },
+       { AMOVD,        C_ADDCON,C_NONE, C_NONE, C_REG,          3, 4, REGZERO },
+       { AMOVW,        C_SECON,C_NONE, C_NONE,         C_REG,           3, 4, REGSB }, /* TO DO: check */
+       { AMOVW,        C_SACON,C_NONE, C_NONE,         C_REG,           3, 4, REGSP },
+       { AMOVW,        C_LECON,C_NONE, C_NONE,         C_REG,          26, 8, REGSB }, 
+       { AMOVW,        C_LACON,C_NONE, C_NONE,         C_REG,          26, 8, REGSP },
+       { AMOVW,        C_ADDCON,C_NONE, C_NONE, C_REG,          3, 4, REGZERO },
+       { AMOVWZ,       C_SECON,C_NONE, C_NONE,         C_REG,           3, 4, REGSB }, /* TO DO: check */
+       { AMOVWZ,       C_SACON,C_NONE, C_NONE,         C_REG,           3, 4, REGSP },
+       { AMOVWZ,       C_LECON,C_NONE, C_NONE,         C_REG,          26, 8, REGSB }, 
+       { AMOVWZ,       C_LACON,C_NONE, C_NONE,         C_REG,          26, 8, REGSP },
+       { AMOVWZ,       C_ADDCON,C_NONE, C_NONE, C_REG,          3, 4, REGZERO },
+
+       /* load unsigned/long constants (TO DO: check) */
+       { AMOVD,        C_UCON, C_NONE, C_NONE,  C_REG,         3, 4, REGZERO },
+       { AMOVD,        C_LCON, C_NONE, C_NONE,         C_REG,          19, 8, 0 },
+       { AMOVW,        C_UCON, C_NONE, C_NONE,  C_REG,         3, 4, REGZERO },
+       { AMOVW,        C_LCON, C_NONE, C_NONE,         C_REG,          19, 8, 0 },
+       { AMOVWZ,       C_UCON, C_NONE, C_NONE,  C_REG,         3, 4, REGZERO },
+       { AMOVWZ,       C_LCON, C_NONE, C_NONE,         C_REG,          19, 8, 0 },
+
+       { AMOVHBR,      C_ZOREG,        C_REG, C_NONE, C_REG,           45, 4, 0 },
+       { AMOVHBR,      C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0 },
+       { AMOVHBR,      C_REG,  C_REG, C_NONE,  C_ZOREG,                44, 4, 0 },
+       { AMOVHBR,      C_REG,  C_NONE, C_NONE, C_ZOREG,                44, 4, 0 },
+
+       { ASYSCALL,     C_NONE, C_NONE, C_NONE,         C_NONE,          5, 4, 0 },
+       { ASYSCALL,     C_REG,  C_NONE, C_NONE,         C_NONE,          77, 12, 0 },
+       { ASYSCALL,     C_SCON, C_NONE, C_NONE,         C_NONE,          77, 12, 0 },
+
+       { ABEQ,         C_NONE, C_NONE, C_NONE,         C_SBRA,         16, 4, 0 },
+       { ABEQ,         C_CREG, C_NONE, C_NONE,         C_SBRA,         16, 4, 0 },
+
+       { ABR,          C_NONE, C_NONE, C_NONE,         C_LBRA,         11, 4, 0 },
+
+       { ABC,          C_SCON, C_REG, C_NONE,  C_SBRA,         16, 4, 0 },
+       { ABC,          C_SCON, C_REG, C_NONE,  C_LBRA,         17, 4, 0 },
+
+       { ABR,          C_NONE, C_NONE, C_NONE,         C_LR,           18, 4, 0 },
+       { ABR,          C_NONE, C_NONE, C_NONE,         C_CTR,          18, 4, 0 },
+       { ABR,          C_REG,  C_NONE, C_NONE,         C_CTR,          18, 4, 0 },
+       { ABR,          C_NONE, C_NONE, C_NONE,         C_ZOREG,                15, 8, 0 },
+
+       { ABC,          C_NONE, C_REG, C_NONE,  C_LR,           18, 4, 0 },
+       { ABC,          C_NONE, C_REG, C_NONE,  C_CTR,          18, 4, 0 },
+       { ABC,          C_SCON, C_REG, C_NONE,  C_LR,           18, 4, 0 },
+       { ABC,          C_SCON, C_REG, C_NONE,  C_CTR,          18, 4, 0 },
+       { ABC,          C_NONE, C_NONE, C_NONE,         C_ZOREG,                15, 8, 0 },
+
+       { AFMOVD,       C_SEXT, C_NONE, C_NONE,         C_FREG,         8, 4, REGSB },
+       { AFMOVD,       C_SAUTO,C_NONE, C_NONE,         C_FREG,         8, 4, REGSP },
+       { AFMOVD,       C_SOREG,C_NONE, C_NONE,         C_FREG,         8, 4, REGZERO },
+
+       { AFMOVD,       C_LEXT, C_NONE, C_NONE,         C_FREG,         36, 8, REGSB },
+       { AFMOVD,       C_LAUTO,C_NONE, C_NONE,         C_FREG,         36, 8, REGSP },
+       { AFMOVD,       C_LOREG,C_NONE, C_NONE,         C_FREG,         36, 8, REGZERO },
+       { AFMOVD,       C_ADDR, C_NONE, C_NONE,         C_FREG,         75, 8, 0 },
+
+       { AFMOVD,       C_FREG, C_NONE, C_NONE,         C_SEXT,         7, 4, REGSB },
+       { AFMOVD,       C_FREG, C_NONE, C_NONE,         C_SAUTO,        7, 4, REGSP },
+       { AFMOVD,       C_FREG, C_NONE, C_NONE,         C_SOREG,        7, 4, REGZERO },
+
+       { AFMOVD,       C_FREG, C_NONE, C_NONE,         C_LEXT,         35, 8, REGSB },
+       { AFMOVD,       C_FREG, C_NONE, C_NONE,         C_LAUTO,        35, 8, REGSP },
+       { AFMOVD,       C_FREG, C_NONE, C_NONE,         C_LOREG,        35, 8, REGZERO },
+       { AFMOVD,       C_FREG, C_NONE, C_NONE,         C_ADDR,         74, 8, 0 },
+
+       { ASYNC,                C_NONE, C_NONE, C_NONE,         C_NONE,         46, 4, 0 },
+       { AWORD,        C_LCON, C_NONE, C_NONE,         C_NONE,         40, 4, 0 },
+       { ADWORD,       C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0 },
+       { ADWORD,       C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0 },
+
+       { AADDME,       C_REG,  C_NONE, C_NONE,         C_REG,          47, 4, 0 },
+
+       { AEXTSB,       C_REG,  C_NONE, C_NONE,         C_REG,          48, 4, 0 },
+       { AEXTSB,       C_NONE, C_NONE, C_NONE,         C_REG,          48, 4, 0 },
+
+       { ANEG,         C_REG,  C_NONE, C_NONE,         C_REG,          47, 4, 0 },
+       { ANEG,         C_NONE, C_NONE, C_NONE,         C_REG,          47, 4, 0 },
+
+       { AREM,         C_REG,  C_NONE, C_NONE,         C_REG,          50, 12, 0 },
+       { AREM,         C_REG,  C_REG, C_NONE,  C_REG,          50, 12, 0 },
+       { AREMU,                C_REG,  C_NONE, C_NONE,         C_REG,          50, 16, 0 },
+       { AREMU,                C_REG,  C_REG, C_NONE,  C_REG,          50, 16, 0 },
+       { AREMD,                C_REG,  C_NONE, C_NONE,         C_REG,          51, 12, 0 },
+       { AREMD,                C_REG,  C_REG, C_NONE,  C_REG,          51, 12, 0 },
+       { AREMDU,               C_REG,  C_NONE, C_NONE,         C_REG,          51, 12, 0 },
+       { AREMDU,               C_REG,  C_REG, C_NONE,  C_REG,          51, 12, 0 },
+
+       { AMTFSB0,      C_SCON, C_NONE, C_NONE,         C_NONE,         52, 4, 0 },
+       { AMOVFL, C_FPSCR, C_NONE, C_NONE,      C_FREG,         53, 4, 0 },
+       { AMOVFL, C_FREG, C_NONE, C_NONE,       C_FPSCR,                64, 4, 0 },
+       { AMOVFL, C_FREG, C_NONE, C_LCON,       C_FPSCR,                64, 4, 0 },
+       { AMOVFL,       C_LCON, C_NONE, C_NONE, C_FPSCR,                65, 4, 0 },
+
+       { AMOVD,        C_MSR,  C_NONE, C_NONE,         C_REG,          54, 4, 0 },             /* mfmsr */
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_MSR,          54, 4, 0 },             /* mtmsrd */
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_MSR,          54, 4, 0 },             /* mtmsr */
+
+       /* 64-bit special registers */
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_SPR,          66, 4, 0 },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_LR,           66, 4, 0 },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_CTR,          66, 4, 0 },
+       { AMOVD,        C_REG,  C_NONE, C_NONE,         C_XER,          66, 4, 0 },
+       { AMOVD,        C_SPR,  C_NONE, C_NONE,         C_REG,          66, 4, 0 },
+       { AMOVD,        C_LR,   C_NONE, C_NONE,         C_REG,          66, 4, 0 },
+       { AMOVD,        C_CTR,  C_NONE, C_NONE,         C_REG,          66, 4, 0 },
+       { AMOVD,        C_XER,  C_NONE, C_NONE,         C_REG,          66, 4, 0 },
+
+       /* 32-bit special registers (gloss over sign-extension or not?) */
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_SPR,          66, 4, 0 },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_CTR,          66, 4, 0 },
+       { AMOVW,        C_REG,  C_NONE, C_NONE,         C_XER,          66, 4, 0 },
+       { AMOVW,        C_SPR,  C_NONE, C_NONE,         C_REG,          66, 4, 0 },
+       { AMOVW,        C_XER,  C_NONE, C_NONE,         C_REG,          66, 4, 0 },
+
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_SPR,          66, 4, 0 },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_CTR,          66, 4, 0 },
+       { AMOVWZ,       C_REG,  C_NONE, C_NONE,         C_XER,          66, 4, 0 },
+       { AMOVWZ,       C_SPR,  C_NONE, C_NONE,         C_REG,          66, 4, 0 },
+       { AMOVWZ,       C_XER,  C_NONE, C_NONE,         C_REG,          66, 4, 0 },
+
+       { AMOVFL,       C_FPSCR, C_NONE, C_NONE,        C_CREG,         73, 4, 0 },
+       { AMOVFL,       C_CREG, C_NONE, C_NONE,         C_CREG,         67, 4, 0 },
+       { AMOVW,        C_CREG, C_NONE, C_NONE,         C_REG,          68, 4, 0 },
+       { AMOVWZ,       C_CREG, C_NONE, C_NONE,         C_REG,          68, 4, 0 },
+       { AMOVFL,       C_REG, C_NONE, C_LCON, C_CREG,          69, 4, 0 },
+       { AMOVFL,       C_REG, C_NONE, C_NONE, C_CREG,          69, 4, 0 },
+       { AMOVW,        C_REG, C_NONE, C_NONE, C_CREG,          69, 4, 0 },
+       { AMOVWZ,       C_REG, C_NONE, C_NONE, C_CREG,          69, 4, 0 },
+
+       { ACMP, C_REG,  C_NONE, C_NONE,         C_REG,  70, 4, 0 },
+       { ACMP, C_REG,  C_REG, C_NONE,  C_REG,  70, 4, 0 },
+       { ACMP, C_REG,  C_NONE, C_NONE, C_ADDCON,       71, 4, 0 },
+       { ACMP, C_REG,  C_REG, C_NONE,  C_ADDCON,       71, 4, 0 },
+
+       { ACMPU,        C_REG,  C_NONE, C_NONE,         C_REG,  70, 4, 0 },
+       { ACMPU,        C_REG,  C_REG, C_NONE,  C_REG,  70, 4, 0 },
+       { ACMPU,        C_REG,  C_NONE, C_NONE, C_ANDCON,       71, 4, 0 },
+       { ACMPU,        C_REG,  C_REG, C_NONE,  C_ANDCON,       71, 4, 0 },
+
+       { AFCMPO,       C_FREG, C_NONE, C_NONE,         C_FREG, 70, 4, 0 },
+       { AFCMPO,       C_FREG, C_REG, C_NONE,  C_FREG, 70, 4, 0 },
+
+       { ATW,          C_LCON, C_REG, C_NONE,  C_REG,          60, 4, 0 },
+       { ATW,          C_LCON, C_REG, C_NONE,  C_ADDCON,       61, 4, 0 },
+
+       { ADCBF,        C_ZOREG, C_NONE, C_NONE,  C_NONE,       43, 4, 0 },
+       { ADCBF,        C_ZOREG, C_REG, C_NONE,  C_NONE,        43, 4, 0 },
+
+       { AECOWX,       C_REG,  C_REG, C_NONE,  C_ZOREG,        44, 4, 0 },
+       { AECIWX,       C_ZOREG, C_REG, C_NONE,  C_REG,         45, 4, 0 },
+       { AECOWX,       C_REG,  C_NONE, C_NONE,         C_ZOREG,        44, 4, 0 },
+       { AECIWX,       C_ZOREG, C_NONE, C_NONE,  C_REG,                45, 4, 0 },
+
+       { AEIEIO,       C_NONE, C_NONE, C_NONE,         C_NONE,         46, 4, 0 },
+       { ATLBIE,       C_REG, C_NONE, C_NONE,          C_NONE,         49, 4, 0 },
+       { ATLBIE,       C_SCON, C_NONE, C_NONE, C_REG,  49, 4, 0 },
+       { ASLBMFEE, C_REG, C_NONE, C_NONE,      C_REG,  55, 4, 0 },
+       { ASLBMTE, C_REG, C_NONE, C_NONE,       C_REG,  55, 4, 0 },
+
+       { ASTSW,        C_REG,  C_NONE, C_NONE,         C_ZOREG,        44, 4, 0 },
+       { ASTSW,        C_REG,  C_NONE, C_LCON,         C_ZOREG,        41, 4, 0 },
+       { ALSW, C_ZOREG, C_NONE, C_NONE,  C_REG,                45, 4, 0 },
+       { ALSW, C_ZOREG, C_NONE, C_LCON,  C_REG,                42, 4, 0 },
+
+       { AUNDEF,       C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0 },
+       { AUSEFIELD,    C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0 },
+       { APCDATA,      C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0 },
+       { AFUNCDATA,    C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0 },
+       { ANOP,         C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0 },
+
+       { ADUFFZERO,    C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0 },  // same as ABR/ABL
+       { ADUFFCOPY,    C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0 },  // same as ABR/ABL
+
+       { AXXX,         C_NONE, C_NONE, C_NONE,         C_NONE,          0, 4, 0 },
+};
+
+static int ocmp(const void *, const void *);
+static int cmp(int, int);
+static void buildop(Link*);
+static void prasm(Prog *);
+static int isint32(vlong);
+static int isuint32(uvlong);
+static int aclass(Link*, Addr*);
+static Optab* oplook(Link*, Prog*);
+static void asmout(Link*, Prog*, Optab*, int32*);
+static vlong vregoff(Link*, Addr*);
+static int32 regoff(Link*, Addr*);
+static int32 oprrr(Link*, int);
+static int32 opirr(Link*, int);
+static int32 opload(Link*, int);
+static int32 opstore(Link*, int);
+static int32 oploadx(Link*, int);
+static int32 opstorex(Link*, int);
+static int getmask(uchar*, uint32);
+static void maskgen(Link*, Prog*, uchar*, uint32);
+static int getmask64(uchar*, uvlong);
+static void maskgen64(Link*, Prog*, uchar*, uvlong);
+static uint32 loadu32(int, vlong);
+static void addaddrreloc(Link*, LSym*, int*, int*);
+
+static struct
+{
+       Optab*  start;
+       Optab*  stop;
+} oprange[ALAST];
+
+static uchar   xcmp[C_NCLASS][C_NCLASS];
+
+
+void
+span9(Link *ctxt, LSym *cursym)
+{
+       Prog *p, *q;
+       Optab *o;
+       int m, bflag;
+       vlong c, otxt;
+       int32 out[6], i, j;
+       uchar *bp, *cast;
+
+       p = cursym->text;
+       if(p == nil || p->link == nil) // handle external functions and ELF section symbols
+               return;
+       ctxt->cursym = cursym;
+       ctxt->autosize = (int32)(p->to.offset & 0xffffffffll) + 8;
+
+       if(oprange[AANDN].start == nil)
+               buildop(ctxt);
+
+       bflag = 0;
+       c = 0;  
+       p->pc = c;
+
+       for(p = p->link; p != nil; p = p->link) {
+               ctxt->curp = p;
+               p->pc = c;
+               o = oplook(ctxt, p);
+               m = o->size;
+               if(m == 0) {
+                       if(p->as != ANOP && p->as != AFUNCDATA && p->as != APCDATA)
+                               ctxt->diag("zero-width instruction\n%P", p);
+                       continue;
+               }
+               c += m;
+       }
+       cursym->size = c;
+
+       /*
+        * if any procedure is large enough to
+        * generate a large SBRA branch, then
+        * generate extra passes putting branches
+        * around jmps to fix. this is rare.
+        */
+       bflag = 1;
+       while(bflag) {
+               if(ctxt->debugvlog)
+                       Bprint(ctxt->bso, "%5.2f span1\n", cputime());
+               bflag = 0;
+               c = 0;
+               for(p = cursym->text->link; p != nil; p = p->link) {
+                       p->pc = c;
+                       o = oplook(ctxt, p);
+
+                       // very large conditional branches
+                       if((o->type == 16 || o->type == 17) && p->pcond) {
+                               otxt = p->pcond->pc - c;
+                               if(otxt < -(1L<<15)+10 || otxt >= (1L<<15)-10) {
+                                       q = ctxt->arch->prg();
+                                       q->link = p->link;
+                                       p->link = q;
+                                       q->as = ABR;
+                                       q->to.type = D_BRANCH;
+                                       q->pcond = p->pcond;
+                                       p->pcond = q;
+                                       q = ctxt->arch->prg();
+                                       q->link = p->link;
+                                       p->link = q;
+                                       q->as = ABR;
+                                       q->to.type = D_BRANCH;
+                                       q->pcond = q->link->link;
+                                       //addnop(p->link);
+                                       //addnop(p);
+                                       bflag = 1;
+                               }
+                       }
+
+                       m = o->size;
+                       if(m == 0) {
+                               if(p->as != ANOP && p->as != AFUNCDATA && p->as != APCDATA)
+                                       ctxt->diag("zero-width instruction\n%P", p);
+                               continue;
+                       }
+                       c += m;
+               }
+               cursym->size = c;
+       }
+
+       c += -c&(FuncAlign-1);
+       cursym->size = c;
+
+       /*
+        * lay out the code, emitting code and data relocations.
+        */
+       if(ctxt->tlsg == nil)
+               ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
+
+       symgrow(ctxt, cursym, cursym->size);
+
+       bp = cursym->p;
+       for(p = cursym->text->link; p != nil; p = p->link) {
+               ctxt->pc = p->pc;
+               ctxt->curp = p;
+               o = oplook(ctxt, p);
+               if(o->size > 4*nelem(out))
+                       sysfatal("out array in span9 is too small, need at least %d for %P", o->size/4, p);
+               asmout(ctxt, p, o, out);
+               for(i=0; i<o->size/4; i++) {
+                       cast = (uchar*)&out[i];
+                       for(j=0; j<4; j++)
+                               *bp++ = cast[inuxi4[j]];
+               }
+       }
+}
+
+static int
+isint32(vlong v)
+{
+       return (int32)v == v;
+}
+
+static int
+isuint32(uvlong v)
+{
+       return (uint32)v == v;
+}
+
+static int
+aclass(Link *ctxt, Addr *a)
+{
+       LSym *s;
+
+       switch(a->type) {
+       case D_NONE:
+               return C_NONE;
+
+       case D_REG:
+               return C_REG;
+
+       case D_FREG:
+               return C_FREG;
+
+       case D_CREG:
+               return C_CREG;
+
+       case D_SPR:
+               if(a->offset == D_LR)
+                       return C_LR;
+               if(a->offset == D_XER)
+                       return C_XER;
+               if(a->offset == D_CTR)
+                       return C_CTR;
+               return C_SPR;
+
+       case D_DCR:
+               return C_SPR;
+
+       case D_FPSCR:
+               return C_FPSCR;
+
+       case D_MSR:
+               return C_MSR;
+
+       case D_OREG:
+               switch(a->name) {
+               case D_EXTERN:
+               case D_STATIC:
+                       if(a->sym == nil)
+                               break;
+                       ctxt->instoffset = a->offset;
+                       if(a->sym != nil) // use relocation
+                               return C_ADDR;
+                       return C_LEXT;
+               case D_AUTO:
+                       ctxt->instoffset = ctxt->autosize + a->offset;
+                       if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
+                               return C_SAUTO;
+                       return C_LAUTO;
+               case D_PARAM:
+                       ctxt->instoffset = ctxt->autosize + a->offset + 8L;
+                       if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
+                               return C_SAUTO;
+                       return C_LAUTO;
+               case D_NONE:
+                       ctxt->instoffset = a->offset;
+                       if(ctxt->instoffset == 0)
+                               return C_ZOREG;
+                       if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
+                               return C_SOREG;
+                       return C_LOREG;
+               }
+               return C_GOK;
+
+       case D_OPT:
+               ctxt->instoffset = a->offset & 31L;
+               if(a->name == D_NONE)
+                       return C_SCON;
+               return C_GOK;
+
+       case D_CONST:
+               switch(a->name) {
+               case D_NONE:
+                       ctxt->instoffset = a->offset;
+                       if(a->reg != NREG) {
+                               if(-BIG <= ctxt->instoffset && ctxt->instoffset <= BIG)
+                                       return C_SACON;
+                               return C_LACON;
+                       }
+               consize:
+                       if(ctxt->instoffset >= 0) {
+                               if(ctxt->instoffset == 0)
+                                       return C_ZCON;
+                               if(ctxt->instoffset <= 0x7fff)
+                                       return C_SCON;
+                               if(ctxt->instoffset <= 0xffff)
+                                       return C_ANDCON;
+                               if((ctxt->instoffset & 0xffff) == 0 && isuint32(ctxt->instoffset))      /* && (instoffset & (1<<31)) == 0) */
+                                       return C_UCON;
+                               if(isint32(ctxt->instoffset) || isuint32(ctxt->instoffset))
+                                       return C_LCON;
+                               return C_DCON;
+                       }
+                       if(ctxt->instoffset >= -0x8000)
+                               return C_ADDCON;
+                       if((ctxt->instoffset & 0xffff) == 0 && isint32(ctxt->instoffset))
+                               return C_UCON;
+                       if(isint32(ctxt->instoffset))
+                               return C_LCON;
+                       return C_DCON;
+
+               case D_EXTERN:
+               case D_STATIC:
+                       s = a->sym;
+                       if(s == nil)
+                               break;
+                       if(s->type == SCONST) {
+                               ctxt->instoffset = s->value + a->offset;
+                               goto consize;
+                       }
+                       ctxt->instoffset = s->value + a->offset;
+                       /* not sure why this barfs */
+                       return C_LCON;
+
+               case D_AUTO:
+                       ctxt->instoffset = ctxt->autosize + a->offset;
+                       if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
+                               return C_SACON;
+                       return C_LACON;
+
+               case D_PARAM:
+                       ctxt->instoffset = ctxt->autosize + a->offset + 8L;
+                       if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
+                               return C_SACON;
+                       return C_LACON;
+               }
+               return C_GOK;
+
+       case D_BRANCH:
+               return C_SBRA;
+       }
+       return C_GOK;
+}
+
+static void
+prasm(Prog *p)
+{
+       print("%P\n", p);
+}
+
+static Optab*
+oplook(Link *ctxt, Prog *p)
+{
+       int a1, a2, a3, a4, r;
+       uchar *c1, *c3, *c4;
+       Optab *o, *e;
+
+       a1 = p->optab;
+       if(a1)
+               return optab+(a1-1);
+       a1 = p->from.class;
+       if(a1 == 0) {
+               a1 = aclass(ctxt, &p->from) + 1;
+               p->from.class = a1;
+       }
+       a1--;
+       a3 = p->from3.class;
+       if(a3 == 0) {
+               a3 = aclass(ctxt, &p->from3) + 1;
+               p->from3.class = a3;
+       }
+       a3--;
+       a4 = p->to.class;
+       if(a4 == 0) {
+               a4 = aclass(ctxt, &p->to) + 1;
+               p->to.class = a4;
+       }
+       a4--;
+       a2 = C_NONE;
+       if(p->reg != NREG)
+               a2 = C_REG;
+//print("oplook %P %d %d %d %d\n", p, a1, a2, a3, a4);
+       r = p->as;
+       o = oprange[r].start;
+       if(o == 0)
+               o = oprange[r].stop; /* just generate an error */
+       e = oprange[r].stop;
+       c1 = xcmp[a1];
+       c3 = xcmp[a3];
+       c4 = xcmp[a4];
+       for(; o<e; o++)
+               if(o->a2 == a2)
+               if(c1[o->a1])
+               if(c3[o->a3])
+               if(c4[o->a4]) {
+                       p->optab = (o-optab)+1;
+                       return o;
+               }
+       ctxt->diag("illegal combination %A %^ %^ %^ %^",
+               p->as, a1, a2, a3, a4);
+       prasm(p);
+       if(o == 0)
+               o = optab;
+       return o;
+}
+
+static int
+cmp(int a, int b)
+{
+
+       if(a == b)
+               return 1;
+       switch(a) {
+       case C_LCON:
+               if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
+                       return 1;
+               break;
+       case C_ADDCON:
+               if(b == C_ZCON || b == C_SCON)
+                       return 1;
+               break;
+       case C_ANDCON:
+               if(b == C_ZCON || b == C_SCON)
+                       return 1;
+               break;
+       case C_SPR:
+               if(b == C_LR || b == C_XER || b == C_CTR)
+                       return 1;
+               break;
+       case C_UCON:
+               if(b == C_ZCON)
+                       return 1;
+               break;
+       case C_SCON:
+               if(b == C_ZCON)
+                       return 1;
+               break;
+       case C_LACON:
+               if(b == C_SACON)
+                       return 1;
+               break;
+       case C_LBRA:
+               if(b == C_SBRA)
+                       return 1;
+               break;
+       case C_LEXT:
+               if(b == C_SEXT)
+                       return 1;
+               break;
+       case C_LAUTO:
+               if(b == C_SAUTO)
+                       return 1;
+               break;
+       case C_REG:
+               if(b == C_ZCON)
+                       return r0iszero;
+               break;
+       case C_LOREG:
+               if(b == C_ZOREG || b == C_SOREG)
+                       return 1;
+               break;
+       case C_SOREG:
+               if(b == C_ZOREG)
+                       return 1;
+               break;
+
+       case C_ANY:
+               return 1;
+       }
+       return 0;
+}
+
+static int
+ocmp(const void *a1, const void *a2)
+{
+       const Optab *p1, *p2;
+       int n;
+
+       p1 = a1;
+       p2 = a2;
+       n = p1->as - p2->as;
+       if(n)
+               return n;
+       n = p1->a1 - p2->a1;
+       if(n)
+               return n;
+       n = p1->a2 - p2->a2;
+       if(n)
+               return n;
+       n = p1->a3 - p2->a3;
+       if(n)
+               return n;
+       n = p1->a4 - p2->a4;
+       if(n)
+               return n;
+       return 0;
+}
+
+static void
+buildop(Link *ctxt)
+{
+       int i, n, r;
+
+       for(i=0; i<C_NCLASS; i++)
+               for(n=0; n<C_NCLASS; n++)
+                       xcmp[i][n] = cmp(n, i);
+       for(n=0; optab[n].as != AXXX; n++)
+               ;
+       qsort(optab, n, sizeof(optab[0]), ocmp);
+       for(i=0; i<n; i++) {
+               r = optab[i].as;
+               oprange[r].start = optab+i;
+               while(optab[i].as == r)
+                       i++;
+               oprange[r].stop = optab+i;
+               i--;
+               
+               switch(r)
+               {
+               default:
+                       ctxt->diag("unknown op in build: %A", r);
+                       sysfatal("bad code");
+               case ADCBF:     /* unary indexed: op (b+a); op (b) */
+                       oprange[ADCBI] = oprange[r];
+                       oprange[ADCBST] = oprange[r];
+                       oprange[ADCBT] = oprange[r];
+                       oprange[ADCBTST] = oprange[r];
+                       oprange[ADCBZ] = oprange[r];
+                       oprange[AICBI] = oprange[r];
+                       break;
+               case AECOWX:    /* indexed store: op s,(b+a); op s,(b) */
+                       oprange[ASTWCCC] = oprange[r];
+                       oprange[ASTDCCC] = oprange[r];
+                       break;
+               case AREM:      /* macro */
+                       oprange[AREMCC] = oprange[r];
+                       oprange[AREMV] = oprange[r];
+                       oprange[AREMVCC] = oprange[r];
+                       break;
+               case AREMU:
+                       oprange[AREMU] = oprange[r];
+                       oprange[AREMUCC] = oprange[r];
+                       oprange[AREMUV] = oprange[r];
+                       oprange[AREMUVCC] = oprange[r];
+                       break;
+               case AREMD:
+                       oprange[AREMDCC] = oprange[r];
+                       oprange[AREMDV] = oprange[r];
+                       oprange[AREMDVCC] = oprange[r];
+                       break;
+               case AREMDU:
+                       oprange[AREMDU] = oprange[r];
+                       oprange[AREMDUCC] = oprange[r];
+                       oprange[AREMDUV] = oprange[r];
+                       oprange[AREMDUVCC] = oprange[r];
+                       break;
+               case ADIVW:     /* op Rb[,Ra],Rd */
+                       oprange[AMULHW] = oprange[r];
+                       oprange[AMULHWCC] = oprange[r];
+                       oprange[AMULHWU] = oprange[r];
+                       oprange[AMULHWUCC] = oprange[r];
+                       oprange[AMULLWCC] = oprange[r];
+                       oprange[AMULLWVCC] = oprange[r];
+                       oprange[AMULLWV] = oprange[r];
+                       oprange[ADIVWCC] = oprange[r];
+                       oprange[ADIVWV] = oprange[r];
+                       oprange[ADIVWVCC] = oprange[r];
+                       oprange[ADIVWU] = oprange[r];
+                       oprange[ADIVWUCC] = oprange[r];
+                       oprange[ADIVWUV] = oprange[r];
+                       oprange[ADIVWUVCC] = oprange[r];
+                       oprange[AADDCC] = oprange[r];
+                       oprange[AADDCV] = oprange[r];
+                       oprange[AADDCVCC] = oprange[r];
+                       oprange[AADDV] = oprange[r];
+                       oprange[AADDVCC] = oprange[r];
+                       oprange[AADDE] = oprange[r];
+                       oprange[AADDECC] = oprange[r];
+                       oprange[AADDEV] = oprange[r];
+                       oprange[AADDEVCC] = oprange[r];
+                       oprange[ACRAND] = oprange[r];
+                       oprange[ACRANDN] = oprange[r];
+                       oprange[ACREQV] = oprange[r];
+                       oprange[ACRNAND] = oprange[r];
+                       oprange[ACRNOR] = oprange[r];
+                       oprange[ACROR] = oprange[r];
+                       oprange[ACRORN] = oprange[r];
+                       oprange[ACRXOR] = oprange[r];
+                       oprange[AMULHD] = oprange[r];
+                       oprange[AMULHDCC] = oprange[r];
+                       oprange[AMULHDU] = oprange[r];
+                       oprange[AMULHDUCC] = oprange[r];
+                       oprange[AMULLD] = oprange[r];
+                       oprange[AMULLDCC] = oprange[r];
+                       oprange[AMULLDVCC] = oprange[r];
+                       oprange[AMULLDV] = oprange[r];
+                       oprange[ADIVD] = oprange[r];
+                       oprange[ADIVDCC] = oprange[r];
+                       oprange[ADIVDVCC] = oprange[r];
+                       oprange[ADIVDV] = oprange[r];
+                       oprange[ADIVDU] = oprange[r];
+                       oprange[ADIVDUCC] = oprange[r];
+                       oprange[ADIVDUVCC] = oprange[r];
+                       oprange[ADIVDUCC] = oprange[r];
+                       break;
+               case AMOVBZ:    /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
+                       oprange[AMOVH] = oprange[r];
+                       oprange[AMOVHZ] = oprange[r];
+                       break;
+               case AMOVBZU:   /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
+                       oprange[AMOVHU] = oprange[r];
+                       oprange[AMOVHZU] = oprange[r];
+                       oprange[AMOVWU] = oprange[r];
+                       oprange[AMOVWZU] = oprange[r];
+                       oprange[AMOVDU] = oprange[r];
+                       oprange[AMOVMW] = oprange[r];
+                       break;
+               case AAND:      /* logical op Rb,Rs,Ra; no literal */
+                       oprange[AANDN] = oprange[r];
+                       oprange[AANDNCC] = oprange[r];
+                       oprange[AEQV] = oprange[r];
+                       oprange[AEQVCC] = oprange[r];
+                       oprange[ANAND] = oprange[r];
+                       oprange[ANANDCC] = oprange[r];
+                       oprange[ANOR] = oprange[r];
+                       oprange[ANORCC] = oprange[r];
+                       oprange[AORCC] = oprange[r];
+                       oprange[AORN] = oprange[r];
+                       oprange[AORNCC] = oprange[r];
+                       oprange[AXORCC] = oprange[r];
+                       break;
+               case AADDME:    /* op Ra, Rd */
+                       oprange[AADDMECC] = oprange[r];
+                       oprange[AADDMEV] = oprange[r];
+                       oprange[AADDMEVCC] = oprange[r];
+                       oprange[AADDZE] = oprange[r];
+                       oprange[AADDZECC] = oprange[r];
+                       oprange[AADDZEV] = oprange[r];
+                       oprange[AADDZEVCC] = oprange[r];
+                       oprange[ASUBME] = oprange[r];
+                       oprange[ASUBMECC] = oprange[r];
+                       oprange[ASUBMEV] = oprange[r];
+                       oprange[ASUBMEVCC] = oprange[r];
+                       oprange[ASUBZE] = oprange[r];
+                       oprange[ASUBZECC] = oprange[r];
+                       oprange[ASUBZEV] = oprange[r];
+                       oprange[ASUBZEVCC] = oprange[r];
+                       break;
+               case AADDC:
+                       oprange[AADDCCC] = oprange[r];
+                       break;
+               case ABEQ:
+                       oprange[ABGE] = oprange[r];
+                       oprange[ABGT] = oprange[r];
+                       oprange[ABLE] = oprange[r];
+                       oprange[ABLT] = oprange[r];
+                       oprange[ABNE] = oprange[r];
+                       oprange[ABVC] = oprange[r];
+                       oprange[ABVS] = oprange[r];
+                       break;
+               case ABR:
+                       oprange[ABL] = oprange[r];
+                       break;
+               case ABC:
+                       oprange[ABCL] = oprange[r];
+                       break;
+               case AEXTSB:    /* op Rs, Ra */
+                       oprange[AEXTSBCC] = oprange[r];
+                       oprange[AEXTSH] = oprange[r];
+                       oprange[AEXTSHCC] = oprange[r];
+                       oprange[ACNTLZW] = oprange[r];
+                       oprange[ACNTLZWCC] = oprange[r];
+                       oprange[ACNTLZD] = oprange[r];
+                       oprange[AEXTSW] = oprange[r];
+                       oprange[AEXTSWCC] = oprange[r];
+                       oprange[ACNTLZDCC] = oprange[r];
+                       break;
+               case AFABS:     /* fop [s,]d */
+                       oprange[AFABSCC] = oprange[r];
+                       oprange[AFNABS] = oprange[r];
+                       oprange[AFNABSCC] = oprange[r];
+                       oprange[AFNEG] = oprange[r];
+                       oprange[AFNEGCC] = oprange[r];
+                       oprange[AFRSP] = oprange[r];
+                       oprange[AFRSPCC] = oprange[r];
+                       oprange[AFCTIW] = oprange[r];
+                       oprange[AFCTIWCC] = oprange[r];
+                       oprange[AFCTIWZ] = oprange[r];
+                       oprange[AFCTIWZCC] = oprange[r];
+                       oprange[AFCTID] = oprange[r];
+                       oprange[AFCTIDCC] = oprange[r];
+                       oprange[AFCTIDZ] = oprange[r];
+                       oprange[AFCTIDZCC] = oprange[r];
+                       oprange[AFCFID] = oprange[r];
+                       oprange[AFCFIDCC] = oprange[r];
+                       oprange[AFRES] = oprange[r];
+                       oprange[AFRESCC] = oprange[r];
+                       oprange[AFRSQRTE] = oprange[r];
+                       oprange[AFRSQRTECC] = oprange[r];
+                       oprange[AFSQRT] = oprange[r];
+                       oprange[AFSQRTCC] = oprange[r];
+                       oprange[AFSQRTS] = oprange[r];
+                       oprange[AFSQRTSCC] = oprange[r];
+                       break;
+               case AFADD:
+                       oprange[AFADDS] = oprange[r];
+                       oprange[AFADDCC] = oprange[r];
+                       oprange[AFADDSCC] = oprange[r];
+                       oprange[AFDIV] = oprange[r];
+                       oprange[AFDIVS] = oprange[r];
+                       oprange[AFDIVCC] = oprange[r];
+                       oprange[AFDIVSCC] = oprange[r];
+                       oprange[AFSUB] = oprange[r];
+                       oprange[AFSUBS] = oprange[r];
+                       oprange[AFSUBCC] = oprange[r];
+                       oprange[AFSUBSCC] = oprange[r];
+                       break;
+               case AFMADD:
+                       oprange[AFMADDCC] = oprange[r];
+                       oprange[AFMADDS] = oprange[r];
+                       oprange[AFMADDSCC] = oprange[r];
+                       oprange[AFMSUB] = oprange[r];
+                       oprange[AFMSUBCC] = oprange[r];
+                       oprange[AFMSUBS] = oprange[r];
+                       oprange[AFMSUBSCC] = oprange[r];
+                       oprange[AFNMADD] = oprange[r];
+                       oprange[AFNMADDCC] = oprange[r];
+                       oprange[AFNMADDS] = oprange[r];
+                       oprange[AFNMADDSCC] = oprange[r];
+                       oprange[AFNMSUB] = oprange[r];
+                       oprange[AFNMSUBCC] = oprange[r];
+                       oprange[AFNMSUBS] = oprange[r];
+                       oprange[AFNMSUBSCC] = oprange[r];
+                       oprange[AFSEL] = oprange[r];
+                       oprange[AFSELCC] = oprange[r];
+                       break;
+               case AFMUL:
+                       oprange[AFMULS] = oprange[r];
+                       oprange[AFMULCC] = oprange[r];
+                       oprange[AFMULSCC] = oprange[r];
+                       break;
+               case AFCMPO:
+                       oprange[AFCMPU] = oprange[r];
+                       break;
+               case AMTFSB0:
+                       oprange[AMTFSB0CC] = oprange[r];
+                       oprange[AMTFSB1] = oprange[r];
+                       oprange[AMTFSB1CC] = oprange[r];
+                       break;
+               case ANEG:      /* op [Ra,] Rd */
+                       oprange[ANEGCC] = oprange[r];
+                       oprange[ANEGV] = oprange[r];
+                       oprange[ANEGVCC] = oprange[r];
+                       break;
+               case AOR:       /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
+                       oprange[AXOR] = oprange[r];
+                       break;
+               case ASLW:
+                       oprange[ASLWCC] = oprange[r];
+                       oprange[ASRW] = oprange[r];
+                       oprange[ASRWCC] = oprange[r];
+                       break;
+               case ASLD:
+                       oprange[ASLDCC] = oprange[r];
+                       oprange[ASRD] = oprange[r];
+                       oprange[ASRDCC] = oprange[r];
+                       break;
+               case ASRAW:     /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
+                       oprange[ASRAWCC] = oprange[r];
+                       break;
+               case ASRAD:     /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
+                       oprange[ASRADCC] = oprange[r];
+                       break;
+               case ASUB:      /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
+                       oprange[ASUB] = oprange[r];
+                       oprange[ASUBCC] = oprange[r];
+                       oprange[ASUBV] = oprange[r];
+                       oprange[ASUBVCC] = oprange[r];
+                       oprange[ASUBCCC] = oprange[r];
+                       oprange[ASUBCV] = oprange[r];
+                       oprange[ASUBCVCC] = oprange[r];
+                       oprange[ASUBE] = oprange[r];
+                       oprange[ASUBECC] = oprange[r];
+                       oprange[ASUBEV] = oprange[r];
+                       oprange[ASUBEVCC] = oprange[r];
+                       break;
+               case ASYNC:
+                       oprange[AISYNC] = oprange[r];
+                       oprange[APTESYNC] = oprange[r];
+                       oprange[ATLBSYNC] = oprange[r];
+                       break;
+               case ARLWMI:
+                       oprange[ARLWMICC] = oprange[r];
+                       oprange[ARLWNM] = oprange[r];
+                       oprange[ARLWNMCC] = oprange[r];
+                       break;
+               case ARLDMI:
+                       oprange[ARLDMICC] = oprange[r];
+                       break;
+               case ARLDC:
+                       oprange[ARLDCCC] = oprange[r];
+                       break;
+               case ARLDCL:
+                       oprange[ARLDCR] = oprange[r];
+                       oprange[ARLDCLCC] = oprange[r];
+                       oprange[ARLDCRCC] = oprange[r];
+                       break;
+               case AFMOVD:
+                       oprange[AFMOVDCC] = oprange[r];
+                       oprange[AFMOVDU] = oprange[r];
+                       oprange[AFMOVS] = oprange[r];
+                       oprange[AFMOVSU] = oprange[r];
+                       break;
+               case AECIWX:
+                       oprange[ALWAR] = oprange[r];
+                       oprange[ALDAR] = oprange[r];
+                       break;
+               case ASYSCALL:  /* just the op; flow of control */
+                       oprange[ARFI] = oprange[r];
+                       oprange[ARFCI] = oprange[r];
+                       oprange[ARFID] = oprange[r];
+                       oprange[AHRFID] = oprange[r];
+                       break;
+               case AMOVHBR:
+                       oprange[AMOVWBR] = oprange[r];
+                       break;
+               case ASLBMFEE:
+                       oprange[ASLBMFEV] = oprange[r];
+                       break;
+               case ATW:
+                       oprange[ATD] = oprange[r];
+                       break;
+               case ATLBIE:
+                       oprange[ASLBIE] = oprange[r];
+                       oprange[ATLBIEL] = oprange[r];
+                       break;
+               case AEIEIO:
+                       oprange[ASLBIA] = oprange[r];
+                       break;
+               case ACMP:
+                       oprange[ACMPW] = oprange[r];
+                       break;
+               case ACMPU:
+                       oprange[ACMPWU] = oprange[r];
+                       break;
+               case AADD:
+               case AANDCC:    /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
+               case ALSW:
+               case AMOVW:     /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
+               case AMOVWZ:    /* load/store/move word with zero extension; move 32-bit literals  */
+               case AMOVD:     /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
+               case AMOVB:     /* macro: move byte with sign extension */
+               case AMOVBU:    /* macro: move byte with sign extension & update */
+               case AMOVFL:
+               case AMULLW:    /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
+               case ASUBC:     /* op r1,$s,r3; op r1[,r2],r3 */
+               case ASTSW:
+               case ASLBMTE:
+               case AWORD:
+               case ADWORD:
+               case ANOP:
+               case ATEXT:
+               case AUNDEF:
+               case AUSEFIELD:
+               case AFUNCDATA:
+               case APCDATA:
+               case ADUFFZERO:
+               case ADUFFCOPY:
+                       break;
+               }
+       }
+}
+
+#define        OPVCC(o,xo,oe,rc) (((o)<<26)|((xo)<<1)|((oe)<<10)|((rc)&1))
+#define        OPCC(o,xo,rc) OPVCC((o),(xo),0,(rc))
+#define        OP(o,xo) OPVCC((o),(xo),0,0)
+
+/* the order is dest, a/s, b/imm for both arithmetic and logical operations */
+#define        AOP_RRR(op,d,a,b) ((op)|(((d)&31L)<<21)|(((a)&31L)<<16)|(((b)&31L)<<11))
+#define        AOP_IRR(op,d,a,simm) ((op)|(((d)&31L)<<21)|(((a)&31L)<<16)|((simm)&0xFFFF))
+#define        LOP_RRR(op,a,s,b) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((b)&31L)<<11))
+#define        LOP_IRR(op,a,s,uimm) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|((uimm)&0xFFFF))
+#define        OP_BR(op,li,aa) ((op)|((li)&0x03FFFFFC)|((aa)<<1))
+#define        OP_BC(op,bo,bi,bd,aa) ((op)|(((bo)&0x1F)<<21)|(((bi)&0x1F)<<16)|((bd)&0xFFFC)|((aa)<<1))
+#define        OP_BCR(op,bo,bi) ((op)|(((bo)&0x1F)<<21)|(((bi)&0x1F)<<16))
+#define        OP_RLW(op,a,s,sh,mb,me) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((sh)&31L)<<11)|\
+                                       (((mb)&31L)<<6)|(((me)&31L)<<1))
+
+#define        OP_ADD  OPVCC(31,266,0,0)
+#define        OP_ADDI OPVCC(14,0,0,0)
+#define        OP_ADDIS OPVCC(15,0,0,0)
+#define        OP_ANDI OPVCC(28,0,0,0)
+#define        OP_EXTSB        OPVCC(31,954,0,0)
+#define        OP_EXTSH OPVCC(31,922,0,0)
+#define        OP_EXTSW OPVCC(31,986,0,0)
+#define        OP_MCRF OPVCC(19,0,0,0)
+#define        OP_MCRFS OPVCC(63,64,0,0)
+#define        OP_MCRXR OPVCC(31,512,0,0)
+#define        OP_MFCR OPVCC(31,19,0,0)
+#define        OP_MFFS OPVCC(63,583,0,0)
+#define        OP_MFMSR OPVCC(31,83,0,0)
+#define        OP_MFSPR OPVCC(31,339,0,0)
+#define        OP_MFSR OPVCC(31,595,0,0)
+#define        OP_MFSRIN       OPVCC(31,659,0,0)
+#define        OP_MTCRF OPVCC(31,144,0,0)
+#define        OP_MTFSF OPVCC(63,711,0,0)
+#define        OP_MTFSFI OPVCC(63,134,0,0)
+#define        OP_MTMSR OPVCC(31,146,0,0)
+#define        OP_MTMSRD OPVCC(31,178,0,0)
+#define        OP_MTSPR OPVCC(31,467,0,0)
+#define        OP_MTSR OPVCC(31,210,0,0)
+#define        OP_MTSRIN       OPVCC(31,242,0,0)
+#define        OP_MULLW OPVCC(31,235,0,0)
+#define        OP_MULLD OPVCC(31,233,0,0)
+#define        OP_OR   OPVCC(31,444,0,0)
+#define        OP_ORI  OPVCC(24,0,0,0)
+#define        OP_ORIS OPVCC(25,0,0,0)
+#define        OP_RLWINM       OPVCC(21,0,0,0)
+#define        OP_SUBF OPVCC(31,40,0,0)
+#define        OP_RLDIC        OPVCC(30,4,0,0)
+#define        OP_RLDICR       OPVCC(30,2,0,0)
+#define        OP_RLDICL       OPVCC(30,0,0,0)
+
+#define        oclass(v)       ((v).class-1)
+
+// add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2.
+static void
+addaddrreloc(Link *ctxt, LSym *s, int *o1, int *o2)
+{
+       Reloc *rel;
+
+       rel = addrel(ctxt->cursym);
+       rel->off = ctxt->pc;
+       rel->siz = 8;
+       rel->sym = s;
+       rel->add = ((uvlong)*o1<<32) | (uint32)*o2;
+       rel->type = R_ADDRPOWER;
+}
+
+/*
+ * 32-bit masks
+ */
+static int
+getmask(uchar *m, uint32 v)
+{
+       int i;
+
+       m[0] = m[1] = 0;
+       if(v != ~0U && v & (1<<31) && v & 1){   /* MB > ME */
+               if(getmask(m, ~v)){
+                       i = m[0]; m[0] = m[1]+1; m[1] = i-1;
+                       return 1;
+               }
+               return 0;
+       }
+       for(i=0; i<32; i++)
+               if(v & (1<<(31-i))){
+                       m[0] = i;
+                       do {
+                               m[1] = i;
+                       } while(++i<32 && (v & (1<<(31-i))) != 0);
+                       for(; i<32; i++)
+                               if(v & (1<<(31-i)))
+                                       return 0;
+                       return 1;
+               }
+       return 0;
+}
+
+static void
+maskgen(Link *ctxt, Prog *p, uchar *m, uint32 v)
+{
+       if(!getmask(m, v))
+               ctxt->diag("cannot generate mask #%lux\n%P", v, p);
+}
+
+/*
+ * 64-bit masks (rldic etc)
+ */
+static int
+getmask64(uchar *m, uvlong v)
+{
+       int i;
+
+       m[0] = m[1] = 0;
+       for(i=0; i<64; i++)
+               if(v & ((uvlong)1<<(63-i))){
+                       m[0] = i;
+                       do {
+                               m[1] = i;
+                       } while(++i<64 && (v & ((uvlong)1<<(63-i))) != 0);
+                       for(; i<64; i++)
+                               if(v & ((uvlong)1<<(63-i)))
+                                       return 0;
+                       return 1;
+               }
+       return 0;
+}
+
+static void
+maskgen64(Link *ctxt, Prog *p, uchar *m, uvlong v)
+{
+       if(!getmask64(m, v))
+               ctxt->diag("cannot generate mask #%llux\n%P", v, p);
+}
+
+static uint32
+loadu32(int r, vlong d)
+{
+       int32 v;
+
+       v = d>>16;
+       if(isuint32(d))
+               return LOP_IRR(OP_ORIS, r, REGZERO, v);
+       return AOP_IRR(OP_ADDIS, r, REGZERO, v);
+}
+
+static uint16
+high16adjusted(int32 d)
+{
+       if(d & 0x8000)
+               return (d>>16) + 1;
+       return d>>16;
+}
+
+static void
+asmout(Link *ctxt, Prog *p, Optab *o, int32 *out)
+{
+       int32 o1, o2, o3, o4, o5, v, t;
+       vlong d;
+       int r, a;
+       uchar mask[2];
+       Reloc *rel;
+
+       o1 = 0;
+       o2 = 0;
+       o3 = 0;
+       o4 = 0;
+       o5 = 0;
+
+//print("%P => case %d\n", p, o->type);
+       switch(o->type) {
+       default:
+               ctxt->diag("unknown type %d", o->type);
+               prasm(p);
+               break;
+
+       case 0:         /* pseudo ops */
+               break;
+
+       case 1:         /* mov r1,r2 ==> OR Rs,Rs,Ra */
+               if(p->to.reg == REGZERO && p->from.type == D_CONST) {
+                       v = regoff(ctxt, &p->from);
+                       if(r0iszero && v != 0) {
+                               //nerrors--;
+                               ctxt->diag("literal operation on R0\n%P", p);
+                       }
+                       o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, v);
+                       break;
+               }
+               o1 = LOP_RRR(OP_OR, p->to.reg, p->from.reg, p->from.reg);
+               break;
+
+       case 2:         /* int/cr/fp op Rb,[Ra],Rd */
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, p->from.reg);
+               break;
+
+       case 3:         /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
+               d = vregoff(ctxt, &p->from);
+               v = d;
+               r = p->from.reg;
+               if(r == NREG)
+                       r = o->param;
+               if(r0iszero && p->to.reg == 0 && (r != 0 || v != 0))
+                       ctxt->diag("literal operation on R0\n%P", p);
+               a = OP_ADDI;
+               if(o->a1 == C_UCON) {
+                       if((d&0xffff) != 0)
+                               sysfatal("invalid handling of %P", p);
+                       v >>= 16;
+                       if(r == REGZERO && isuint32(d)){
+                               o1 = LOP_IRR(OP_ORIS, p->to.reg, REGZERO, v);
+                               break;
+                       }
+                       a = OP_ADDIS;
+               } else {
+                       if((int16)d != d)
+                               sysfatal("invalid handling of %P", p);
+               }
+               o1 = AOP_IRR(a, p->to.reg, r, v);
+               break;
+
+       case 4:         /* add/mul $scon,[r1],r2 */
+               v = regoff(ctxt, &p->from);
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               if(r0iszero && p->to.reg == 0)
+                       ctxt->diag("literal operation on R0\n%P", p);
+               if((int16)v != v)
+                       sysfatal("mishandled instruction %P", p);
+               o1 = AOP_IRR(opirr(ctxt, p->as), p->to.reg, r, v);
+               break;
+
+       case 5:         /* syscall */
+               o1 = oprrr(ctxt, p->as);
+               break;
+
+       case 6:         /* logical op Rb,[Rs,]Ra; no literal */
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, p->from.reg);
+               break;
+
+       case 7:         /* mov r, soreg ==> stw o(r) */
+               r = p->to.reg;
+               if(r == NREG)
+                       r = o->param;
+               v = regoff(ctxt, &p->to);
+               if(p->to.type == D_OREG && p->reg != NREG) {
+                       if(v)
+                               ctxt->diag("illegal indexed instruction\n%P", p);
+                       o1 = AOP_RRR(opstorex(ctxt, p->as), p->from.reg, p->reg, r);
+               } else {
+                       if((int16)v != v)
+                               sysfatal("mishandled instruction %P", p);       
+                       o1 = AOP_IRR(opstore(ctxt, p->as), p->from.reg, r, v);
+               }
+               break;
+
+       case 8:         /* mov soreg, r ==> lbz/lhz/lwz o(r) */
+               r = p->from.reg;
+               if(r == NREG)
+                       r = o->param;
+               v = regoff(ctxt, &p->from);
+               if(p->from.type == D_OREG && p->reg != NREG) {
+                       if(v)
+                               ctxt->diag("illegal indexed instruction\n%P", p);
+                       o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, p->reg, r);
+               } else {
+                       if((int16)v != v)
+                               sysfatal("mishandled instruction %P", p);
+                       o1 = AOP_IRR(opload(ctxt, p->as), p->to.reg, r, v);
+               }
+               break;
+
+       case 9:         /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
+               r = p->from.reg;
+               if(r == NREG)
+                       r = o->param;
+               v = regoff(ctxt, &p->from);
+               if(p->from.type == D_OREG && p->reg != NREG) {
+                       if(v)
+                               ctxt->diag("illegal indexed instruction\n%P", p);
+                       o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, p->reg, r);
+               } else
+                       o1 = AOP_IRR(opload(ctxt, p->as), p->to.reg, r, v);
+               o2 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
+               break;
+
+       case 10:                /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, p->from.reg, r);
+               break;
+
+       case 11:        /* br/bl lbra */
+               v = 0;
+               if(p->pcond) {
+                       v = p->pcond->pc - p->pc;
+                       if(v & 03) {
+                               ctxt->diag("odd branch target address\n%P", p);
+                               v &= ~03;
+                       }
+                       if(v < -(1L<<25) || v >= (1L<<24))
+                               ctxt->diag("branch too far\n%P", p);
+               }
+               o1 = OP_BR(opirr(ctxt, p->as), v, 0);
+               if(p->to.sym != nil) {
+                       rel = addrel(ctxt->cursym);
+                       rel->off = ctxt->pc;
+                       rel->siz = 4;
+                       rel->sym = p->to.sym;
+                       v += p->to.offset;
+                       if(v & 03) {
+                               ctxt->diag("odd branch target address\n%P", p);
+                               v &= ~03;
+                       }
+                       rel->add = o1 | (v & 0x03FFFFFC);
+                       rel->type = R_CALLPOWER;
+               }
+               break;
+
+       case 12:        /* movb r,r (extsb); movw r,r (extsw) */
+               if(p->to.reg == REGZERO && p->from.type == D_CONST) {
+                       v = regoff(ctxt, &p->from);
+                       if(r0iszero && v != 0) {
+                               ctxt->diag("literal operation on R0\n%P", p);
+                       }
+                       o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, v);
+                       break;
+               }
+               if(p->as == AMOVW)
+                       o1 = LOP_RRR(OP_EXTSW, p->to.reg, p->from.reg, 0);
+               else
+                       o1 = LOP_RRR(OP_EXTSB, p->to.reg, p->from.reg, 0);
+               break;
+
+       case 13:        /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
+               if(p->as == AMOVBZ)
+                       o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 24, 31);
+               else if(p->as == AMOVH)
+                       o1 = LOP_RRR(OP_EXTSH, p->to.reg, p->from.reg, 0);
+               else if(p->as == AMOVHZ)
+                       o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 16, 31);
+               else if(p->as == AMOVWZ)
+                       o1 = OP_RLW(OP_RLDIC, p->to.reg, p->from.reg, 0, 0, 0) | (1<<5);        /* MB=32 */
+               else
+                       ctxt->diag("internal: bad mov[bhw]z\n%P", p);
+               break;
+
+       case 14:        /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               d = vregoff(ctxt, &p->from3);
+               maskgen64(ctxt, p, mask, d);
+               switch(p->as){
+               case ARLDCL: case ARLDCLCC:
+                       a = mask[0];    /* MB */
+                       if(mask[1] != 63)
+                               ctxt->diag("invalid mask for rotate: %llux (end != bit 63)\n%P", d, p);
+                       break;
+               case ARLDCR: case ARLDCRCC:
+                       a = mask[1];    /* ME */
+                       if(mask[0] != 0)
+                               ctxt->diag("invalid mask for rotate: %llux (start != 0)\n%P", d, p);
+                       break;
+               default:
+                       ctxt->diag("unexpected op in rldc case\n%P", p);
+                       a = 0;
+               }
+               o1 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, p->from.reg);
+               o1 |= (a&31L)<<6;
+               if(a & 0x20)
+                       o1 |= 1<<5;     /* mb[5] is top bit */
+               break;
+
+       case 17:        /* bc bo,bi,lbra (same for now) */
+       case 16:        /* bc bo,bi,sbra */
+               a = 0;
+               if(p->from.type == D_CONST)
+                       a = regoff(ctxt, &p->from);
+               r = p->reg;
+               if(r == NREG)
+                       r = 0;
+               v = 0;
+               if(p->pcond)
+                       v = p->pcond->pc - p->pc;
+               if(v & 03) {
+                       ctxt->diag("odd branch target address\n%P", p);
+                       v &= ~03;
+               }
+               if(v < -(1L<<16) || v >= (1L<<15))
+                       ctxt->diag("branch too far\n%P", p);
+               o1 = OP_BC(opirr(ctxt, p->as), a, r, v, 0);
+               break;
+
+       case 15:        /* br/bl (r) => mov r,lr; br/bl (lr) */
+               if(p->as == ABC || p->as == ABCL)
+                       v = regoff(ctxt, &p->to)&31L;
+               else
+                       v = 20; /* unconditional */
+               r = p->reg;
+               if(r == NREG)
+                       r = 0;
+               o1 = AOP_RRR(OP_MTSPR, p->to.reg, 0, 0) | ((D_LR&0x1f)<<16) | (((D_LR>>5)&0x1f)<<11);
+               o2 = OPVCC(19, 16, 0, 0);
+               if(p->as == ABL || p->as == ABCL)
+                       o2 |= 1;
+               o2 = OP_BCR(o2, v, r);
+               break;
+
+       case 18:        /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
+               if(p->as == ABC || p->as == ABCL)
+                       v = regoff(ctxt, &p->from)&31L;
+               else
+                       v = 20; /* unconditional */
+               r = p->reg;
+               if(r == NREG)
+                       r = 0;
+               switch(oclass(p->to)) {
+               case C_CTR:
+                       o1 = OPVCC(19, 528, 0, 0);
+                       break;
+               case C_LR:
+                       o1 = OPVCC(19, 16, 0, 0);
+                       break;
+               default:
+                       ctxt->diag("bad optab entry (18): %d\n%P", p->to.class, p);
+                       v = 0;
+               }
+               if(p->as == ABL || p->as == ABCL)
+                       o1 |= 1;
+               o1 = OP_BCR(o1, v, r);
+               break;
+
+       case 19:        /* mov $lcon,r ==> cau+or */
+               d = vregoff(ctxt, &p->from);
+               if(p->from.sym == nil) {
+                       o1 = loadu32(p->to.reg, d);
+                       o2 = LOP_IRR(OP_ORI, p->to.reg, p->to.reg, (int32)d);
+               } else {
+                       o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, high16adjusted(d));
+                       o2 = AOP_IRR(OP_ADDI, p->to.reg, REGTMP, d);
+                       addaddrreloc(ctxt, p->from.sym, &o1, &o2);
+               }
+               //if(dlm) reloc(&p->from, p->pc, 0);
+               break;
+
+       case 20:        /* add $ucon,,r */
+               v = regoff(ctxt, &p->from);
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               if(p->as == AADD && (!r0iszero && p->reg == 0 || r0iszero && p->to.reg == 0))
+                       ctxt->diag("literal operation on R0\n%P", p);
+               o1 = AOP_IRR(opirr(ctxt, p->as+AEND), p->to.reg, r, v>>16);
+               break;
+
+       case 22:        /* add $lcon,r1,r2 ==> cau+or+add */    /* could do add/sub more efficiently */
+               if(p->to.reg == REGTMP || p->reg == REGTMP)
+                       ctxt->diag("cant synthesize large constant\n%P", p);
+               d = vregoff(ctxt, &p->from);
+               o1 = loadu32(REGTMP, d);
+               o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, (int32)d);
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o3 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, REGTMP, r);
+               if(p->from.sym != nil)
+                       ctxt->diag("%P is not supported", p);
+               //if(dlm) reloc(&p->from, p->pc, 0);
+               break;
+
+       case 23:        /* and $lcon,r1,r2 ==> cau+or+and */    /* masks could be done using rlnm etc. */
+               if(p->to.reg == REGTMP || p->reg == REGTMP)
+                       ctxt->diag("cant synthesize large constant\n%P", p);
+               d = vregoff(ctxt, &p->from);
+               o1 = loadu32(REGTMP, d);
+               o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, (int32)d);
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o3 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, REGTMP, r);
+               if(p->from.sym != nil)
+                       ctxt->diag("%P is not supported", p);
+               //if(dlm) reloc(&p->from, p->pc, 0);
+               break;
+/*24*/
+
+       case 25:        /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
+               v = regoff(ctxt, &p->from);
+               if(v < 0)
+                       v = 0;
+               else if(v > 63)
+                       v = 63;
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               switch(p->as){
+               case ASLD: case ASLDCC:
+                       a = 63-v;
+                       o1 = OP_RLDICR;
+                       break;
+               case ASRD: case ASRDCC:
+                       a = v;
+                       v = 64-v;
+                       o1 = OP_RLDICL;
+                       break;
+               default:
+                       ctxt->diag("unexpected op in sldi case\n%P", p);
+                       a = 0;
+                       o1 = 0;
+               }
+               o1 = AOP_RRR(o1, r, p->to.reg, (v&0x1F));
+               o1 |= (a&31L)<<6;
+               if(v & 0x20)
+                       o1 |= 1<<1;
+               if(a & 0x20)
+                       o1 |= 1<<5;     /* mb[5] is top bit */
+               if(p->as == ASLDCC || p->as == ASRDCC)
+                       o1 |= 1;        /* Rc */
+               break;
+
+       case 26:        /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
+               if(p->to.reg == REGTMP)
+                       ctxt->diag("can't synthesize large constant\n%P", p);
+               v = regoff(ctxt, &p->from);
+               if(v & 0x8000L)
+                       v += 0x10000L;
+               r = p->from.reg;
+               if(r == NREG)
+                       r = o->param;
+               o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
+               o2 = AOP_IRR(OP_ADDI, p->to.reg, REGTMP, v);
+               break;
+
+       case 27:                /* subc ra,$simm,rd => subfic rd,ra,$simm */
+               v = regoff(ctxt, &p->from3);
+               r = p->from.reg;
+               o1 = AOP_IRR(opirr(ctxt, p->as), p->to.reg, r, v);
+               break;
+
+       case 28:        /* subc r1,$lcon,r2 ==> cau+or+subfc */
+               if(p->to.reg == REGTMP || p->from.reg == REGTMP)
+                       ctxt->diag("can't synthesize large constant\n%P", p);
+               v = regoff(ctxt, &p->from3);
+               o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
+               o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
+               o3 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, p->from.reg, REGTMP);
+               if(p->from.sym != nil)
+                       ctxt->diag("%P is not supported", p);
+               //if(dlm) reloc(&p->from3, p->pc, 0);
+               break;
+
+       case 29:        /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
+               v = regoff(ctxt, &p->from);
+               d = vregoff(ctxt, &p->from3);
+               maskgen64(ctxt, p, mask, d);
+               switch(p->as){
+               case ARLDC: case ARLDCCC:
+                       a = mask[0];    /* MB */
+                       if(mask[1] != (63-v))
+                               ctxt->diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
+                       break;
+               case ARLDCL: case ARLDCLCC:
+                       a = mask[0];    /* MB */
+                       if(mask[1] != 63)
+                               ctxt->diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
+                       break;
+               case ARLDCR: case ARLDCRCC:
+                       a = mask[1];    /* ME */
+                       if(mask[0] != 0)
+                               ctxt->diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
+                       break;
+               default:
+                       ctxt->diag("unexpected op in rldic case\n%P", p);
+                       a = 0;
+               }
+               o1 = AOP_RRR(opirr(ctxt, p->as), p->reg, p->to.reg, (v&0x1F));
+               o1 |= (a&31L)<<6;
+               if(v & 0x20)
+                       o1 |= 1<<1;
+               if(a & 0x20)
+                       o1 |= 1<<5;     /* mb[5] is top bit */
+               break;
+
+       case 30:        /* rldimi $sh,s,$mask,a */
+               v = regoff(ctxt, &p->from);
+               d = vregoff(ctxt, &p->from3);
+               maskgen64(ctxt, p, mask, d);
+               if(mask[1] != (63-v))
+                       ctxt->diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
+               o1 = AOP_RRR(opirr(ctxt, p->as), p->reg, p->to.reg, (v&0x1F));
+               o1 |= (mask[0]&31L)<<6;
+               if(v & 0x20)
+                       o1 |= 1<<1;
+               if(mask[0] & 0x20)
+                       o1 |= 1<<5;     /* mb[5] is top bit */
+               break;
+
+       case 31:        /* dword */
+               d = vregoff(ctxt, &p->from);
+               if(ctxt->arch->endian == BigEndian) {
+                       o1 = d>>32;
+                       o2 = d;
+               } else {
+                       o1 = d;
+                       o2 = d>>32;
+               }
+               if(p->from.sym != nil) {
+                       rel = addrel(ctxt->cursym);
+                       rel->off = ctxt->pc;
+                       rel->siz = 8;
+                       rel->sym = p->from.sym;
+                       rel->add = p->from.offset;
+                       rel->type = R_ADDR;
+                       o1 = o2 = 0;
+               }
+               break;
+
+       case 32:        /* fmul frc,fra,frd */
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0)|((p->from.reg&31L)<<6);
+               break;
+
+       case 33:        /* fabs [frb,]frd; fmr. frb,frd */
+               r = p->from.reg;
+               if(oclass(p->from) == C_NONE)
+                       r = p->to.reg;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, 0, r);
+               break;
+
+       case 34:        /* FMADDx fra,frb,frc,frd (d=a*b+c); FSELx a<0? (d=b): (d=c) */
+               o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, p->from.reg, p->reg)|((p->from3.reg&31L)<<6);
+               break;
+
+       case 35:        /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
+               v = regoff(ctxt, &p->to);
+               if(v & 0x8000L)
+                       v += 0x10000L;
+               r = p->to.reg;
+               if(r == NREG)
+                       r = o->param;
+               o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
+               o2 = AOP_IRR(opstore(ctxt, p->as), p->from.reg, REGTMP, v);
+               break;
+
+       case 36:        /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
+               v = regoff(ctxt, &p->from);
+               if(v & 0x8000L)
+                       v += 0x10000L;
+               r = p->from.reg;
+               if(r == NREG)
+                       r = o->param;
+               o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
+               o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
+               break;
+
+       case 37:        /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
+               v = regoff(ctxt, &p->from);
+               if(v & 0x8000L)
+                       v += 0x10000L;
+               r = p->from.reg;
+               if(r == NREG)
+                       r = o->param;
+               o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
+               o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
+               o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
+               break;
+
+       case 40:        /* word */
+               o1 = regoff(ctxt, &p->from);
+               break;
+
+       case 41:        /* stswi */
+               o1 = AOP_RRR(opirr(ctxt, p->as), p->from.reg, p->to.reg, 0) | ((regoff(ctxt, &p->from3)&0x7F)<<11);
+               break;
+
+       case 42:        /* lswi */
+               o1 = AOP_RRR(opirr(ctxt, p->as), p->to.reg, p->from.reg, 0) | ((regoff(ctxt, &p->from3)&0x7F)<<11);
+               break;
+
+       case 43:        /* unary indexed source: dcbf (b); dcbf (a+b) */
+               r = p->reg;
+               if(r == NREG)
+                       r = 0;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), 0, r, p->from.reg);
+               break;
+
+       case 44:        /* indexed store */
+               r = p->reg;
+               if(r == NREG)
+                       r = 0;
+               o1 = AOP_RRR(opstorex(ctxt, p->as), p->from.reg, r, p->to.reg);
+               break;
+       case 45:        /* indexed load */
+               r = p->reg;
+               if(r == NREG)
+                       r = 0;
+               o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, r, p->from.reg);
+               break;
+
+       case 46:        /* plain op */
+               o1 = oprrr(ctxt, p->as);
+               break;
+
+       case 47:        /* op Ra, Rd; also op [Ra,] Rd */
+               r = p->from.reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0);
+               break;
+
+       case 48:        /* op Rs, Ra */
+               r = p->from.reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0);
+               break;
+
+       case 49:        /* op Rb; op $n, Rb */
+               if(p->from.type != D_REG){      /* tlbie $L, rB */
+                       v = regoff(ctxt, &p->from) & 1;
+                       o1 = AOP_RRR(oprrr(ctxt, p->as), 0, 0, p->to.reg) | (v<<21);
+               }else
+                       o1 = AOP_RRR(oprrr(ctxt, p->as), 0, 0, p->from.reg);
+               break;
+
+       case 50:        /* rem[u] r1[,r2],r3 */
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               v = oprrr(ctxt, p->as);
+               t = v & ((1<<10)|1);    /* OE|Rc */
+               o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
+               o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, p->from.reg);
+               o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
+               if(p->as == AREMU) {
+                       o4 = o3;
+                       /* Clear top 32 bits */
+                       o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | (1<<5);
+               }
+               break;
+
+       case 51:        /* remd[u] r1[,r2],r3 */
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               v = oprrr(ctxt, p->as);
+               t = v & ((1<<10)|1);    /* OE|Rc */
+               o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
+               o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, p->from.reg);
+               o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
+               break;
+
+       case 52:        /* mtfsbNx cr(n) */
+               v = regoff(ctxt, &p->from)&31L;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), v, 0, 0);
+               break;
+
+       case 53:        /* mffsX ,fr1 */
+               o1 = AOP_RRR(OP_MFFS, p->to.reg, 0, 0);
+               break;
+
+       case 54:        /* mov msr,r1; mov r1, msr*/
+               if(oclass(p->from) == C_REG){
+                       if(p->as == AMOVD)
+                               o1 = AOP_RRR(OP_MTMSRD, p->from.reg, 0, 0);
+                       else
+                               o1 = AOP_RRR(OP_MTMSR, p->from.reg, 0, 0);
+               }else
+                       o1 = AOP_RRR(OP_MFMSR, p->to.reg, 0, 0);
+               break;
+
+       case 55:        /* op Rb, Rd */
+               o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, 0, p->from.reg);
+               break;
+
+       case 56:        /* sra $sh,[s,]a; srd $sh,[s,]a */
+               v = regoff(ctxt, &p->from);
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = AOP_RRR(opirr(ctxt, p->as), r, p->to.reg, v&31L);
+               if(p->as == ASRAD && (v&0x20))
+                       o1 |= 1<<1;     /* mb[5] */
+               break;
+
+       case 57:        /* slw $sh,[s,]a -> rlwinm ... */
+               v = regoff(ctxt, &p->from);
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               /*
+                * Let user (gs) shoot himself in the foot. 
+                * qc has already complained.
+                *
+               if(v < 0 || v > 31)
+                       ctxt->diag("illegal shift %ld\n%P", v, p);
+                */
+               if(v < 0)
+                       v = 0;
+               else if(v > 32)
+                       v = 32;
+               if(p->as == ASRW || p->as == ASRWCC) {  /* shift right */
+                       mask[0] = v;
+                       mask[1] = 31;
+                       v = 32-v;
+               } else {
+                       mask[0] = 0;
+                       mask[1] = 31-v;
+               }
+               o1 = OP_RLW(OP_RLWINM, p->to.reg, r, v, mask[0], mask[1]);
+               if(p->as == ASLWCC || p->as == ASRWCC)
+                       o1 |= 1;        /* Rc */
+               break;
+
+       case 58:                /* logical $andcon,[s],a */
+               v = regoff(ctxt, &p->from);
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = LOP_IRR(opirr(ctxt, p->as), p->to.reg, r, v);
+               break;
+
+       case 59:        /* or/and $ucon,,r */
+               v = regoff(ctxt, &p->from);
+               r = p->reg;
+               if(r == NREG)
+                       r = p->to.reg;
+               o1 = LOP_IRR(opirr(ctxt, p->as+AEND), p->to.reg, r, v>>16);     /* oris, xoris, andis */
+               break;
+
+       case 60:        /* tw to,a,b */
+               r = regoff(ctxt, &p->from)&31L;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), r, p->reg, p->to.reg);
+               break;
+
+       case 61:        /* tw to,a,$simm */
+               r = regoff(ctxt, &p->from)&31L;
+               v = regoff(ctxt, &p->to);
+               o1 = AOP_IRR(opirr(ctxt, p->as), r, p->reg, v);
+               break;
+
+       case 62:        /* rlwmi $sh,s,$mask,a */
+               v = regoff(ctxt, &p->from);
+               maskgen(ctxt, p, mask, regoff(ctxt, &p->from3));
+               o1 = AOP_RRR(opirr(ctxt, p->as), p->reg, p->to.reg, v);
+               o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
+               break;
+
+       case 63:        /* rlwmi b,s,$mask,a */
+               maskgen(ctxt, p, mask, regoff(ctxt, &p->from3));
+               o1 = AOP_RRR(opirr(ctxt, p->as), p->reg, p->to.reg, p->from.reg);
+               o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
+               break;
+
+       case 64:        /* mtfsf fr[, $m] {,fpcsr} */
+               if(p->from3.type != D_NONE)
+                       v = regoff(ctxt, &p->from3)&255L;
+               else
+                       v = 255;
+               o1 = OP_MTFSF | (v<<17) | (p->from.reg<<11);
+               break;
+
+       case 65:        /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
+               if(p->to.reg == NREG)
+                       ctxt->diag("must specify FPSCR(n)\n%P", p);
+               o1 = OP_MTFSFI | ((p->to.reg&15L)<<23) | ((regoff(ctxt, &p->from)&31L)<<12);
+               break;
+
+       case 66:        /* mov spr,r1; mov r1,spr, also dcr */
+               if(p->from.type == D_REG) {
+                       r = p->from.reg;
+                       v = p->to.offset;
+                       if(p->to.type == D_DCR)
+                               o1 = OPVCC(31,451,0,0); /* mtdcr */
+                       else
+                               o1 = OPVCC(31,467,0,0); /* mtspr */
+               } else {
+                       r = p->to.reg;
+                       v = p->from.offset;
+                       if(p->from.type == D_DCR)
+                               o1 = OPVCC(31,323,0,0); /* mfdcr */
+                       else
+                               o1 = OPVCC(31,339,0,0); /* mfspr */
+               }
+               o1 = AOP_RRR(o1, r, 0, 0) | ((v&0x1f)<<16) | (((v>>5)&0x1f)<<11);
+               break;
+
+       case 67:        /* mcrf crfD,crfS */
+               if(p->from.type != D_CREG || p->from.reg == NREG ||
+                  p->to.type != D_CREG || p->to.reg == NREG)
+                       ctxt->diag("illegal CR field number\n%P", p);
+               o1 = AOP_RRR(OP_MCRF, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
+               break;
+
+       case 68:        /* mfcr rD; mfocrf CRM,rD */
+               if(p->from.type == D_CREG && p->from.reg != NREG){
+                       v = 1<<(7-(p->to.reg&7));       /* CR(n) */
+                       o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0) | (1<<20) | (v<<12);     /* new form, mfocrf */
+               }else
+                       o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0); /* old form, whole register */
+               break;
+
+       case 69:        /* mtcrf CRM,rS */
+               if(p->from3.type != D_NONE) {
+                       if(p->to.reg != NREG)
+                               ctxt->diag("can't use both mask and CR(n)\n%P", p);
+                       v = regoff(ctxt, &p->from3) & 0xff;
+               } else {
+                       if(p->to.reg == NREG)
+                               v = 0xff;       /* CR */
+                       else
+                               v = 1<<(7-(p->to.reg&7));       /* CR(n) */
+               }
+               o1 = AOP_RRR(OP_MTCRF, p->from.reg, 0, 0) | (v<<12);
+               break;
+
+       case 70:        /* [f]cmp r,r,cr*/
+               if(p->reg == NREG)
+                       r = 0;
+               else
+                       r = (p->reg&7)<<2;
+               o1 = AOP_RRR(oprrr(ctxt, p->as), r, p->from.reg, p->to.reg);
+               break;
+
+       case 71:        /* cmp[l] r,i,cr*/
+               if(p->reg == NREG)
+                       r = 0;
+               else
+                       r = (p->reg&7)<<2;
+               o1 = AOP_RRR(opirr(ctxt, p->as), r, p->from.reg, 0) | (regoff(ctxt, &p->to)&0xffff);
+               break;
+
+       case 72:        /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
+               o1 = AOP_RRR(oprrr(ctxt, p->as), p->from.reg, 0, p->to.reg);
+               break;
+
+       case 73:        /* mcrfs crfD,crfS */
+               if(p->from.type != D_FPSCR || p->from.reg == NREG ||
+                  p->to.type != D_CREG || p->to.reg == NREG)
+                       ctxt->diag("illegal FPSCR/CR field number\n%P", p);
+               o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
+               break;
+
+       case 77:        /* syscall $scon, syscall Rx */
+               if(p->from.type == D_CONST) {
+                       if(p->from.offset > BIG || p->from.offset < -BIG)
+                               ctxt->diag("illegal syscall, sysnum too large: %P", p);
+                       o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, p->from.offset);
+               } else if(p->from.type == D_REG) {
+                       o1 = LOP_RRR(OP_OR, REGZERO, p->from.reg, p->from.reg);
+               } else {
+                       ctxt->diag("illegal syscall: %P", p);
+                       o1 = 0x7fe00008; // trap always
+               }
+               o2 = oprrr(ctxt, p->as);
+               o3 = AOP_RRR(oprrr(ctxt, AXOR), REGZERO, REGZERO, REGZERO); // XOR R0, R0
+               break;
+
+       case 78:        /* undef */
+               o1 = 0; /* "An instruction consisting entirely of binary 0s is guaranteed
+                          always to be an illegal instruction."  */
+               break;
+
+       /* relocation operations */
+
+       case 74:
+               v = regoff(ctxt, &p->to);
+               o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, high16adjusted(v));
+               o2 = AOP_IRR(opstore(ctxt, p->as), p->from.reg, REGTMP, v);
+               addaddrreloc(ctxt, p->to.sym, &o1, &o2);
+               //if(dlm) reloc(&p->to, p->pc, 1);
+               break;
+
+       case 75:
+               v = regoff(ctxt, &p->from);
+               o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, high16adjusted(v));
+               o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
+               addaddrreloc(ctxt, p->from.sym, &o1, &o2);
+               //if(dlm) reloc(&p->from, p->pc, 1);
+               break;
+
+       case 76:
+               v = regoff(ctxt, &p->from);
+               o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, high16adjusted(v));
+               o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
+               addaddrreloc(ctxt, p->from.sym, &o1, &o2);
+               o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
+               //if(dlm) reloc(&p->from, p->pc, 1);
+               break;
+
+       }
+
+       out[0] = o1;
+       out[1] = o2;
+       out[2] = o3;
+       out[3] = o4;
+       out[4] = o5;
+       return;
+}
+
+static vlong
+vregoff(Link *ctxt, Addr *a)
+{
+
+       ctxt->instoffset = 0;
+       aclass(ctxt, a);
+       return ctxt->instoffset;
+}
+
+static int32
+regoff(Link *ctxt, Addr *a)
+{
+       return vregoff(ctxt, a);
+}
+
+static int32
+oprrr(Link *ctxt, int a)
+{
+       switch(a) {
+       case AADD:      return OPVCC(31,266,0,0);
+       case AADDCC:    return OPVCC(31,266,0,1);
+       case AADDV:     return OPVCC(31,266,1,0);
+       case AADDVCC:   return OPVCC(31,266,1,1);
+       case AADDC:     return OPVCC(31,10,0,0);
+       case AADDCCC:   return OPVCC(31,10,0,1);
+       case AADDCV:    return OPVCC(31,10,1,0);
+       case AADDCVCC:  return OPVCC(31,10,1,1);
+       case AADDE:     return OPVCC(31,138,0,0);
+       case AADDECC:   return OPVCC(31,138,0,1);
+       case AADDEV:    return OPVCC(31,138,1,0);
+       case AADDEVCC:  return OPVCC(31,138,1,1);
+       case AADDME:    return OPVCC(31,234,0,0);
+       case AADDMECC:  return OPVCC(31,234,0,1);
+       case AADDMEV:   return OPVCC(31,234,1,0);
+       case AADDMEVCC: return OPVCC(31,234,1,1);
+       case AADDZE:    return OPVCC(31,202,0,0);
+       case AADDZECC:  return OPVCC(31,202,0,1);
+       case AADDZEV:   return OPVCC(31,202,1,0);
+       case AADDZEVCC: return OPVCC(31,202,1,1);
+
+       case AAND:      return OPVCC(31,28,0,0);
+       case AANDCC:    return OPVCC(31,28,0,1);
+       case AANDN:     return OPVCC(31,60,0,0);
+       case AANDNCC:   return OPVCC(31,60,0,1);
+
+       case ACMP:      return OPVCC(31,0,0,0)|(1<<21); /* L=1 */
+       case ACMPU:     return OPVCC(31,32,0,0)|(1<<21);
+       case ACMPW:     return OPVCC(31,0,0,0); /* L=0 */
+       case ACMPWU:    return OPVCC(31,32,0,0);
+
+       case ACNTLZW:   return OPVCC(31,26,0,0);
+       case ACNTLZWCC: return OPVCC(31,26,0,1);
+       case ACNTLZD:           return OPVCC(31,58,0,0);
+       case ACNTLZDCC: return OPVCC(31,58,0,1);
+
+       case ACRAND:    return OPVCC(19,257,0,0);
+       case ACRANDN:   return OPVCC(19,129,0,0);
+       case ACREQV:    return OPVCC(19,289,0,0);
+       case ACRNAND:   return OPVCC(19,225,0,0);
+       case ACRNOR:    return OPVCC(19,33,0,0);
+       case ACROR:     return OPVCC(19,449,0,0);
+       case ACRORN:    return OPVCC(19,417,0,0);
+       case ACRXOR:    return OPVCC(19,193,0,0);
+
+       case ADCBF:     return OPVCC(31,86,0,0);
+       case ADCBI:     return OPVCC(31,470,0,0);
+       case ADCBST:    return OPVCC(31,54,0,0);
+       case ADCBT:     return OPVCC(31,278,0,0);
+       case ADCBTST:   return OPVCC(31,246,0,0);
+       case ADCBZ:     return OPVCC(31,1014,0,0);
+
+       case AREM:
+       case ADIVW:     return OPVCC(31,491,0,0);
+       case AREMCC:
+       case ADIVWCC:   return OPVCC(31,491,0,1);
+       case AREMV:
+       case ADIVWV:    return OPVCC(31,491,1,0);
+       case AREMVCC:
+       case ADIVWVCC:  return OPVCC(31,491,1,1);
+       case AREMU:
+       case ADIVWU:    return OPVCC(31,459,0,0);
+       case AREMUCC:
+       case ADIVWUCC:  return OPVCC(31,459,0,1);
+       case AREMUV:
+       case ADIVWUV:   return OPVCC(31,459,1,0);
+       case AREMUVCC:
+       case ADIVWUVCC: return OPVCC(31,459,1,1);
+
+       case AREMD:
+       case ADIVD:     return OPVCC(31,489,0,0);
+       case AREMDCC:
+       case ADIVDCC:   return OPVCC(31,489,0,1);
+       case AREMDV:
+       case ADIVDV:    return OPVCC(31,489,1,0);
+       case AREMDVCC:
+       case ADIVDVCC:  return OPVCC(31,489,1,1);
+       case AREMDU:
+       case ADIVDU:    return OPVCC(31,457,0,0);
+       case AREMDUCC:
+       case ADIVDUCC:  return OPVCC(31,457,0,1);
+       case AREMDUV:
+       case ADIVDUV:   return OPVCC(31,457,1,0);
+       case AREMDUVCC:
+       case ADIVDUVCC: return OPVCC(31,457,1,1);
+
+       case AEIEIO:    return OPVCC(31,854,0,0);
+
+       case AEQV:      return OPVCC(31,284,0,0);
+       case AEQVCC:    return OPVCC(31,284,0,1);
+
+       case AEXTSB:    return OPVCC(31,954,0,0);
+       case AEXTSBCC:  return OPVCC(31,954,0,1);
+       case AEXTSH:    return OPVCC(31,922,0,0);
+       case AEXTSHCC:  return OPVCC(31,922,0,1);
+       case AEXTSW:    return OPVCC(31,986,0,0);
+       case AEXTSWCC:  return OPVCC(31,986,0,1);
+
+       case AFABS:     return OPVCC(63,264,0,0);
+       case AFABSCC:   return OPVCC(63,264,0,1);
+       case AFADD:     return OPVCC(63,21,0,0);
+       case AFADDCC:   return OPVCC(63,21,0,1);
+       case AFADDS:    return OPVCC(59,21,0,0);
+       case AFADDSCC:  return OPVCC(59,21,0,1);
+       case AFCMPO:    return OPVCC(63,32,0,0);
+       case AFCMPU:    return OPVCC(63,0,0,0);
+       case AFCFID:    return OPVCC(63,846,0,0);
+       case AFCFIDCC:  return OPVCC(63,846,0,1);
+       case AFCTIW:    return OPVCC(63,14,0,0);
+       case AFCTIWCC:  return OPVCC(63,14,0,1);
+       case AFCTIWZ:   return OPVCC(63,15,0,0);
+       case AFCTIWZCC: return OPVCC(63,15,0,1);
+       case AFCTID:    return OPVCC(63,814,0,0);
+       case AFCTIDCC:  return OPVCC(63,814,0,1);
+       case AFCTIDZ:   return OPVCC(63,815,0,0);
+       case AFCTIDZCC: return OPVCC(63,815,0,1);
+       case AFDIV:     return OPVCC(63,18,0,0);
+       case AFDIVCC:   return OPVCC(63,18,0,1);
+       case AFDIVS:    return OPVCC(59,18,0,0);
+       case AFDIVSCC:  return OPVCC(59,18,0,1);
+       case AFMADD:    return OPVCC(63,29,0,0);
+       case AFMADDCC:  return OPVCC(63,29,0,1);
+       case AFMADDS:   return OPVCC(59,29,0,0);
+       case AFMADDSCC: return OPVCC(59,29,0,1);
+       case AFMOVS:
+       case AFMOVD:    return OPVCC(63,72,0,0);        /* load */
+       case AFMOVDCC:  return OPVCC(63,72,0,1);
+       case AFMSUB:    return OPVCC(63,28,0,0);
+       case AFMSUBCC:  return OPVCC(63,28,0,1);
+       case AFMSUBS:   return OPVCC(59,28,0,0);
+       case AFMSUBSCC: return OPVCC(59,28,0,1);
+       case AFMUL:     return OPVCC(63,25,0,0);
+       case AFMULCC:   return OPVCC(63,25,0,1);
+       case AFMULS:    return OPVCC(59,25,0,0);
+       case AFMULSCC:  return OPVCC(59,25,0,1);
+       case AFNABS:    return OPVCC(63,136,0,0);
+       case AFNABSCC:  return OPVCC(63,136,0,1);
+       case AFNEG:     return OPVCC(63,40,0,0);
+       case AFNEGCC:   return OPVCC(63,40,0,1);
+       case AFNMADD:   return OPVCC(63,31,0,0);
+       case AFNMADDCC: return OPVCC(63,31,0,1);
+       case AFNMADDS:  return OPVCC(59,31,0,0);
+       case AFNMADDSCC:        return OPVCC(59,31,0,1);
+       case AFNMSUB:   return OPVCC(63,30,0,0);
+       case AFNMSUBCC: return OPVCC(63,30,0,1);
+       case AFNMSUBS:  return OPVCC(59,30,0,0);
+       case AFNMSUBSCC:        return OPVCC(59,30,0,1);
+       case AFRES:     return OPVCC(59,24,0,0);
+       case AFRESCC:   return OPVCC(59,24,0,1);
+       case AFRSP:     return OPVCC(63,12,0,0);
+       case AFRSPCC:   return OPVCC(63,12,0,1);
+       case AFRSQRTE:  return OPVCC(63,26,0,0);
+       case AFRSQRTECC:        return OPVCC(63,26,0,1);
+       case AFSEL:     return OPVCC(63,23,0,0);
+       case AFSELCC:   return OPVCC(63,23,0,1);
+       case AFSQRT:    return OPVCC(63,22,0,0);
+       case AFSQRTCC:  return OPVCC(63,22,0,1);
+       case AFSQRTS:   return OPVCC(59,22,0,0);
+       case AFSQRTSCC: return OPVCC(59,22,0,1);
+       case AFSUB:     return OPVCC(63,20,0,0);
+       case AFSUBCC:   return OPVCC(63,20,0,1);
+       case AFSUBS:    return OPVCC(59,20,0,0);
+       case AFSUBSCC:  return OPVCC(59,20,0,1);
+
+       case AICBI:     return OPVCC(31,982,0,0);
+       case AISYNC:    return OPVCC(19,150,0,0);
+
+       case AMTFSB0:   return OPVCC(63,70,0,0);
+       case AMTFSB0CC: return OPVCC(63,70,0,1);
+       case AMTFSB1:   return OPVCC(63,38,0,0);
+       case AMTFSB1CC: return OPVCC(63,38,0,1);
+
+       case AMULHW:    return OPVCC(31,75,0,0);
+       case AMULHWCC:  return OPVCC(31,75,0,1);
+       case AMULHWU:   return OPVCC(31,11,0,0);
+       case AMULHWUCC: return OPVCC(31,11,0,1);
+       case AMULLW:    return OPVCC(31,235,0,0);
+       case AMULLWCC:  return OPVCC(31,235,0,1);
+       case AMULLWV:   return OPVCC(31,235,1,0);
+       case AMULLWVCC: return OPVCC(31,235,1,1);
+
+       case AMULHD:    return OPVCC(31,73,0,0);
+       case AMULHDCC:  return OPVCC(31,73,0,1);
+       case AMULHDU:   return OPVCC(31,9,0,0);
+       case AMULHDUCC: return OPVCC(31,9,0,1);
+       case AMULLD:    return OPVCC(31,233,0,0);
+       case AMULLDCC:  return OPVCC(31,233,0,1);
+       case AMULLDV:   return OPVCC(31,233,1,0);
+       case AMULLDVCC: return OPVCC(31,233,1,1);
+
+       case ANAND:     return OPVCC(31,476,0,0);
+       case ANANDCC:   return OPVCC(31,476,0,1);
+       case ANEG:      return OPVCC(31,104,0,0);
+       case ANEGCC:    return OPVCC(31,104,0,1);
+       case ANEGV:     return OPVCC(31,104,1,0);
+       case ANEGVCC:   return OPVCC(31,104,1,1);
+       case ANOR:      return OPVCC(31,124,0,0);
+       case ANORCC:    return OPVCC(31,124,0,1);
+       case AOR:       return OPVCC(31,444,0,0);
+       case AORCC:     return OPVCC(31,444,0,1);
+       case AORN:      return OPVCC(31,412,0,0);
+       case AORNCC:    return OPVCC(31,412,0,1);
+
+       case ARFI:      return OPVCC(19,50,0,0);
+       case ARFCI:     return OPVCC(19,51,0,0);
+       case ARFID:     return OPVCC(19,18,0,0);
+       case AHRFID: return OPVCC(19,274,0,0);
+
+       case ARLWMI:    return OPVCC(20,0,0,0);
+       case ARLWMICC: return OPVCC(20,0,0,1);
+       case ARLWNM:    return OPVCC(23,0,0,0);
+       case ARLWNMCC:  return OPVCC(23,0,0,1);
+
+       case ARLDCL:    return OPVCC(30,8,0,0);
+       case ARLDCR:    return OPVCC(30,9,0,0);
+
+       case ASYSCALL:  return OPVCC(17,1,0,0);
+
+       case ASLW:      return OPVCC(31,24,0,0);
+       case ASLWCC:    return OPVCC(31,24,0,1);
+       case ASLD:      return OPVCC(31,27,0,0);
+       case ASLDCC:    return OPVCC(31,27,0,1);
+
+       case ASRAW:     return OPVCC(31,792,0,0);
+       case ASRAWCC:   return OPVCC(31,792,0,1);
+       case ASRAD:     return OPVCC(31,794,0,0);
+       case ASRADCC:   return OPVCC(31,794,0,1);
+
+       case ASRW:      return OPVCC(31,536,0,0);
+       case ASRWCC:    return OPVCC(31,536,0,1);
+       case ASRD:      return OPVCC(31,539,0,0);
+       case ASRDCC:    return OPVCC(31,539,0,1);
+
+       case ASUB:      return OPVCC(31,40,0,0);
+       case ASUBCC:    return OPVCC(31,40,0,1);
+       case ASUBV:     return OPVCC(31,40,1,0);
+       case ASUBVCC:   return OPVCC(31,40,1,1);
+       case ASUBC:     return OPVCC(31,8,0,0);
+       case ASUBCCC:   return OPVCC(31,8,0,1);
+       case ASUBCV:    return OPVCC(31,8,1,0);
+       case ASUBCVCC:  return OPVCC(31,8,1,1);
+       case ASUBE:     return OPVCC(31,136,0,0);
+       case ASUBECC:   return OPVCC(31,136,0,1);
+       case ASUBEV:    return OPVCC(31,136,1,0);
+       case ASUBEVCC:  return OPVCC(31,136,1,1);
+       case ASUBME:    return OPVCC(31,232,0,0);
+       case ASUBMECC:  return OPVCC(31,232,0,1);
+       case ASUBMEV:   return OPVCC(31,232,1,0);
+       case ASUBMEVCC: return OPVCC(31,232,1,1);
+       case ASUBZE:    return OPVCC(31,200,0,0);
+       case ASUBZECC:  return OPVCC(31,200,0,1);
+       case ASUBZEV:   return OPVCC(31,200,1,0);
+       case ASUBZEVCC: return OPVCC(31,200,1,1);
+
+       case ASYNC:     return OPVCC(31,598,0,0);
+       case APTESYNC:  return OPVCC(31,598,0,0) | (2<<21);
+
+       case ATLBIE:    return OPVCC(31,306,0,0);
+       case ATLBIEL:   return OPVCC(31,274,0,0);
+       case ATLBSYNC:  return OPVCC(31,566,0,0);
+       case ASLBIA:    return OPVCC(31,498,0,0);
+       case ASLBIE:    return OPVCC(31,434,0,0);
+       case ASLBMFEE:  return OPVCC(31,915,0,0);
+       case ASLBMFEV:  return OPVCC(31,851,0,0);
+       case ASLBMTE:           return OPVCC(31,402,0,0);
+
+       case ATW:       return OPVCC(31,4,0,0);
+       case ATD:       return OPVCC(31,68,0,0);
+
+       case AXOR:      return OPVCC(31,316,0,0);
+       case AXORCC:    return OPVCC(31,316,0,1);
+       }
+       ctxt->diag("bad r/r opcode %A", a);
+       return 0;
+}
+
+static int32
+opirr(Link *ctxt, int a)
+{
+       switch(a) {
+       case AADD:      return OPVCC(14,0,0,0);
+       case AADDC:     return OPVCC(12,0,0,0);
+       case AADDCCC:   return OPVCC(13,0,0,0);
+       case AADD+AEND: return OPVCC(15,0,0,0);         /* ADDIS/CAU */
+
+       case AANDCC:    return OPVCC(28,0,0,0);
+       case AANDCC+AEND:       return OPVCC(29,0,0,0);         /* ANDIS./ANDIU. */
+
+       case ABR:       return OPVCC(18,0,0,0);
+       case ABL:       return OPVCC(18,0,0,0) | 1;
+       case ADUFFZERO: return OPVCC(18,0,0,0) | 1;
+       case ADUFFCOPY: return OPVCC(18,0,0,0) | 1;
+       case ABC:       return OPVCC(16,0,0,0);
+       case ABCL:      return OPVCC(16,0,0,0) | 1;
+
+       case ABEQ:      return AOP_RRR(16<<26,12,2,0);
+       case ABGE:      return AOP_RRR(16<<26,4,0,0);
+       case ABGT:      return AOP_RRR(16<<26,12,1,0);
+       case ABLE:      return AOP_RRR(16<<26,4,1,0);
+       case ABLT:      return AOP_RRR(16<<26,12,0,0);
+       case ABNE:      return AOP_RRR(16<<26,4,2,0);
+       case ABVC:      return AOP_RRR(16<<26,4,3,0);
+       case ABVS:      return AOP_RRR(16<<26,12,3,0);
+
+       case ACMP:      return OPVCC(11,0,0,0)|(1<<21); /* L=1 */
+       case ACMPU:     return OPVCC(10,0,0,0)|(1<<21);
+       case ACMPW:     return OPVCC(11,0,0,0); /* L=0 */
+       case ACMPWU:    return OPVCC(10,0,0,0);
+       case ALSW:      return OPVCC(31,597,0,0);
+
+       case AMULLW:    return OPVCC(7,0,0,0);
+
+       case AOR:       return OPVCC(24,0,0,0);
+       case AOR+AEND:  return OPVCC(25,0,0,0);         /* ORIS/ORIU */
+
+       case ARLWMI:    return OPVCC(20,0,0,0);         /* rlwimi */
+       case ARLWMICC:  return OPVCC(20,0,0,1);
+       case ARLDMI:    return OPVCC(30,0,0,0) | (3<<2);        /* rldimi */
+       case ARLDMICC:  return OPVCC(30,0,0,1) | (3<<2);
+
+       case ARLWNM:    return OPVCC(21,0,0,0);         /* rlwinm */
+       case ARLWNMCC:  return OPVCC(21,0,0,1);
+
+       case ARLDCL:    return OPVCC(30,0,0,0);         /* rldicl */
+       case ARLDCLCC:  return OPVCC(30,0,0,1);
+       case ARLDCR:    return OPVCC(30,1,0,0);         /* rldicr */
+       case ARLDCRCC:  return OPVCC(30,1,0,1);
+       case ARLDC:     return OPVCC(30,0,0,0) | (2<<2);
+       case ARLDCCC:   return OPVCC(30,0,0,1) | (2<<2);
+
+       case ASRAW:     return OPVCC(31,824,0,0);
+       case ASRAWCC:   return OPVCC(31,824,0,1);
+       case ASRAD:     return OPVCC(31,(413<<1),0,0);
+       case ASRADCC:   return OPVCC(31,(413<<1),0,1);
+
+       case ASTSW:     return OPVCC(31,725,0,0);
+
+       case ASUBC:     return OPVCC(8,0,0,0);
+
+       case ATW:       return OPVCC(3,0,0,0);
+       case ATD:       return OPVCC(2,0,0,0);
+
+       case AXOR:      return OPVCC(26,0,0,0);         /* XORIL */
+       case AXOR+AEND: return OPVCC(27,0,0,0);         /* XORIU */
+       }
+       ctxt->diag("bad opcode i/r %A", a);
+       return 0;
+}
+
+/*
+ * load o(a),d
+ */
+static int32
+opload(Link *ctxt, int a)
+{
+       switch(a) {
+       case AMOVD:     return OPVCC(58,0,0,0); /* ld */
+       case AMOVDU:    return OPVCC(58,0,0,1); /* ldu */
+       case AMOVWZ:    return OPVCC(32,0,0,0);         /* lwz */
+       case AMOVWZU:   return OPVCC(33,0,0,0);         /* lwzu */
+       case AMOVW:             return OPVCC(58,0,0,0)|(1<<1);  /* lwa */
+       /* no AMOVWU */
+       case AMOVB:
+       case AMOVBZ:    return OPVCC(34,0,0,0);         /* load */
+       case AMOVBU:
+       case AMOVBZU:   return OPVCC(35,0,0,0);
+       case AFMOVD:    return OPVCC(50,0,0,0);
+       case AFMOVDU:   return OPVCC(51,0,0,0);
+       case AFMOVS:    return OPVCC(48,0,0,0);
+       case AFMOVSU:   return OPVCC(49,0,0,0);
+       case AMOVH:     return OPVCC(42,0,0,0);
+       case AMOVHU:    return OPVCC(43,0,0,0);
+       case AMOVHZ:    return OPVCC(40,0,0,0);
+       case AMOVHZU:   return OPVCC(41,0,0,0);
+       case AMOVMW:    return OPVCC(46,0,0,0); /* lmw */
+       }
+       ctxt->diag("bad load opcode %A", a);
+       return 0;
+}
+
+/*
+ * indexed load a(b),d
+ */
+static int32
+oploadx(Link *ctxt, int a)
+{
+       switch(a) {
+       case AMOVWZ: return OPVCC(31,23,0,0);   /* lwzx */
+       case AMOVWZU:   return OPVCC(31,55,0,0); /* lwzux */
+       case AMOVW:     return OPVCC(31,341,0,0);       /* lwax */
+       case AMOVWU:    return OPVCC(31,373,0,0);       /* lwaux */
+       case AMOVB:
+       case AMOVBZ: return OPVCC(31,87,0,0);   /* lbzx */
+       case AMOVBU:
+       case AMOVBZU: return OPVCC(31,119,0,0); /* lbzux */
+       case AFMOVD:    return OPVCC(31,599,0,0);       /* lfdx */
+       case AFMOVDU:   return OPVCC(31,631,0,0);       /*  lfdux */
+       case AFMOVS:    return OPVCC(31,535,0,0);       /* lfsx */
+       case AFMOVSU:   return OPVCC(31,567,0,0);       /* lfsux */
+       case AMOVH:     return OPVCC(31,343,0,0);       /* lhax */
+       case AMOVHU:    return OPVCC(31,375,0,0);       /* lhaux */
+       case AMOVHBR:   return OPVCC(31,790,0,0);       /* lhbrx */
+       case AMOVWBR:   return OPVCC(31,534,0,0);       /* lwbrx */
+       case AMOVHZ:    return OPVCC(31,279,0,0);       /* lhzx */
+       case AMOVHZU:   return OPVCC(31,311,0,0);       /* lhzux */
+       case AECIWX:    return OPVCC(31,310,0,0);       /* eciwx */
+       case ALWAR:     return OPVCC(31,20,0,0);        /* lwarx */
+       case ALDAR:     return OPVCC(31,84,0,0);
+       case ALSW:      return OPVCC(31,533,0,0);       /* lswx */
+       case AMOVD:     return OPVCC(31,21,0,0);        /* ldx */
+       case AMOVDU:    return OPVCC(31,53,0,0);        /* ldux */
+       }
+       ctxt->diag("bad loadx opcode %A", a);
+       return 0;
+}
+
+/*
+ * store s,o(d)
+ */
+static int32
+opstore(Link *ctxt, int a)
+{
+       switch(a) {
+       case AMOVB:
+       case AMOVBZ:    return OPVCC(38,0,0,0); /* stb */
+       case AMOVBU:
+       case AMOVBZU:   return OPVCC(39,0,0,0); /* stbu */
+       case AFMOVD:    return OPVCC(54,0,0,0); /* stfd */
+       case AFMOVDU:   return OPVCC(55,0,0,0); /* stfdu */
+       case AFMOVS:    return OPVCC(52,0,0,0); /* stfs */
+       case AFMOVSU:   return OPVCC(53,0,0,0); /* stfsu */
+       case AMOVHZ:
+       case AMOVH:     return OPVCC(44,0,0,0); /* sth */
+       case AMOVHZU:
+       case AMOVHU:    return OPVCC(45,0,0,0); /* sthu */
+       case AMOVMW:    return OPVCC(47,0,0,0); /* stmw */
+       case ASTSW:     return OPVCC(31,725,0,0);       /* stswi */
+       case AMOVWZ:
+       case AMOVW:     return OPVCC(36,0,0,0); /* stw */
+       case AMOVWZU:
+       case AMOVWU:    return OPVCC(37,0,0,0); /* stwu */
+       case AMOVD:     return OPVCC(62,0,0,0); /* std */
+       case AMOVDU:    return OPVCC(62,0,0,1); /* stdu */
+       }
+       ctxt->diag("unknown store opcode %A", a);
+       return 0;
+}
+
+/*
+ * indexed store s,a(b)
+ */
+static int32
+opstorex(Link *ctxt, int a)
+{
+       switch(a) {
+       case AMOVB:
+       case AMOVBZ:    return OPVCC(31,215,0,0);       /* stbx */
+       case AMOVBU:
+       case AMOVBZU:   return OPVCC(31,247,0,0);       /* stbux */
+       case AFMOVD:    return OPVCC(31,727,0,0);       /* stfdx */
+       case AFMOVDU:   return OPVCC(31,759,0,0);       /* stfdux */
+       case AFMOVS:    return OPVCC(31,663,0,0);       /* stfsx */
+       case AFMOVSU:   return OPVCC(31,695,0,0);       /* stfsux */
+       case AMOVHZ:
+       case AMOVH:     return OPVCC(31,407,0,0);       /* sthx */
+       case AMOVHBR:   return OPVCC(31,918,0,0);       /* sthbrx */
+       case AMOVHZU:
+       case AMOVHU:    return OPVCC(31,439,0,0);       /* sthux */
+       case AMOVWZ:
+       case AMOVW:     return OPVCC(31,151,0,0);       /* stwx */
+       case AMOVWZU:
+       case AMOVWU:    return OPVCC(31,183,0,0);       /* stwux */
+       case ASTSW:     return OPVCC(31,661,0,0);       /* stswx */
+       case AMOVWBR:   return OPVCC(31,662,0,0);       /* stwbrx */
+       case ASTWCCC:   return OPVCC(31,150,0,1);       /* stwcx. */
+       case ASTDCCC:   return OPVCC(31,214,0,1);       /* stwdx. */
+       case AECOWX:    return OPVCC(31,438,0,0);       /* ecowx */
+       case AMOVD:     return OPVCC(31,149,0,0);       /* stdx */
+       case AMOVDU:    return OPVCC(31,181,0,0);       /* stdux */
+       }
+       ctxt->diag("unknown storex opcode %A", a);
+       return 0;
+}
+
diff --git a/src/liblink/list9.c b/src/liblink/list9.c
new file mode 100644 (file)
index 0000000..041c688
--- /dev/null
@@ -0,0 +1,409 @@
+// cmd/9l/list.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.
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <link.h>
+#include "../cmd/9l/9.out.h"
+
+enum
+{
+       STRINGSZ        = 1000,
+};
+
+static int     Aconv(Fmt*);
+static int     Dconv(Fmt*);
+static int     Pconv(Fmt*);
+static int     Rconv(Fmt*);
+static int     DSconv(Fmt*);
+static int     Mconv(Fmt*);
+static int     DRconv(Fmt*);
+
+//
+// Format conversions
+//     %A int          Opcodes (instruction mnemonics)
+//
+//     %D Addr*        Addresses (instruction operands)
+//             Flags: "%lD": seperate the high and low words of a constant by "-"
+//
+//     %P Prog*        Instructions
+//
+//     %R int          Registers
+//
+//     %$ char*        String constant addresses (for internal use only)
+//     %^ int          C_* classes (for liblink internal use)
+
+#pragma        varargck        type    "$"     char*
+#pragma        varargck        type    "M"     Addr*
+
+void
+listinit9(void)
+{
+       fmtinstall('A', Aconv);
+       fmtinstall('D', Dconv);
+       fmtinstall('P', Pconv);
+       fmtinstall('R', Rconv);
+
+       // for liblink internal use
+       fmtinstall('^', DRconv);
+
+       // for internal use
+       fmtinstall('$', DSconv);
+       fmtinstall('M', Mconv);
+}
+
+static Prog*   bigP;
+
+static int
+Pconv(Fmt *fp)
+{
+       char str[STRINGSZ], *s;
+       Prog *p;
+       int a;
+
+       p = va_arg(fp->args, Prog*);
+       bigP = p;
+       a = p->as;
+       if(a == ADATA || a == AINIT || a == ADYNT)
+               sprint(str, "%.5lld (%L)        %A      %D/%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
+       else if(a == ATEXT) {
+               if(p->reg != 0)
+                       sprint(str, "%.5lld (%L)        %A      %D,%d,%lD", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
+               else
+                       sprint(str, "%.5lld (%L)        %A      %D,%lD", p->pc, p->lineno, a, &p->from, &p->to);
+       } else if(a == AGLOBL) {
+               if(p->reg != 0)
+                       sprint(str, "%.5lld (%L)        %A      %D,%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
+               else
+                       sprint(str, "%.5lld (%L)        %A      %D,%D", p->pc, p->lineno, a, &p->from, &p->to);
+       } else {
+               s = str;
+               if(p->mark & NOSCHED)
+                       s += sprint(s, "*");
+               if(p->reg == NREG && p->from3.type == D_NONE)
+                       sprint(s, "%.5lld (%L)  %A      %D,%D", p->pc, p->lineno, a, &p->from, &p->to);
+               else
+               if(a != ATEXT && p->from.type == D_OREG) {
+                       sprint(s, "%.5lld (%L)  %A      %lld(R%d+R%d),%D", p->pc, p->lineno, a,
+                               p->from.offset, p->from.reg, p->reg, &p->to);
+               } else
+               if(p->to.type == D_OREG) {
+                       sprint(s, "%.5lld (%L)  %A      %D,%lld(R%d+R%d)", p->pc, p->lineno, a,
+                                       &p->from, p->to.offset, p->to.reg, p->reg);
+               } else {
+                       s += sprint(s, "%.5lld (%L)     %A      %D", p->pc, p->lineno, a, &p->from);
+                       if(p->reg != NREG)
+                               s += sprint(s, ",%c%d", p->from.type==D_FREG?'F':'R', p->reg);
+                       if(p->from3.type != D_NONE)
+                               s += sprint(s, ",%D", &p->from3);
+                       sprint(s, ",%D", &p->to);
+               }
+               if(p->spadj != 0)
+                       return fmtprint(fp, "%s # spadj=%d", str, p->spadj);
+       }
+       return fmtstrcpy(fp, str);
+}
+
+static int
+Aconv(Fmt *fp)
+{
+       char *s;
+       int a;
+
+       a = va_arg(fp->args, int);
+       s = "???";
+       if(a >= AXXX && a < ALAST)
+               s = anames9[a];
+       return fmtstrcpy(fp, s);
+}
+
+static int
+Dconv(Fmt *fp)
+{
+       char str[STRINGSZ];
+       Addr *a;
+       int32 v;
+
+       a = va_arg(fp->args, Addr*);
+
+       if(fp->flags & FmtLong) {
+               if(a->type == D_CONST)
+                       sprint(str, "$%d-%d", (int32)a->offset, (int32)(a->offset>>32));
+               else {
+                       // ATEXT dst is not constant
+                       sprint(str, "!!%D", a);
+               }
+               goto ret;
+       }
+
+       switch(a->type) {
+       default:
+               sprint(str, "GOK-type(%d)", a->type);
+               break;
+
+       case D_NONE:
+               str[0] = 0;
+               if(a->name != D_NONE || a->reg != NREG || a->sym != nil)
+                       sprint(str, "%M(R%d)(NONE)", a, a->reg);
+               break;
+
+       case D_CONST:
+       case D_DCONST:
+               if(a->reg != NREG)
+                       sprint(str, "$%M(R%d)", a, a->reg);
+               else
+                       sprint(str, "$%M", a);
+               break;
+
+       case D_OREG:
+               if(a->reg != NREG)
+                       sprint(str, "%M(R%d)", a, a->reg);
+               else
+                       sprint(str, "%M", a);
+               break;
+
+       case D_REG:
+               sprint(str, "R%d", a->reg);
+               if(a->name != D_NONE || a->sym != nil)
+                       sprint(str, "%M(R%d)(REG)", a, a->reg);
+               break;
+
+       case D_FREG:
+               sprint(str, "F%d", a->reg);
+               if(a->name != D_NONE || a->sym != nil)
+                       sprint(str, "%M(F%d)(REG)", a, a->reg);
+               break;
+
+       case D_CREG:
+               if(a->reg == NREG)
+                       strcpy(str, "CR");
+               else
+                       sprint(str, "CR%d", a->reg);
+               if(a->name != D_NONE || a->sym != nil)
+                       sprint(str, "%M(C%d)(REG)", a, a->reg);
+               break;
+
+       case D_SPR:
+               if(a->name == D_NONE && a->sym == nil) {
+                       switch((ulong)a->offset) {
+                       case D_XER: sprint(str, "XER"); break;
+                       case D_LR: sprint(str, "LR"); break;
+                       case D_CTR: sprint(str, "CTR"); break;
+                       default: sprint(str, "SPR(%lld)", a->offset); break;
+                       }
+                       break;
+               }
+               sprint(str, "SPR-GOK(%d)", a->reg);
+               if(a->name != D_NONE || a->sym != nil)
+                       sprint(str, "%M(SPR-GOK%d)(REG)", a, a->reg);
+               break;
+
+       case D_DCR:
+               if(a->name == D_NONE && a->sym == nil) {
+                       sprint(str, "DCR(%lld)", a->offset);
+                       break;
+               }
+               sprint(str, "DCR-GOK(%d)", a->reg);
+               if(a->name != D_NONE || a->sym != nil)
+                       sprint(str, "%M(DCR-GOK%d)(REG)", a, a->reg);
+               break;
+
+       case D_OPT:
+               sprint(str, "OPT(%d)", a->reg);
+               break;
+
+       case D_FPSCR:
+               if(a->reg == NREG)
+                       strcpy(str, "FPSCR");
+               else
+                       sprint(str, "FPSCR(%d)", a->reg);
+               break;
+
+       case D_MSR:
+               sprint(str, "MSR");
+               break;
+
+       case D_BRANCH:
+               if(bigP->pcond != nil) {
+                       v = bigP->pcond->pc;
+                       //if(v >= INITTEXT)
+                       //      v -= INITTEXT-HEADR;
+                       if(a->sym != nil)
+                               sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
+                       else
+                               sprint(str, "%.5lux(BRANCH)", v);
+               } else
+                       if(a->sym != nil)
+                               sprint(str, "%s+%lld(APC)", a->sym->name, a->offset);
+                       else
+                               sprint(str, "%lld(APC)", a->offset);
+               break;
+
+       case D_FCONST:
+               //sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
+               sprint(str, "$%.17g", a->u.dval);
+               break;
+
+       case D_SCONST:
+               sprint(str, "$\"%$\"", a->u.sval);
+               break;
+       }
+
+ret:
+       return fmtstrcpy(fp, str);
+}
+
+static int
+Mconv(Fmt *fp)
+{
+       char str[STRINGSZ];
+       Addr *a;
+       LSym *s;
+       int32 l;
+
+       a = va_arg(fp->args, Addr*);
+       s = a->sym;
+       //if(s == nil) {
+       //      l = a->offset;
+       //      if((vlong)l != a->offset)
+       //              sprint(str, "0x%llux", a->offset);
+       //      else
+       //              sprint(str, "%lld", a->offset);
+       //      goto out;
+       //}
+       switch(a->name) {
+       default:
+               sprint(str, "GOK-name(%d)", a->name);
+               break;
+
+       case D_NONE:
+               l = a->offset;
+               if((vlong)l != a->offset)
+                       sprint(str, "0x%llux", a->offset);
+               else
+                       sprint(str, "%lld", a->offset);
+               break;
+
+       case D_EXTERN:
+               if(a->offset != 0)
+                       sprint(str, "%s+%lld(SB)", s->name, a->offset);
+               else
+                       sprint(str, "%s(SB)", s->name, a->offset);
+               break;
+
+       case D_STATIC:
+               sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
+               break;
+
+       case D_AUTO:
+               if(s == nil)
+                       sprint(str, "%lld(SP)", -a->offset);
+               else
+                       sprint(str, "%s-%lld(SP)", s->name, -a->offset);
+               break;
+
+       case D_PARAM:
+               if(s == nil)
+                       sprint(str, "%lld(FP)", a->offset);
+               else
+                       sprint(str, "%s+%lld(FP)", s->name, a->offset);
+               break;
+       }
+//out:
+       return fmtstrcpy(fp, str);
+}
+
+static int
+Rconv(Fmt *fp)
+{
+       char str[STRINGSZ];
+       int r;
+
+       r = va_arg(fp->args, int);
+       if(r < NREG)
+               sprint(str, "r%d", r);
+       else
+               sprint(str, "f%d", r-NREG);
+       return fmtstrcpy(fp, str);
+}
+
+static int
+DRconv(Fmt *fp)
+{
+       char *s;
+       int a;
+
+       a = va_arg(fp->args, int);
+       s = "C_??";
+       if(a >= C_NONE && a <= C_NCLASS)
+               s = cnames9[a];
+       return fmtstrcpy(fp, s);
+}
+
+static int
+DSconv(Fmt *fp)
+{
+       int i, c;
+       char str[STRINGSZ], *p, *a;
+
+       a = va_arg(fp->args, char*);
+       p = str;
+       for(i=0; i<sizeof(int32); i++) {
+               c = a[i] & 0xff;
+               if(c >= 'a' && c <= 'z' ||
+                  c >= 'A' && c <= 'Z' ||
+                  c >= '0' && c <= '9' ||
+                  c == ' ' || c == '%') {
+                       *p++ = c;
+                       continue;
+               }
+               *p++ = '\\';
+               switch(c) {
+               case 0:
+                       *p++ = 'z';
+                       continue;
+               case '\\':
+               case '"':
+                       *p++ = c;
+                       continue;
+               case '\n':
+                       *p++ = 'n';
+                       continue;
+               case '\t':
+                       *p++ = 't';
+                       continue;
+               }
+               *p++ = (c>>6) + '0';
+               *p++ = ((c>>3) & 7) + '0';
+               *p++ = (c & 7) + '0';
+       }
+       *p = 0;
+       return fmtstrcpy(fp, str);
+}
diff --git a/src/liblink/obj9.c b/src/liblink/obj9.c
new file mode 100644 (file)
index 0000000..0bae64d
--- /dev/null
@@ -0,0 +1,1086 @@
+// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.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.
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <link.h>
+#include "../cmd/9l/9.out.h"
+#include "../runtime/stack.h"
+#include "../runtime/funcdata.h"
+
+static Prog zprg = {
+       .as = AGOK,
+       .reg = NREG,
+       .from = {
+               .name = D_NONE,
+               .type = D_NONE,
+               .reg = NREG,
+       },
+       .from3 = {
+               .name = D_NONE,
+               .type = D_NONE,
+               .reg = NREG,
+       },
+       .to = {
+               .name = D_NONE,
+               .type = D_NONE,
+               .reg = NREG,
+       },
+};
+
+static int
+symtype(Addr *a)
+{
+       return a->name;
+}
+
+static int
+isdata(Prog *p)
+{
+       return p->as == ADATA || p->as == AGLOBL;
+}
+
+static int
+iscall(Prog *p)
+{
+       return p->as == ABL;
+}
+
+static int
+datasize(Prog *p)
+{
+       return p->reg;
+}
+
+static int
+textflag(Prog *p)
+{
+       return p->reg;
+}
+
+static void
+settextflag(Prog *p, int f)
+{
+       p->reg = f;
+}
+
+static void
+progedit(Link *ctxt, Prog *p)
+{
+       char literal[64];
+       LSym *s;
+
+       USED(ctxt);
+
+       p->from.class = 0;
+       p->to.class = 0;
+
+       // Rewrite BR/BL to symbol as D_BRANCH.
+       switch(p->as) {
+       case ABR:
+       case ABL:
+       case ARETURN:
+       case ADUFFZERO:
+       case ADUFFCOPY:
+               if(p->to.sym != nil)
+                       p->to.type = D_BRANCH;
+               break;
+       }
+
+       // Rewrite float constants to values stored in memory.
+       switch(p->as) {
+       case AFMOVS:
+               if(p->from.type == D_FCONST) {
+                       int32 i32;
+                       float32 f32;
+                       f32 = p->from.u.dval;
+                       memmove(&i32, &f32, 4);
+                       sprint(literal, "$f32.%08ux", (uint32)i32);
+                       s = linklookup(ctxt, literal, 0);
+                       s->size = 4;
+                       p->from.type = D_OREG;
+                       p->from.sym = s;
+                       p->from.name = D_EXTERN;
+                       p->from.offset = 0;
+               }
+               break;
+       case AFMOVD:
+               if(p->from.type == D_FCONST) {
+                       int64 i64;
+                       memmove(&i64, &p->from.u.dval, 8);
+                       sprint(literal, "$f64.%016llux", (uvlong)i64);
+                       s = linklookup(ctxt, literal, 0);
+                       s->size = 8;
+                       p->from.type = D_OREG;
+                       p->from.sym = s;
+                       p->from.name = D_EXTERN;
+                       p->from.offset = 0;
+               }
+               break;
+       case AMOVD:
+               if(p->from.type == D_CONST && p->from.name == D_NONE && (int64)(uint32)p->from.offset != p->from.offset) {
+                       sprint(literal, "$i64.%016llux", (uvlong)p->from.offset);
+                       s = linklookup(ctxt, literal, 0);
+                       s->size = 8;
+                       p->from.type = D_OREG;
+                       p->from.sym = s;
+                       p->from.name = D_EXTERN;
+                       p->from.offset = 0;
+               }
+       }
+
+       // Rewrite SUB constants into ADD.
+       switch(p->as) {
+       case ASUBC:
+               if(p->from.type == D_CONST) {
+                       p->from.offset = -p->from.offset;
+                       p->as = AADDC;
+               }
+               break;
+
+       case ASUBCCC:
+               if(p->from.type == D_CONST) {
+                       p->from.offset = -p->from.offset;
+                       p->as = AADDCCC;
+               }
+               break;
+
+       case ASUB:
+               if(p->from.type == D_CONST) {
+                       p->from.offset = -p->from.offset;
+                       p->as = AADD;
+               }
+               break;
+       }
+}
+
+static Prog*   stacksplit(Link*, Prog*, int32, int);
+
+static void
+parsetextconst(vlong arg, vlong *textstksiz, vlong *textarg)
+{
+       *textstksiz = arg & 0xffffffffLL;
+       if(*textstksiz & 0x80000000LL)
+               *textstksiz = -(-*textstksiz & 0xffffffffLL);
+
+       *textarg = (arg >> 32) & 0xffffffffLL;
+       if(*textarg & 0x80000000LL)
+               *textarg = 0;
+       *textarg = (*textarg+7) & ~7LL;
+}
+
+static void
+addstacksplit(Link *ctxt, LSym *cursym)
+{
+       Prog *p, *q, *p1, *p2, *q1;
+       int o, mov, aoffset;
+       vlong textstksiz, textarg;
+       int32 autoffset, autosize;
+
+       if(ctxt->symmorestack[0] == nil) {
+               ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
+               ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
+               // TODO(minux): add morestack short-cuts with small fixed frame-size.
+       }
+
+       ctxt->cursym = cursym;
+
+       if(cursym->text == nil || cursym->text->link == nil)
+               return;                         
+
+       p = cursym->text;
+       parsetextconst(p->to.offset, &textstksiz, &textarg);
+       autoffset = textstksiz;
+       if(autoffset < 0)
+               autoffset = 0;
+       
+       cursym->args = p->to.offset>>32;
+       cursym->locals = textstksiz;
+
+       /*
+        * find leaf subroutines
+        * strip NOPs
+        * expand RET
+        * expand BECOME pseudo
+        */
+
+       if(ctxt->debugvlog)
+               Bprint(ctxt->bso, "%5.2f noops\n", cputime());
+       Bflush(ctxt->bso);
+
+       q = nil;
+       for(p = cursym->text; p != nil; p = p->link) {
+               switch(p->as) {
+               /* too hard, just leave alone */
+               case ATEXT:
+                       q = p;
+                       p->mark |= LABEL|LEAF|SYNC;
+                       if(p->link)
+                               p->link->mark |= LABEL;
+                       break;
+
+               case ANOR:
+                       q = p;
+                       if(p->to.type == D_REG)
+                               if(p->to.reg == REGZERO)
+                                       p->mark |= LABEL|SYNC;
+                       break;
+
+               case ALWAR:
+               case ASTWCCC:
+               case AECIWX:
+               case AECOWX:
+               case AEIEIO:
+               case AICBI:
+               case AISYNC:
+               case ATLBIE:
+               case ATLBIEL:
+               case ASLBIA:
+               case ASLBIE:
+               case ASLBMFEE:
+               case ASLBMFEV:
+               case ASLBMTE:
+               case ADCBF:
+               case ADCBI:
+               case ADCBST:
+               case ADCBT:
+               case ADCBTST:
+               case ADCBZ:
+               case ASYNC:
+               case ATLBSYNC:
+               case APTESYNC:
+               case ATW:
+               case AWORD:
+               case ARFI:
+               case ARFCI:
+               case ARFID:
+               case AHRFID:
+                       q = p;
+                       p->mark |= LABEL|SYNC;
+                       continue;
+
+               case AMOVW:
+               case AMOVWZ:
+               case AMOVD:
+                       q = p;
+                       switch(p->from.type) {
+                       case D_MSR:
+                       case D_SPR:
+                       case D_FPSCR:
+                       case D_CREG:
+                       case D_DCR:
+                               p->mark |= LABEL|SYNC;
+                       }
+                       switch(p->to.type) {
+                       case D_MSR:
+                       case D_SPR:
+                       case D_FPSCR:
+                       case D_CREG:
+                       case D_DCR:
+                               p->mark |= LABEL|SYNC;
+                       }
+                       continue;
+
+               case AFABS:
+               case AFABSCC:
+               case AFADD:
+               case AFADDCC:
+               case AFCTIW:
+               case AFCTIWCC:
+               case AFCTIWZ:
+               case AFCTIWZCC:
+               case AFDIV:
+               case AFDIVCC:
+               case AFMADD:
+               case AFMADDCC:
+               case AFMOVD:
+               case AFMOVDU:
+               /* case AFMOVDS: */
+               case AFMOVS:
+               case AFMOVSU:
+               /* case AFMOVSD: */
+               case AFMSUB:
+               case AFMSUBCC:
+               case AFMUL:
+               case AFMULCC:
+               case AFNABS:
+               case AFNABSCC:
+               case AFNEG:
+               case AFNEGCC:
+               case AFNMADD:
+               case AFNMADDCC:
+               case AFNMSUB:
+               case AFNMSUBCC:
+               case AFRSP:
+               case AFRSPCC:
+               case AFSUB:
+               case AFSUBCC:
+                       q = p;
+                       p->mark |= FLOAT;
+                       continue;
+
+               case ABL:
+               case ABCL:
+               case ADUFFZERO:
+               case ADUFFCOPY:
+                       cursym->text->mark &= ~LEAF;
+
+               case ABC:
+               case ABEQ:
+               case ABGE:
+               case ABGT:
+               case ABLE:
+               case ABLT:
+               case ABNE:
+               case ABR:
+               case ABVC:
+               case ABVS:
+                       p->mark |= BRANCH;
+                       q = p;
+                       q1 = p->pcond;
+                       if(q1 != nil) {
+                               while(q1->as == ANOP) {
+                                       q1 = q1->link;
+                                       p->pcond = q1;
+                               }
+                               if(!(q1->mark & LEAF))
+                                       q1->mark |= LABEL;
+                       } else
+                               p->mark |= LABEL;
+                       q1 = p->link;
+                       if(q1 != nil)
+                               q1->mark |= LABEL;
+                       continue;
+
+               case AFCMPO:
+               case AFCMPU:
+                       q = p;
+                       p->mark |= FCMP|FLOAT;
+                       continue;
+
+               case ARETURN:
+                       q = p;
+                       if(p->link != nil)
+                               p->link->mark |= LABEL;
+                       continue;
+
+               case ANOP:
+                       q1 = p->link;
+                       q->link = q1;           /* q is non-nop */
+                       q1->mark |= p->mark;
+                       continue;
+
+               default:
+                       q = p;
+                       continue;
+               }
+       }
+
+       autosize = 0;
+       for(p = cursym->text; p != nil; p = p->link) {
+               o = p->as;
+               switch(o) {
+               case ATEXT:
+                       mov = AMOVD;
+                       aoffset = 0;
+                       autosize = textstksiz + 8;
+                       if((p->mark & LEAF) && autosize <= 8)
+                               autosize = 0;
+                       else
+                               if(autosize & 4)
+                                       autosize += 4;
+                       p->to.offset = (p->to.offset & (0xffffffffull<<32)) | (uint32)(autosize-8);
+
+                       if(!(p->reg & NOSPLIT))
+                               p = stacksplit(ctxt, p, autosize, !(cursym->text->reg&NEEDCTXT)); // emit split check
+
+                       q = p;
+                       if(autosize) {
+                               /* use MOVDU to adjust R1 when saving R31, if autosize is small */
+                               if(!(cursym->text->mark & LEAF) && autosize >= -BIG && autosize <= BIG) {
+                                       mov = AMOVDU;
+                                       aoffset = -autosize;
+                               } else {
+                                       q = appendp(ctxt, p);
+                                       q->as = AADD;
+                                       q->lineno = p->lineno;
+                                       q->from.type = D_CONST;
+                                       q->from.offset = -autosize;
+                                       q->to.type = D_REG;
+                                       q->to.reg = REGSP;
+                                       q->spadj = +autosize;
+                               }
+                       } else
+                       if(!(cursym->text->mark & LEAF)) {
+                               if(ctxt->debugvlog) {
+                                       Bprint(ctxt->bso, "save suppressed in: %s\n",
+                                               cursym->name);
+                                       Bflush(ctxt->bso);
+                               }
+                               cursym->text->mark |= LEAF;
+                       }
+
+                       if(cursym->text->mark & LEAF) {
+                               cursym->leaf = 1;
+                               break;
+                       }
+
+                       q = appendp(ctxt, q);
+                       q->as = AMOVD;
+                       q->lineno = p->lineno;
+                       q->from.type = D_SPR;
+                       q->from.offset = D_LR;
+                       q->to.type = D_REG;
+                       q->to.reg = REGTMP;
+
+                       q = appendp(ctxt, q);
+                       q->as = mov;
+                       q->lineno = p->lineno;
+                       q->from.type = D_REG;
+                       q->from.reg = REGTMP;
+                       q->to.type = D_OREG;
+                       q->to.offset = aoffset;
+                       q->to.reg = REGSP;
+                       if(q->as == AMOVDU)
+                               q->spadj = -aoffset;
+
+                       if(cursym->text->reg & WRAPPER) {
+                               // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
+                               //
+                               //      MOVD g_panic(g), R3
+                               //      CMP R0, R3
+                               //      BEQ end
+                               //      MOVD panic_argp(R3), R4
+                               //      ADD $(autosize+8), R1, R5
+                               //      CMP R4, R5
+                               //      BNE end
+                               //      ADD $8, R1, R6
+                               //      MOVD R6, panic_argp(R3)
+                               // end:
+                               //      NOP
+                               //
+                               // The NOP is needed to give the jumps somewhere to land.
+                               // It is a liblink NOP, not a Power64 NOP: it encodes to 0 instruction bytes.
+
+
+                               q = appendp(ctxt, q);
+                               q->as = AMOVD;
+                               q->from.type = D_OREG;
+                               q->from.reg = REGG;
+                               q->from.offset = 4*ctxt->arch->ptrsize; // G.panic
+                               q->to.type = D_REG;
+                               q->to.reg = 3;
+
+                               q = appendp(ctxt, q);
+                               q->as = ACMP;
+                               q->from.type = D_REG;
+                               q->from.reg = 0;
+                               q->to.type = D_REG;
+                               q->to.reg = 3;
+
+                               q = appendp(ctxt, q);
+                               q->as = ABEQ;
+                               q->to.type = D_BRANCH;
+                               p1 = q;
+
+                               q = appendp(ctxt, q);
+                               q->as = AMOVD;
+                               q->from.type = D_OREG;
+                               q->from.reg = 3;
+                               q->from.offset = 0; // Panic.argp
+                               q->to.type = D_REG;
+                               q->to.reg = 4;
+
+                               q = appendp(ctxt, q);
+                               q->as = AADD;
+                               q->from.type = D_CONST;
+                               q->from.offset = autosize+8;
+                               q->reg = REGSP;
+                               q->to.type = D_REG;
+                               q->to.reg = 5;
+
+                               q = appendp(ctxt, q);
+                               q->as = ACMP;
+                               q->from.type = D_REG;
+                               q->from.reg = 4;
+                               q->to.type = D_REG;
+                               q->to.reg = 5;
+
+                               q = appendp(ctxt, q);
+                               q->as = ABNE;
+                               q->to.type = D_BRANCH;
+                               p2 = q;
+
+                               q = appendp(ctxt, q);
+                               q->as = AADD;
+                               q->from.type = D_CONST;
+                               q->from.offset = 8;
+                               q->reg = REGSP;
+                               q->to.type = D_REG;
+                               q->to.reg = 6;
+
+                               q = appendp(ctxt, q);
+                               q->as = AMOVD;
+                               q->from.type = D_REG;
+                               q->from.reg = 6;
+                               q->to.type = D_OREG;
+                               q->to.reg = 3;
+                               q->to.offset = 0; // Panic.argp
+
+                               q = appendp(ctxt, q);
+                               q->as = ANOP;
+                               p1->pcond = q;
+                               p2->pcond = q;
+                       }
+
+                       break;
+
+               case ARETURN:
+                       if(p->from.type == D_CONST) {
+                               ctxt->diag("using BECOME (%P) is not supported!", p);
+                               break;
+                       }
+                       if(p->to.sym) { // retjmp
+                               p->as = ABR;
+                               p->to.type = D_BRANCH;
+                               break;
+                       }
+                       if(cursym->text->mark & LEAF) {
+                               if(!autosize) {
+                                       p->as = ABR;
+                                       p->from = zprg.from;
+                                       p->to.type = D_SPR;
+                                       p->to.offset = D_LR;
+                                       p->mark |= BRANCH;
+                                       break;
+                               }
+
+                               p->as = AADD;
+                               p->from.type = D_CONST;
+                               p->from.offset = autosize;
+                               p->to.type = D_REG;
+                               p->to.reg = REGSP;
+                               p->spadj = -autosize;
+
+                               q = ctxt->arch->prg();
+                               q->as = ABR;
+                               q->lineno = p->lineno;
+                               q->to.type = D_SPR;
+                               q->to.offset = D_LR;
+                               q->mark |= BRANCH;
+                               q->spadj = +autosize;
+
+                               q->link = p->link;
+                               p->link = q;
+                               break;
+                       }
+
+                       p->as = AMOVD;
+                       p->from.type = D_OREG;
+                       p->from.offset = 0;
+                       p->from.reg = REGSP;
+                       p->to.type = D_REG;
+                       p->to.reg = REGTMP;
+
+                       q = ctxt->arch->prg();
+                       q->as = AMOVD;
+                       q->lineno = p->lineno;
+                       q->from.type = D_REG;
+                       q->from.reg = REGTMP;
+                       q->to.type = D_SPR;
+                       q->to.offset = D_LR;
+
+                       q->link = p->link;
+                       p->link = q;
+                       p = q;
+
+                       if(autosize) {
+                               q = ctxt->arch->prg();
+                               q->as = AADD;
+                               q->lineno = p->lineno;
+                               q->from.type = D_CONST;
+                               q->from.offset = autosize;
+                               q->to.type = D_REG;
+                               q->to.reg = REGSP;
+                               q->spadj = -autosize;
+
+                               q->link = p->link;
+                               p->link = q;
+                       }
+
+                       q1 = ctxt->arch->prg();
+                       q1->as = ABR;
+                       q1->lineno = p->lineno;
+                       q1->to.type = D_SPR;
+                       q1->to.offset = D_LR;
+                       q1->mark |= BRANCH;
+                       q1->spadj = +autosize;
+
+                       q1->link = q->link;
+                       q->link = q1;
+                       break;
+
+               case AADD:
+                       if(p->to.type == D_REG && p->to.reg == REGSP && p->from.type == D_CONST)
+                               p->spadj = -p->from.offset;
+                       break;
+               }
+       }
+
+#if 0 // instruction scheduling
+       if(debug['Q'] == 0)
+               return;
+
+       curtext = nil;
+       q = nil;        /* p - 1 */
+       q1 = firstp;    /* top of block */
+       o = 0;          /* count of instructions */
+       for(p = firstp; p != nil; p = p1) {
+               p1 = p->link;
+               o++;
+               if(p->mark & NOSCHED){
+                       if(q1 != p){
+                               sched(q1, q);
+                       }
+                       for(; p != nil; p = p->link){
+                               if(!(p->mark & NOSCHED))
+                                       break;
+                               q = p;
+                       }
+                       p1 = p;
+                       q1 = p;
+                       o = 0;
+                       continue;
+               }
+               if(p->mark & (LABEL|SYNC)) {
+                       if(q1 != p)
+                               sched(q1, q);
+                       q1 = p;
+                       o = 1;
+               }
+               if(p->mark & (BRANCH|SYNC)) {
+                       sched(q1, p);
+                       q1 = p1;
+                       o = 0;
+               }
+               if(o >= NSCHED) {
+                       sched(q1, p);
+                       q1 = p1;
+                       o = 0;
+               }
+               q = p;
+       }
+#endif
+}
+
+static Prog*
+stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
+{
+       Prog *q, *q1;
+
+       // MOVD g_stackguard(g), R3
+       p = appendp(ctxt, p);
+       p->as = AMOVD;
+       p->from.type = D_OREG;
+       p->from.reg = REGG;
+       p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0
+       if(ctxt->cursym->cfunc)
+               p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1
+       p->to.type = D_REG;
+       p->to.reg = 3;
+
+       q = nil;
+       if(framesize <= StackSmall) {
+               // small stack: SP < stackguard
+               //      CMP     stackguard, SP
+               p = appendp(ctxt, p);
+               p->as = ACMPU;
+               p->from.type = D_REG;
+               p->from.reg = 3;
+               p->to.type = D_REG;
+               p->to.reg = REGSP;
+       } else if(framesize <= StackBig) {
+               // large stack: SP-framesize < stackguard-StackSmall
+               //      ADD $-framesize, SP, R4
+               //      CMP stackguard, R4
+               p = appendp(ctxt, p);
+               p->as = AADD;
+               p->from.type = D_CONST;
+               p->from.offset = -framesize;
+               p->reg = REGSP;
+               p->to.type = D_REG;
+               p->to.reg = 4;
+
+               p = appendp(ctxt, p);
+               p->as = ACMPU;
+               p->from.type = D_REG;
+               p->from.reg = 3;
+               p->to.type = D_REG;
+               p->to.reg = 4;
+       } else {
+               // Such a large stack we need to protect against wraparound.
+               // If SP is close to zero:
+               //      SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
+               // The +StackGuard on both sides is required to keep the left side positive:
+               // SP is allowed to be slightly below stackguard. See stack.h.
+               //
+               // Preemption sets stackguard to StackPreempt, a very large value.
+               // That breaks the math above, so we have to check for that explicitly.
+               //      // stackguard is R3
+               //      CMP     R3, $StackPreempt
+               //      BEQ     label-of-call-to-morestack
+               //      ADD     $StackGuard, SP, R4
+               //      SUB     R3, R4
+               //      MOVD    $(framesize+(StackGuard-StackSmall)), R31
+               //      CMPU    R31, R4
+               p = appendp(ctxt, p);
+               p->as = ACMP;
+               p->from.type = D_REG;
+               p->from.reg = 3;
+               p->to.type = D_CONST;
+               p->to.offset = StackPreempt;
+
+               q = p = appendp(ctxt, p);
+               p->as = ABEQ;
+               p->to.type = D_BRANCH;
+
+               p = appendp(ctxt, p);
+               p->as = AADD;
+               p->from.type = D_CONST;
+               p->from.offset = StackGuard;
+               p->reg = REGSP;
+               p->to.type = D_REG;
+               p->to.reg = 4;
+
+               p = appendp(ctxt, p);
+               p->as = ASUB;
+               p->from.type = D_REG;
+               p->from.reg = 3;
+               p->to.type = D_REG;
+               p->to.reg = 4;
+
+               p = appendp(ctxt, p);
+               p->as = AMOVD;
+               p->from.type = D_CONST;
+               p->from.offset = framesize + StackGuard - StackSmall;
+               p->to.type = D_REG;
+               p->to.reg = REGTMP;
+
+               p = appendp(ctxt, p);
+               p->as = ACMPU;
+               p->from.type = D_REG;
+               p->from.reg = REGTMP;
+               p->to.type = D_REG;
+               p->to.reg = 4;
+       }
+
+       // q1: BLT      done
+       q1 = p = appendp(ctxt, p);
+       p->as = ABLT;
+       p->to.type = D_BRANCH;
+
+       // MOVD LR, R5
+       p = appendp(ctxt, p);
+       p->as = AMOVD;
+       p->from.type = D_SPR;
+       p->from.offset = D_LR;
+       p->to.type = D_REG;
+       p->to.reg = 5;
+       if(q)
+               q->pcond = p;
+
+       // BL   runtime.morestack(SB)
+       p = appendp(ctxt, p);
+       p->as = ABL;
+       p->to.type = D_BRANCH;
+       if(ctxt->cursym->cfunc)
+               p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
+       else
+               p->to.sym = ctxt->symmorestack[noctxt];
+
+       // BR   start
+       p = appendp(ctxt, p);
+       p->as = ABR;
+       p->to.type = D_BRANCH;
+       p->pcond = ctxt->cursym->text->link;
+
+       // placeholder for q1's jump target
+       p = appendp(ctxt, p);
+       p->as = ANOP; // zero-width place holder
+       q1->pcond = p;
+
+       return p;
+}
+
+static void xfol(Link*, Prog*, Prog**);
+
+static void
+follow(Link *ctxt, LSym *s)
+{
+       Prog *firstp, *lastp;
+
+       ctxt->cursym = s;
+
+       firstp = ctxt->arch->prg();
+       lastp = firstp;
+       xfol(ctxt, s->text, &lastp);
+       lastp->link = nil;
+       s->text = firstp->link;
+}
+
+static int
+relinv(int a)
+{
+
+       switch(a) {
+       case ABEQ:      return ABNE;
+       case ABNE:      return ABEQ;
+
+       case ABGE:      return ABLT;
+       case ABLT:      return ABGE;
+
+       case ABGT:      return ABLE;
+       case ABLE:      return ABGT;
+
+       case ABVC:      return ABVS;
+       case ABVS:      return ABVC;
+       }
+       return 0;
+}
+
+static void
+xfol(Link *ctxt, Prog *p, Prog **last)
+{
+       Prog *q, *r;
+       int a, b, i;
+
+loop:
+       if(p == nil)
+               return;
+       a = p->as;
+       if(a == ABR) {
+               q = p->pcond;
+               if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){
+                       p->mark |= FOLL;
+                       (*last)->link = p;
+                       *last = p;
+                       p = p->link;
+                       xfol(ctxt, p, last);
+                       p = q;
+                       if(p && !(p->mark & FOLL))
+                               goto loop;
+                       return;
+               }
+               if(q != nil) {
+                       p->mark |= FOLL;
+                       p = q;
+                       if(!(p->mark & FOLL))
+                               goto loop;
+               }
+       }
+       if(p->mark & FOLL) {
+               for(i=0,q=p; i<4; i++,q=q->link) {
+                       if(q == *last || (q->mark&NOSCHED))
+                               break;
+                       b = 0;          /* set */
+                       a = q->as;
+                       if(a == ANOP) {
+                               i--;
+                               continue;
+                       }
+                       if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
+                               goto copy;
+                       if(!q->pcond || (q->pcond->mark&FOLL))
+                               continue;
+                       b = relinv(a);
+                       if(!b)
+                               continue;
+               copy:
+                       for(;;) {
+                               r = ctxt->arch->prg();
+                               *r = *p;
+                               if(!(r->mark&FOLL))
+                                       print("cant happen 1\n");
+                               r->mark |= FOLL;
+                               if(p != q) {
+                                       p = p->link;
+                                       (*last)->link = r;
+                                       *last = r;
+                                       continue;
+                               }
+                               (*last)->link = r;
+                               *last = r;
+                               if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
+                                       return;
+                               r->as = b;
+                               r->pcond = p->link;
+                               r->link = p->pcond;
+                               if(!(r->link->mark&FOLL))
+                                       xfol(ctxt, r->link, last);
+                               if(!(r->pcond->mark&FOLL))
+                                       print("cant happen 2\n");
+                               return;
+                       }
+               }
+
+               a = ABR;
+               q = ctxt->arch->prg();
+               q->as = a;
+               q->lineno = p->lineno;
+               q->to.type = D_BRANCH;
+               q->to.offset = p->pc;
+               q->pcond = p;
+               p = q;
+       }
+       p->mark |= FOLL;
+       (*last)->link = p;
+       *last = p;
+       if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID){
+               if(p->mark & NOSCHED){
+                       p = p->link;
+                       goto loop;
+               }
+               return;
+       }
+       if(p->pcond != nil)
+       if(a != ABL && p->link != nil) {
+               xfol(ctxt, p->link, last);
+               p = p->pcond;
+               if(p == nil || (p->mark&FOLL))
+                       return;
+               goto loop;
+       }
+       p = p->link;
+       goto loop;
+}
+
+static Prog*
+prg(void)
+{
+       Prog *p;
+
+       p = emallocz(sizeof(*p));
+       *p = zprg;
+       return p;
+}
+
+LinkArch linkpower64 = {
+       .name = "power64",
+       .thechar = '9',
+       .endian = BigEndian,
+
+       .addstacksplit = addstacksplit,
+       .assemble = span9,
+       .datasize = datasize,
+       .follow = follow,
+       .iscall = iscall,
+       .isdata = isdata,
+       .prg = prg,
+       .progedit = progedit,
+       .settextflag = settextflag,
+       .symtype = symtype,
+       .textflag = textflag,
+
+       .minlc = 4,
+       .ptrsize = 8,
+       .regsize = 8,
+
+       .D_ADDR = D_ADDR,
+       .D_AUTO = D_AUTO,
+       .D_BRANCH = D_BRANCH,
+       .D_CONST = D_CONST,
+       .D_EXTERN = D_EXTERN,
+       .D_FCONST = D_FCONST,
+       .D_NONE = D_NONE,
+       .D_PARAM = D_PARAM,
+       .D_SCONST = D_SCONST,
+       .D_STATIC = D_STATIC,
+       .D_OREG = D_OREG,
+
+       .ACALL = ABL,
+       .ADATA = ADATA,
+       .AEND = AEND,
+       .AFUNCDATA = AFUNCDATA,
+       .AGLOBL = AGLOBL,
+       .AJMP = ABR,
+       .ANOP = ANOP,
+       .APCDATA = APCDATA,
+       .ARET = ARETURN,
+       .ATEXT = ATEXT,
+       .ATYPE = ATYPE,
+       .AUSEFIELD = AUSEFIELD,
+};
+
+LinkArch linkpower64le = {
+       .name = "power64le",
+       .thechar = '9',
+       .endian = LittleEndian,
+
+       .addstacksplit = addstacksplit,
+       .assemble = span9,
+       .datasize = datasize,
+       .follow = follow,
+       .iscall = iscall,
+       .isdata = isdata,
+       .prg = prg,
+       .progedit = progedit,
+       .settextflag = settextflag,
+       .symtype = symtype,
+       .textflag = textflag,
+
+       .minlc = 4,
+       .ptrsize = 8,
+       .regsize = 8,
+
+       .D_ADDR = D_ADDR,
+       .D_AUTO = D_AUTO,
+       .D_BRANCH = D_BRANCH,
+       .D_CONST = D_CONST,
+       .D_EXTERN = D_EXTERN,
+       .D_FCONST = D_FCONST,
+       .D_NONE = D_NONE,
+       .D_PARAM = D_PARAM,
+       .D_SCONST = D_SCONST,
+       .D_STATIC = D_STATIC,
+       .D_OREG = D_OREG,
+
+       .ACALL = ABL,
+       .ADATA = ADATA,
+       .AEND = AEND,
+       .AFUNCDATA = AFUNCDATA,
+       .AGLOBL = AGLOBL,
+       .AJMP = ABR,
+       .ANOP = ANOP,
+       .APCDATA = APCDATA,
+       .ARET = ARETURN,
+       .ATEXT = ATEXT,
+       .ATYPE = ATYPE,
+       .AUSEFIELD = AUSEFIELD,
+};
index b2478ec17847f9d130587f7cd39455e7881be5c9..6d869495358995c13f956338afc98a2207a0d157 100644 (file)
@@ -142,6 +142,8 @@ writeobj(Link *ctxt, Biobuf *b)
        edata = nil;
        for(pl = ctxt->plist; pl != nil; pl = pl->link) {
                for(p = pl->firstpc; p != nil; p = plink) {
+                       if(ctxt->debugasm && ctxt->debugvlog)
+                               print("obj: %p %P\n", p, p);
                        plink = p->link;
                        p->link = nil;
 
@@ -365,7 +367,10 @@ writesym(Link *ctxt, Biobuf *b, LSym *s)
                        name = "";
                        if(r->sym != nil)
                                name = r->sym->name;
-                       Bprint(ctxt->bso, "\trel %d+%d t=%d %s+%lld\n", (int)r->off, r->siz, r->type, name, (vlong)r->add);
+                       if(ctxt->arch->thechar == '5' || ctxt->arch->thechar == '9')
+                               Bprint(ctxt->bso, "\trel %d+%d t=%d %s+%llux\n", (int)r->off, r->siz, r->type, name, (vlong)r->add);
+                       else
+                               Bprint(ctxt->bso, "\trel %d+%d t=%d %s+%lld\n", (int)r->off, r->siz, r->type, name, (vlong)r->add);
                }
        }
 
@@ -777,7 +782,7 @@ rdsym(Link *ctxt, Biobuf *f, char *pkg)
                        s->type = SRODATA;
                        adduint32(ctxt, s, i32);
                        s->reachable = 0;
-               } else if(strncmp(s->name, "$f64.", 5) == 0) {
+               } else if(strncmp(s->name, "$f64.", 5) == 0 || strncmp(s->name, "$i64.", 5) == 0) {
                        int64 i64;
                        i64 = strtoull(s->name+5, nil, 16);
                        s->type = SRODATA;
diff --git a/src/liblink/sched9.c b/src/liblink/sched9.c
new file mode 100644 (file)
index 0000000..a9083df
--- /dev/null
@@ -0,0 +1,835 @@
+// cmd/9l/sched.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.
+
+// +build ignore
+
+#include       "l.h"
+
+enum
+{
+       E_ICC   = 1<<0,
+       E_FCC   = 1<<1,
+       E_MEM   = 1<<2,
+       E_MEMSP = 1<<3, /* uses offset and size */
+       E_MEMSB = 1<<4, /* uses offset and size */
+       E_LR    = 1<<5,
+       E_CR = 1<<6,
+       E_CTR = 1<<7,
+       E_XER = 1<<8,
+
+       E_CR0 = 0xF<<0,
+       E_CR1 = 0xF<<4,
+
+       ANYMEM  = E_MEM|E_MEMSP|E_MEMSB,
+       ALL     = ~0,
+};
+
+typedef        struct  Sch     Sch;
+typedef        struct  Dep     Dep;
+
+struct Dep
+{
+       ulong   ireg;
+       ulong   freg;
+       ulong   cc;
+       ulong   cr;
+};
+struct Sch
+{
+       Prog    p;
+       Dep     set;
+       Dep     used;
+       long    soffset;
+       char    size;
+       char    comp;
+};
+
+void   regused(Sch*, Prog*);
+int    depend(Sch*, Sch*);
+int    conflict(Sch*, Sch*);
+int    offoverlap(Sch*, Sch*);
+void   dumpbits(Sch*, Dep*);
+
+void
+sched(Prog *p0, Prog *pe)
+{
+       Prog *p, *q;
+       Sch sch[NSCHED], *s, *t, *u, *se, stmp;
+
+       if(!debug['Q'])
+               return;
+       /*
+        * build side structure
+        */
+       s = sch;
+       for(p=p0;; p=p->link) {
+               memset(s, 0, sizeof(*s));
+               s->p = *p;
+               regused(s, p);
+               if(debug['X']) {
+                       Bprint(&bso, "%P\tset", &s->p);
+                       dumpbits(s, &s->set);
+                       Bprint(&bso, "; used");
+                       dumpbits(s, &s->used);
+                       if(s->comp)
+                               Bprint(&bso, "; compound");
+                       if(s->p.mark & LOAD)
+                               Bprint(&bso, "; load");
+                       if(s->p.mark & BRANCH)
+                               Bprint(&bso, "; branch");
+                       if(s->p.mark & FCMP)
+                               Bprint(&bso, "; fcmp");
+                       Bprint(&bso, "\n");
+               }
+               s++;
+               if(p == pe)
+                       break;
+       }
+       se = s;
+
+       for(s=se-1; s>=sch; s--) {
+
+               /*
+                * load delay. interlocked.
+                */
+               if(s->p.mark & LOAD) {
+                       if(s >= se-1)
+                               continue;
+                       if(!conflict(s, (s+1)))
+                               continue;
+                       /*
+                        * s is load, s+1 is immediate use of result
+                        * t is the trial instruction to insert between s and s+1
+                        */
+                       for(t=s-1; t>=sch; t--) {
+                               if(t->p.mark & BRANCH)
+                                       goto no2;
+                               if(t->p.mark & FCMP)
+                                       if((s+1)->p.mark & BRANCH)
+                                               goto no2;
+                               if(t->p.mark & LOAD)
+                                       if(conflict(t, (s+1)))
+                                               goto no2;
+                               for(u=t+1; u<=s; u++)
+                                       if(depend(u, t))
+                                               goto no2;
+                               goto out2;
+                       no2:;
+                       }
+                       if(debug['X'])
+                               Bprint(&bso, "?l%P\n", &s->p);
+                       continue;
+               out2:
+                       if(debug['X']) {
+                               Bprint(&bso, "!l%P\n", &t->p);
+                               Bprint(&bso, "%P\n", &s->p);
+                       }
+                       stmp = *t;
+                       memmove(t, t+1, (uchar*)s - (uchar*)t);
+                       *s = stmp;
+                       s--;
+                       continue;
+               }
+
+               /*
+                * fop2 delay.
+                */
+               if(s->p.mark & FCMP) {
+                       if(s >= se-1)
+                               continue;
+                       if(!((s+1)->p.mark & BRANCH))
+                               continue;
+                       /* t is the trial instruction to use */
+                       for(t=s-1; t>=sch; t--) {
+                               for(u=t+1; u<=s; u++)
+                                       if(depend(u, t))
+                                               goto no3;
+                               goto out3;
+                       no3:;
+                       }
+                       if(debug['X'])
+                               Bprint(&bso, "?f%P\n", &s->p);
+                       continue;
+               out3:
+                       if(debug['X']) {
+                               Bprint(&bso, "!f%P\n", &t->p);
+                               Bprint(&bso, "%P\n", &s->p);
+                       }
+                       stmp = *t;
+                       memmove(t, t+1, (uchar*)s - (uchar*)t);
+                       *s = stmp;
+                       s--;
+                       continue;
+               }
+       }
+
+       /*
+        * put it all back
+        */
+       for(s=sch, p=p0; s<se; s++, p=q) {
+               q = p->link;
+               if(q != s->p.link) {
+                       *p = s->p;
+                       p->link = q;
+               }
+       }
+       if(debug['X'])
+               Bprint(&bso, "\n");
+}
+
+void
+regused(Sch *s, Prog *realp)
+{
+       int c, ar, ad, ld, sz, nr, upd;
+       ulong m;
+       Prog *p;
+
+       p = &s->p;
+       s->comp = compound(p);
+       if(s->comp) {
+               s->set.ireg |= 1<<REGTMP;
+               s->used.ireg |= 1<<REGTMP;
+       }
+       ar = 0;         /* dest is really reference */
+       ad = 0;         /* source/dest is really address */
+       ld = 0;         /* opcode is load instruction */
+       sz = 32*4;              /* size of load/store for overlap computation */
+       nr = 0; /* source/dest is not really reg */
+       upd = 0;        /* move with update; changes reg */
+
+/*
+ * flags based on opcode
+ */
+       switch(p->as) {
+       case ATEXT:
+               curtext = realp;
+               autosize = p->to.offset + 8;
+               ad = 1;
+               break;
+       case ABL:
+               s->set.cc |= E_LR;
+               ar = 1;
+               ad = 1;
+               break;
+       case ABR:
+               ar = 1;
+               ad = 1;
+               break;
+       case ACMP:
+       case ACMPU:
+       case ACMPW:
+       case ACMPWU:
+               s->set.cc |= E_ICC;
+               if(p->reg == 0)
+                       s->set.cr |= E_CR0;
+               else
+                       s->set.cr |= (0xF<<((p->reg&7)*4));
+               ar = 1;
+               break;
+       case AFCMPO:
+       case AFCMPU:
+               s->set.cc |= E_FCC;
+               if(p->reg == 0)
+                       s->set.cr |= E_CR0;
+               else
+                       s->set.cr |= (0xF<<((p->reg&7)*4));
+               ar = 1;
+               break;
+       case ACRAND:
+       case ACRANDN:
+       case ACREQV:
+       case ACRNAND:
+       case ACRNOR:
+       case ACROR:
+       case ACRORN:
+       case ACRXOR:
+               s->used.cr |= 1<<p->from.reg;
+               s->set.cr |= 1<<p->to.reg;
+               nr = 1;
+               break;
+       case ABCL:      /* tricky */
+               s->used.cc |= E_FCC|E_ICC;
+               s->used.cr = ALL;
+               s->set.cc |= E_LR;
+               ar = 1;
+               break;
+       case ABC:               /* tricky */
+               s->used.cc |= E_FCC|E_ICC;
+               s->used.cr = ALL;
+               ar = 1;
+               break;
+       case ABEQ:
+       case ABGE:
+       case ABGT:
+       case ABLE:
+       case ABLT:
+       case ABNE:
+       case ABVC:
+       case ABVS:
+               s->used.cc |= E_ICC;
+               s->used.cr |= E_CR0;
+               ar = 1;
+               break;
+       case ALSW:
+       case AMOVMW:
+               /* could do better */
+               sz = 32*4;
+               ld = 1;
+               break;
+       case AMOVBU:
+       case AMOVBZU:
+               upd = 1;
+               sz = 1;
+               ld = 1;
+               break;
+       case AMOVB:
+       case AMOVBZ:
+               sz = 1;
+               ld = 1;
+               break;
+       case AMOVHU:
+       case AMOVHZU:
+               upd = 1;
+               sz = 2;
+               ld = 1;
+               break;
+       case AMOVH:
+       case AMOVHBR:
+       case AMOVHZ:
+               sz = 2;
+               ld = 1;
+               break;
+       case AFMOVSU:
+       case AMOVWU:
+       case AMOVWZU:
+               upd = 1;
+               sz = 4;
+               ld = 1;
+               break;
+       case AFMOVS:
+       case AMOVW:
+       case AMOVWZ:
+       case AMOVWBR:
+       case ALWAR:
+               sz = 4;
+               ld = 1;
+               break;
+       case AFMOVDU:
+               upd = 1;
+               sz = 8;
+               ld = 1;
+               break;
+       case AFMOVD:
+               sz = 8;
+               ld = 1;
+               break;
+       case AFMOVDCC:
+               sz = 8;
+               ld = 1;
+               s->set.cc |= E_FCC;
+               s->set.cr |= E_CR1;
+               break;
+       case AMOVFL:
+       case AMOVCRFS:
+       case AMTFSB0:
+       case AMTFSB0CC:
+       case AMTFSB1:
+       case AMTFSB1CC:
+               s->set.ireg = ALL;
+               s->set.freg = ALL;
+               s->set.cc = ALL;
+               s->set.cr = ALL;
+               break;
+       case AADDCC:
+       case AADDVCC:
+       case AADDCCC:
+       case AADDCVCC:
+       case AADDMECC:
+       case AADDMEVCC:
+       case AADDECC:
+       case AADDEVCC:
+       case AADDZECC:
+       case AADDZEVCC:
+       case AANDCC:
+       case AANDNCC:
+       case ACNTLZWCC:
+       case ADIVWCC:
+       case ADIVWVCC:
+       case ADIVWUCC:
+       case ADIVWUVCC:
+       case AEQVCC:
+       case AEXTSBCC:
+       case AEXTSHCC:
+       case AMULHWCC:
+       case AMULHWUCC:
+       case AMULLWCC:
+       case AMULLWVCC:
+       case ANANDCC:
+       case ANEGCC:
+       case ANEGVCC:
+       case ANORCC:
+       case AORCC:
+       case AORNCC:
+       case AREMCC:
+       case AREMVCC:
+       case AREMUCC:
+       case AREMUVCC:
+       case ARLWMICC:
+       case ARLWNMCC:
+       case ASLWCC:
+       case ASRAWCC:
+       case ASRWCC:
+       case ASTWCCC:
+       case ASUBCC:
+       case ASUBVCC:
+       case ASUBCCC:
+       case ASUBCVCC:
+       case ASUBMECC:
+       case ASUBMEVCC:
+       case ASUBECC:
+       case ASUBEVCC:
+       case ASUBZECC:
+       case ASUBZEVCC:
+       case AXORCC:
+               s->set.cc |= E_ICC;
+               s->set.cr |= E_CR0;
+               break;
+       case AFABSCC:
+       case AFADDCC:
+       case AFADDSCC:
+       case AFCTIWCC:
+       case AFCTIWZCC:
+       case AFDIVCC:
+       case AFDIVSCC:
+       case AFMADDCC:
+       case AFMADDSCC:
+       case AFMSUBCC:
+       case AFMSUBSCC:
+       case AFMULCC:
+       case AFMULSCC:
+       case AFNABSCC:
+       case AFNEGCC:
+       case AFNMADDCC:
+       case AFNMADDSCC:
+       case AFNMSUBCC:
+       case AFNMSUBSCC:
+       case AFRSPCC:
+       case AFSUBCC:
+       case AFSUBSCC:
+               s->set.cc |= E_FCC;
+               s->set.cr |= E_CR1;
+               break;
+       }
+
+/*
+ * flags based on 'to' field
+ */
+       c = p->to.class;
+       if(c == 0) {
+               c = aclass(&p->to) + 1;
+               p->to.class = c;
+       }
+       c--;
+       switch(c) {
+       default:
+               print("unknown class %d %D\n", c, &p->to);
+
+       case C_NONE:
+       case C_ZCON:
+       case C_SCON:
+       case C_UCON:
+       case C_LCON:
+       case C_ADDCON:
+       case C_ANDCON:
+       case C_SBRA:
+       case C_LBRA:
+               break;
+       case C_CREG:
+               c = p->to.reg;
+               if(c == NREG)
+                       s->set.cr = ALL;
+               else
+                       s->set.cr |= (0xF << ((p->from.reg&7)*4));
+               s->set.cc = ALL;
+               break;
+       case C_SPR:
+       case C_FPSCR:
+       case C_MSR:
+       case C_XER:
+               s->set.ireg = ALL;
+               s->set.freg = ALL;
+               s->set.cc = ALL;
+               s->set.cr = ALL;
+               break;
+       case C_LR:
+               s->set.cc |= E_LR;
+               break;
+       case C_CTR:
+               s->set.cc |= E_CTR;
+               break;
+       case C_ZOREG:
+       case C_SOREG:
+       case C_LOREG:
+               c = p->to.reg;
+               s->used.ireg |= 1<<c;
+               if(upd)
+                       s->set.ireg |= 1<<c;
+               if(ad)
+                       break;
+               s->size = sz;
+               s->soffset = regoff(&p->to);
+
+               m = ANYMEM;
+               if(c == REGSB)
+                       m = E_MEMSB;
+               if(c == REGSP)
+                       m = E_MEMSP;
+
+               if(ar)
+                       s->used.cc |= m;
+               else
+                       s->set.cc |= m;
+               break;
+       case C_SACON:
+       case C_LACON:
+               s->used.ireg |= 1<<REGSP;
+               if(upd)
+                       s->set.ireg |= 1<<c;
+               break;
+       case C_SECON:
+       case C_LECON:
+               s->used.ireg |= 1<<REGSB;
+               if(upd)
+                       s->set.ireg |= 1<<c;
+               break;
+       case C_REG:
+               if(nr)
+                       break;
+               if(ar)
+                       s->used.ireg |= 1<<p->to.reg;
+               else
+                       s->set.ireg |= 1<<p->to.reg;
+               break;
+       case C_FREG:
+               if(ar)
+                       s->used.freg |= 1<<p->to.reg;
+               else
+                       s->set.freg |= 1<<p->to.reg;
+               break;
+       case C_SAUTO:
+       case C_LAUTO:
+               s->used.ireg |= 1<<REGSP;
+               if(upd)
+                       s->set.ireg |= 1<<c;
+               if(ad)
+                       break;
+               s->size = sz;
+               s->soffset = regoff(&p->to);
+
+               if(ar)
+                       s->used.cc |= E_MEMSP;
+               else
+                       s->set.cc |= E_MEMSP;
+               break;
+       case C_SEXT:
+       case C_LEXT:
+               s->used.ireg |= 1<<REGSB;
+               if(upd)
+                       s->set.ireg |= 1<<c;
+               if(ad)
+                       break;
+               s->size = sz;
+               s->soffset = regoff(&p->to);
+
+               if(ar)
+                       s->used.cc |= E_MEMSB;
+               else
+                       s->set.cc |= E_MEMSB;
+               break;
+       }
+
+/*
+ * flags based on 'from' field
+ */
+       c = p->from.class;
+       if(c == 0) {
+               c = aclass(&p->from) + 1;
+               p->from.class = c;
+       }
+       c--;
+       switch(c) {
+       default:
+               print("unknown class %d %D\n", c, &p->from);
+
+       case C_NONE:
+       case C_ZCON:
+       case C_SCON:
+       case C_UCON:
+       case C_LCON:
+       case C_ADDCON:
+       case C_ANDCON:
+       case C_SBRA:
+       case C_LBRA:
+               c = p->from.reg;
+               if(c != NREG)
+                       s->used.ireg |= 1<<c;
+               break;
+       case C_CREG:
+               c = p->from.reg;
+               if(c == NREG)
+                       s->used.cr = ALL;
+               else
+                       s->used.cr |= (0xF << ((p->from.reg&7)*4));
+               s->used.cc = ALL;
+               break;
+       case C_SPR:
+       case C_FPSCR:
+       case C_MSR:
+       case C_XER:
+               s->set.ireg = ALL;
+               s->set.freg = ALL;
+               s->set.cc = ALL;
+               s->set.cr = ALL;
+               break;
+       case C_LR:
+               s->used.cc |= E_LR;
+               break;
+       case C_CTR:
+               s->used.cc |= E_CTR;
+               break;
+       case C_ZOREG:
+       case C_SOREG:
+       case C_LOREG:
+               c = p->from.reg;
+               s->used.ireg |= 1<<c;
+               if(ld)
+                       p->mark |= LOAD;
+               if(ad)
+                       break;
+               s->size = sz;
+               s->soffset = regoff(&p->from);
+
+               m = ANYMEM;
+               if(c == REGSB)
+                       m = E_MEMSB;
+               if(c == REGSP)
+                       m = E_MEMSP;
+
+               s->used.cc |= m;
+               break;
+       case C_SACON:
+       case C_LACON:
+               s->used.ireg |= 1<<REGSP;
+               break;
+       case C_SECON:
+       case C_LECON:
+               s->used.ireg |= 1<<REGSB;
+               break;
+       case C_REG:
+               if(nr)
+                       break;
+               s->used.ireg |= 1<<p->from.reg;
+               break;
+       case C_FREG:
+               s->used.freg |= 1<<p->from.reg;
+               break;
+       case C_SAUTO:
+       case C_LAUTO:
+               s->used.ireg |= 1<<REGSP;
+               if(ld)
+                       p->mark |= LOAD;
+               if(ad)
+                       break;
+               s->size = sz;
+               s->soffset = regoff(&p->from);
+
+               s->used.cc |= E_MEMSP;
+               break;
+       case C_SEXT:
+       case C_LEXT:
+               s->used.ireg |= 1<<REGSB;
+               if(ld)
+                       p->mark |= LOAD;
+               if(ad)
+                       break;
+               s->size = sz;
+               s->soffset = regoff(&p->from);
+
+               s->used.cc |= E_MEMSB;
+               break;
+       }
+       
+       c = p->reg;
+       if(c != NREG) {
+               if(p->from.type == D_FREG || p->to.type == D_FREG)
+                       s->used.freg |= 1<<c;
+               else
+                       s->used.ireg |= 1<<c;
+       }
+}
+
+/*
+ * test to see if 2 instrictions can be
+ * interchanged without changing semantics
+ */
+int
+depend(Sch *sa, Sch *sb)
+{
+       ulong x;
+
+       if(sa->set.ireg & (sb->set.ireg|sb->used.ireg))
+               return 1;
+       if(sb->set.ireg & sa->used.ireg)
+               return 1;
+
+       if(sa->set.freg & (sb->set.freg|sb->used.freg))
+               return 1;
+       if(sb->set.freg & sa->used.freg)
+               return 1;
+
+       if(sa->set.cr & (sb->set.cr|sb->used.cr))
+               return 1;
+       if(sb->set.cr & sa->used.cr)
+               return 1;
+
+
+       x = (sa->set.cc & (sb->set.cc|sb->used.cc)) |
+               (sb->set.cc & sa->used.cc);
+       if(x) {
+               /*
+                * allow SB and SP to pass each other.
+                * allow SB to pass SB iff doffsets are ok
+                * anything else conflicts
+                */
+               if(x != E_MEMSP && x != E_MEMSB)
+                       return 1;
+               x = sa->set.cc | sb->set.cc |
+                       sa->used.cc | sb->used.cc;
+               if(x & E_MEM)
+                       return 1;
+               if(offoverlap(sa, sb))
+                       return 1;
+       }
+
+       return 0; 
+}
+
+int
+offoverlap(Sch *sa, Sch *sb)
+{
+
+       if(sa->soffset < sb->soffset) {
+               if(sa->soffset+sa->size > sb->soffset)
+                       return 1;
+               return 0;
+       }
+       if(sb->soffset+sb->size > sa->soffset)
+               return 1;
+       return 0;
+}
+
+/*
+ * test 2 adjacent instructions
+ * and find out if inserted instructions
+ * are desired to prevent stalls.
+ * first instruction is a load instruction.
+ */
+int
+conflict(Sch *sa, Sch *sb)
+{
+
+       if(sa->set.ireg & sb->used.ireg)
+               return 1;
+       if(sa->set.freg & sb->used.freg)
+               return 1;
+       if(sa->set.cr & sb->used.cr)
+               return 1;
+       return 0;
+}
+
+int
+compound(Prog *p)
+{
+       Optab *o;
+
+       o = oplook(p);
+       if(o->size != 4)
+               return 1;
+       if(p->to.type == D_REG && p->to.reg == REGSB)
+               return 1;
+       return 0;
+}
+
+void
+dumpbits(Sch *s, Dep *d)
+{
+       int i;
+
+       for(i=0; i<32; i++)
+               if(d->ireg & (1<<i))
+                       Bprint(&bso, " R%d", i);
+       for(i=0; i<32; i++)
+               if(d->freg & (1<<i))
+                       Bprint(&bso, " F%d", i);
+       for(i=0; i<32; i++)
+               if(d->cr & (1<<i))
+                       Bprint(&bso, " C%d", i);
+       for(i=0; i<32; i++)
+               switch(d->cc & (1<<i)) {
+               default:
+                       break;
+               case E_ICC:
+                       Bprint(&bso, " ICC");
+                       break;
+               case E_FCC:
+                       Bprint(&bso, " FCC");
+                       break;
+               case E_LR:
+                       Bprint(&bso, " LR");
+                       break;
+               case E_CR:
+                       Bprint(&bso, " CR");
+                       break;
+               case E_CTR:
+                       Bprint(&bso, " CTR");
+                       break;
+               case E_XER:
+                       Bprint(&bso, " XER");
+                       break;
+               case E_MEM:
+                       Bprint(&bso, " MEM%d", s->size);
+                       break;
+               case E_MEMSB:
+                       Bprint(&bso, " SB%d", s->size);
+                       break;
+               case E_MEMSP:
+                       Bprint(&bso, " SP%d", s->size);
+                       break;
+               }
+}
diff --git a/src/math/abs_power64x.s b/src/math/abs_power64x.s
new file mode 100644 (file)
index 0000000..3ba8201
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "textflag.h"
+
+TEXT Â·Abs(SB),NOSPLIT,$0-16
+       MOVD    x+0(FP), R3
+       MOVD    $((1<<63)-1), R4
+       AND     R4, R3
+       MOVD    R3, ret+8(FP)
+       RETURN
diff --git a/src/math/big/arith_power64x.s b/src/math/big/arith_power64x.s
new file mode 100644 (file)
index 0000000..c33a920
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "textflag.h"
+
+// This file provides fast assembly versions for the elementary
+// arithmetic operations on vectors implemented in arith.go.
+
+TEXT Â·mulWW(SB),NOSPLIT,$0
+       BR Â·mulWW_g(SB)
+
+TEXT Â·divWW(SB),NOSPLIT,$0
+       BR Â·divWW_g(SB)
+
+TEXT Â·addVV(SB),NOSPLIT,$0
+       BR Â·addVV_g(SB)
+
+TEXT Â·subVV(SB),NOSPLIT,$0
+       BR Â·subVV_g(SB)
+
+TEXT Â·addVW(SB),NOSPLIT,$0
+       BR Â·addVW_g(SB)
+
+TEXT Â·subVW(SB),NOSPLIT,$0
+       BR Â·subVW_g(SB)
+
+TEXT Â·shlVU(SB),NOSPLIT,$0
+       BR Â·shlVU_g(SB)
+
+TEXT Â·shrVU(SB),NOSPLIT,$0
+       BR Â·shrVU_g(SB)
+
+TEXT Â·mulAddVWW(SB),NOSPLIT,$0
+       BR Â·mulAddVWW_g(SB)
+
+TEXT Â·addMulVVW(SB),NOSPLIT,$0
+       BR Â·addMulVVW_g(SB)
+
+TEXT Â·divWVW(SB),NOSPLIT,$0
+       BR Â·divWVW_g(SB)
+
+TEXT Â·bitLen(SB),NOSPLIT,$0
+       BR Â·bitLen_g(SB)
diff --git a/src/math/stubs_power64x.s b/src/math/stubs_power64x.s
new file mode 100644 (file)
index 0000000..36b7625
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "textflag.h"
+
+TEXT Â·Asin(SB),NOSPLIT,$0
+       BR Â·asin(SB)
+
+TEXT Â·Acos(SB),NOSPLIT,$0
+       BR Â·acos(SB)
+
+TEXT Â·Atan2(SB),NOSPLIT,$0
+       BR Â·atan2(SB)
+
+TEXT Â·Atan(SB),NOSPLIT,$0
+       BR Â·atan(SB)
+
+TEXT Â·Dim(SB),NOSPLIT,$0
+       BR Â·dim(SB)
+
+TEXT Â·Min(SB),NOSPLIT,$0
+       BR Â·min(SB)
+
+TEXT Â·Max(SB),NOSPLIT,$0
+       BR Â·max(SB)
+
+TEXT Â·Exp2(SB),NOSPLIT,$0
+       BR Â·exp2(SB)
+
+TEXT Â·Expm1(SB),NOSPLIT,$0
+       BR Â·expm1(SB)
+
+TEXT Â·Exp(SB),NOSPLIT,$0
+       BR Â·exp(SB)
+
+TEXT Â·Floor(SB),NOSPLIT,$0
+       BR Â·floor(SB)
+
+TEXT Â·Ceil(SB),NOSPLIT,$0
+       BR Â·ceil(SB)
+
+TEXT Â·Trunc(SB),NOSPLIT,$0
+       BR Â·trunc(SB)
+
+TEXT Â·Frexp(SB),NOSPLIT,$0
+       BR Â·frexp(SB)
+
+TEXT Â·Hypot(SB),NOSPLIT,$0
+       BR Â·hypot(SB)
+
+TEXT Â·Ldexp(SB),NOSPLIT,$0
+       BR Â·ldexp(SB)
+
+TEXT Â·Log10(SB),NOSPLIT,$0
+       BR Â·log10(SB)
+
+TEXT Â·Log2(SB),NOSPLIT,$0
+       BR Â·log2(SB)
+
+TEXT Â·Log1p(SB),NOSPLIT,$0
+       BR Â·log1p(SB)
+
+TEXT Â·Log(SB),NOSPLIT,$0
+       BR Â·log(SB)
+
+TEXT Â·Modf(SB),NOSPLIT,$0
+       BR Â·modf(SB)
+
+TEXT Â·Mod(SB),NOSPLIT,$0
+       BR Â·mod(SB)
+
+TEXT Â·Remainder(SB),NOSPLIT,$0
+       BR Â·remainder(SB)
+
+TEXT Â·Sincos(SB),NOSPLIT,$0
+       BR Â·sincos(SB)
+
+TEXT Â·Sin(SB),NOSPLIT,$0
+       BR Â·sin(SB)
+
+TEXT Â·Cos(SB),NOSPLIT,$0
+       BR Â·cos(SB)
+
+TEXT Â·Sqrt(SB),NOSPLIT,$0
+       BR Â·sqrt(SB)
+
+TEXT Â·Tan(SB),NOSPLIT,$0
+       BR Â·tan(SB)
index d54c284b5e9d90be76d6cb37e4aa79b74204d49b..1826c37fbd19585952aabe222ac95a6af307253b 100644 (file)
@@ -4,13 +4,19 @@
 
 // Assembly to get into package runtime without using exported symbols.
 
-// +build amd64 amd64p32 arm 386
+// +build amd64 amd64p32 arm 386 power64 power64le
 
 #include "textflag.h"
 
 #ifdef GOARCH_arm
 #define JMP B
 #endif
+#ifdef GOARCH_power64
+#define JMP BR
+#endif
+#ifdef GOARCH_power64le
+#define JMP BR
+#endif
 
 TEXT Â·signal_disable(SB),NOSPLIT,$0
        JMP runtime·signal_disable(SB)
index 268a9e319f6758adfc0cac38cdb179f64c0795a0..c62f227f435a880716cf2da90e57459ec1d9d44e 100644 (file)
@@ -1052,6 +1052,11 @@ func TestChan(t *testing.T) {
                ok = cv.TrySend(ValueOf(6))
                if !ok {
                        t.Errorf("TrySend on empty chan failed")
+                       select {
+                       case x := <-c:
+                               t.Errorf("TrySend failed but it did send %d", x)
+                       default:
+                       }
                } else {
                        if i = <-c; i != 6 {
                                t.Errorf("TrySend 6, recv %d", i)
diff --git a/src/reflect/asm_power64x.s b/src/reflect/asm_power64x.s
new file mode 100644 (file)
index 0000000..e430cdf
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "textflag.h"
+
+// makeFuncStub is the code half of the function returned by MakeFunc.
+// See the comment on the declaration of makeFuncStub in makefunc.go
+// for more details.
+// No argsize here, gc generates argsize info at call site.
+TEXT Â·makeFuncStub(SB),(NOSPLIT|WRAPPER),$16
+       MOVD    R11, 8(R1)
+       MOVD    $argframe+0(FP), R3
+       MOVD    R3, 16(R1)
+       BL      Â·callReflect(SB)
+       RETURN
+
+// methodValueCall is the code half of the function returned by makeMethodValue.
+// See the comment on the declaration of methodValueCall in makefunc.go
+// for more details.
+// No argsize here, gc generates argsize info at call site.
+TEXT Â·methodValueCall(SB),(NOSPLIT|WRAPPER),$16
+       MOVD    R11, 8(R1)
+       MOVD    $argframe+0(FP), R3
+       MOVD    R3, 16(R1)
+       BL      Â·callMethod(SB)
+       RETURN
diff --git a/src/runtime/arch_power64.go b/src/runtime/arch_power64.go
new file mode 100644 (file)
index 0000000..270cd7b
--- /dev/null
@@ -0,0 +1,8 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+type uintreg uint64
+type intptr int64 // TODO(rsc): remove
diff --git a/src/runtime/arch_power64.h b/src/runtime/arch_power64.h
new file mode 100644 (file)
index 0000000..7cfb9da
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+enum {
+       thechar = '9',
+       BigEndian = 1,
+       CacheLineSize = 64,
+       RuntimeGogoBytes = 64,
+       PhysPageSize = 65536,
+       PCQuantum = 4,
+       Int64Align = 8
+};
+
diff --git a/src/runtime/arch_power64le.go b/src/runtime/arch_power64le.go
new file mode 100644 (file)
index 0000000..270cd7b
--- /dev/null
@@ -0,0 +1,8 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+type uintreg uint64
+type intptr int64 // TODO(rsc): remove
diff --git a/src/runtime/arch_power64le.h b/src/runtime/arch_power64le.h
new file mode 100644 (file)
index 0000000..684ac99
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+enum {
+       thechar = '9',
+       BigEndian = 0,
+       CacheLineSize = 64,
+       RuntimeGogoBytes = 64,
+       PhysPageSize = 65536,
+       PCQuantum = 4,
+       Int64Align = 8
+};
+
index 0d46a9eff78035a6fca583a0f4b6800c32cabcde..2d102b27358b618c46ed3a320d61587313234eb2 100644 (file)
@@ -486,11 +486,11 @@ TEXT runtime·cas64(SB), NOSPLIT, $0-21
        MOVL    new_hi+16(FP), CX
        LOCK
        CMPXCHG8B       0(BP)
-       JNZ     cas64_fail
+       JNZ     fail
        MOVL    $1, AX
        MOVB    AX, ret+20(FP)
        RET
-cas64_fail:
+fail:
        MOVL    $0, AX
        MOVB    AX, ret+20(FP)
        RET
@@ -1356,29 +1356,29 @@ TEXT strings·IndexByte(SB),NOSPLIT,$0
 //   AX = 1/0/-1
 TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
        CMPL    SI, DI
-       JEQ     cmp_allsame
+       JEQ     allsame
        CMPL    BX, DX
        MOVL    DX, BP
        CMOVLLT BX, BP // BP = min(alen, blen)
        CMPL    BP, $4
-       JB      cmp_small
+       JB      small
        TESTL   $0x4000000, runtime·cpuid_edx(SB) // check for sse2
-       JE      cmp_mediumloop
-cmp_largeloop:
+       JE      mediumloop
+largeloop:
        CMPL    BP, $16
-       JB      cmp_mediumloop
+       JB      mediumloop
        MOVOU   (SI), X0
        MOVOU   (DI), X1
        PCMPEQB X0, X1
        PMOVMSKB X1, AX
        XORL    $0xffff, AX     // convert EQ to NE
-       JNE     cmp_diff16      // branch if at least one byte is not equal
+       JNE     diff16  // branch if at least one byte is not equal
        ADDL    $16, SI
        ADDL    $16, DI
        SUBL    $16, BP
-       JMP     cmp_largeloop
+       JMP     largeloop
 
-cmp_diff16:
+diff16:
        BSFL    AX, BX  // index of first byte that differs
        XORL    AX, AX
        MOVB    (SI)(BX*1), CX
@@ -1387,25 +1387,25 @@ cmp_diff16:
        LEAL    -1(AX*2), AX    // convert 1/0 to +1/-1
        RET
 
-cmp_mediumloop:
+mediumloop:
        CMPL    BP, $4
-       JBE     cmp_0through4
+       JBE     _0through4
        MOVL    (SI), AX
        MOVL    (DI), CX
        CMPL    AX, CX
-       JNE     cmp_diff4
+       JNE     diff4
        ADDL    $4, SI
        ADDL    $4, DI
        SUBL    $4, BP
-       JMP     cmp_mediumloop
+       JMP     mediumloop
 
-cmp_0through4:
+_0through4:
        MOVL    -4(SI)(BP*1), AX
        MOVL    -4(DI)(BP*1), CX
        CMPL    AX, CX
-       JEQ     cmp_allsame
+       JEQ     allsame
 
-cmp_diff4:
+diff4:
        BSWAPL  AX      // reverse order of bytes
        BSWAPL  CX
        XORL    AX, CX  // find bit differences
@@ -1416,37 +1416,37 @@ cmp_diff4:
        RET
 
        // 0-3 bytes in common
-cmp_small:
+small:
        LEAL    (BP*8), CX
        NEGL    CX
-       JEQ     cmp_allsame
+       JEQ     allsame
 
        // load si
        CMPB    SI, $0xfc
-       JA      cmp_si_high
+       JA      si_high
        MOVL    (SI), SI
-       JMP     cmp_si_finish
-cmp_si_high:
+       JMP     si_finish
+si_high:
        MOVL    -4(SI)(BP*1), SI
        SHRL    CX, SI
-cmp_si_finish:
+si_finish:
        SHLL    CX, SI
 
        // same for di
        CMPB    DI, $0xfc
-       JA      cmp_di_high
+       JA      di_high
        MOVL    (DI), DI
-       JMP     cmp_di_finish
-cmp_di_high:
+       JMP     di_finish
+di_high:
        MOVL    -4(DI)(BP*1), DI
        SHRL    CX, DI
-cmp_di_finish:
+di_finish:
        SHLL    CX, DI
 
        BSWAPL  SI      // reverse order of bytes
        BSWAPL  DI
        XORL    SI, DI  // find bit differences
-       JEQ     cmp_allsame
+       JEQ     allsame
        BSRL    DI, CX  // index of highest bit difference
        SHRL    CX, SI  // move a's bit to bottom
        ANDL    $1, SI  // mask bit
@@ -1455,7 +1455,7 @@ cmp_di_finish:
 
        // all the bytes in common are the same, so we just need
        // to compare the lengths.
-cmp_allsame:
+allsame:
        XORL    AX, AX
        XORL    CX, CX
        CMPL    BX, DX
index a9b082beb82a66f28d9e808166f66e334415de3e..ac9c58cf3e2cce8e23304fdd418f88af7aea9eab 100644 (file)
@@ -461,11 +461,11 @@ TEXT runtime·cas64(SB), NOSPLIT, $0-25
        MOVQ    new+16(FP), CX
        LOCK
        CMPXCHGQ        CX, 0(BX)
-       JNZ     cas64_fail
+       JNZ     fail
        MOVL    $1, AX
        MOVB    AX, ret+24(FP)
        RET
-cas64_fail:
+fail:
        MOVL    $0, AX
        MOVB    AX, ret+24(FP)
        RET
@@ -890,24 +890,24 @@ TEXT runtime·aeshashbody(SB),NOSPLIT,$0-32
        MOVO    runtime·aeskeysched+0(SB), X2
        MOVO    runtime·aeskeysched+16(SB), X3
        CMPQ    CX, $16
-       JB      aessmall
-aesloop:
+       JB      small
+loop:
        CMPQ    CX, $16
-       JBE     aesloopend
+       JBE     loopend
        MOVOU   (AX), X1
        AESENC  X2, X0
        AESENC  X1, X0
        SUBQ    $16, CX
        ADDQ    $16, AX
-       JMP     aesloop
+       JMP     loop
 // 1-16 bytes remaining
-aesloopend:
+loopend:
        // This load may overlap with the previous load above.
        // We'll hash some bytes twice, but that's ok.
        MOVOU   -16(AX)(CX*1), X1
        JMP     partial
 // 0-15 bytes
-aessmall:
+small:
        TESTQ   CX, CX
        JE      finalize        // 0 bytes
 
@@ -1050,18 +1050,18 @@ TEXT runtime·eqstring(SB),NOSPLIT,$0-33
        MOVQ    s1len+8(FP), AX
        MOVQ    s2len+24(FP), BX
        CMPQ    AX, BX
-       JNE     different
+       JNE     noteq
        MOVQ    s1str+0(FP), SI
        MOVQ    s2str+16(FP), DI
        CMPQ    SI, DI
-       JEQ     same
+       JEQ     eq
        CALL    runtime·memeqbody(SB)
        MOVB    AX, v+32(FP)
        RET
-same:
+eq:
        MOVB    $1, v+32(FP)
        RET
-different:
+noteq:
        MOVB    $0, v+32(FP)
        RET
 
@@ -1184,29 +1184,29 @@ TEXT runtime·cmpbytes(SB),NOSPLIT,$0-56
 //   AX = 1/0/-1
 TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
        CMPQ    SI, DI
-       JEQ     cmp_allsame
+       JEQ     allsame
        CMPQ    BX, DX
        MOVQ    DX, BP
        CMOVQLT BX, BP // BP = min(alen, blen) = # of bytes to compare
        CMPQ    BP, $8
-       JB      cmp_small
+       JB      small
 
-cmp_loop:
+loop:
        CMPQ    BP, $16
-       JBE     cmp_0through16
+       JBE     _0through16
        MOVOU   (SI), X0
        MOVOU   (DI), X1
        PCMPEQB X0, X1
        PMOVMSKB X1, AX
        XORQ    $0xffff, AX     // convert EQ to NE
-       JNE     cmp_diff16      // branch if at least one byte is not equal
+       JNE     diff16  // branch if at least one byte is not equal
        ADDQ    $16, SI
        ADDQ    $16, DI
        SUBQ    $16, BP
-       JMP     cmp_loop
+       JMP     loop
        
        // AX = bit mask of differences
-cmp_diff16:
+diff16:
        BSFQ    AX, BX  // index of first byte that differs
        XORQ    AX, AX
        MOVB    (SI)(BX*1), CX
@@ -1216,21 +1216,21 @@ cmp_diff16:
        RET
 
        // 0 through 16 bytes left, alen>=8, blen>=8
-cmp_0through16:
+_0through16:
        CMPQ    BP, $8
-       JBE     cmp_0through8
+       JBE     _0through8
        MOVQ    (SI), AX
        MOVQ    (DI), CX
        CMPQ    AX, CX
-       JNE     cmp_diff8
-cmp_0through8:
+       JNE     diff8
+_0through8:
        MOVQ    -8(SI)(BP*1), AX
        MOVQ    -8(DI)(BP*1), CX
        CMPQ    AX, CX
-       JEQ     cmp_allsame
+       JEQ     allsame
 
        // AX and CX contain parts of a and b that differ.
-cmp_diff8:
+diff8:
        BSWAPQ  AX      // reverse order of bytes
        BSWAPQ  CX
        XORQ    AX, CX
@@ -1241,44 +1241,44 @@ cmp_diff8:
        RET
 
        // 0-7 bytes in common
-cmp_small:
+small:
        LEAQ    (BP*8), CX      // bytes left -> bits left
        NEGQ    CX              //  - bits lift (== 64 - bits left mod 64)
-       JEQ     cmp_allsame
+       JEQ     allsame
 
        // load bytes of a into high bytes of AX
        CMPB    SI, $0xf8
-       JA      cmp_si_high
+       JA      si_high
        MOVQ    (SI), SI
-       JMP     cmp_si_finish
-cmp_si_high:
+       JMP     si_finish
+si_high:
        MOVQ    -8(SI)(BP*1), SI
        SHRQ    CX, SI
-cmp_si_finish:
+si_finish:
        SHLQ    CX, SI
 
        // load bytes of b in to high bytes of BX
        CMPB    DI, $0xf8
-       JA      cmp_di_high
+       JA      di_high
        MOVQ    (DI), DI
-       JMP     cmp_di_finish
-cmp_di_high:
+       JMP     di_finish
+di_high:
        MOVQ    -8(DI)(BP*1), DI
        SHRQ    CX, DI
-cmp_di_finish:
+di_finish:
        SHLQ    CX, DI
 
        BSWAPQ  SI      // reverse order of bytes
        BSWAPQ  DI
        XORQ    SI, DI  // find bit differences
-       JEQ     cmp_allsame
+       JEQ     allsame
        BSRQ    DI, CX  // index of highest bit difference
        SHRQ    CX, SI  // move a's bit to bottom
        ANDQ    $1, SI  // mask bit
        LEAQ    -1(SI*2), AX // 1/0 => +1/-1
        RET
 
-cmp_allsame:
+allsame:
        XORQ    AX, AX
        XORQ    CX, CX
        CMPQ    BX, DX
@@ -1313,7 +1313,7 @@ TEXT runtime·indexbytebody(SB),NOSPLIT,$0
        MOVQ SI, DI
 
        CMPQ BX, $16
-       JLT indexbyte_small
+       JLT small
 
        // round up to first 16-byte boundary
        TESTQ $15, SI
@@ -1371,7 +1371,7 @@ failure:
        RET
 
 // handle for lengths < 16
-indexbyte_small:
+small:
        MOVQ BX, CX
        REPN; SCASB
        JZ success
index 28875bc55a146a4e386b68c58f4731f3de0288ea..de3ef3a237fc996b4a8c2bff215de0edc47f1483 100644 (file)
@@ -444,11 +444,11 @@ TEXT runtime·cas64(SB), NOSPLIT, $0-25
        MOVQ    new+16(FP), CX
        LOCK
        CMPXCHGQ        CX, 0(BX)
-       JNZ     cas64_fail
+       JNZ     fail
        MOVL    $1, AX
        MOVB    AX, ret+24(FP)
        RET
-cas64_fail:
+fail:
        MOVL    $0, AX
        MOVB    AX, ret+24(FP)
        RET
@@ -834,29 +834,29 @@ TEXT runtime·cmpbytes(SB),NOSPLIT,$0-28
 //   AX = 1/0/-1
 TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
        CMPQ    SI, DI
-       JEQ     cmp_allsame
+       JEQ     allsame
        CMPQ    BX, DX
        MOVQ    DX, R8
        CMOVQLT BX, R8 // R8 = min(alen, blen) = # of bytes to compare
        CMPQ    R8, $8
-       JB      cmp_small
+       JB      small
 
-cmp_loop:
+loop:
        CMPQ    R8, $16
-       JBE     cmp_0through16
+       JBE     _0through16
        MOVOU   (SI), X0
        MOVOU   (DI), X1
        PCMPEQB X0, X1
        PMOVMSKB X1, AX
        XORQ    $0xffff, AX     // convert EQ to NE
-       JNE     cmp_diff16      // branch if at least one byte is not equal
+       JNE     diff16  // branch if at least one byte is not equal
        ADDQ    $16, SI
        ADDQ    $16, DI
        SUBQ    $16, R8
-       JMP     cmp_loop
+       JMP     loop
        
        // AX = bit mask of differences
-cmp_diff16:
+diff16:
        BSFQ    AX, BX  // index of first byte that differs
        XORQ    AX, AX
        ADDQ    BX, SI
@@ -868,23 +868,23 @@ cmp_diff16:
        RET
 
        // 0 through 16 bytes left, alen>=8, blen>=8
-cmp_0through16:
+_0through16:
        CMPQ    R8, $8
-       JBE     cmp_0through8
+       JBE     _0through8
        MOVQ    (SI), AX
        MOVQ    (DI), CX
        CMPQ    AX, CX
-       JNE     cmp_diff8
-cmp_0through8:
+       JNE     diff8
+_0through8:
        ADDQ    R8, SI
        ADDQ    R8, DI
        MOVQ    -8(SI), AX
        MOVQ    -8(DI), CX
        CMPQ    AX, CX
-       JEQ     cmp_allsame
+       JEQ     allsame
 
        // AX and CX contain parts of a and b that differ.
-cmp_diff8:
+diff8:
        BSWAPQ  AX      // reverse order of bytes
        BSWAPQ  CX
        XORQ    AX, CX
@@ -895,46 +895,46 @@ cmp_diff8:
        RET
 
        // 0-7 bytes in common
-cmp_small:
+small:
        LEAQ    (R8*8), CX      // bytes left -> bits left
        NEGQ    CX              //  - bits lift (== 64 - bits left mod 64)
-       JEQ     cmp_allsame
+       JEQ     allsame
 
        // load bytes of a into high bytes of AX
        CMPB    SI, $0xf8
-       JA      cmp_si_high
+       JA      si_high
        MOVQ    (SI), SI
-       JMP     cmp_si_finish
-cmp_si_high:
+       JMP     si_finish
+si_high:
        ADDQ    R8, SI
        MOVQ    -8(SI), SI
        SHRQ    CX, SI
-cmp_si_finish:
+si_finish:
        SHLQ    CX, SI
 
        // load bytes of b in to high bytes of BX
        CMPB    DI, $0xf8
-       JA      cmp_di_high
+       JA      di_high
        MOVQ    (DI), DI
-       JMP     cmp_di_finish
-cmp_di_high:
+       JMP     di_finish
+di_high:
        ADDQ    R8, DI
        MOVQ    -8(DI), DI
        SHRQ    CX, DI
-cmp_di_finish:
+di_finish:
        SHLQ    CX, DI
 
        BSWAPQ  SI      // reverse order of bytes
        BSWAPQ  DI
        XORQ    SI, DI  // find bit differences
-       JEQ     cmp_allsame
+       JEQ     allsame
        BSRQ    DI, CX  // index of highest bit difference
        SHRQ    CX, SI  // move a's bit to bottom
        ANDQ    $1, SI  // mask bit
        LEAQ    -1(SI*2), AX // 1/0 => +1/-1
        RET
 
-cmp_allsame:
+allsame:
        XORQ    AX, AX
        XORQ    CX, CX
        CMPQ    BX, DX
@@ -969,7 +969,7 @@ TEXT runtime·indexbytebody(SB),NOSPLIT,$0
        MOVL SI, DI
 
        CMPL BX, $16
-       JLT indexbyte_small
+       JLT small
 
        // round up to first 16-byte boundary
        TESTL $15, SI
@@ -1027,7 +1027,7 @@ failure:
        RET
 
 // handle for lengths < 16
-indexbyte_small:
+small:
        MOVL BX, CX
        REPN; SCASB
        JZ success
index e94b4c1ff61560f3424b45ff0dc9c758980e1dae..9a58fdc51e25a1d4e9853c6d0a47f68fd6933cd1 100644 (file)
@@ -492,7 +492,7 @@ TEXT asmcgocall<>(SB),NOSPLIT,$0-0
        MOVW    g_m(g), R8
        MOVW    m_g0(R8), R3
        CMP     R3, g
-       BEQ     asmcgocall_g0
+       BEQ     g0
        BL      gosave<>(SB)
        MOVW    R0, R5
        MOVW    R3, R0
@@ -501,7 +501,7 @@ TEXT asmcgocall<>(SB),NOSPLIT,$0-0
        MOVW    (g_sched+gobuf_sp)(g), R13
 
        // Now on a scheduling stack (a pthread-created stack).
-asmcgocall_g0:
+g0:
        SUB     $24, R13
        BIC     $0x7, R13       // alignment for gcc ABI
        MOVW    R4, 20(R13) // save old g
@@ -751,13 +751,13 @@ TEXT runtime·memeq(SB),NOSPLIT,$-4-13
        ADD     R1, R3, R6
        MOVW    $1, R0
        MOVB    R0, ret+12(FP)
-_next2:
+loop:
        CMP     R1, R6
        RET.EQ
        MOVBU.P 1(R1), R4
        MOVBU.P 1(R2), R5
        CMP     R4, R5
-       BEQ     _next2
+       BEQ     loop
 
        MOVW    $0, R0
        MOVB    R0, ret+12(FP)
@@ -780,13 +780,13 @@ TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
        CMP     R2, R3
        RET.EQ
        ADD     R2, R0, R6
-_eqnext:
+loop:
        CMP     R2, R6
        RET.EQ
        MOVBU.P 1(R2), R4
        MOVBU.P 1(R3), R5
        CMP     R4, R5
-       BEQ     _eqnext
+       BEQ     loop
        MOVB    R7, v+16(FP)
        RET
 
@@ -801,26 +801,26 @@ TEXT bytes·Equal(SB),NOSPLIT,$0
        MOVW    b_len+16(FP), R3
        
        CMP     R1, R3          // unequal lengths are not equal
-       B.NE    _notequal
+       B.NE    notequal
 
        MOVW    a+0(FP), R0
        MOVW    b+12(FP), R2
        ADD     R0, R1          // end
 
-_byteseq_next:
+loop:
        CMP     R0, R1
-       B.EQ    _equal          // reached the end
+       B.EQ    equal           // reached the end
        MOVBU.P 1(R0), R4
        MOVBU.P 1(R2), R5
        CMP     R4, R5
-       B.EQ    _byteseq_next
+       B.EQ    loop
 
-_notequal:
+notequal:
        MOVW    $0, R0
        MOVBU   R0, ret+24(FP)
        RET
 
-_equal:
+equal:
        MOVW    $1, R0
        MOVBU   R0, ret+24(FP)
        RET
diff --git a/src/runtime/asm_power64x.s b/src/runtime/asm_power64x.s
new file mode 100644 (file)
index 0000000..f776580
--- /dev/null
@@ -0,0 +1,981 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "zasm_GOOS_GOARCH.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+TEXT runtime·rt0_go(SB),NOSPLIT,$0
+       // initialize essential registers
+       BL      runtime·reginit(SB)
+
+       SUB     $24, R1
+       MOVW    R3, 8(R1) // argc
+       MOVD    R4, 16(R1) // argv
+
+       // create istack out of the given (operating system) stack.
+       // _cgo_init may update stackguard.
+       MOVD    $runtime·g0(SB), g
+       MOVD    $(-64*1024), R31
+       ADD     R31, R1, R3
+       MOVD    R3, g_stackguard0(g)
+       MOVD    R3, g_stackguard1(g)
+       MOVD    R3, (g_stack+stack_lo)(g)
+       MOVD    R1, (g_stack+stack_hi)(g)
+
+       // TODO: if there is a _cgo_init, call it.
+       // TODO: add TLS
+
+       // set the per-goroutine and per-mach "registers"
+       MOVD    $runtime·m0(SB), R3
+
+       // save m->g0 = g0
+       MOVD    g, m_g0(R3)
+       // save m0 to g0->m
+       MOVD    R3, g_m(g)
+
+       BL      runtime·check(SB)
+
+       // args are already prepared
+       BL      runtime·args(SB)
+       BL      runtime·osinit(SB)
+       BL      runtime·schedinit(SB)
+
+       // create a new goroutine to start program
+       MOVD    $runtime·main·f(SB), R3               // entry
+       MOVDU   R3, -8(R1)
+       MOVDU   R0, -8(R1)
+       MOVDU   R0, -8(R1)
+       BL      runtime·newproc(SB)
+       ADD     $24, R1
+
+       // start this M
+       BL      runtime·mstart(SB)
+
+       MOVD    R0, 1(R0)
+       RETURN
+
+DATA   runtime·main·f+0(SB)/8,$runtime·main(SB)
+GLOBL  runtime·main·f(SB),RODATA,$8
+
+TEXT runtime·breakpoint(SB),NOSPLIT,$-8-0
+       MOVD    R0, 2(R0) // TODO: TD
+       RETURN
+
+TEXT runtime·asminit(SB),NOSPLIT,$-8-0
+       RETURN
+
+TEXT runtime·reginit(SB),NOSPLIT,$-8-0
+       // set R0 to zero, it's expected by the toolchain
+       XOR R0, R0
+       // initialize essential FP registers
+       FMOVD   $4503601774854144.0, F27
+       FMOVD   $0.5, F29
+       FSUB    F29, F29, F28
+       FADD    F29, F29, F30
+       FADD    F30, F30, F31
+       RETURN
+
+/*
+ *  go-routine
+ */
+
+// void gosave(Gobuf*)
+// save state in Gobuf; setjmp
+TEXT runtime·gosave(SB), NOSPLIT, $-8-8
+       MOVD    gobuf+0(FP), R3
+       MOVD    R1, gobuf_sp(R3)
+       MOVD    LR, R31
+       MOVD    R31, gobuf_pc(R3)
+       MOVD    g, gobuf_g(R3)
+       MOVD    R0, gobuf_lr(R3)
+       MOVD    R0, gobuf_ret(R3)
+       MOVD    R0, gobuf_ctxt(R3)
+       RETURN
+
+// void gogo(Gobuf*)
+// restore state from Gobuf; longjmp
+TEXT runtime·gogo(SB), NOSPLIT, $-8-8
+       MOVD    gobuf+0(FP), R5
+       MOVD    gobuf_g(R5), g  // make sure g is not nil
+       MOVD    0(g), R4
+       MOVD    gobuf_sp(R5), R1
+       MOVD    gobuf_lr(R5), R31
+       MOVD    R31, LR
+       MOVD    gobuf_ret(R5), R3
+       MOVD    gobuf_ctxt(R5), R11
+       MOVD    R0, gobuf_sp(R5)
+       MOVD    R0, gobuf_ret(R5)
+       MOVD    R0, gobuf_lr(R5)
+       MOVD    R0, gobuf_ctxt(R5)
+       CMP     R0, R0 // set condition codes for == test, needed by stack split
+       MOVD    gobuf_pc(R5), R31
+       MOVD    R31, CTR
+       BR      (CTR)
+
+// void mcall(fn func(*g))
+// Switch to m->g0's stack, call fn(g).
+// Fn must never return.  It should gogo(&g->sched)
+// to keep running g.
+TEXT runtime·mcall(SB), NOSPLIT, $-8-8
+       // Save caller state in g->sched
+       MOVD    R1, (g_sched+gobuf_sp)(g)
+       MOVD    LR, R31
+       MOVD    R31, (g_sched+gobuf_pc)(g)
+       MOVD    R0, (g_sched+gobuf_lr)(g)
+       MOVD    g, (g_sched+gobuf_g)(g)
+
+       // Switch to m->g0 & its stack, call fn.
+       MOVD    g, R3
+       MOVD    g_m(g), R8
+       MOVD    m_g0(R8), g
+       CMP     g, R3
+       BNE     2(PC)
+       BR      runtime·badmcall(SB)
+       MOVD    fn+0(FP), R11                   // context
+       MOVD    0(R11), R4                      // code pointer
+       MOVD    R4, CTR
+       MOVD    (g_sched+gobuf_sp)(g), R1       // sp = m->g0->sched.sp
+       MOVDU   R3, -8(R1)
+       MOVDU   R0, -8(R1)
+       BL      (CTR)
+       BR      runtime·badmcall2(SB)
+
+// switchtoM is a dummy routine that onM leaves at the bottom
+// of the G stack.  We need to distinguish the routine that
+// lives at the bottom of the G stack from the one that lives
+// at the top of the M stack because the one at the top of
+// the M stack terminates the stack walk (see topofstack()).
+TEXT runtime·switchtoM(SB), NOSPLIT, $0-0
+       UNDEF
+       BL      (LR)    // make sure this function is not leaf
+       RETURN
+
+// func onM_signalok(fn func())
+TEXT runtime·onM_signalok(SB), NOSPLIT, $8-8
+       MOVD    g, R3                   // R3 = g
+       MOVD    g_m(R3), R4             // R4 = g->m
+       MOVD    m_gsignal(R4), R4       // R4 = g->m->gsignal
+       MOVD    fn+0(FP), R11           // context for call below
+       CMP     R3, R4
+       BEQ     onsignal
+       MOVD    R11, 8(R1)
+       BL      runtime·onM(SB)
+       RETURN
+
+onsignal:
+       MOVD    0(R11), R3              // code pointer
+       MOVD    R3, CTR
+       BL      (CTR)
+       RETURN
+
+// void onM(fn func())
+TEXT runtime·onM(SB), NOSPLIT, $0-8
+       MOVD    fn+0(FP), R3    // R3 = fn
+       MOVD    R3, R11         // context
+       MOVD    g_m(g), R4      // R4 = m
+
+       MOVD    m_g0(R4), R5    // R5 = g0
+       CMP     g, R5
+       BEQ     onm
+
+       MOVD    m_curg(R4), R6
+       CMP     g, R6
+       BEQ     oncurg
+
+       // Not g0, not curg. Must be gsignal, but that's not allowed.
+       // Hide call from linker nosplit analysis.
+       MOVD    $runtime·badonm(SB), R3
+       MOVD    R3, CTR
+       BL      (CTR)
+
+oncurg:
+       // save our state in g->sched.  Pretend to
+       // be switchtoM if the G stack is scanned.
+       MOVD    $runtime·switchtoM(SB), R6
+       ADD     $8, R6  // get past prologue
+       MOVD    R6, (g_sched+gobuf_pc)(g)
+       MOVD    R1, (g_sched+gobuf_sp)(g)
+       MOVD    R0, (g_sched+gobuf_lr)(g)
+       MOVD    g, (g_sched+gobuf_g)(g)
+
+       // switch to g0
+       MOVD    R5, g
+       MOVD    (g_sched+gobuf_sp)(g), R3
+       // make it look like mstart called onM on g0, to stop traceback
+       SUB     $8, R3
+       MOVD    $runtime·mstart(SB), R4
+       MOVD    R4, 0(R3)
+       MOVD    R3, R1
+
+       // call target function
+       MOVD    0(R11), R3      // code pointer
+       MOVD    R3, CTR
+       BL      (CTR)
+
+       // switch back to g
+       MOVD    g_m(g), R3
+       MOVD    m_curg(R3), g
+       MOVD    (g_sched+gobuf_sp)(g), R1
+       MOVD    R0, (g_sched+gobuf_sp)(g)
+       RETURN
+
+onm:
+       // already on m stack, just call directly
+       MOVD    0(R11), R3      // code pointer
+       MOVD    R3, CTR
+       BL      (CTR)
+       RETURN
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+// Caller has already loaded:
+// R3: framesize, R4: argsize, R5: LR
+//
+// The traceback routines see morestack on a g0 as being
+// the top of a stack (for example, morestack calling newstack
+// calling the scheduler calling newm calling gc), so we must
+// record an argument size. For that purpose, it has no arguments.
+TEXT runtime·morestack(SB),NOSPLIT,$-8-0
+       // Cannot grow scheduler stack (m->g0).
+       MOVD    g_m(g), R7
+       MOVD    m_g0(R7), R8
+       CMP     g, R8
+       BNE     2(PC)
+       BL      runtime·abort(SB)
+
+       // Cannot grow signal stack (m->gsignal).
+       MOVD    m_gsignal(R7), R8
+       CMP     g, R8
+       BNE     2(PC)
+       BL      runtime·abort(SB)
+
+       // Called from f.
+       // Set g->sched to context in f.
+       MOVD    R11, (g_sched+gobuf_ctxt)(g)
+       MOVD    R1, (g_sched+gobuf_sp)(g)
+       MOVD    LR, R8
+       MOVD    R8, (g_sched+gobuf_pc)(g)
+       MOVD    R5, (g_sched+gobuf_lr)(g)
+
+       // Called from f.
+       // Set m->morebuf to f's caller.
+       MOVD    R5, (m_morebuf+gobuf_pc)(R7)    // f's caller's PC
+       MOVD    R1, (m_morebuf+gobuf_sp)(R7)    // f's caller's SP
+       MOVD    g, (m_morebuf+gobuf_g)(R7)
+
+       // Call newstack on m->g0's stack.
+       MOVD    m_g0(R7), g
+       MOVD    (g_sched+gobuf_sp)(g), R1
+       BL      runtime·newstack(SB)
+
+       // Not reached, but make sure the return PC from the call to newstack
+       // is still in this function, and not the beginning of the next.
+       UNDEF
+
+TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-8-0
+       MOVD    R0, R11
+       BR      runtime·morestack(SB)
+
+// reflectcall: call a function with the given argument list
+// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
+// we don't have variable-sized frames, so we use a small number
+// of constant-sized-frame functions to encode a few bits of size in the pc.
+// Caution: ugly multiline assembly macros in your future!
+
+#define DISPATCH(NAME,MAXSIZE)         \
+       MOVD    $MAXSIZE, R31;          \
+       CMP     R3, R31;                \
+       BGT     4(PC);                  \
+       MOVD    $NAME(SB), R31; \
+       MOVD    R31, CTR;               \
+       BR      (CTR)
+// Note: can't just "BR NAME(SB)" - bad inlining results.
+
+TEXT Â·reflectcall(SB), NOSPLIT, $-8-24
+       MOVW argsize+16(FP), R3
+       DISPATCH(runtime·call16, 16)
+       DISPATCH(runtime·call32, 32)
+       DISPATCH(runtime·call64, 64)
+       DISPATCH(runtime·call128, 128)
+       DISPATCH(runtime·call256, 256)
+       DISPATCH(runtime·call512, 512)
+       DISPATCH(runtime·call1024, 1024)
+       DISPATCH(runtime·call2048, 2048)
+       DISPATCH(runtime·call4096, 4096)
+       DISPATCH(runtime·call8192, 8192)
+       DISPATCH(runtime·call16384, 16384)
+       DISPATCH(runtime·call32768, 32768)
+       DISPATCH(runtime·call65536, 65536)
+       DISPATCH(runtime·call131072, 131072)
+       DISPATCH(runtime·call262144, 262144)
+       DISPATCH(runtime·call524288, 524288)
+       DISPATCH(runtime·call1048576, 1048576)
+       DISPATCH(runtime·call2097152, 2097152)
+       DISPATCH(runtime·call4194304, 4194304)
+       DISPATCH(runtime·call8388608, 8388608)
+       DISPATCH(runtime·call16777216, 16777216)
+       DISPATCH(runtime·call33554432, 33554432)
+       DISPATCH(runtime·call67108864, 67108864)
+       DISPATCH(runtime·call134217728, 134217728)
+       DISPATCH(runtime·call268435456, 268435456)
+       DISPATCH(runtime·call536870912, 536870912)
+       DISPATCH(runtime·call1073741824, 1073741824)
+       MOVD    $runtime·badreflectcall(SB), R31
+       MOVD    R31, CTR
+       BR      (CTR)
+
+#define CALLFN(NAME,MAXSIZE)                   \
+TEXT NAME(SB), WRAPPER, $MAXSIZE-24;           \
+       NO_LOCAL_POINTERS;                      \
+       /* copy arguments to stack */           \
+       MOVD    argptr+8(FP), R3;               \
+       MOVW    argsize+16(FP), R4;             \
+       MOVD    R1, R5;                         \
+       ADD     $(8-1), R5;                     \
+       SUB     $1, R3;                         \
+       ADD     R5, R4;                         \
+       CMP     R5, R4;                         \
+       BEQ     4(PC);                          \
+       MOVBZU  1(R3), R6;                      \
+       MOVBZU  R6, 1(R5);                      \
+       BR      -4(PC);                         \
+       /* call function */                     \
+       MOVD    f+0(FP), R11;                   \
+       MOVD    (R11), R31;                     \
+       MOVD    R31, CTR;                       \
+       PCDATA  $PCDATA_StackMapIndex, $0;      \
+       BL      (CTR);                          \
+       /* copy return values back */           \
+       MOVD    argptr+8(FP), R3;               \
+       MOVW    argsize+16(FP), R4;             \
+       MOVW    retoffset+20(FP), R6;           \
+       MOVD    R1, R5;                         \
+       ADD     R6, R5;                         \
+       ADD     R6, R3;                         \
+       SUB     R6, R4;                         \
+       ADD     $(8-1), R5;                     \
+       SUB     $1, R3;                         \
+       ADD     R5, R4;                         \
+       CMP     R5, R4;                         \
+       BEQ     4(PC);                          \
+       MOVBZU  1(R5), R6;                      \
+       MOVBZU  R6, 1(R3);                      \
+       BR      -4(PC);                         \
+       RETURN
+
+CALLFN(·call16, 16)
+CALLFN(·call32, 32)
+CALLFN(·call64, 64)
+CALLFN(·call128, 128)
+CALLFN(·call256, 256)
+CALLFN(·call512, 512)
+CALLFN(·call1024, 1024)
+CALLFN(·call2048, 2048)
+CALLFN(·call4096, 4096)
+CALLFN(·call8192, 8192)
+CALLFN(·call16384, 16384)
+CALLFN(·call32768, 32768)
+CALLFN(·call65536, 65536)
+CALLFN(·call131072, 131072)
+CALLFN(·call262144, 262144)
+CALLFN(·call524288, 524288)
+CALLFN(·call1048576, 1048576)
+CALLFN(·call2097152, 2097152)
+CALLFN(·call4194304, 4194304)
+CALLFN(·call8388608, 8388608)
+CALLFN(·call16777216, 16777216)
+CALLFN(·call33554432, 33554432)
+CALLFN(·call67108864, 67108864)
+CALLFN(·call134217728, 134217728)
+CALLFN(·call268435456, 268435456)
+CALLFN(·call536870912, 536870912)
+CALLFN(·call1073741824, 1073741824)
+
+// bool cas(int32 *val, int32 old, int32 new)
+// Atomically:
+//     if(*val == old){
+//             *val = new;
+//             return 1;
+//     } else
+//             return 0;
+TEXT runtime·cas(SB), NOSPLIT, $0-17
+       MOVD    p+0(FP), R3
+       MOVW    old+8(FP), R4
+       MOVW    new+12(FP), R5
+cas_again:
+       SYNC
+       LWAR    (R3), R6
+       CMPW    R6, R4
+       BNE     cas_fail
+       STWCCC  R5, (R3)
+       BNE     cas_again
+       MOVD    $1, R3
+       SYNC
+       ISYNC
+       MOVB    R3, ret+16(FP)
+       RETURN
+cas_fail:
+       MOVD    $0, R3
+       BR      -5(PC)
+
+// bool        runtime·cas64(uint64 *val, uint64 old, uint64 new)
+// Atomically:
+//     if(*val == *old){
+//             *val = new;
+//             return 1;
+//     } else {
+//             return 0;
+//     }
+TEXT runtime·cas64(SB), NOSPLIT, $0-25
+       MOVD    p+0(FP), R3
+       MOVD    old+8(FP), R4
+       MOVD    new+16(FP), R5
+cas64_again:
+       SYNC
+       LDAR    (R3), R6
+       CMP     R6, R4
+       BNE     cas64_fail
+       STDCCC  R5, (R3)
+       BNE     cas64_again
+       MOVD    $1, R3
+       SYNC
+       ISYNC
+       MOVB    R3, ret+24(FP)
+       RETURN
+cas64_fail:
+       MOVD    $0, R3
+       BR      -5(PC)
+
+TEXT runtime·casuintptr(SB), NOSPLIT, $0-25
+       BR      runtime·cas64(SB)
+
+TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $-8-16
+       BR      runtime·atomicload64(SB)
+
+TEXT runtime·atomicloaduint(SB), NOSPLIT, $-8-16
+       BR      runtime·atomicload64(SB)
+
+TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16
+       BR      runtime·atomicstore64(SB)
+
+// bool casp(void **val, void *old, void *new)
+// Atomically:
+//     if(*val == old){
+//             *val = new;
+//             return 1;
+//     } else
+//             return 0;
+TEXT runtime·casp(SB), NOSPLIT, $0-25
+       BR runtime·cas64(SB)
+
+// uint32 xadd(uint32 volatile *val, int32 delta)
+// Atomically:
+//     *val += delta;
+//     return *val;
+TEXT runtime·xadd(SB), NOSPLIT, $0-20
+       MOVD    p+0(FP), R4
+       MOVW    delta+8(FP), R5
+       SYNC
+       LWAR    (R4), R3
+       ADD     R5, R3
+       STWCCC  R3, (R4)
+       BNE     -4(PC)
+       SYNC
+       ISYNC
+       MOVW    R3, ret+16(FP)
+       RETURN
+
+TEXT runtime·xadd64(SB), NOSPLIT, $0-24
+       MOVD    p+0(FP), R4
+       MOVD    delta+8(FP), R5
+       SYNC
+       LDAR    (R4), R3
+       ADD     R5, R3
+       STDCCC  R3, (R4)
+       BNE     -4(PC)
+       SYNC
+       ISYNC
+       MOVD    R3, ret+16(FP)
+       RETURN
+
+TEXT runtime·xchg(SB), NOSPLIT, $0-20
+       MOVD    p+0(FP), R4
+       MOVW    new+8(FP), R5
+       SYNC
+       LWAR    (R4), R3
+       STWCCC  R5, (R4)
+       BNE     -3(PC)
+       SYNC
+       ISYNC
+       MOVW    R3, ret+16(FP)
+       RETURN
+
+TEXT runtime·xchg64(SB), NOSPLIT, $0-24
+       MOVD    p+0(FP), R4
+       MOVD    new+8(FP), R5
+       SYNC
+       LDAR    (R4), R3
+       STDCCC  R5, (R4)
+       BNE     -3(PC)
+       SYNC
+       ISYNC
+       MOVD    R3, ret+16(FP)
+       RETURN
+
+TEXT runtime·xchgp(SB), NOSPLIT, $0-24
+       BR      runtime·xchg64(SB)
+
+TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24
+       BR      runtime·xchg64(SB)
+
+TEXT runtime·procyield(SB),NOSPLIT,$0-0
+       RETURN
+
+TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16
+       BR      runtime·atomicstore64(SB)
+
+TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
+       MOVD    ptr+0(FP), R3
+       MOVW    val+8(FP), R4
+       SYNC
+       MOVW    R4, 0(R3)
+       RETURN
+
+TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
+       MOVD    ptr+0(FP), R3
+       MOVD    val+8(FP), R4
+       SYNC
+       MOVD    R4, 0(R3)
+       RETURN
+
+// void        runtime·atomicor8(byte volatile*, byte);
+TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
+       MOVD    ptr+0(FP), R3
+       MOVBZ   val+8(FP), R4
+       // Align ptr down to 4 bytes so we can use 32-bit load/store.
+       // R5 = (R3 << 0) & ~3
+       RLDCR   $0, R3, $~3, R5
+       // Compute val shift.
+#ifdef GOARCH_power64
+       // Big endian.  ptr = ptr ^ 3
+       XOR     $3, R3
+#endif
+       // R6 = ((ptr & 3) * 8) = (ptr << 3) & (3*8)
+       RLDC    $3, R3, $(3*8), R6
+       // Shift val for aligned ptr.  R4 = val << R6
+       SLD     R6, R4, R4
+
+atomicor8_again:
+       SYNC
+       LWAR    (R5), R6
+       OR      R4, R6
+       STWCCC  R6, (R5)
+       BNE     atomicor8_again
+       SYNC
+       ISYNC
+       RETURN
+
+// void jmpdefer(fv, sp);
+// called from deferreturn.
+// 1. grab stored LR for caller
+// 2. sub 4 bytes to get back to BL deferreturn
+// 3. BR to fn
+TEXT runtime·jmpdefer(SB), NOSPLIT, $-8-16
+       MOVD    0(R1), R31
+       SUB     $4, R31
+       MOVD    R31, LR
+
+       MOVD    fv+0(FP), R11
+       MOVD    argp+8(FP), R1
+       SUB     $8, R1
+       MOVD    0(R11), R3
+       MOVD    R3, CTR
+       BR      (CTR)
+
+// Save state of caller into g->sched. Smashes R31.
+TEXT gosave<>(SB),NOSPLIT,$-8
+       MOVD    LR, R31
+       MOVD    R31, (g_sched+gobuf_pc)(g)
+       MOVD    R1, (g_sched+gobuf_sp)(g)
+       MOVD    R0, (g_sched+gobuf_lr)(g)
+       MOVD    R0, (g_sched+gobuf_ret)(g)
+       MOVD    R0, (g_sched+gobuf_ctxt)(g)
+       RETURN
+
+// asmcgocall(void(*fn)(void*), void *arg)
+// Call fn(arg) on the scheduler stack,
+// aligned appropriately for the gcc ABI.
+// See cgocall.c for more details.
+TEXT Â·asmcgocall(SB),NOSPLIT,$0-16
+       MOVD    R0, 21(R0)
+
+// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
+// Turn the fn into a Go func (by taking its address) and call
+// cgocallback_gofunc.
+TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
+       MOVD    R0, 22(R0)
+
+// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
+// See cgocall.c for more details.
+TEXT Â·cgocallback_gofunc(SB),NOSPLIT,$8-24
+       MOVD    R0, 23(R0)
+
+// void setg(G*); set g. for use by needm.
+TEXT runtime·setg(SB), NOSPLIT, $0-8
+       MOVD    R0, 24(R0)
+
+// void setg_gcc(G*); set g called from gcc.
+TEXT setg_gcc<>(SB),NOSPLIT,$0
+       MOVD    R0, 25(R0)
+
+TEXT runtime·getcallerpc(SB),NOSPLIT,$-8-16
+       MOVD    0(R1), R3
+       MOVD    R3, ret+8(FP)
+       RETURN
+
+TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-8-16
+       MOVD    0(R1), R3
+       MOVD    R3,ret+8(FP)
+       RETURN
+
+TEXT runtime·setcallerpc(SB),NOSPLIT,$-8-16
+       MOVD    pc+8(FP), R3
+       MOVD    R3, 0(R1)               // set calling pc
+       RETURN
+
+TEXT runtime·getcallersp(SB),NOSPLIT,$0-16
+       MOVD    sp+0(FP), R3
+       SUB     $8, R3
+       MOVD    R3, ret+8(FP)
+       RETURN
+
+// func gogetcallersp(p unsafe.Pointer) uintptr
+TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
+       MOVD    sp+0(FP), R3
+       SUB     $8, R3
+       MOVD    R3,ret+8(FP)
+       RETURN
+
+TEXT runtime·abort(SB),NOSPLIT,$-8-0
+       MOVW    (R0), R0
+       UNDEF
+
+#define        TBRL    268
+#define        TBRU    269             /* Time base Upper/Lower */
+
+// int64 runtime·cputicks(void)
+TEXT runtime·cputicks(SB),NOSPLIT,$0-8
+       MOVW    SPR(TBRU), R4
+       MOVW    SPR(TBRL), R3
+       MOVW    SPR(TBRU), R5
+       CMPW    R4, R5
+       BNE     -4(PC)
+       SLD     $32, R5
+       OR      R5, R3
+       MOVD    R3, ret+0(FP)
+       RETURN
+
+// AES hashing not implemented for Power
+TEXT runtime·aeshash(SB),NOSPLIT,$-8-0
+       MOVW    (R0), R1
+TEXT runtime·aeshash32(SB),NOSPLIT,$-8-0
+       MOVW    (R0), R1
+TEXT runtime·aeshash64(SB),NOSPLIT,$-8-0
+       MOVW    (R0), R1
+TEXT runtime·aeshashstr(SB),NOSPLIT,$-8-0
+       MOVW    (R0), R1
+
+TEXT runtime·memeq(SB),NOSPLIT,$-8-25
+       MOVD    a+0(FP), R3
+       MOVD    b+8(FP), R4
+       MOVD    count+16(FP), R5
+       SUB     $1, R3
+       SUB     $1, R4
+       ADD     R3, R5, R8
+loop:
+       CMP     R3, R8
+       BNE     4(PC)
+       MOVD    $1, R3
+       MOVB    R3, ret+24(FP)
+       RETURN
+       MOVBZU  1(R3), R6
+       MOVBZU  1(R4), R7
+       CMP     R6, R7
+       BEQ     loop
+
+       MOVB    R0, ret+24(FP)
+       RETURN
+
+// eqstring tests whether two strings are equal.
+// See runtime_test.go:eqstring_generic for
+// equivalent Go code.
+TEXT runtime·eqstring(SB),NOSPLIT,$0-33
+       MOVD    s1len+8(FP), R4
+       MOVD    s2len+24(FP), R5
+       CMP     R4, R5
+       BNE     noteq
+
+       MOVD    s1str+0(FP), R3
+       MOVD    s2str+16(FP), R4
+       SUB     $1, R3
+       SUB     $1, R4
+       ADD     R3, R5, R8
+loop:
+       CMP     R3, R8
+       BNE     4(PC)
+       MOVD    $1, R3
+       MOVB    R3, ret+32(FP)
+       RETURN
+       MOVBZU  1(R3), R6
+       MOVBZU  1(R4), R7
+       CMP     R6, R7
+       BEQ     loop
+noteq:
+       MOVB    R0, ret+32(FP)
+       RETURN
+
+// TODO: share code with memeq?
+TEXT bytes·Equal(SB),NOSPLIT,$0-49
+       MOVD    a_len+8(FP), R3
+       MOVD    b_len+32(FP), R4
+
+       CMP     R3, R4          // unequal lengths are not equal
+       BNE     noteq
+
+       MOVD    a+0(FP), R5
+       MOVD    b+24(FP), R6
+       SUB     $1, R5
+       SUB     $1, R6
+       ADD     R5, R3          // end-1
+
+loop:
+       CMP     R5, R3
+       BEQ     equal           // reached the end
+       MOVBZU  1(R5), R4
+       MOVBZU  1(R6), R7
+       CMP     R4, R7
+       BEQ     loop
+
+noteq:
+       MOVBZ   R0, ret+48(FP)
+       RETURN
+
+equal:
+       MOVD    $1, R3
+       MOVBZ   R3, ret+48(FP)
+       RETURN
+
+TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
+       MOVD    s+0(FP), R3
+       MOVD    s_len+8(FP), R4
+       MOVBZ   c+24(FP), R5    // byte to find
+       MOVD    R3, R6          // store base for later
+       SUB     $1, R3
+       ADD     R3, R4          // end-1
+
+loop:
+       CMP     R3, R4
+       BEQ     notfound
+       MOVBZU  1(R3), R7
+       CMP     R7, R5
+       BNE     loop
+
+       SUB     R6, R3          // remove base
+       MOVD    R3, ret+32(FP)
+       RETURN
+
+notfound:
+       MOVD    $-1, R3
+       MOVD    R3, ret+32(FP)
+       RETURN
+
+TEXT strings·IndexByte(SB),NOSPLIT,$0
+       MOVD    p+0(FP), R3
+       MOVD    b_len+8(FP), R4
+       MOVBZ   c+16(FP), R5    // byte to find
+       MOVD    R3, R6          // store base for later
+       SUB     $1, R3
+       ADD     R3, R4          // end-1
+
+loop:
+       CMP     R3, R4
+       BEQ     notfound
+       MOVBZU  1(R3), R7
+       CMP     R7, R5
+       BNE     loop
+
+       SUB     R6, R3          // remove base
+       MOVD    R3, ret+24(FP)
+       RETURN
+
+notfound:
+       MOVD    $-1, R3
+       MOVD    R3, ret+24(FP)
+       RETURN
+
+
+// A Duff's device for zeroing memory.
+// The compiler jumps to computed addresses within
+// this routine to zero chunks of memory.  Do not
+// change this code without also changing the code
+// in ../../cmd/9g/ggen.c:/^clearfat.
+// R0: always zero
+// R3 (aka REGRT1): ptr to memory to be zeroed - 8
+// R3 is updated as a side effect.
+TEXT runtime·duffzero(SB), NOSPLIT, $-8-0
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       MOVDU   R0, 8(R3)
+       RETURN
+
+TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
+       MOVD    g_m(g), R4
+       MOVWZ   m_fastrand(R4), R3
+       ADD     R3, R3
+       CMP     R3, $0
+       BGE     2(PC)
+       XOR     $0x88888eef, R3
+       MOVW    R3, m_fastrand(R4)
+       MOVW    R3, ret+0(FP)
+       RETURN
+
+TEXT runtime·return0(SB), NOSPLIT, $0
+       MOVW    $0, R3
+       RETURN
+
+// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
+// Must obey the gcc calling convention.
+TEXT _cgo_topofstack(SB),NOSPLIT,$0
+       MOVD    R0, 26(R0)
diff --git a/src/runtime/atomic_power64x.s b/src/runtime/atomic_power64x.s
new file mode 100644 (file)
index 0000000..e728717
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "textflag.h"
+
+// uint32 runtime·atomicload(uint32 volatile* addr)
+TEXT Â·atomicload(SB),NOSPLIT,$-8-12
+       MOVD    0(FP), R3
+       SYNC
+       MOVWZ   0(R3), R3
+       CMPW    R3, R3, CR7
+       BC      4, 30, 1(PC) // bne- cr7,0x4
+       ISYNC
+       MOVW    R3, ret+8(FP)
+       RETURN
+
+// uint64 runtime·atomicload64(uint64 volatile* addr)
+TEXT Â·atomicload64(SB),NOSPLIT,$-8-16
+       MOVD    0(FP), R3
+       SYNC
+       MOVD    0(R3), R3
+       CMP     R3, R3, CR7
+       BC      4, 30, 1(PC) // bne- cr7,0x4
+       ISYNC
+       MOVD    R3, ret+8(FP)
+       RETURN
+
+// void *runtime·atomicloadp(void *volatile *addr)
+TEXT Â·atomicloadp(SB),NOSPLIT,$-8-16
+       MOVD    0(FP), R3
+       SYNC
+       MOVD    0(R3), R3
+       CMP     R3, R3, CR7
+       BC      4, 30, 1(PC) // bne- cr7,0x4
+       ISYNC
+       MOVD    R3, ret+8(FP)
+       RETURN
index d56274f2dc7576e117b824f4f26cf7b9a1aa602f..1e883b72c0d3c25e9e0a90d6be8728ef762528c6 100644 (file)
@@ -7,6 +7,12 @@
 #ifdef GOARCH_arm
 #define JMP B
 #endif
+#ifdef GOARCH_power64
+#define JMP BR
+#endif
+#ifdef GOARCH_power64le
+#define JMP BR
+#endif
 
 TEXT Â·setMaxStack(SB),NOSPLIT,$0-0
   JMP runtime·setMaxStack(SB)
index 392cc4ab58e6aafaf51b09eaf68f7dbd4ae54c96..87c6e02a41c7be5d969e7276ae62e0d226aaf3bd 100644 (file)
@@ -15,12 +15,14 @@ package runtime
 /*
 #include <ucontext.h>
 #include <fcntl.h>
+#include <asm/signal.h>
 */
 import "C"
 
 const (
-       O_RDONLY  = C.O_RDONLY
-       O_CLOEXEC = C.O_CLOEXEC
+       O_RDONLY    = C.O_RDONLY
+       O_CLOEXEC   = C.O_CLOEXEC
+       SA_RESTORER = C.SA_RESTORER
 )
 
 type Usigset C.__sigset_t
diff --git a/src/runtime/defs3_linux.go b/src/runtime/defs3_linux.go
new file mode 100644 (file)
index 0000000..3551a4f
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo -cdefs
+
+GOARCH=power64 cgo -cdefs defs_linux.go defs3_linux.go > defs_linux_power64.h
+*/
+
+package runtime
+
+/*
+#define size_t __kernel_size_t
+#define sigset_t __sigset_t // rename the sigset_t here otherwise cgo will complain about "inconsistent definitions for C.sigset_t"
+#define        _SYS_TYPES_H    // avoid inclusion of sys/types.h
+#include <asm/ucontext.h>
+#include <asm-generic/fcntl.h>
+*/
+import "C"
+
+const (
+       O_RDONLY    = C.O_RDONLY
+       O_CLOEXEC   = C.O_CLOEXEC
+       SA_RESTORER = 0 // unused
+)
+
+type Usigset C.__sigset_t
+
+// types used in sigcontext
+type Ptregs C.struct_pt_regs
+type Gregset C.elf_gregset_t
+type FPregset C.elf_fpregset_t
+type Vreg C.elf_vrreg_t
+
+type SigaltstackT C.struct_sigaltstack
+
+// PPC64 uses sigcontext in place of mcontext in ucontext.
+// see http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/include/uapi/asm/ucontext.h
+type Sigcontext C.struct_sigcontext
+type Ucontext C.struct_ucontext
index 8657dbb0ecf3db72674bc9b0672d7a197e81f9eb..553366a50ba6c5adc70f4cf1cb390d0bf363bb86 100644 (file)
@@ -20,6 +20,7 @@ package runtime
 // headers for things like ucontext_t, so that happens in
 // a separate file, defs1.go.
 
+#define        _SYS_TYPES_H    // avoid inclusion of sys/types.h
 #include <asm/posix_types.h>
 #define size_t __kernel_size_t
 #include <asm/signal.h>
@@ -28,7 +29,7 @@ package runtime
 #include <asm-generic/errno.h>
 #include <asm-generic/poll.h>
 #include <linux/eventpoll.h>
-#undef size_t
+#include <linux/time.h>
 */
 import "C"
 
@@ -48,10 +49,9 @@ const (
 
        MADV_DONTNEED = C.MADV_DONTNEED
 
-       SA_RESTART  = C.SA_RESTART
-       SA_ONSTACK  = C.SA_ONSTACK
-       SA_RESTORER = C.SA_RESTORER
-       SA_SIGINFO  = C.SA_SIGINFO
+       SA_RESTART = C.SA_RESTART
+       SA_ONSTACK = C.SA_ONSTACK
+       SA_SIGINFO = C.SA_SIGINFO
 
        SIGHUP    = C.SIGHUP
        SIGINT    = C.SIGINT
@@ -116,6 +116,7 @@ const (
        EPOLL_CTL_MOD = C.EPOLL_CTL_MOD
 )
 
+type Sigset C.sigset_t
 type Timespec C.struct_timespec
 type Timeval C.struct_timeval
 type Sigaction C.struct_sigaction
diff --git a/src/runtime/defs_linux_power64.h b/src/runtime/defs_linux_power64.h
new file mode 100644 (file)
index 0000000..93742fa
--- /dev/null
@@ -0,0 +1,204 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_linux.go defs3_linux.go
+
+
+enum {
+       EINTR   = 0x4,
+       EAGAIN  = 0xb,
+       ENOMEM  = 0xc,
+
+       PROT_NONE       = 0x0,
+       PROT_READ       = 0x1,
+       PROT_WRITE      = 0x2,
+       PROT_EXEC       = 0x4,
+
+       MAP_ANON        = 0x20,
+       MAP_PRIVATE     = 0x2,
+       MAP_FIXED       = 0x10,
+
+       MADV_DONTNEED   = 0x4,
+
+       SA_RESTART      = 0x10000000,
+       SA_ONSTACK      = 0x8000000,
+       SA_SIGINFO      = 0x4,
+
+       SIGHUP          = 0x1,
+       SIGINT          = 0x2,
+       SIGQUIT         = 0x3,
+       SIGILL          = 0x4,
+       SIGTRAP         = 0x5,
+       SIGABRT         = 0x6,
+       SIGBUS          = 0x7,
+       SIGFPE          = 0x8,
+       SIGKILL         = 0x9,
+       SIGUSR1         = 0xa,
+       SIGSEGV         = 0xb,
+       SIGUSR2         = 0xc,
+       SIGPIPE         = 0xd,
+       SIGALRM         = 0xe,
+       SIGSTKFLT       = 0x10,
+       SIGCHLD         = 0x11,
+       SIGCONT         = 0x12,
+       SIGSTOP         = 0x13,
+       SIGTSTP         = 0x14,
+       SIGTTIN         = 0x15,
+       SIGTTOU         = 0x16,
+       SIGURG          = 0x17,
+       SIGXCPU         = 0x18,
+       SIGXFSZ         = 0x19,
+       SIGVTALRM       = 0x1a,
+       SIGPROF         = 0x1b,
+       SIGWINCH        = 0x1c,
+       SIGIO           = 0x1d,
+       SIGPWR          = 0x1e,
+       SIGSYS          = 0x1f,
+
+       FPE_INTDIV      = 0x1,
+       FPE_INTOVF      = 0x2,
+       FPE_FLTDIV      = 0x3,
+       FPE_FLTOVF      = 0x4,
+       FPE_FLTUND      = 0x5,
+       FPE_FLTRES      = 0x6,
+       FPE_FLTINV      = 0x7,
+       FPE_FLTSUB      = 0x8,
+
+       BUS_ADRALN      = 0x1,
+       BUS_ADRERR      = 0x2,
+       BUS_OBJERR      = 0x3,
+
+       SEGV_MAPERR     = 0x1,
+       SEGV_ACCERR     = 0x2,
+
+       ITIMER_REAL     = 0x0,
+       ITIMER_VIRTUAL  = 0x1,
+       ITIMER_PROF     = 0x2,
+
+       EPOLLIN         = 0x1,
+       EPOLLOUT        = 0x4,
+       EPOLLERR        = 0x8,
+       EPOLLHUP        = 0x10,
+       EPOLLRDHUP      = 0x2000,
+       EPOLLET         = -0x80000000,
+       EPOLL_CLOEXEC   = 0x80000,
+       EPOLL_CTL_ADD   = 0x1,
+       EPOLL_CTL_DEL   = 0x2,
+       EPOLL_CTL_MOD   = 0x3,
+};
+
+typedef struct Sigset Sigset;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct SigactionT SigactionT;
+typedef struct Siginfo Siginfo;
+typedef struct Itimerval Itimerval;
+typedef struct EpollEvent EpollEvent;
+
+#pragma pack on
+
+//struct Sigset {
+//     uint64  sig[1];
+//};
+//typedef uint64 Sigset;
+
+struct Timespec {
+       int64   tv_sec;
+       int64   tv_nsec;
+};
+struct Timeval {
+       int64   tv_sec;
+       int64   tv_usec;
+};
+struct SigactionT {
+       void    *sa_handler;
+       uint64  sa_flags;
+       void    *sa_restorer;
+       uint64  sa_mask;
+};
+struct Siginfo {
+       int32   si_signo;
+       int32   si_errno;
+       int32   si_code;
+       byte    Pad_cgo_0[4];
+       byte    _sifields[112];
+};
+struct Itimerval {
+       Timeval it_interval;
+       Timeval it_value;
+};
+struct EpollEvent {
+       uint32  events;
+       byte    Pad_cgo_0[4];
+       byte    data[8]; // unaligned uintptr
+};
+
+
+#pragma pack off
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_linux.go defs3_linux.go
+
+
+enum {
+       O_RDONLY        = 0x0,
+       O_CLOEXEC       = 0x80000,
+       SA_RESTORER     = 0,
+};
+
+typedef struct Ptregs Ptregs;
+typedef struct Vreg Vreg;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigcontext Sigcontext;
+typedef struct Ucontext Ucontext;
+
+#pragma pack on
+
+struct Ptregs {
+       uint64  gpr[32];
+       uint64  nip;
+       uint64  msr;
+       uint64  orig_gpr3;
+       uint64  ctr;
+       uint64  link;
+       uint64  xer;
+       uint64  ccr;
+       uint64  softe;
+       uint64  trap;
+       uint64  dar;
+       uint64  dsisr;
+       uint64  result;
+};
+typedef        uint64  Gregset[48];
+typedef        float64 FPregset[33];
+struct Vreg {
+       uint32  u[4];
+};
+
+struct SigaltstackT {
+       byte    *ss_sp;
+       int32   ss_flags;
+       byte    Pad_cgo_0[4];
+       uint64  ss_size;
+};
+
+struct Sigcontext {
+       uint64  _unused[4];
+       int32   signal;
+       int32   _pad0;
+       uint64  handler;
+       uint64  oldmask;
+       Ptregs  *regs;
+       uint64  gp_regs[48];
+       float64 fp_regs[33];
+       Vreg    *v_regs;
+       int64   vmx_reserve[101];
+};
+struct Ucontext {
+       uint64  uc_flags;
+       Ucontext        *uc_link;
+       SigaltstackT    uc_stack;
+       uint64  uc_sigmask;
+       uint64  __unused[15];
+       Sigcontext      uc_mcontext;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_linux_power64le.h b/src/runtime/defs_linux_power64le.h
new file mode 100644 (file)
index 0000000..93742fa
--- /dev/null
@@ -0,0 +1,204 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_linux.go defs3_linux.go
+
+
+enum {
+       EINTR   = 0x4,
+       EAGAIN  = 0xb,
+       ENOMEM  = 0xc,
+
+       PROT_NONE       = 0x0,
+       PROT_READ       = 0x1,
+       PROT_WRITE      = 0x2,
+       PROT_EXEC       = 0x4,
+
+       MAP_ANON        = 0x20,
+       MAP_PRIVATE     = 0x2,
+       MAP_FIXED       = 0x10,
+
+       MADV_DONTNEED   = 0x4,
+
+       SA_RESTART      = 0x10000000,
+       SA_ONSTACK      = 0x8000000,
+       SA_SIGINFO      = 0x4,
+
+       SIGHUP          = 0x1,
+       SIGINT          = 0x2,
+       SIGQUIT         = 0x3,
+       SIGILL          = 0x4,
+       SIGTRAP         = 0x5,
+       SIGABRT         = 0x6,
+       SIGBUS          = 0x7,
+       SIGFPE          = 0x8,
+       SIGKILL         = 0x9,
+       SIGUSR1         = 0xa,
+       SIGSEGV         = 0xb,
+       SIGUSR2         = 0xc,
+       SIGPIPE         = 0xd,
+       SIGALRM         = 0xe,
+       SIGSTKFLT       = 0x10,
+       SIGCHLD         = 0x11,
+       SIGCONT         = 0x12,
+       SIGSTOP         = 0x13,
+       SIGTSTP         = 0x14,
+       SIGTTIN         = 0x15,
+       SIGTTOU         = 0x16,
+       SIGURG          = 0x17,
+       SIGXCPU         = 0x18,
+       SIGXFSZ         = 0x19,
+       SIGVTALRM       = 0x1a,
+       SIGPROF         = 0x1b,
+       SIGWINCH        = 0x1c,
+       SIGIO           = 0x1d,
+       SIGPWR          = 0x1e,
+       SIGSYS          = 0x1f,
+
+       FPE_INTDIV      = 0x1,
+       FPE_INTOVF      = 0x2,
+       FPE_FLTDIV      = 0x3,
+       FPE_FLTOVF      = 0x4,
+       FPE_FLTUND      = 0x5,
+       FPE_FLTRES      = 0x6,
+       FPE_FLTINV      = 0x7,
+       FPE_FLTSUB      = 0x8,
+
+       BUS_ADRALN      = 0x1,
+       BUS_ADRERR      = 0x2,
+       BUS_OBJERR      = 0x3,
+
+       SEGV_MAPERR     = 0x1,
+       SEGV_ACCERR     = 0x2,
+
+       ITIMER_REAL     = 0x0,
+       ITIMER_VIRTUAL  = 0x1,
+       ITIMER_PROF     = 0x2,
+
+       EPOLLIN         = 0x1,
+       EPOLLOUT        = 0x4,
+       EPOLLERR        = 0x8,
+       EPOLLHUP        = 0x10,
+       EPOLLRDHUP      = 0x2000,
+       EPOLLET         = -0x80000000,
+       EPOLL_CLOEXEC   = 0x80000,
+       EPOLL_CTL_ADD   = 0x1,
+       EPOLL_CTL_DEL   = 0x2,
+       EPOLL_CTL_MOD   = 0x3,
+};
+
+typedef struct Sigset Sigset;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct SigactionT SigactionT;
+typedef struct Siginfo Siginfo;
+typedef struct Itimerval Itimerval;
+typedef struct EpollEvent EpollEvent;
+
+#pragma pack on
+
+//struct Sigset {
+//     uint64  sig[1];
+//};
+//typedef uint64 Sigset;
+
+struct Timespec {
+       int64   tv_sec;
+       int64   tv_nsec;
+};
+struct Timeval {
+       int64   tv_sec;
+       int64   tv_usec;
+};
+struct SigactionT {
+       void    *sa_handler;
+       uint64  sa_flags;
+       void    *sa_restorer;
+       uint64  sa_mask;
+};
+struct Siginfo {
+       int32   si_signo;
+       int32   si_errno;
+       int32   si_code;
+       byte    Pad_cgo_0[4];
+       byte    _sifields[112];
+};
+struct Itimerval {
+       Timeval it_interval;
+       Timeval it_value;
+};
+struct EpollEvent {
+       uint32  events;
+       byte    Pad_cgo_0[4];
+       byte    data[8]; // unaligned uintptr
+};
+
+
+#pragma pack off
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_linux.go defs3_linux.go
+
+
+enum {
+       O_RDONLY        = 0x0,
+       O_CLOEXEC       = 0x80000,
+       SA_RESTORER     = 0,
+};
+
+typedef struct Ptregs Ptregs;
+typedef struct Vreg Vreg;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigcontext Sigcontext;
+typedef struct Ucontext Ucontext;
+
+#pragma pack on
+
+struct Ptregs {
+       uint64  gpr[32];
+       uint64  nip;
+       uint64  msr;
+       uint64  orig_gpr3;
+       uint64  ctr;
+       uint64  link;
+       uint64  xer;
+       uint64  ccr;
+       uint64  softe;
+       uint64  trap;
+       uint64  dar;
+       uint64  dsisr;
+       uint64  result;
+};
+typedef        uint64  Gregset[48];
+typedef        float64 FPregset[33];
+struct Vreg {
+       uint32  u[4];
+};
+
+struct SigaltstackT {
+       byte    *ss_sp;
+       int32   ss_flags;
+       byte    Pad_cgo_0[4];
+       uint64  ss_size;
+};
+
+struct Sigcontext {
+       uint64  _unused[4];
+       int32   signal;
+       int32   _pad0;
+       uint64  handler;
+       uint64  oldmask;
+       Ptregs  *regs;
+       uint64  gp_regs[48];
+       float64 fp_regs[33];
+       Vreg    *v_regs;
+       int64   vmx_reserve[101];
+};
+struct Ucontext {
+       uint64  uc_flags;
+       Ucontext        *uc_link;
+       SigaltstackT    uc_stack;
+       uint64  uc_sigmask;
+       uint64  __unused[15];
+       Sigcontext      uc_mcontext;
+};
+
+
+#pragma pack off
index 88f6703f97df8f21d3a12c9b4c8fafa6c1cf007d..7d432983b1186cbc9baab5f9d5a4c965d8934200 100644 (file)
@@ -153,6 +153,12 @@ func infoBigStruct() []byte {
                        BitsScalar, BitsScalar, BitsDead, BitsScalar, BitsScalar, // t int; y uint16; u uint64
                        BitsPointer, BitsDead, // i string
                }
+       case "power64", "power64le":
+               return []byte{
+                       BitsPointer, BitsScalar, BitsScalar, BitsScalar,
+                       BitsMultiWord, BitsSlice, BitsScalar, BitsScalar,
+                       BitsScalar, BitsScalar, BitsMultiWord, BitsString,
+               }
        default:
                panic("unknown arch")
        }
index 9b4264f2b3daccedeb5ba3eeef3578b90ab24a77..294bc4870ed0e1d27dc9a074e8632aceca3ed6bb 100644 (file)
@@ -4,9 +4,7 @@
 
 package runtime
 
-import (
-       "unsafe"
-)
+import "unsafe"
 
 const (
        debugMalloc = false
@@ -261,8 +259,10 @@ func mallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer {
                                goto marked
                        }
                        ptrmask = (*uint8)(unsafe.Pointer(uintptr(typ.gc[0])))
-                       // Check whether the program is already unrolled.
-                       if uintptr(atomicloadp(unsafe.Pointer(ptrmask)))&0xff == 0 {
+                       // Check whether the program is already unrolled
+                       // by checking if the unroll flag byte is set
+                       maskword := uintptr(atomicloadp(unsafe.Pointer(ptrmask)))
+                       if *(*uint8)(unsafe.Pointer(&maskword)) == 0 {
                                mp := acquirem()
                                mp.ptrarg[0] = unsafe.Pointer(typ)
                                onM(unrollgcprog_m)
index bfb405607eaf6b3105873fb7d86f34f85a2291db..52e02b34e8beaee71b33c429067da41d08834c5b 100644 (file)
@@ -11,7 +11,7 @@
 
 enum
 {
-       _PAGE_SIZE = 4096,
+       _PAGE_SIZE = PhysPageSize,
        EACCES = 13,
 };
 
@@ -36,8 +36,9 @@ addrspace_free(void *v, uintptr n)
                errval = runtime·mincore((int8*)v + off, chunk, vec);
                // ENOMEM means unmapped, which is what we want.
                // Anything else we assume means the pages are mapped.
-               if (errval != -ENOMEM)
+               if (errval != -ENOMEM && errval != ENOMEM) {
                        return 0;
+               }
        }
        return 1;
 }
@@ -48,12 +49,15 @@ mmap_fixed(byte *v, uintptr n, int32 prot, int32 flags, int32 fd, uint32 offset)
        void *p;
 
        p = runtime·mmap(v, n, prot, flags, fd, offset);
-       if(p != v && addrspace_free(v, n)) {
+       if(p != v) {
+               if(p > (void*)4096) {
+                       runtime·munmap(p, n);
+                       p = nil;
+               }
                // On some systems, mmap ignores v without
                // MAP_FIXED, so retry if the address space is free.
-               if(p > (void*)4096)
-                       runtime·munmap(p, n);
-               p = runtime·mmap(v, n, prot, flags|MAP_FIXED, fd, offset);
+               if(addrspace_free(v, n))
+                       p = runtime·mmap(v, n, prot, flags|MAP_FIXED, fd, offset);
        }
        return p;
 }
index 1520aea2e0fbbb220f1b9836e5d3bdd7f95afa1b..3f20b69c8219b6dc139ded7316173a21102e8de1 100644 (file)
@@ -15,31 +15,31 @@ TEXT runtime·memclr(SB), NOSPLIT, $0-8
        XORL    AX, AX
 
        // MOVOU seems always faster than REP STOSL.
-clr_tail:
+tail:
        TESTL   BX, BX
-       JEQ     clr_0
+       JEQ     _0
        CMPL    BX, $2
-       JBE     clr_1or2
+       JBE     _1or2
        CMPL    BX, $4
-       JBE     clr_3or4
+       JBE     _3or4
        CMPL    BX, $8
-       JBE     clr_5through8
+       JBE     _5through8
        CMPL    BX, $16
-       JBE     clr_9through16
+       JBE     _9through16
        TESTL   $0x4000000, runtime·cpuid_edx(SB) // check for sse2
        JEQ     nosse2
        PXOR    X0, X0
        CMPL    BX, $32
-       JBE     clr_17through32
+       JBE     _17through32
        CMPL    BX, $64
-       JBE     clr_33through64
+       JBE     _33through64
        CMPL    BX, $128
-       JBE     clr_65through128
+       JBE     _65through128
        CMPL    BX, $256
-       JBE     clr_129through256
+       JBE     _129through256
        // TODO: use branch table and BSR to make this just a single dispatch
 
-clr_loop:
+loop:
        MOVOU   X0, 0(DI)
        MOVOU   X0, 16(DI)
        MOVOU   X0, 32(DI)
@@ -59,40 +59,40 @@ clr_loop:
        SUBL    $256, BX
        ADDL    $256, DI
        CMPL    BX, $256
-       JAE     clr_loop
-       JMP     clr_tail
+       JAE     loop
+       JMP     tail
 
-clr_1or2:
+_1or2:
        MOVB    AX, (DI)
        MOVB    AX, -1(DI)(BX*1)
        RET
-clr_0:
+_0:
        RET
-clr_3or4:
+_3or4:
        MOVW    AX, (DI)
        MOVW    AX, -2(DI)(BX*1)
        RET
-clr_5through8:
+_5through8:
        MOVL    AX, (DI)
        MOVL    AX, -4(DI)(BX*1)
        RET
-clr_9through16:
+_9through16:
        MOVL    AX, (DI)
        MOVL    AX, 4(DI)
        MOVL    AX, -8(DI)(BX*1)
        MOVL    AX, -4(DI)(BX*1)
        RET
-clr_17through32:
+_17through32:
        MOVOU   X0, (DI)
        MOVOU   X0, -16(DI)(BX*1)
        RET
-clr_33through64:
+_33through64:
        MOVOU   X0, (DI)
        MOVOU   X0, 16(DI)
        MOVOU   X0, -32(DI)(BX*1)
        MOVOU   X0, -16(DI)(BX*1)
        RET
-clr_65through128:
+_65through128:
        MOVOU   X0, (DI)
        MOVOU   X0, 16(DI)
        MOVOU   X0, 32(DI)
@@ -102,7 +102,7 @@ clr_65through128:
        MOVOU   X0, -32(DI)(BX*1)
        MOVOU   X0, -16(DI)(BX*1)
        RET
-clr_129through256:
+_129through256:
        MOVOU   X0, (DI)
        MOVOU   X0, 16(DI)
        MOVOU   X0, 32(DI)
@@ -126,5 +126,5 @@ nosse2:
        REP
        STOSL
        ANDL    $3, BX
-       JNE     clr_tail
+       JNE     tail
        RET
index 94a2c7f2360dbf6ad45daf048d907fcdc00fddf9..ec24f1db239032e1a52a9e293342f9038e8e0371 100644 (file)
@@ -15,30 +15,30 @@ TEXT runtime·memclr(SB), NOSPLIT, $0-16
        XORQ    AX, AX
 
        // MOVOU seems always faster than REP STOSQ.
-clr_tail:
+tail:
        TESTQ   BX, BX
-       JEQ     clr_0
+       JEQ     _0
        CMPQ    BX, $2
-       JBE     clr_1or2
+       JBE     _1or2
        CMPQ    BX, $4
-       JBE     clr_3or4
+       JBE     _3or4
        CMPQ    BX, $8
-       JBE     clr_5through8
+       JBE     _5through8
        CMPQ    BX, $16
-       JBE     clr_9through16
+       JBE     _9through16
        PXOR    X0, X0
        CMPQ    BX, $32
-       JBE     clr_17through32
+       JBE     _17through32
        CMPQ    BX, $64
-       JBE     clr_33through64
+       JBE     _33through64
        CMPQ    BX, $128
-       JBE     clr_65through128
+       JBE     _65through128
        CMPQ    BX, $256
-       JBE     clr_129through256
+       JBE     _129through256
        // TODO: use branch table and BSR to make this just a single dispatch
        // TODO: for really big clears, use MOVNTDQ.
 
-clr_loop:
+loop:
        MOVOU   X0, 0(DI)
        MOVOU   X0, 16(DI)
        MOVOU   X0, 32(DI)
@@ -58,38 +58,38 @@ clr_loop:
        SUBQ    $256, BX
        ADDQ    $256, DI
        CMPQ    BX, $256
-       JAE     clr_loop
-       JMP     clr_tail
+       JAE     loop
+       JMP     tail
 
-clr_1or2:
+_1or2:
        MOVB    AX, (DI)
        MOVB    AX, -1(DI)(BX*1)
        RET
-clr_0:
+_0:
        RET
-clr_3or4:
+_3or4:
        MOVW    AX, (DI)
        MOVW    AX, -2(DI)(BX*1)
        RET
-clr_5through8:
+_5through8:
        MOVL    AX, (DI)
        MOVL    AX, -4(DI)(BX*1)
        RET
-clr_9through16:
+_9through16:
        MOVQ    AX, (DI)
        MOVQ    AX, -8(DI)(BX*1)
        RET
-clr_17through32:
+_17through32:
        MOVOU   X0, (DI)
        MOVOU   X0, -16(DI)(BX*1)
        RET
-clr_33through64:
+_33through64:
        MOVOU   X0, (DI)
        MOVOU   X0, 16(DI)
        MOVOU   X0, -32(DI)(BX*1)
        MOVOU   X0, -16(DI)(BX*1)
        RET
-clr_65through128:
+_65through128:
        MOVOU   X0, (DI)
        MOVOU   X0, 16(DI)
        MOVOU   X0, 32(DI)
@@ -99,7 +99,7 @@ clr_65through128:
        MOVOU   X0, -32(DI)(BX*1)
        MOVOU   X0, -16(DI)(BX*1)
        RET
-clr_129through256:
+_129through256:
        MOVOU   X0, (DI)
        MOVOU   X0, 16(DI)
        MOVOU   X0, 32(DI)
index b4b671f773e3f07a4322c64a924a03e0c6fb9434..50f327b4ed0201f3456d38666c07483b613b1a93 100644 (file)
@@ -10,40 +10,40 @@ TEXT runtime·memclr(SB), NOSPLIT, $0-8
        MOVL    n+4(FP), BX
        XORL    AX, AX
 
-clr_tail:
+tail:
        TESTL   BX, BX
-       JEQ     clr_0
+       JEQ     _0
        CMPL    BX, $2
-       JBE     clr_1or2
+       JBE     _1or2
        CMPL    BX, $4
-       JBE     clr_3or4
+       JBE     _3or4
        CMPL    BX, $8
-       JBE     clr_5through8
+       JBE     _5through8
        CMPL    BX, $16
-       JBE     clr_9through16
+       JBE     _9through16
        MOVL    BX, CX
        SHRL    $2, CX
        REP
        STOSL
        ANDL    $3, BX
-       JNE     clr_tail
+       JNE     tail
        RET
 
-clr_1or2:
+_1or2:
        MOVB    AX, (DI)
        MOVB    AX, -1(DI)(BX*1)
        RET
-clr_0:
+_0:
        RET
-clr_3or4:
+_3or4:
        MOVW    AX, (DI)
        MOVW    AX, -2(DI)(BX*1)
        RET
-clr_5through8:
+_5through8:
        MOVL    AX, (DI)
        MOVL    AX, -4(DI)(BX*1)
        RET
-clr_9through16:
+_9through16:
        MOVL    AX, (DI)
        MOVL    AX, 4(DI)
        MOVL    AX, -8(DI)(BX*1)
diff --git a/src/runtime/memclr_power64x.s b/src/runtime/memclr_power64x.s
new file mode 100644 (file)
index 0000000..dfad64b
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "textflag.h"
+
+// void runtime·memclr(void*, uintptr)
+TEXT runtime·memclr(SB),NOSPLIT,$0-16
+       MOVD    ptr+0(FP), R3
+       MOVD    n+8(FP), R4
+       CMP     R4, $0
+       BEQ     done
+       SUB     $1, R3
+       MOVD    R4, CTR
+       MOVBU   R0, 1(R3)
+       BC      25, 0, -1(PC) // bdnz+ $-4
+done:
+       RETURN
diff --git a/src/runtime/memmove_power64x.s b/src/runtime/memmove_power64x.s
new file mode 100644 (file)
index 0000000..2b04d83
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "textflag.h"
+
+// void runtime·memmove(void*, void*, uintptr)
+TEXT runtime·memmove(SB), NOSPLIT, $-8-24
+       MOVD    to+0(FP), R3
+       MOVD    from+8(FP), R4
+       MOVD    n+16(FP), R5
+       CMP     R5, $0
+       BNE     check
+       RETURN
+
+check:
+       CMP     R3, R4
+       BGT     backward
+
+       SUB     $1, R3
+       ADD     R3, R5
+       SUB     $1, R4
+loop:
+       MOVBU   1(R4), R6
+       MOVBU   R6, 1(R3)
+       CMP     R3, R5
+       BNE     loop
+       RETURN
+
+backward:
+       ADD     R5, R4
+       ADD     R3, R5
+loop1:
+       MOVBU   -1(R4), R6
+       MOVBU   R6, -1(R5)
+       CMP     R3, R5
+       BNE     loop1
+       RETURN
index 1b41bf9a79419627c791092102922c05e737f57b..e5b6870c668d8a5887d9924a928aee7277a2b05c 100644 (file)
@@ -65,7 +65,7 @@
 enum {
        Debug           = 0,
        DebugPtrs       = 0, // if 1, print trace of every pointer load during GC
-       ConcurrentSweep = 1,
+       ConcurrentSweep = 0,
 
        WorkbufSize     = 4*1024,
        FinBlockSize    = 4*1024,
@@ -1784,7 +1784,7 @@ runtime·unrollgcprog_m(void)
        Type *typ;
        byte *mask, *prog;
        uintptr pos;
-       uint32 x;
+       uintptr x;
 
        typ = g->m->ptrarg[0];
        g->m->ptrarg[0] = nil;
@@ -1802,9 +1802,11 @@ runtime·unrollgcprog_m(void)
                        prog = (byte*)typ->gc[1];
                        unrollgcprog1(mask, prog, &pos, false, true);
                }
+               
                // atomic way to say mask[0] = 1
-               x = ((uint32*)mask)[0];
-               runtime·atomicstore((uint32*)mask, x|1);
+               x = *(uintptr*)mask;
+               ((byte*)&x)[0] = 1;
+               runtime·atomicstorep((void**)mask, (void*)x);
        }
        runtime·unlock(&lock);
 }
similarity index 96%
rename from src/runtime/noasm_arm.go
rename to src/runtime/noasm.go
index dd3ef8267662ce68e773048e0a088e8b14ef4ec5..43c16860b2b96930e26d1d775f8a00da8ece9f7d 100644 (file)
@@ -5,6 +5,8 @@
 // Routines that are implemented in assembly in asm_{amd64,386}.s
 // but are implemented in Go for arm.
 
+// +build arm power64 power64le
+
 package runtime
 
 func cmpstring(s1, s2 string) int {
index 0d8ffc995fce22ad6309d3ffe429d853ebb4d145..9bd123d597b28a431b4f3f2808754e134734f493 100644 (file)
@@ -49,9 +49,22 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
                runtime·futex(addr, FUTEX_WAIT, val, nil, nil, 0);
                return;
        }
-       // NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
+
+       // It's difficult to live within the no-split stack limits here.
+       // On ARM and 386, a 64-bit divide invokes a general software routine
+       // that needs more stack than we can afford. So we use timediv instead.
+       // But on real 64-bit systems, where words are larger but the stack limit
+       // is not, even timediv is too heavy, and we really need to use just an
+       // ordinary machine instruction.
+       // Sorry for the #ifdef.
+       // For what it's worth, the #ifdef eliminated an implicit little-endian assumption.
+#ifdef _64BIT
+       ts.tv_sec = ns / 1000000000LL;
+       ts.tv_nsec = ns % 1000000000LL;
+#else
        ts.tv_nsec = 0;
        ts.tv_sec = runtime·timediv(ns, 1000000000LL, (int32*)&ts.tv_nsec);
+#endif
        runtime·futex(addr, FUTEX_WAIT, val, &ts, nil, 0);
 }
 
@@ -98,19 +111,22 @@ static int32
 getproccount(void)
 {
        uintptr buf[16], t;
-       int32 r, cnt, i;
+       int32 r, n, i;
 
-       cnt = 0;
        r = runtime·sched_getaffinity(0, sizeof(buf), buf);
-       if(r > 0)
+       if(r <= 0)
+               return 1;
+       n = 0;
        for(i = 0; i < r/sizeof(buf[0]); i++) {
                t = buf[i];
-               t = t - ((t >> 1) & 0x5555555555555555ULL);
-               t = (t & 0x3333333333333333ULL) + ((t >> 2) & 0x3333333333333333ULL);
-               cnt += (int32)((((t + (t >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56);
+               while(t != 0) {
+                       n += t&1;
+                       t >>= 1;
+               }
        }
-
-       return cnt ? cnt : 1;
+       if(n < 1)
+               n = 1;
+       return n;
 }
 
 // Clone, the Linux rfork.
@@ -298,7 +314,8 @@ runtime·setsig(int32 i, GoSighandler *fn, bool restart)
        if(fn == runtime·sighandler)
                fn = (void*)runtime·sigtramp;
        sa.sa_handler = fn;
-       if(runtime·rt_sigaction(i, &sa, nil, sizeof(sa.sa_mask)) != 0)
+       // Qemu rejects rt_sigaction of SIGRTMAX (64).
+       if(runtime·rt_sigaction(i, &sa, nil, sizeof(sa.sa_mask)) != 0 && i != 64)
                runtime·throw("rt_sigaction failure");
 }
 
index 24eb6dbfe0887872e2c8e52709839a4c1cb79f45..46683b2b0c705befebed3778b0e281f8ffc7b49d 100644 (file)
@@ -70,7 +70,7 @@ runtime·recovery_m(G *gp)
        // (The pc we're returning to does pop pop
        // before it tests the return value.)
        // On the arm there are 2 saved LRs mixed in too.
-       if(thechar == '5')
+       if(thechar == '5' || thechar == '9')
                gp->sched.sp = (uintptr)argp - 4*sizeof(uintptr);
        else
                gp->sched.sp = (uintptr)argp - 2*sizeof(uintptr);
index 685ff5ca0bcc3aff9c1dd75400c216d336359fac..91b5da2943a5fc9c65493aff9ec1d08587e051ce 100644 (file)
@@ -61,7 +61,7 @@ func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
        // we can only call nosplit routines.
        argp := uintptr(unsafe.Pointer(&fn))
        argp += unsafe.Sizeof(fn)
-       if GOARCH == "arm" {
+       if GOARCH == "arm" || GOARCH == "power64" || GOARCH == "power64le" {
                argp += ptrSize // skip caller's saved link register
        }
        mp := acquirem()
@@ -494,12 +494,12 @@ func throw(s *byte) {
 
 //go:nosplit
 func gothrow(s string) {
+       print("fatal error: ", s, "\n")
        gp := getg()
        if gp.m.throwing == 0 {
                gp.m.throwing = 1
        }
        startpanic()
-       print("fatal error: ", s, "\n")
        dopanic(0)
        *(*int)(nil) = 0 // not reached
 }
index 52f7ef3a5bfbca96f63904fab25e35e4e3d62207..31c62d43f5798499bcf3d55f622600dd58bc25c9 100644 (file)
@@ -2124,7 +2124,7 @@ runtime·newproc(int32 siz, FuncVal* fn, ...)
        byte *argp;
        void (*mfn)(void);
 
-       if(thechar == '5')
+       if(thechar == '5' || thechar == '9')
                argp = (byte*)(&fn+2);  // skip caller's saved LR
        else
                argp = (byte*)(&fn+1);
@@ -2184,7 +2184,7 @@ runtime·newproc1(FuncVal *fn, byte *argp, int32 narg, int32 nret, void *callerp
        sp -= 4*sizeof(uintreg); // extra space in case of reads slightly beyond frame
        sp -= siz;
        runtime·memmove(sp, argp, narg);
-       if(thechar == '5') {
+       if(thechar == '5' || thechar == '9') {
                // caller's LR
                sp -= sizeof(void*);
                *(void**)sp = nil;
index bdea28c7c08e577b11d66cb653ef965757c7bedb..15b18ff8f8fdddf78cb38bf13145b3030c37be92 100644 (file)
@@ -140,20 +140,20 @@ TEXT      racecalladdr<>(SB), NOSPLIT, $0-0
        MOVQ    g_racectx(R14), RARG0   // goroutine context
        // Check that addr is within [arenastart, arenaend) or within [noptrdata, enoptrbss).
        CMPQ    RARG1, runtime·racearenastart(SB)
-       JB      racecalladdr_data
+       JB      data
        CMPQ    RARG1, runtime·racearenaend(SB)
-       JB      racecalladdr_call
-racecalladdr_data:
+       JB      call
+data:
        MOVQ    $runtime·noptrdata(SB), R13
        CMPQ    RARG1, R13
-       JB      racecalladdr_ret
+       JB      ret
        MOVQ    $runtime·enoptrbss(SB), R13
        CMPQ    RARG1, R13
-       JAE     racecalladdr_ret
-racecalladdr_call:
+       JAE     ret
+call:
        MOVQ    AX, AX          // w/o this 6a miscompiles this function
        JMP     racecall<>(SB)
-racecalladdr_ret:
+ret:
        RET
 
 // func runtime·racefuncenter(pc uintptr)
@@ -335,9 +335,9 @@ TEXT        racecall<>(SB), NOSPLIT, $0-0
        MOVQ    SP, R12         // callee-saved, preserved across the CALL
        MOVQ    m_g0(R13), R10
        CMPQ    R10, R14
-       JE      racecall_cont   // already on g0
+       JE      call    // already on g0
        MOVQ    (g_sched+gobuf_sp)(R10), SP
-racecall_cont:
+call:
        ANDQ    $~15, SP        // alignment for gcc ABI
        CALL    AX
        MOVQ    R12, SP
diff --git a/src/runtime/rt0_linux_power64.s b/src/runtime/rt0_linux_power64.s
new file mode 100644 (file)
index 0000000..970b6a6
--- /dev/null
@@ -0,0 +1,17 @@
+#include "textflag.h"
+
+// actually a function descriptor for _main<>(SB)
+TEXT _rt0_power64_linux(SB),NOSPLIT,$0
+       DWORD $_main<>(SB)
+       DWORD $0
+       DWORD $0
+
+TEXT _main<>(SB),NOSPLIT,$-8
+       MOVD 0(R1), R3 // argc
+       ADD $8, R1, R4 // argv
+       BR main(SB)
+
+TEXT main(SB),NOSPLIT,$-8
+       MOVD    $runtime·rt0_go(SB), R31
+       MOVD    R31, CTR
+       BR      (CTR)
diff --git a/src/runtime/rt0_linux_power64le.s b/src/runtime/rt0_linux_power64le.s
new file mode 100644 (file)
index 0000000..85ce847
--- /dev/null
@@ -0,0 +1,14 @@
+#include "textflag.h"
+
+TEXT _rt0_power64le_linux(SB),NOSPLIT,$0
+       BR _main<>(SB)
+
+TEXT _main<>(SB),NOSPLIT,$-8
+       MOVD 0(R1), R3 // argc
+       ADD $8, R1, R4 // argv
+       BR main(SB)
+
+TEXT main(SB),NOSPLIT,$-8
+       MOVD    $runtime·rt0_go(SB), R31
+       MOVD    R31, CTR
+       BR      (CTR)
index c823691ec5a178ca27f1ef5f2d60cdede2be83a1..f19f8e4be3c397aab8da7923d47ea56ef324cbad 100644 (file)
@@ -185,6 +185,7 @@ runtime·check(void)
        float64 j, j1;
        byte *k, *k1;
        uint16* l;
+       byte m[4];
        struct x1 {
                byte x;
        };
@@ -236,6 +237,11 @@ runtime·check(void)
        if(k != k1)
                runtime·throw("casp3");
 
+       m[0] = m[1] = m[2] = m[3] = 0x1;
+       runtime·atomicor8(&m[1], 0xf0);
+       if (m[0] != 0x1 || m[1] != 0xf1 || m[2] != 0x1 || m[3] != 0x1)
+               runtime·throw("atomicor8");
+
        *(uint64*)&j = ~0ULL;
        if(j == j)
                runtime·throw("float64nan");
diff --git a/src/runtime/signal_linux_power64.h b/src/runtime/signal_linux_power64.h
new file mode 100644 (file)
index 0000000..8406489
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext)->regs)
+
+#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).gpr[0])
+#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).gpr[1])
+#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).gpr[2])
+#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).gpr[3])
+#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).gpr[4])
+#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).gpr[5])
+#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).gpr[6])
+#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).gpr[7])
+#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).gpr[8])
+#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).gpr[9])
+#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).gpr[10])
+#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).gpr[11])
+#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).gpr[12])
+#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).gpr[13])
+#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).gpr[14])
+#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).gpr[15])
+#define SIG_R16(info, ctxt) (SIG_REGS(ctxt).gpr[16])
+#define SIG_R17(info, ctxt) (SIG_REGS(ctxt).gpr[17])
+#define SIG_R18(info, ctxt) (SIG_REGS(ctxt).gpr[18])
+#define SIG_R19(info, ctxt) (SIG_REGS(ctxt).gpr[19])
+#define SIG_R20(info, ctxt) (SIG_REGS(ctxt).gpr[20])
+#define SIG_R21(info, ctxt) (SIG_REGS(ctxt).gpr[21])
+#define SIG_R22(info, ctxt) (SIG_REGS(ctxt).gpr[22])
+#define SIG_R23(info, ctxt) (SIG_REGS(ctxt).gpr[23])
+#define SIG_R24(info, ctxt) (SIG_REGS(ctxt).gpr[24])
+#define SIG_R25(info, ctxt) (SIG_REGS(ctxt).gpr[25])
+#define SIG_R26(info, ctxt) (SIG_REGS(ctxt).gpr[26])
+#define SIG_R27(info, ctxt) (SIG_REGS(ctxt).gpr[27])
+#define SIG_R28(info, ctxt) (SIG_REGS(ctxt).gpr[28])
+#define SIG_R29(info, ctxt) (SIG_REGS(ctxt).gpr[29])
+#define SIG_R30(info, ctxt) (SIG_REGS(ctxt).gpr[30])
+#define SIG_R31(info, ctxt) (SIG_REGS(ctxt).gpr[31])
+
+#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).gpr[1])
+#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).nip)
+#define SIG_TRAP(info, ctxt) (SIG_REGS(ctxt).trap)
+#define SIG_CTR(info, ctxt) (SIG_REGS(ctxt).ctr)
+#define SIG_LINK(info, ctxt) (SIG_REGS(ctxt).link)
+#define SIG_XER(info, ctxt) (SIG_REGS(ctxt).xer)
+#define SIG_CCR(info, ctxt) (SIG_REGS(ctxt).ccr)
+
+#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
+#define SIG_FAULT(info, ctxt) (SIG_REGS(ctxt).dar)
diff --git a/src/runtime/signal_linux_power64le.h b/src/runtime/signal_linux_power64le.h
new file mode 100644 (file)
index 0000000..8406489
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext)->regs)
+
+#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).gpr[0])
+#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).gpr[1])
+#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).gpr[2])
+#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).gpr[3])
+#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).gpr[4])
+#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).gpr[5])
+#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).gpr[6])
+#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).gpr[7])
+#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).gpr[8])
+#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).gpr[9])
+#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).gpr[10])
+#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).gpr[11])
+#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).gpr[12])
+#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).gpr[13])
+#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).gpr[14])
+#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).gpr[15])
+#define SIG_R16(info, ctxt) (SIG_REGS(ctxt).gpr[16])
+#define SIG_R17(info, ctxt) (SIG_REGS(ctxt).gpr[17])
+#define SIG_R18(info, ctxt) (SIG_REGS(ctxt).gpr[18])
+#define SIG_R19(info, ctxt) (SIG_REGS(ctxt).gpr[19])
+#define SIG_R20(info, ctxt) (SIG_REGS(ctxt).gpr[20])
+#define SIG_R21(info, ctxt) (SIG_REGS(ctxt).gpr[21])
+#define SIG_R22(info, ctxt) (SIG_REGS(ctxt).gpr[22])
+#define SIG_R23(info, ctxt) (SIG_REGS(ctxt).gpr[23])
+#define SIG_R24(info, ctxt) (SIG_REGS(ctxt).gpr[24])
+#define SIG_R25(info, ctxt) (SIG_REGS(ctxt).gpr[25])
+#define SIG_R26(info, ctxt) (SIG_REGS(ctxt).gpr[26])
+#define SIG_R27(info, ctxt) (SIG_REGS(ctxt).gpr[27])
+#define SIG_R28(info, ctxt) (SIG_REGS(ctxt).gpr[28])
+#define SIG_R29(info, ctxt) (SIG_REGS(ctxt).gpr[29])
+#define SIG_R30(info, ctxt) (SIG_REGS(ctxt).gpr[30])
+#define SIG_R31(info, ctxt) (SIG_REGS(ctxt).gpr[31])
+
+#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).gpr[1])
+#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).nip)
+#define SIG_TRAP(info, ctxt) (SIG_REGS(ctxt).trap)
+#define SIG_CTR(info, ctxt) (SIG_REGS(ctxt).ctr)
+#define SIG_LINK(info, ctxt) (SIG_REGS(ctxt).link)
+#define SIG_XER(info, ctxt) (SIG_REGS(ctxt).xer)
+#define SIG_CCR(info, ctxt) (SIG_REGS(ctxt).ccr)
+
+#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
+#define SIG_FAULT(info, ctxt) (SIG_REGS(ctxt).dar)
diff --git a/src/runtime/signal_power64x.c b/src/runtime/signal_power64x.c
new file mode 100644 (file)
index 0000000..89c5c78
--- /dev/null
@@ -0,0 +1,137 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+// +build power64 power64le
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_GOOS_GOARCH.h"
+#include "signals_GOOS.h"
+
+void
+runtime·dumpregs(Siginfo *info, void *ctxt)
+{
+       USED(info); USED(ctxt);
+       runtime·printf("r0  %X\t", SIG_R0(info, ctxt));
+       runtime·printf("r1  %X\n", SIG_R1(info, ctxt));
+       runtime·printf("r2  %X\t", SIG_R2(info, ctxt));
+       runtime·printf("r3  %X\n", SIG_R3(info, ctxt));
+       runtime·printf("r4  %X\t", SIG_R4(info, ctxt));
+       runtime·printf("r5  %X\n", SIG_R5(info, ctxt));
+       runtime·printf("r6  %X\t", SIG_R6(info, ctxt));
+       runtime·printf("r7  %X\n", SIG_R7(info, ctxt));
+       runtime·printf("r8  %X\t", SIG_R8(info, ctxt));
+       runtime·printf("r9  %X\n", SIG_R9(info, ctxt));
+       runtime·printf("r10  %X\t", SIG_R10(info, ctxt));
+       runtime·printf("r11  %X\n", SIG_R11(info, ctxt));
+       runtime·printf("r12  %X\t", SIG_R12(info, ctxt));
+       runtime·printf("r13  %X\n", SIG_R13(info, ctxt));
+       runtime·printf("r14  %X\t", SIG_R14(info, ctxt));
+       runtime·printf("r15  %X\n", SIG_R15(info, ctxt));
+       runtime·printf("r16  %X\t", SIG_R16(info, ctxt));
+       runtime·printf("r17  %X\n", SIG_R17(info, ctxt));
+       runtime·printf("r18  %X\t", SIG_R18(info, ctxt));
+       runtime·printf("r19  %X\n", SIG_R19(info, ctxt));
+       runtime·printf("r20  %X\t", SIG_R20(info, ctxt));
+       runtime·printf("r21  %X\n", SIG_R21(info, ctxt));
+       runtime·printf("r22  %X\t", SIG_R22(info, ctxt));
+       runtime·printf("r23  %X\n", SIG_R23(info, ctxt));
+       runtime·printf("r24  %X\t", SIG_R24(info, ctxt));
+       runtime·printf("r25  %X\n", SIG_R25(info, ctxt));
+       runtime·printf("r26  %X\t", SIG_R26(info, ctxt));
+       runtime·printf("r27  %X\n", SIG_R27(info, ctxt));
+       runtime·printf("r28  %X\t", SIG_R28(info, ctxt));
+       runtime·printf("r29  %X\n", SIG_R29(info, ctxt));
+       runtime·printf("r30  %X\t", SIG_R30(info, ctxt));
+       runtime·printf("r31  %X\n", SIG_R31(info, ctxt));
+       runtime·printf("pc   %X\t", SIG_PC(info, ctxt));
+       runtime·printf("ctr  %X\n", SIG_CTR(info, ctxt));
+       runtime·printf("link %X\t", SIG_LINK(info, ctxt));
+       runtime·printf("xer  %X\n", SIG_XER(info, ctxt));
+       runtime·printf("ccr  %X\t", SIG_CCR(info, ctxt));
+       runtime·printf("trap %X\n", SIG_TRAP(info, ctxt));
+}
+
+void
+runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
+{
+       SigTab *t;
+       bool crash;
+
+       if(sig == SIGPROF) {
+               runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LINK(info, ctxt), gp, g->m);
+               return;
+       }
+       t = &runtime·sigtab[sig];
+       if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
+               // Make it look like a call to the signal func.
+               // Have to pass arguments out of band since
+               // augmenting the stack frame would break
+               // the unwinding code.
+               gp->sig = sig;
+               gp->sigcode0 = SIG_CODE0(info, ctxt);
+               gp->sigcode1 = SIG_FAULT(info, ctxt);
+               gp->sigpc = SIG_PC(info, ctxt);
+
+               // We arrange link, and pc to pretend the panicking
+               // function calls sigpanic directly.
+               // Always save LINK to stack so that panics in leaf
+               // functions are correctly handled. This smashes
+               // the stack frame but we're not going back there
+               // anyway.
+               SIG_SP(info, ctxt) -= sizeof(uintptr);
+               *(uintptr*)SIG_SP(info, ctxt) = SIG_LINK(info, ctxt);
+               // Don't bother saving PC if it's zero, which is
+               // probably a call to a nil func: the old link register
+               // is more useful in the stack trace.
+               if(gp->sigpc != 0)
+                       SIG_LINK(info, ctxt) = gp->sigpc;
+               // In case we are panicking from external C code
+               SIG_R0(info, ctxt) = 0;
+               SIG_R30(info, ctxt) = (uintptr)gp;
+               SIG_PC(info, ctxt) = (uintptr)runtime·sigpanic;
+               return;
+       }
+
+       if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
+               if(runtime·sigsend(sig))
+                       return;
+       if(t->flags & SigKill)
+               runtime·exit(2);
+       if(!(t->flags & SigThrow))
+               return;
+
+       g->m->throwing = 1;
+       g->m->caughtsig = gp;
+       if(runtime·panicking)  // traceback already printed
+               runtime·exit(2);
+       runtime·panicking = 1;
+
+       if(sig < 0 || sig >= NSIG)
+               runtime·printf("Signal %d\n", sig);
+       else
+               runtime·printf("%s\n", runtime·sigtab[sig].name);
+
+       runtime·printf("PC=%x\n", SIG_PC(info, ctxt));
+       if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
+               runtime·printf("signal arrived during cgo execution\n");
+               gp = g->m->lockedg;
+       }
+       runtime·printf("\n");
+
+       if(runtime·gotraceback(&crash)){
+               runtime·goroutineheader(gp);
+               runtime·traceback(SIG_PC(info, ctxt), SIG_SP(info, ctxt), SIG_LINK(info, ctxt), gp);
+               runtime·tracebackothers(gp);
+               runtime·printf("\n");
+               runtime·dumpregs(info, ctxt);
+       }
+       
+       if(crash)
+               runtime·crash();
+
+       runtime·exit(2);
+}
index 0809f89bc1fe1796b3fcb54885185cb270522814..882281605ab23492e11f722dfb7d41c20105a312 100644 (file)
@@ -39,22 +39,18 @@ func concatstrings(a []string) string {
        return s
 }
 
-//go:nosplit
 func concatstring2(a [2]string) string {
        return concatstrings(a[:])
 }
 
-//go:nosplit
 func concatstring3(a [3]string) string {
        return concatstrings(a[:])
 }
 
-//go:nosplit
 func concatstring4(a [4]string) string {
        return concatstrings(a[:])
 }
 
-//go:nosplit
 func concatstring5(a [5]string) string {
        return concatstrings(a[:])
 }
index a961c71a83abe602527da067fd78d51edadd113a..3bf8b1d411c80cab9031f168ac4c4994be651ab7 100644 (file)
@@ -248,7 +248,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$40
        MOVL    BX, 0(SP)
        MOVL    $runtime·badsignal(SB), AX
        CALL    AX
-       JMP     sigtramp_ret
+       JMP     ret
 
        // save g
        MOVL    DI, 20(SP)
@@ -275,7 +275,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$40
        MOVL    20(SP), DI
        MOVL    DI, g(CX)
 
-sigtramp_ret:
+ret:
        // call sigreturn
        MOVL    context+16(FP), CX
        MOVL    style+4(FP), BX
index bd397d72a76ae538f81b938499a6b8574fa83c68..8a8928e066529361014fed0fffc18150b8e6d47f 100644 (file)
@@ -211,7 +211,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
        MOVL    DX, 0(SP)
        MOVQ    $runtime·badsignal(SB), AX
        CALL    AX
-       JMP     sigtramp_ret
+       JMP     ret
 
        // save g
        MOVQ    R10, 48(SP)
@@ -233,7 +233,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
        MOVQ    48(SP), R10
        MOVQ    R10, g(BX)
 
-sigtramp_ret:
+ret:
        // call sigreturn
        MOVL    $(0x2000000+184), AX    // sigreturn(ucontext, infostyle)
        MOVQ    32(SP), DI      // saved ucontext
index 161eaec19d3688b3064a5ddc80b5654e3bff0180..71ece9ecbf07ca9fb5858568d38514f3c67122ff 100644 (file)
@@ -217,7 +217,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44
        MOVL    BX, 0(SP)
        MOVL    $runtime·badsignal(SB), AX
        CALL    AX
-       JMP     sigtramp_ret
+       JMP     ret
 
        // save g
        MOVL    DI, 20(SP)
@@ -243,7 +243,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44
        MOVL    20(SP), BX
        MOVL    BX, g(CX)
 
-sigtramp_ret:
+ret:
        // call sigreturn
        MOVL    context+8(FP), AX
        MOVL    $0, 0(SP)       // syscall gap
index 2c40fc433bb0addda7d10833e9948f7f8d16660b..66d03c27da27968ab7c5fcedb4c4bf47cb531f49 100644 (file)
@@ -197,7 +197,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44
        MOVL    BX, 0(SP)
        MOVL    $runtime·badsignal(SB), AX
        CALL    AX
-       JMP     sigtramp_ret
+       JMP     ret
 
        // save g
        MOVL    DI, 20(SP)
@@ -223,7 +223,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44
        MOVL    20(SP), BX
        MOVL    BX, g(CX)
 
-sigtramp_ret:
+ret:
        // call sigreturn
        MOVL    context+8(FP), AX
        MOVL    $0, 0(SP)       // syscall gap
index 33b91e872f9a00a99221c08588394eec5d4c4ff2..d8d86ffadf7c5789e921c0916b11deaca77111d8 100644 (file)
@@ -115,7 +115,7 @@ TEXT time·now(SB),NOSPLIT,$16
        // That leaves 104 for the gettime code to use. Hope that's enough!
        MOVQ    runtime·__vdso_clock_gettime_sym(SB), AX
        CMPQ    AX, $0
-       JEQ     fallback_gtod
+       JEQ     fallback
        MOVL    $0, DI // CLOCK_REALTIME
        LEAQ    0(SP), SI
        CALL    AX
@@ -124,7 +124,7 @@ TEXT time·now(SB),NOSPLIT,$16
        MOVQ    AX, sec+0(FP)
        MOVL    DX, nsec+8(FP)
        RET
-fallback_gtod:
+fallback:
        LEAQ    0(SP), DI
        MOVQ    $0, SI
        MOVQ    runtime·__vdso_gettimeofday_sym(SB), AX
@@ -141,7 +141,7 @@ TEXT runtime·nanotime(SB),NOSPLIT,$16
        // See comment above in time.now.
        MOVQ    runtime·__vdso_clock_gettime_sym(SB), AX
        CMPQ    AX, $0
-       JEQ     fallback_gtod_nt
+       JEQ     fallback
        MOVL    $1, DI // CLOCK_MONOTONIC
        LEAQ    0(SP), SI
        CALL    AX
@@ -153,7 +153,7 @@ TEXT runtime·nanotime(SB),NOSPLIT,$16
        ADDQ    DX, AX
        MOVQ    AX, ret+0(FP)
        RET
-fallback_gtod_nt:
+fallback:
        LEAQ    0(SP), DI
        MOVQ    $0, SI
        MOVQ    runtime·__vdso_gettimeofday_sym(SB), AX
index bd285f399820395c7a96e1b26107741516e876a4..033a0364273bd05448aece289a091de3d2c1b73b 100644 (file)
@@ -373,20 +373,20 @@ TEXT cas<>(SB),NOSPLIT,$0
 TEXT runtime·cas(SB),NOSPLIT,$0
        MOVW    ptr+0(FP), R2
        MOVW    old+4(FP), R0
-casagain:
+loop:
        MOVW    new+8(FP), R1
        BL      cas<>(SB)
-       BCC     cascheck
+       BCC     check
        MOVW    $1, R0
        MOVB    R0, ret+12(FP)
        RET
-cascheck:
+check:
        // Kernel lies; double-check.
        MOVW    ptr+0(FP), R2
        MOVW    old+4(FP), R0
        MOVW    0(R2), R3
        CMP     R0, R3
-       BEQ     casagain
+       BEQ     loop
        MOVW    $0, R0
        MOVB    R0, ret+12(FP)
        RET
diff --git a/src/runtime/sys_linux_power64x.s b/src/runtime/sys_linux_power64x.s
new file mode 100644 (file)
index 0000000..fb24d3e
--- /dev/null
@@ -0,0 +1,383 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+// +build power64 power64le
+
+//
+// System calls and other sys.stuff for Power64, Linux
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+#define SYS_exit                 1
+#define SYS_read                 3
+#define SYS_write                4
+#define SYS_open                 5
+#define SYS_close                6
+#define SYS_fcntl               55
+#define SYS_gettimeofday        78
+#define SYS_select              82     // always return -ENOSYS
+#define SYS_mmap                90
+#define SYS_munmap              91
+#define SYS_setitimer          104
+#define SYS_clone              120
+#define SYS_newselect          142
+#define SYS_sched_yield                158
+#define SYS_rt_sigreturn       172
+#define SYS_rt_sigaction       173
+#define SYS_rt_sigprocmask     174
+#define SYS_sigaltstack                185
+#define SYS_ugetrlimit         190
+#define SYS_madvise            205
+#define SYS_mincore            206
+#define SYS_gettid             207
+#define SYS_tkill              208
+#define SYS_futex              221
+#define SYS_sched_getaffinity  223
+#define SYS_exit_group         234
+#define SYS_epoll_create       236
+#define SYS_epoll_ctl          237
+#define SYS_epoll_wait         238
+#define SYS_clock_gettime      246
+#define SYS_epoll_create1      315
+
+TEXT runtime·exit(SB),NOSPLIT,$-8-4
+       MOVW    code+0(FP), R3
+       SYSCALL $SYS_exit_group
+       RETURN
+
+TEXT runtime·exit1(SB),NOSPLIT,$-8-4
+       MOVW    code+0(FP), R3
+       SYSCALL $SYS_exit
+       RETURN
+
+TEXT runtime·open(SB),NOSPLIT,$-8-20
+       MOVD    name+0(FP), R3
+       MOVW    mode+8(FP), R4
+       MOVW    perm+12(FP), R5
+       SYSCALL $SYS_open
+       MOVW    R3, ret+16(FP)
+       RETURN
+
+TEXT runtime·close(SB),NOSPLIT,$-8-12
+       MOVW    fd+0(FP), R3
+       SYSCALL $SYS_close
+       MOVW    R3, ret+8(FP)
+       RETURN
+
+TEXT runtime·write(SB),NOSPLIT,$-8-28
+       MOVD    fd+0(FP), R3
+       MOVD    p+8(FP), R4
+       MOVW    n+16(FP), R5
+       SYSCALL $SYS_write
+       MOVW    R3, ret+24(FP)
+       RETURN
+
+TEXT runtime·read(SB),NOSPLIT,$-8-28
+       MOVW    fd+0(FP), R3
+       MOVD    p+8(FP), R4
+       MOVW    n+16(FP), R5
+       SYSCALL $SYS_read
+       MOVW    R3, ret+24(FP)
+       RETURN
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$-8-20
+       MOVW    kind+0(FP), R3
+       MOVD    limit+8(FP), R4
+       SYSCALL $SYS_ugetrlimit
+       MOVW    R3, ret+16(FP)
+       RETURN
+
+TEXT runtime·usleep(SB),NOSPLIT,$16-4
+       MOVW    usec+0(FP), R3
+       MOVD    R3, R5
+       MOVW    $1000000, R4
+       DIVD    R4, R3
+       MOVD    R3, 8(R1)
+       MULLD   R3, R4
+       SUB     R4, R5
+       MOVD    R5, 16(R1)
+
+       // select(0, 0, 0, 0, &tv)
+       MOVW    $0, R3
+       MOVW    $0, R4
+       MOVW    $0, R5
+       MOVW    $0, R6
+       ADD     $8, R1, R7
+       SYSCALL $SYS_newselect
+       RETURN
+
+TEXT runtime·raise(SB),NOSPLIT,$-8
+       SYSCALL $SYS_gettid
+       MOVW    R3, R3  // arg 1 tid
+       MOVW    sig+0(FP), R4   // arg 2
+       SYSCALL $SYS_tkill
+       RETURN
+
+TEXT runtime·setitimer(SB),NOSPLIT,$-8-24
+       MOVW    mode+0(FP), R3
+       MOVD    new+8(FP), R4
+       MOVD    old+16(FP), R5
+       SYSCALL $SYS_setitimer
+       RETURN
+
+TEXT runtime·mincore(SB),NOSPLIT,$-8-28
+       MOVD    addr+0(FP), R3
+       MOVD    n+8(FP), R4
+       MOVD    dst+16(FP), R5
+       SYSCALL $SYS_mincore
+       MOVW    R3, ret+24(FP)
+       RETURN
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$16
+       MOVD    $0(R1), R3
+       MOVD    $0, R4
+       SYSCALL $SYS_gettimeofday
+       MOVD    0(R1), R3       // sec
+       MOVD    8(R1), R5       // usec
+       MOVD    $1000, R4
+       MULLD   R4, R5
+       MOVD    R3, sec+0(FP)
+       MOVW    R5, nsec+8(FP)
+       RETURN
+
+TEXT runtime·nanotime(SB),NOSPLIT,$16
+       MOVW    $1, R3 // CLOCK_MONOTONIC
+       MOVD    $0(R1), R4
+       SYSCALL $SYS_clock_gettime
+       MOVD    0(R1), R3       // sec
+       MOVD    8(R1), R5       // nsec
+       // sec is in R3, nsec in R5
+       // return nsec in R3
+       MOVD    $1000000000, R4
+       MULLD   R4, R3
+       ADD     R5, R3
+       MOVD    R3, ret+0(FP)
+       RETURN
+
+TEXT runtime·rtsigprocmask(SB),NOSPLIT,$-8-28
+       MOVW    sig+0(FP), R3
+       MOVD    new+8(FP), R4
+       MOVD    old+16(FP), R5
+       MOVW    size+24(FP), R6
+       SYSCALL $SYS_rt_sigprocmask
+       BVC     2(PC)
+       MOVD    R0, 0xf1(R0)    // crash
+       RETURN
+
+TEXT runtime·rt_sigaction(SB),NOSPLIT,$-8-36
+       MOVD    sig+0(FP), R3
+       MOVD    new+8(FP), R4
+       MOVD    old+16(FP), R5
+       MOVD    size+24(FP), R6
+       SYSCALL $SYS_rt_sigaction
+       MOVW    R3, ret+32(FP)
+       RETURN
+
+#ifdef GOARCH_power64le
+// power64le doesn't need function descriptors
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+#else
+// function descriptor for the real sigtramp
+TEXT runtime·sigtramp(SB),NOSPLIT,$-8
+       DWORD   $runtime·_sigtramp(SB)
+       DWORD   $0
+       DWORD   $0
+TEXT runtime·_sigtramp(SB),NOSPLIT,$64
+#endif
+       // initialize essential registers (just in case)
+       BL      runtime·reginit(SB)
+
+       // check that g exists
+       CMP     g, $0
+       BNE     6(PC)
+       MOVD    R3, 8(R1)
+       MOVD    $runtime·badsignal(SB), R31
+       MOVD    R31, CTR
+       BL      (CTR)
+       RETURN
+
+       // save g
+       MOVD    g, 40(R1)
+       MOVD    g, R6
+
+       // g = m->gsignal
+       MOVD    g_m(g), R7
+       MOVD    m_gsignal(R7), g
+
+       MOVW    R3, 8(R1)
+       MOVD    R4, 16(R1)
+       MOVD    R5, 24(R1)
+       MOVD    R6, 32(R1)
+
+       BL      runtime·sighandler(SB)
+
+       // restore g
+       MOVD    40(R1), g
+
+       RETURN
+
+TEXT runtime·mmap(SB),NOSPLIT,$-8
+       MOVD    addr+0(FP), R3
+       MOVD    n+8(FP), R4
+       MOVW    prot+16(FP), R5
+       MOVW    flags+20(FP), R6
+       MOVW    fd+24(FP), R7
+       MOVW    off+28(FP), R8
+
+       SYSCALL $SYS_mmap
+       MOVD    R3, ret+32(FP)
+       RETURN
+
+TEXT runtime·munmap(SB),NOSPLIT,$-8
+       MOVD    addr+0(FP), R3
+       MOVD    n+8(FP), R4
+       SYSCALL $SYS_munmap
+       BVC     2(PC)
+       MOVD    R0, 0xf3(R0)
+       RETURN
+
+TEXT runtime·madvise(SB),NOSPLIT,$-8
+       MOVD    addr+0(FP), R3
+       MOVD    n+8(FP), R4
+       MOVW    flags+16(FP), R5
+       SYSCALL $SYS_madvise
+       // ignore failure - maybe pages are locked
+       RETURN
+
+// int64 futex(int32 *uaddr, int32 op, int32 val,
+//     struct timespec *timeout, int32 *uaddr2, int32 val2);
+TEXT runtime·futex(SB),NOSPLIT,$-8
+       MOVD    addr+0(FP), R3
+       MOVW    op+8(FP), R4
+       MOVW    val+12(FP), R5
+       MOVD    ts+16(FP), R6
+       MOVD    addr2+24(FP), R7
+       MOVW    val3+32(FP), R8
+       SYSCALL $SYS_futex
+       MOVW    R3, ret+40(FP)
+       RETURN
+
+// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·clone(SB),NOSPLIT,$-8
+       MOVW    flags+0(FP), R3
+       MOVD    stk+8(FP), R4
+
+       // Copy mp, gp, fn off parent stack for use by child.
+       // Careful: Linux system call clobbers ???.
+       MOVD    mm+16(FP), R7
+       MOVD    gg+24(FP), R8
+       MOVD    fn+32(FP), R12
+
+       MOVD    R7, -8(R4)
+       MOVD    R8, -16(R4)
+       MOVD    R12, -24(R4)
+       MOVD    $1234, R7
+       MOVD    R7, -32(R4)
+
+       SYSCALL $SYS_clone
+
+       // In parent, return.
+       CMP     R3, $0
+       BEQ     3(PC)
+       MOVW    R3, ret+40(FP)
+       RETURN
+
+       // In child, on new stack.
+       // initialize essential registers
+       BL      runtime·reginit(SB)
+       MOVD    -32(R1), R7
+       CMP     R7, $1234
+       BEQ     2(PC)
+       MOVD    R0, 0(R0)
+
+       // Initialize m->procid to Linux tid
+       SYSCALL $SYS_gettid
+
+       MOVD    -24(R1), R12
+       MOVD    -16(R1), R8
+       MOVD    -8(R1), R7
+
+       MOVD    R3, m_procid(R7)
+
+       // TODO: setup TLS.
+
+       // In child, set up new stack
+       MOVD    R7, g_m(R8)
+       MOVD    R8, g
+       //CALL  runtime·stackcheck(SB)
+
+       // Call fn
+       MOVD    R12, CTR
+       BL      (CTR)
+
+       // It shouldn't return.  If it does, exit
+       MOVW    $111, R3
+       SYSCALL $SYS_exit_group
+       BR      -2(PC)  // keep exiting
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+       MOVD    new+0(FP), R3
+       MOVD    old+8(FP), R4
+       SYSCALL $SYS_sigaltstack
+       BVC     2(PC)
+       MOVD    R0, 0xf1(R0)  // crash
+       RETURN
+
+TEXT runtime·osyield(SB),NOSPLIT,$-8
+       SYSCALL $SYS_sched_yield
+       RETURN
+
+TEXT runtime·sched_getaffinity(SB),NOSPLIT,$-8
+       MOVD    pid+0(FP), R3
+       MOVD    len+8(FP), R4
+       MOVD    buf+16(FP), R5
+       SYSCALL $SYS_sched_getaffinity
+       MOVW    R3, ret+24(FP)
+       RETURN
+
+// int32 runtime·epollcreate(int32 size);
+TEXT runtime·epollcreate(SB),NOSPLIT,$-8
+       MOVW    size+0(FP), R3
+       SYSCALL $SYS_epoll_create
+       MOVW    R3, ret+8(FP)
+       RETURN
+
+// int32 runtime·epollcreate1(int32 flags);
+TEXT runtime·epollcreate1(SB),NOSPLIT,$-8
+       MOVW    flags+0(FP), R3
+       SYSCALL $SYS_epoll_create1
+       MOVW    R3, ret+8(FP)
+       RETURN
+
+// func epollctl(epfd, op, fd int32, ev *epollEvent) int
+TEXT runtime·epollctl(SB),NOSPLIT,$-8
+       MOVW    epfd+0(FP), R3
+       MOVW    op+4(FP), R4
+       MOVW    fd+8(FP), R5
+       MOVD    ev+16(FP), R6
+       SYSCALL $SYS_epoll_ctl
+       MOVW    R3, ret+24(FP)
+       RETURN
+
+// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
+TEXT runtime·epollwait(SB),NOSPLIT,$-8
+       MOVW    epfd+0(FP), R3
+       MOVD    ev+8(FP), R4
+       MOVW    nev+16(FP), R5
+       MOVW    timeout+20(FP), R6
+       SYSCALL $SYS_epoll_wait
+       MOVW    R3, ret+24(FP)
+       RETURN
+
+// void runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$-8
+       MOVW    fd+0(FP), R3  // fd
+       MOVD    $2, R4  // F_SETFD
+       MOVD    $1, R5  // FD_CLOEXEC
+       SYSCALL $SYS_fcntl
+       RETURN
index 47985f31f5607b2a40e8abc5083186f0d91cc79d..16cd721d9b19664a5865e6285a675e7edd5dcecf 100644 (file)
@@ -293,7 +293,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0
        MOVL    $0, 0(SP)
        MOVL    $runtime·badsignal(SB), AX
        CALL    AX
-       JMP     sigtramp_ret
+       JMP     ret
 
        // save g
        MOVL    DI, 20(SP)
@@ -317,7 +317,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0
        MOVL    20(SP), BX
        MOVL    BX, g(CX)
 
-sigtramp_ret:
+ret:
        // Enable exceptions again.
        NACL_SYSCALL(SYS_exception_clear_flag)
 
index 4eb4aacdd58cad0dd2d3b02b6b60d75292ee0b35..9cfbef6efaf41baef9c5e1ebf43ef06729421e11 100644 (file)
@@ -338,7 +338,6 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$80
        MOVL    20(SP), BX
        MOVL    BX, g(CX)
 
-sigtramp_ret:
        // Enable exceptions again.
        NACL_SYSCALL(SYS_exception_clear_flag)
 
index d354ab48373157731bb272512316c7a0cec9c50a..432deadf44e7006330bc0364550c531b0d48bb94 100644 (file)
@@ -269,7 +269,6 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$80
        // restore g
        MOVW    20(R13), g
 
-sigtramp_ret:
        // Enable exceptions again.
        NACL_SYSCALL(SYS_exception_clear_flag)
 
index 5cda7768ae97bd0201514615ea9c113384ac76f6..b1ae5eceec520ee532c44356d0d379ae05a67fe4 100644 (file)
@@ -186,7 +186,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44
        MOVL    BX, 0(SP)
        MOVL    $runtime·badsignal(SB), AX
        CALL    AX
-       JMP     sigtramp_ret
+       JMP     ret
 
        // save g
        MOVL    DI, 20(SP)
@@ -212,7 +212,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44
        MOVL    20(SP), BX
        MOVL    BX, g(CX)
 
-sigtramp_ret:
+ret:
        // call sigreturn
        MOVL    context+8(FP), AX
        MOVL    $0, 0(SP)               // syscall gap
diff --git a/src/runtime/sys_power64x.c b/src/runtime/sys_power64x.c
new file mode 100644 (file)
index 0000000..79d9762
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "runtime.h"
+
+// adjust Gobuf as if it executed a call to fn with context ctxt
+// and then did an immediate Gosave.
+void
+runtime·gostartcall(Gobuf *gobuf, void (*fn)(void), void *ctxt)
+{
+       if(gobuf->lr != 0)
+               runtime·throw("invalid use of gostartcall");
+       gobuf->lr = gobuf->pc;
+       gobuf->pc = (uintptr)fn;
+       gobuf->ctxt = ctxt;
+}
+
+// Called to rewind context saved during morestack back to beginning of function.
+// To help us, the linker emits a jmp back to the beginning right after the
+// call to morestack. We just have to decode and apply that jump.
+void
+runtime·rewindmorestack(Gobuf *gobuf)
+{
+       uint32 inst;
+
+       inst = *(uint32*)gobuf->pc;
+       if((gobuf->pc&3) == 0 && (inst>>24) == 0x4b && (inst&3) == 0) {
+               //runtime·printf("runtime: rewind pc=%p to pc=%p\n", gobuf->pc, gobuf->pc + ((int32)(inst<<8)>>8));
+               gobuf->pc += (int32)(inst<<8)>>8;
+               return;
+       }
+       runtime·printf("runtime: pc=%p %x\n", gobuf->pc, inst);
+       runtime·throw("runtime: misuse of rewindmorestack");
+}
+
index 0ebdab6ee2e5bdfd2243e6ea925eb2286fb957ba..3981893b01fd77dae5c4b8cf74fcb04125f13155 100644 (file)
@@ -287,24 +287,24 @@ TEXT runtime·usleep1(SB),NOSPLIT,$0
        // Execute call on m->g0.
        get_tls(R15)
        CMPQ    R15, $0
-       JE      usleep1_noswitch
+       JE      noswitch
 
        MOVQ    g(R15), R13
        CMPQ    R13, $0
-       JE      usleep1_noswitch
+       JE      noswitch
        MOVQ    g_m(R13), R13
        CMPQ    R13, $0
-       JE      usleep1_noswitch
+       JE      noswitch
        // TODO(aram): do something about the cpu profiler here.
 
        MOVQ    m_g0(R13), R14
        CMPQ    g(R15), R14
-       JNE     usleep1_switch
+       JNE     switch
        // executing on m->g0 already
        CALL    AX
        RET
 
-usleep1_switch:
+switch:
        // Switch to m->g0 stack and back.
        MOVQ    (g_sched+gobuf_sp)(R14), R14
        MOVQ    SP, -8(R14)
@@ -313,7 +313,7 @@ usleep1_switch:
        MOVQ    0(SP), SP
        RET
 
-usleep1_noswitch:
+noswitch:
        // Not a Go-managed thread. Do not switch stack.
        CALL    AX
        RET
index 932fe9dd2450c0eee0082d2b109d63080af3965e..13fb5bdc933b662972921234146212a9949b5e09 100644 (file)
@@ -106,7 +106,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
        MOVL    g_m(DX), BX
        MOVL    m_g0(BX), BX
        CMPL    DX, BX
-       JEQ     sigtramp_g0
+       JEQ     g0
 
        // switch to the g0 stack
        get_tls(BP)
@@ -123,7 +123,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
        MOVL    SP, 36(DI)
        MOVL    DI, SP
 
-sigtramp_g0:
+g0:
        MOVL    0(CX), BX // ExceptionRecord*
        MOVL    4(CX), CX // Context*
        MOVL    BX, 0(SP)
@@ -383,12 +383,12 @@ TEXT runtime·usleep1(SB),NOSPLIT,$0
 
        MOVL    m_g0(BP), SI
        CMPL    g(CX), SI
-       JNE     usleep1_switch
+       JNE     switch
        // executing on m->g0 already
        CALL    AX
-       JMP     usleep1_ret
+       JMP     ret
 
-usleep1_switch:
+switch:
        // Switch to m->g0 stack and back.
        MOVL    (g_sched+gobuf_sp)(SI), SI
        MOVL    SP, -4(SI)
@@ -396,7 +396,7 @@ usleep1_switch:
        CALL    AX
        MOVL    0(SP), SP
 
-usleep1_ret:
+ret:
        get_tls(CX)
        MOVL    g(CX), BP
        MOVL    g_m(BP), BP
index e6190ce684d70e7b4a7bea86e09bc8194178568f..8b95f6d6c16c1d04054ff9cfa8f652664a2af35c 100644 (file)
@@ -138,7 +138,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
        MOVQ    g_m(DX), BX
        MOVQ    m_g0(BX), BX
        CMPQ    DX, BX
-       JEQ     sigtramp_g0
+       JEQ     g0
 
        // switch to g0 stack
        get_tls(BP)
@@ -157,7 +157,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
        MOVQ    SP, 104(DI)
        MOVQ    DI, SP
 
-sigtramp_g0:
+g0:
        MOVQ    0(CX), BX // ExceptionRecord*
        MOVQ    8(CX), CX // Context*
        MOVQ    BX, 0(SP)
@@ -407,12 +407,12 @@ TEXT runtime·usleep1(SB),NOSPLIT,$0
 
        MOVQ    m_g0(R13), R14
        CMPQ    g(R15), R14
-       JNE     usleep1_switch
+       JNE     switch
        // executing on m->g0 already
        CALL    AX
-       JMP     usleep1_ret
+       JMP     ret
 
-usleep1_switch:
+switch:
        // Switch to m->g0 stack and back.
        MOVQ    (g_sched+gobuf_sp)(R14), R14
        MOVQ    SP, -8(R14)
@@ -420,7 +420,7 @@ usleep1_switch:
        CALL    AX
        MOVQ    0(SP), SP
 
-usleep1_ret:
+ret:
        MOVQ    $0, m_libcallsp(R13)
        RET
 
index 0a0f147c4b45aee91cf3f32bc54d797a61b6c9ce..1a5b65502858b496bdd84d9294a6d6cd98468b7a 100644 (file)
 #ifdef GOARCH_arm
 #define JMP B
 #endif
+#ifdef GOARCH_power64
+#define JMP BR
+#endif
+#ifdef GOARCH_power64le
+#define JMP BR
+#endif
 
 TEXT net·runtimeNano(SB),NOSPLIT,$0-0
        JMP     runtime·nanotime(SB)
diff --git a/src/sync/atomic/asm_power64x.s b/src/sync/atomic/asm_power64x.s
new file mode 100644 (file)
index 0000000..1130d3c
--- /dev/null
@@ -0,0 +1,184 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build power64 power64le
+
+#include "textflag.h"
+
+TEXT Â·SwapInt32(SB),NOSPLIT,$0-20
+       BR      Â·SwapUint32(SB)
+
+TEXT Â·SwapUint32(SB),NOSPLIT,$0-20
+       MOVD    addr+0(FP), R3
+       MOVW    new+8(FP), R4
+       SYNC
+       LWAR    (R3), R5
+       STWCCC  R4, (R3)
+       BNE     -3(PC)
+       SYNC
+       ISYNC
+       MOVW    R5, old+16(FP)
+       RETURN
+
+TEXT Â·SwapInt64(SB),NOSPLIT,$0-24
+       BR      Â·SwapUint64(SB)
+
+TEXT Â·SwapUint64(SB),NOSPLIT,$0-24
+       MOVD    addr+0(FP), R3
+       MOVD    new+8(FP), R4
+       SYNC
+       LDAR    (R3), R5
+       STDCCC  R4, (R3)
+       BNE     -3(PC)
+       SYNC
+       ISYNC
+       MOVD    R5, old+16(FP)
+       RETURN
+
+TEXT Â·SwapUintptr(SB),NOSPLIT,$0-24
+       BR      Â·SwapUint64(SB)
+
+TEXT Â·SwapPointer(SB),NOSPLIT,$0-24
+       BR      Â·SwapUint64(SB)
+
+TEXT Â·CompareAndSwapInt32(SB),NOSPLIT,$0-17
+       BR      Â·CompareAndSwapUint32(SB)
+
+TEXT Â·CompareAndSwapUint32(SB),NOSPLIT,$0-17
+       MOVD    addr+0(FP), R3
+       MOVW    old+8(FP), R4
+       MOVW    new+12(FP), R5
+       SYNC
+       LWAR    (R3), R6
+       CMPW    R6, R4
+       BNE     8(PC)
+       STWCCC  R5, (R3)
+       BNE     -5(PC)
+       SYNC
+       ISYNC
+       MOVD    $1, R3
+       MOVB    R3, swapped+16(FP)
+       RETURN
+       MOVB    R0, swapped+16(FP)
+       RETURN
+
+TEXT Â·CompareAndSwapUintptr(SB),NOSPLIT,$0-25
+       BR      Â·CompareAndSwapUint64(SB)
+
+TEXT Â·CompareAndSwapPointer(SB),NOSPLIT,$0-25
+       BR      Â·CompareAndSwapUint64(SB)
+
+TEXT Â·CompareAndSwapInt64(SB),NOSPLIT,$0-25
+       BR      Â·CompareAndSwapUint64(SB)
+
+TEXT Â·CompareAndSwapUint64(SB),NOSPLIT,$0-25
+       MOVD    addr+0(FP), R3
+       MOVD    old+8(FP), R4
+       MOVD    new+16(FP), R5
+       SYNC
+       LDAR    (R3), R6
+       CMP     R6, R4
+       BNE     8(PC)
+       STDCCC  R5, (R3)
+       BNE     -5(PC)
+       SYNC
+       ISYNC
+       MOVD    $1, R3
+       MOVB    R3, swapped+24(FP)
+       RETURN
+       MOVB    R0, swapped+24(FP)
+       RETURN
+
+TEXT Â·AddInt32(SB),NOSPLIT,$0-20
+       BR      Â·AddUint32(SB)
+
+TEXT Â·AddUint32(SB),NOSPLIT,$0-20
+       MOVD    addr+0(FP), R3
+       MOVW    delta+8(FP), R4
+       SYNC
+       LWAR    (R3), R5
+       ADD     R4, R5
+       STWCCC  R5, (R3)
+       BNE     -4(PC)
+       SYNC
+       ISYNC
+       MOVW    R5, ret+16(FP)
+       RETURN
+
+TEXT Â·AddUintptr(SB),NOSPLIT,$0-24
+       BR      Â·AddUint64(SB)
+
+TEXT Â·AddInt64(SB),NOSPLIT,$0-24
+       BR      Â·AddUint64(SB)
+
+TEXT Â·AddUint64(SB),NOSPLIT,$0-24
+       MOVD    addr+0(FP), R3
+       MOVD    delta+8(FP), R4
+       SYNC
+       LDAR    (R3), R5
+       ADD     R4, R5
+       STDCCC  R5, (R3)
+       BNE     -4(PC)
+       SYNC
+       ISYNC
+       MOVD    R5, ret+16(FP)
+       RETURN
+
+TEXT Â·LoadInt32(SB),NOSPLIT,$0-12
+       BR      Â·LoadUint32(SB)
+
+TEXT Â·LoadUint32(SB),NOSPLIT,$0-12
+       MOVD    addr+0(FP), R3
+       SYNC
+       MOVW    0(R3), R3
+       CMPW    R3, R3, CR7
+       BC      4, 30, 1(PC)    // bne- cr7,0x4
+       ISYNC
+       MOVW    R3, val+8(FP)
+       RETURN
+
+TEXT Â·LoadInt64(SB),NOSPLIT,$0-16
+       BR      Â·LoadUint64(SB)
+
+TEXT Â·LoadUint64(SB),NOSPLIT,$0-16
+       MOVD    addr+0(FP), R3
+       SYNC
+       MOVD    0(R3), R3
+       CMP     R3, R3, CR7
+       BC      4, 30, 1(PC)    // bne- cr7,0x4
+       ISYNC
+       MOVD    R3, val+8(FP)
+       RETURN
+
+TEXT Â·LoadUintptr(SB),NOSPLIT,$0-16
+       BR      Â·LoadPointer(SB)
+
+TEXT Â·LoadPointer(SB),NOSPLIT,$0-16
+       BR      Â·LoadUint64(SB)
+
+TEXT Â·StoreInt32(SB),NOSPLIT,$0-12
+       BR      Â·StoreUint32(SB)
+
+TEXT Â·StoreUint32(SB),NOSPLIT,$0-12
+       MOVD    addr+0(FP), R3
+       MOVW    val+8(FP), R4
+       SYNC
+       MOVW    R4, 0(R3)
+       RETURN
+
+TEXT Â·StoreInt64(SB),NOSPLIT,$0-16
+       BR      Â·StoreUint64(SB)
+
+TEXT Â·StoreUint64(SB),NOSPLIT,$0-16
+       MOVD    addr+0(FP), R3
+       MOVD    val+8(FP), R4
+       SYNC
+       MOVD    R4, 0(R3)
+       RETURN
+
+TEXT Â·StoreUintptr(SB),NOSPLIT,$0-16
+       BR      Â·StorePointer(SB)
+
+TEXT Â·StorePointer(SB),NOSPLIT,$0-16
+       BR      Â·StoreUint64(SB)
index d4ca868f17f98e7500163b292a1a139961448ca5..43561e20195dd578a388bf074bcbdf866f85bc10 100644 (file)
@@ -4,5 +4,12 @@
 
 #include "textflag.h"
 
+#ifdef GOARCH_power64
+#define RET RETURN
+#endif
+#ifdef GOARCH_power64le
+#define RET RETURN
+#endif
+
 TEXT Â·use(SB),NOSPLIT,$0
        RET
diff --git a/src/syscall/asm_linux_power64x.s b/src/syscall/asm_linux_power64x.s
new file mode 100644 (file)
index 0000000..be8518a
--- /dev/null
@@ -0,0 +1,104 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+// +build power64 power64le
+
+#include "textflag.h"
+
+//
+// System calls for Power64, Linux
+//
+
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+
+TEXT   Â·Syscall(SB),NOSPLIT,$0-56
+       BL      runtime·entersyscall(SB)
+       MOVD    a1+8(FP), R3
+       MOVD    a2+16(FP), R4
+       MOVD    a3+24(FP), R5
+       MOVD    R0, R6
+       MOVD    R0, R7
+       MOVD    R0, R8
+       MOVD    trap+0(FP), R9  // syscall entry
+       SYSCALL R9
+       BVC     ok
+       MOVD    $-1, R4
+       MOVD    R4, r1+32(FP)   // r1
+       MOVD    R0, r2+40(FP)   // r2
+       MOVD    R3, err+48(FP)  // errno
+       BL      runtime·exitsyscall(SB)
+       RETURN
+ok:
+       MOVD    R3, r1+32(FP)   // r1
+       MOVD    R4, r2+40(FP)   // r2
+       MOVD    R0, err+48(FP)  // errno
+       BL      runtime·exitsyscall(SB)
+       RETURN
+
+TEXT Â·Syscall6(SB),NOSPLIT,$0-80
+       BL      runtime·entersyscall(SB)
+       MOVD    a1+8(FP), R3
+       MOVD    a2+16(FP), R4
+       MOVD    a3+24(FP), R5
+       MOVD    a4+32(FP), R6
+       MOVD    a5+40(FP), R7
+       MOVD    a6+48(FP), R8
+       MOVD    trap+0(FP), R9  // syscall entry
+       SYSCALL R9
+       BVC     ok6
+       MOVD    $-1, R4
+       MOVD    R4, r1+56(FP)   // r1
+       MOVD    R0, r2+64(FP)   // r2
+       MOVD    R3, err+72(FP)  // errno
+       BL      runtime·exitsyscall(SB)
+       RETURN
+ok6:
+       MOVD    R3, r1+56(FP)   // r1
+       MOVD    R4, r2+64(FP)   // r2
+       MOVD    R0, err+72(FP)  // errno
+       BL      runtime·exitsyscall(SB)
+       RETURN
+
+TEXT Â·RawSyscall(SB),NOSPLIT,$0-56
+       MOVD    a1+8(FP), R3
+       MOVD    a2+16(FP), R4
+       MOVD    a3+24(FP), R5
+       MOVD    R0, R6
+       MOVD    R0, R7
+       MOVD    R0, R8
+       MOVD    trap+0(FP), R9  // syscall entry
+       SYSCALL R9
+       BVC     ok1
+       MOVD    $-1, R4
+       MOVD    R4, r1+32(FP)   // r1
+       MOVD    R0, r2+40(FP)   // r2
+       MOVD    R3, err+48(FP)  // errno
+       RETURN
+ok1:
+       MOVD    R3, r1+32(FP)   // r1
+       MOVD    R4, r2+40(FP)   // r2
+       MOVD    R0, err+48(FP)  // errno
+       RETURN
+
+TEXT Â·RawSyscall6(SB),NOSPLIT,$0-80
+       MOVD    a1+8(FP), R3
+       MOVD    a2+16(FP), R4
+       MOVD    a3+24(FP), R5
+       MOVD    a4+32(FP), R6
+       MOVD    a5+40(FP), R7
+       MOVD    a6+48(FP), R8
+       MOVD    trap+0(FP), R9  // syscall entry
+       SYSCALL R9
+       BVC     ok2
+       MOVD    $-1, R4
+       MOVD    R4, r1+56(FP)   // r1
+       MOVD    R0, r2+64(FP)   // r2
+       MOVD    R3, err+72(FP)  // errno
+       RETURN
+ok2:
+       MOVD    R3, r1+56(FP)   // r1
+       MOVD    R4, r2+64(FP)   // r2
+       MOVD    R0, err+72(FP)  // errno
+       RETURN
index 9cb82a608d53f281cc3dd68397b113a1eb5a8df4..febd5a2625fc41cc0ce0572cc315eaa1bb9605a4 100755 (executable)
@@ -107,6 +107,7 @@ case "$#" in
        exit 2
 esac
 
+GOOSARCH_in=syscall_$GOOSARCH.go
 case "$GOOSARCH" in
 _* | *_ | _)
        echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
@@ -176,6 +177,20 @@ linux_arm)
        mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl"
        mktypes="GOARCH=$GOARCH go tool cgo -godefs"
        ;;
+linux_power64)
+       GOOSARCH_in=syscall_linux_power64x.go
+       unistd_h=/usr/include/asm/unistd.h
+       mkerrors="$mkerrors -m64"
+       mksysnum="./mksysnum_linux.pl $unistd_h"
+       mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+       ;;
+linux_power64le)
+       GOOSARCH_in=syscall_linux_power64x.go
+       unistd_h=/usr/include/powerpc64le-linux-gnu/asm/unistd.h
+       mkerrors="$mkerrors -m64"
+       mksysnum="./mksysnum_linux.pl $unistd_h"
+       mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+       ;;
 nacl_386)
        mkerrors=""
        mksyscall="./mksyscall.pl -l32 -nacl"
@@ -254,7 +269,7 @@ esac
                        syscall_goos="syscall_bsd.go $syscall_goos"
                        ;;
                esac
-               if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"; fi
+               if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
                ;;
        esac
        if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
index cf0afe0bdd8966c001f60f553152551600b9e35c..4711f307a8e84cd3ae9feada25d398392ac02197 100755 (executable)
@@ -242,6 +242,7 @@ ccflags="$@"
                $2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
                $2 ~ /^(SCM_SRCRT)$/ {next}
                $2 ~ /^(MAP_FAILED)$/ {next}
+               $2 ~ /^ELF_.*$/ {next}  # <asm/elf.h> contains ELF_ARCH, etc.
 
                $2 !~ /^ETH_/ &&
                $2 !~ /^EPROC_/ &&
diff --git a/src/syscall/syscall_linux_power64x.go b/src/syscall/syscall_linux_power64x.go
new file mode 100644 (file)
index 0000000..fd04362
--- /dev/null
@@ -0,0 +1,97 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+// +build power64 power64le
+
+package syscall
+
+//sys  Chown(path string, uid int, gid int) (err error)
+//sys  Fchown(fd int, uid int, gid int) (err error)
+//sys  Fstat(fd int, stat *Stat_t) (err error)
+//sys  Fstatfs(fd int, buf *Statfs_t) (err error)
+//sys  Ftruncate(fd int, length int64) (err error)
+//sysnb        Getegid() (egid int)
+//sysnb        Geteuid() (euid int)
+//sysnb        Getgid() (gid int)
+//sysnb        Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT
+//sysnb        Getuid() (uid int)
+//sys  Ioperm(from int, num int, on int) (err error)
+//sys  Iopl(level int) (err error)
+//sys  Lchown(path string, uid int, gid int) (err error)
+//sys  Listen(s int, n int) (err error)
+//sys  Lstat(path string, stat *Stat_t) (err error)
+//sys  Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
+//sys  Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
+//sys  Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
+//sys  Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
+//sys  sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
+//sys  Setfsgid(gid int) (err error)
+//sys  Setfsuid(uid int) (err error)
+//sysnb        Setregid(rgid int, egid int) (err error)
+//sysnb        Setresgid(rgid int, egid int, sgid int) (err error)
+//sysnb        Setresuid(ruid int, euid int, suid int) (err error)
+//sysnb        Setrlimit(resource int, rlim *Rlimit) (err error)
+//sysnb        Setreuid(ruid int, euid int) (err error)
+//sys  Shutdown(fd int, how int) (err error)
+//sys  Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
+//sys  Stat(path string, stat *Stat_t) (err error)
+//sys  Statfs(path string, buf *Statfs_t) (err error)
+//sys  SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2
+//sys  Truncate(path string, length int64) (err error)
+//sys  accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
+//sys  accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
+//sys  bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sys  connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sysnb        getgroups(n int, list *_Gid_t) (nn int, err error)
+//sysnb        setgroups(n int, list *_Gid_t) (err error)
+//sys  getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
+//sys  setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
+//sysnb        socket(domain int, typ int, proto int) (fd int, err error)
+//sysnb        socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
+//sysnb        getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sysnb        getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sys  recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
+//sys  sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
+//sys  recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
+//sys  sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
+//sys  mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
+
+func Getpagesize() int { return 65536 }
+
+//sysnb        Gettimeofday(tv *Timeval) (err error)
+//sysnb        Time(t *Time_t) (tt Time_t, err error)
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+       ts.Sec = nsec / 1e9
+       ts.Nsec = nsec % 1e9
+       return
+}
+
+func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+       nsec += 999 // round up to microsecond
+       tv.Sec = nsec / 1e9
+       tv.Usec = nsec % 1e9 / 1e3
+       return
+}
+
+func (r *PtraceRegs) PC() uint64 { return r.Nip }
+
+func (r *PtraceRegs) SetPC(pc uint64) { r.Nip = pc }
+
+func (iov *Iovec) SetLen(length int) {
+       iov.Len = uint64(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+       msghdr.Controllen = uint64(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+       cmsg.Len = uint64(length)
+}
index e8396a41f3659fa10864f184c6f80e14e0cfc2d0..5e9f698cf1b2cad306ae348d41bd08b48ace8739 100644 (file)
@@ -77,8 +77,8 @@ struct sockaddr_any {
 // copied from /usr/include/linux/un.h
 struct my_sockaddr_un {
        sa_family_t sun_family;
-#ifdef __ARM_EABI__
-       // on ARM char is by default unsigned
+#if defined(__ARM_EABI__) || defined(__powerpc64__)
+       // on ARM and PPC char is by default unsigned
        signed char sun_path[108];
 #else
        char sun_path[108];
@@ -87,6 +87,8 @@ struct my_sockaddr_un {
 
 #ifdef __ARM_EABI__
 typedef struct user_regs PtraceRegs;
+#elif defined(__powerpc64__)
+typedef struct pt_regs PtraceRegs;
 #else
 typedef struct user_regs_struct PtraceRegs;
 #endif
@@ -382,103 +384,9 @@ const (
 type Termios C.struct_termios
 
 const (
-       VINTR    = C.VINTR
-       VQUIT    = C.VQUIT
-       VERASE   = C.VERASE
-       VKILL    = C.VKILL
-       VEOF     = C.VEOF
-       VTIME    = C.VTIME
-       VMIN     = C.VMIN
-       VSWTC    = C.VSWTC
-       VSTART   = C.VSTART
-       VSTOP    = C.VSTOP
-       VSUSP    = C.VSUSP
-       VEOL     = C.VEOL
-       VREPRINT = C.VREPRINT
-       VDISCARD = C.VDISCARD
-       VWERASE  = C.VWERASE
-       VLNEXT   = C.VLNEXT
-       VEOL2    = C.VEOL2
-       IGNBRK   = C.IGNBRK
-       BRKINT   = C.BRKINT
-       IGNPAR   = C.IGNPAR
-       PARMRK   = C.PARMRK
-       INPCK    = C.INPCK
-       ISTRIP   = C.ISTRIP
-       INLCR    = C.INLCR
-       IGNCR    = C.IGNCR
-       ICRNL    = C.ICRNL
-       IUCLC    = C.IUCLC
-       IXON     = C.IXON
-       IXANY    = C.IXANY
-       IXOFF    = C.IXOFF
-       IMAXBEL  = C.IMAXBEL
-       IUTF8    = C.IUTF8
-       OPOST    = C.OPOST
-       OLCUC    = C.OLCUC
-       ONLCR    = C.ONLCR
-       OCRNL    = C.OCRNL
-       ONOCR    = C.ONOCR
-       ONLRET   = C.ONLRET
-       OFILL    = C.OFILL
-       OFDEL    = C.OFDEL
-       B0       = C.B0
-       B50      = C.B50
-       B75      = C.B75
-       B110     = C.B110
-       B134     = C.B134
-       B150     = C.B150
-       B200     = C.B200
-       B300     = C.B300
-       B600     = C.B600
-       B1200    = C.B1200
-       B1800    = C.B1800
-       B2400    = C.B2400
-       B4800    = C.B4800
-       B9600    = C.B9600
-       B19200   = C.B19200
-       B38400   = C.B38400
-       CSIZE    = C.CSIZE
-       CS5      = C.CS5
-       CS6      = C.CS6
-       CS7      = C.CS7
-       CS8      = C.CS8
-       CSTOPB   = C.CSTOPB
-       CREAD    = C.CREAD
-       PARENB   = C.PARENB
-       PARODD   = C.PARODD
-       HUPCL    = C.HUPCL
-       CLOCAL   = C.CLOCAL
-       B57600   = C.B57600
-       B115200  = C.B115200
-       B230400  = C.B230400
-       B460800  = C.B460800
-       B500000  = C.B500000
-       B576000  = C.B576000
-       B921600  = C.B921600
-       B1000000 = C.B1000000
-       B1152000 = C.B1152000
-       B1500000 = C.B1500000
-       B2000000 = C.B2000000
-       B2500000 = C.B2500000
-       B3000000 = C.B3000000
-       B3500000 = C.B3500000
-       B4000000 = C.B4000000
-       ISIG     = C.ISIG
-       ICANON   = C.ICANON
-       XCASE    = C.XCASE
-       ECHO     = C.ECHO
-       ECHOE    = C.ECHOE
-       ECHOK    = C.ECHOK
-       ECHONL   = C.ECHONL
-       NOFLSH   = C.NOFLSH
-       TOSTOP   = C.TOSTOP
-       ECHOCTL  = C.ECHOCTL
-       ECHOPRT  = C.ECHOPRT
-       ECHOKE   = C.ECHOKE
-       FLUSHO   = C.FLUSHO
-       PENDIN   = C.PENDIN
-       IEXTEN   = C.IEXTEN
-       TCGETS   = C.TCGETS
-       TCSETS   = C.TCSETS
+       IUCLC  = C.IUCLC
+       OLCUC  = C.OLCUC
+       TCGETS = C.TCGETS
+       TCSETS = C.TCSETS
+       XCASE  = C.XCASE
 )
diff --git a/src/syscall/zerrors_linux_power64.go b/src/syscall/zerrors_linux_power64.go
new file mode 100644 (file)
index 0000000..15e0770
--- /dev/null
@@ -0,0 +1,1878 @@
+// mkerrors.sh -m64
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs -- -m64 _const.go
+
+package syscall
+
+const (
+       AF_ALG                           = 0x26
+       AF_APPLETALK                     = 0x5
+       AF_ASH                           = 0x12
+       AF_ATMPVC                        = 0x8
+       AF_ATMSVC                        = 0x14
+       AF_AX25                          = 0x3
+       AF_BLUETOOTH                     = 0x1f
+       AF_BRIDGE                        = 0x7
+       AF_CAIF                          = 0x25
+       AF_CAN                           = 0x1d
+       AF_DECnet                        = 0xc
+       AF_ECONET                        = 0x13
+       AF_FILE                          = 0x1
+       AF_IEEE802154                    = 0x24
+       AF_INET                          = 0x2
+       AF_INET6                         = 0xa
+       AF_IPX                           = 0x4
+       AF_IRDA                          = 0x17
+       AF_ISDN                          = 0x22
+       AF_IUCV                          = 0x20
+       AF_KEY                           = 0xf
+       AF_LLC                           = 0x1a
+       AF_LOCAL                         = 0x1
+       AF_MAX                           = 0x28
+       AF_NETBEUI                       = 0xd
+       AF_NETLINK                       = 0x10
+       AF_NETROM                        = 0x6
+       AF_NFC                           = 0x27
+       AF_PACKET                        = 0x11
+       AF_PHONET                        = 0x23
+       AF_PPPOX                         = 0x18
+       AF_RDS                           = 0x15
+       AF_ROSE                          = 0xb
+       AF_ROUTE                         = 0x10
+       AF_RXRPC                         = 0x21
+       AF_SECURITY                      = 0xe
+       AF_SNA                           = 0x16
+       AF_TIPC                          = 0x1e
+       AF_UNIX                          = 0x1
+       AF_UNSPEC                        = 0x0
+       AF_WANPIPE                       = 0x19
+       AF_X25                           = 0x9
+       ARPHRD_ADAPT                     = 0x108
+       ARPHRD_APPLETLK                  = 0x8
+       ARPHRD_ARCNET                    = 0x7
+       ARPHRD_ASH                       = 0x30d
+       ARPHRD_ATM                       = 0x13
+       ARPHRD_AX25                      = 0x3
+       ARPHRD_BIF                       = 0x307
+       ARPHRD_CAIF                      = 0x336
+       ARPHRD_CAN                       = 0x118
+       ARPHRD_CHAOS                     = 0x5
+       ARPHRD_CISCO                     = 0x201
+       ARPHRD_CSLIP                     = 0x101
+       ARPHRD_CSLIP6                    = 0x103
+       ARPHRD_DDCMP                     = 0x205
+       ARPHRD_DLCI                      = 0xf
+       ARPHRD_ECONET                    = 0x30e
+       ARPHRD_EETHER                    = 0x2
+       ARPHRD_ETHER                     = 0x1
+       ARPHRD_EUI64                     = 0x1b
+       ARPHRD_FCAL                      = 0x311
+       ARPHRD_FCFABRIC                  = 0x313
+       ARPHRD_FCPL                      = 0x312
+       ARPHRD_FCPP                      = 0x310
+       ARPHRD_FDDI                      = 0x306
+       ARPHRD_FRAD                      = 0x302
+       ARPHRD_HDLC                      = 0x201
+       ARPHRD_HIPPI                     = 0x30c
+       ARPHRD_HWX25                     = 0x110
+       ARPHRD_IEEE1394                  = 0x18
+       ARPHRD_IEEE802                   = 0x6
+       ARPHRD_IEEE80211                 = 0x321
+       ARPHRD_IEEE80211_PRISM           = 0x322
+       ARPHRD_IEEE80211_RADIOTAP        = 0x323
+       ARPHRD_IEEE802154                = 0x324
+       ARPHRD_IEEE802154_MONITOR        = 0x325
+       ARPHRD_IEEE802_TR                = 0x320
+       ARPHRD_INFINIBAND                = 0x20
+       ARPHRD_IP6GRE                    = 0x337
+       ARPHRD_IPDDP                     = 0x309
+       ARPHRD_IPGRE                     = 0x30a
+       ARPHRD_IRDA                      = 0x30f
+       ARPHRD_LAPB                      = 0x204
+       ARPHRD_LOCALTLK                  = 0x305
+       ARPHRD_LOOPBACK                  = 0x304
+       ARPHRD_METRICOM                  = 0x17
+       ARPHRD_NETLINK                   = 0x338
+       ARPHRD_NETROM                    = 0x0
+       ARPHRD_NONE                      = 0xfffe
+       ARPHRD_PHONET                    = 0x334
+       ARPHRD_PHONET_PIPE               = 0x335
+       ARPHRD_PIMREG                    = 0x30b
+       ARPHRD_PPP                       = 0x200
+       ARPHRD_PRONET                    = 0x4
+       ARPHRD_RAWHDLC                   = 0x206
+       ARPHRD_ROSE                      = 0x10e
+       ARPHRD_RSRVD                     = 0x104
+       ARPHRD_SIT                       = 0x308
+       ARPHRD_SKIP                      = 0x303
+       ARPHRD_SLIP                      = 0x100
+       ARPHRD_SLIP6                     = 0x102
+       ARPHRD_TUNNEL                    = 0x300
+       ARPHRD_TUNNEL6                   = 0x301
+       ARPHRD_VOID                      = 0xffff
+       ARPHRD_X25                       = 0x10f
+       B0                               = 0x0
+       B1000000                         = 0x17
+       B110                             = 0x3
+       B115200                          = 0x11
+       B1152000                         = 0x18
+       B1200                            = 0x9
+       B134                             = 0x4
+       B150                             = 0x5
+       B1500000                         = 0x19
+       B1800                            = 0xa
+       B19200                           = 0xe
+       B200                             = 0x6
+       B2000000                         = 0x1a
+       B230400                          = 0x12
+       B2400                            = 0xb
+       B2500000                         = 0x1b
+       B300                             = 0x7
+       B3000000                         = 0x1c
+       B3500000                         = 0x1d
+       B38400                           = 0xf
+       B4000000                         = 0x1e
+       B460800                          = 0x13
+       B4800                            = 0xc
+       B50                              = 0x1
+       B500000                          = 0x14
+       B57600                           = 0x10
+       B576000                          = 0x15
+       B600                             = 0x8
+       B75                              = 0x2
+       B921600                          = 0x16
+       B9600                            = 0xd
+       BPF_A                            = 0x10
+       BPF_ABS                          = 0x20
+       BPF_ADD                          = 0x0
+       BPF_ALU                          = 0x4
+       BPF_AND                          = 0x50
+       BPF_B                            = 0x10
+       BPF_DIV                          = 0x30
+       BPF_H                            = 0x8
+       BPF_IMM                          = 0x0
+       BPF_IND                          = 0x40
+       BPF_JA                           = 0x0
+       BPF_JEQ                          = 0x10
+       BPF_JGE                          = 0x30
+       BPF_JGT                          = 0x20
+       BPF_JMP                          = 0x5
+       BPF_JSET                         = 0x40
+       BPF_K                            = 0x0
+       BPF_LD                           = 0x0
+       BPF_LDX                          = 0x1
+       BPF_LEN                          = 0x80
+       BPF_LSH                          = 0x60
+       BPF_MAJOR_VERSION                = 0x1
+       BPF_MAXINSNS                     = 0x1000
+       BPF_MEM                          = 0x60
+       BPF_MEMWORDS                     = 0x10
+       BPF_MINOR_VERSION                = 0x1
+       BPF_MISC                         = 0x7
+       BPF_MOD                          = 0x90
+       BPF_MSH                          = 0xa0
+       BPF_MUL                          = 0x20
+       BPF_NEG                          = 0x80
+       BPF_OR                           = 0x40
+       BPF_RET                          = 0x6
+       BPF_RSH                          = 0x70
+       BPF_ST                           = 0x2
+       BPF_STX                          = 0x3
+       BPF_SUB                          = 0x10
+       BPF_TAX                          = 0x0
+       BPF_TXA                          = 0x80
+       BPF_W                            = 0x0
+       BPF_X                            = 0x8
+       BPF_XOR                          = 0xa0
+       BRKINT                           = 0x2
+       CFLUSH                           = 0xf
+       CLOCAL                           = 0x8000
+       CLONE_CHILD_CLEARTID             = 0x200000
+       CLONE_CHILD_SETTID               = 0x1000000
+       CLONE_DETACHED                   = 0x400000
+       CLONE_FILES                      = 0x400
+       CLONE_FS                         = 0x200
+       CLONE_IO                         = 0x80000000
+       CLONE_NEWIPC                     = 0x8000000
+       CLONE_NEWNET                     = 0x40000000
+       CLONE_NEWNS                      = 0x20000
+       CLONE_NEWPID                     = 0x20000000
+       CLONE_NEWUSER                    = 0x10000000
+       CLONE_NEWUTS                     = 0x4000000
+       CLONE_PARENT                     = 0x8000
+       CLONE_PARENT_SETTID              = 0x100000
+       CLONE_PTRACE                     = 0x2000
+       CLONE_SETTLS                     = 0x80000
+       CLONE_SIGHAND                    = 0x800
+       CLONE_SYSVSEM                    = 0x40000
+       CLONE_THREAD                     = 0x10000
+       CLONE_UNTRACED                   = 0x800000
+       CLONE_VFORK                      = 0x4000
+       CLONE_VM                         = 0x100
+       CREAD                            = 0x800
+       CS5                              = 0x0
+       CS6                              = 0x100
+       CS7                              = 0x200
+       CS8                              = 0x300
+       CSIGNAL                          = 0xff
+       CSIZE                            = 0x300
+       CSTART                           = 0x11
+       CSTATUS                          = 0x0
+       CSTOP                            = 0x13
+       CSTOPB                           = 0x400
+       CSUSP                            = 0x1a
+       DT_BLK                           = 0x6
+       DT_CHR                           = 0x2
+       DT_DIR                           = 0x4
+       DT_FIFO                          = 0x1
+       DT_LNK                           = 0xa
+       DT_REG                           = 0x8
+       DT_SOCK                          = 0xc
+       DT_UNKNOWN                       = 0x0
+       DT_WHT                           = 0xe
+       ECHO                             = 0x8
+       ECHOCTL                          = 0x40
+       ECHOE                            = 0x2
+       ECHOK                            = 0x4
+       ECHOKE                           = 0x1
+       ECHONL                           = 0x10
+       ECHOPRT                          = 0x20
+       ENCODING_DEFAULT                 = 0x0
+       ENCODING_FM_MARK                 = 0x3
+       ENCODING_FM_SPACE                = 0x4
+       ENCODING_MANCHESTER              = 0x5
+       ENCODING_NRZ                     = 0x1
+       ENCODING_NRZI                    = 0x2
+       EPOLLERR                         = 0x8
+       EPOLLET                          = 0x80000000
+       EPOLLHUP                         = 0x10
+       EPOLLIN                          = 0x1
+       EPOLLMSG                         = 0x400
+       EPOLLONESHOT                     = 0x40000000
+       EPOLLOUT                         = 0x4
+       EPOLLPRI                         = 0x2
+       EPOLLRDBAND                      = 0x80
+       EPOLLRDHUP                       = 0x2000
+       EPOLLRDNORM                      = 0x40
+       EPOLLWAKEUP                      = 0x20000000
+       EPOLLWRBAND                      = 0x200
+       EPOLLWRNORM                      = 0x100
+       EPOLL_CLOEXEC                    = 0x80000
+       EPOLL_CTL_ADD                    = 0x1
+       EPOLL_CTL_DEL                    = 0x2
+       EPOLL_CTL_MOD                    = 0x3
+       EPOLL_NONBLOCK                   = 0x800
+       ETH_P_1588                       = 0x88f7
+       ETH_P_8021AD                     = 0x88a8
+       ETH_P_8021AH                     = 0x88e7
+       ETH_P_8021Q                      = 0x8100
+       ETH_P_802_2                      = 0x4
+       ETH_P_802_3                      = 0x1
+       ETH_P_802_3_MIN                  = 0x600
+       ETH_P_802_EX1                    = 0x88b5
+       ETH_P_AARP                       = 0x80f3
+       ETH_P_AF_IUCV                    = 0xfbfb
+       ETH_P_ALL                        = 0x3
+       ETH_P_AOE                        = 0x88a2
+       ETH_P_ARCNET                     = 0x1a
+       ETH_P_ARP                        = 0x806
+       ETH_P_ATALK                      = 0x809b
+       ETH_P_ATMFATE                    = 0x8884
+       ETH_P_ATMMPOA                    = 0x884c
+       ETH_P_AX25                       = 0x2
+       ETH_P_BATMAN                     = 0x4305
+       ETH_P_BPQ                        = 0x8ff
+       ETH_P_CAIF                       = 0xf7
+       ETH_P_CAN                        = 0xc
+       ETH_P_CANFD                      = 0xd
+       ETH_P_CONTROL                    = 0x16
+       ETH_P_CUST                       = 0x6006
+       ETH_P_DDCMP                      = 0x6
+       ETH_P_DEC                        = 0x6000
+       ETH_P_DIAG                       = 0x6005
+       ETH_P_DNA_DL                     = 0x6001
+       ETH_P_DNA_RC                     = 0x6002
+       ETH_P_DNA_RT                     = 0x6003
+       ETH_P_DSA                        = 0x1b
+       ETH_P_ECONET                     = 0x18
+       ETH_P_EDSA                       = 0xdada
+       ETH_P_FCOE                       = 0x8906
+       ETH_P_FIP                        = 0x8914
+       ETH_P_HDLC                       = 0x19
+       ETH_P_IEEE802154                 = 0xf6
+       ETH_P_IEEEPUP                    = 0xa00
+       ETH_P_IEEEPUPAT                  = 0xa01
+       ETH_P_IP                         = 0x800
+       ETH_P_IPV6                       = 0x86dd
+       ETH_P_IPX                        = 0x8137
+       ETH_P_IRDA                       = 0x17
+       ETH_P_LAT                        = 0x6004
+       ETH_P_LINK_CTL                   = 0x886c
+       ETH_P_LOCALTALK                  = 0x9
+       ETH_P_LOOP                       = 0x60
+       ETH_P_MOBITEX                    = 0x15
+       ETH_P_MPLS_MC                    = 0x8848
+       ETH_P_MPLS_UC                    = 0x8847
+       ETH_P_MVRP                       = 0x88f5
+       ETH_P_PAE                        = 0x888e
+       ETH_P_PAUSE                      = 0x8808
+       ETH_P_PHONET                     = 0xf5
+       ETH_P_PPPTALK                    = 0x10
+       ETH_P_PPP_DISC                   = 0x8863
+       ETH_P_PPP_MP                     = 0x8
+       ETH_P_PPP_SES                    = 0x8864
+       ETH_P_PRP                        = 0x88fb
+       ETH_P_PUP                        = 0x200
+       ETH_P_PUPAT                      = 0x201
+       ETH_P_QINQ1                      = 0x9100
+       ETH_P_QINQ2                      = 0x9200
+       ETH_P_QINQ3                      = 0x9300
+       ETH_P_RARP                       = 0x8035
+       ETH_P_SCA                        = 0x6007
+       ETH_P_SLOW                       = 0x8809
+       ETH_P_SNAP                       = 0x5
+       ETH_P_TDLS                       = 0x890d
+       ETH_P_TEB                        = 0x6558
+       ETH_P_TIPC                       = 0x88ca
+       ETH_P_TRAILER                    = 0x1c
+       ETH_P_TR_802_2                   = 0x11
+       ETH_P_WAN_PPP                    = 0x7
+       ETH_P_WCCP                       = 0x883e
+       ETH_P_X25                        = 0x805
+       EXTA                             = 0xe
+       EXTB                             = 0xf
+       EXTPROC                          = 0x10000000
+       FD_CLOEXEC                       = 0x1
+       FD_SETSIZE                       = 0x400
+       FLUSHO                           = 0x800000
+       F_DUPFD                          = 0x0
+       F_DUPFD_CLOEXEC                  = 0x406
+       F_EXLCK                          = 0x4
+       F_GETFD                          = 0x1
+       F_GETFL                          = 0x3
+       F_GETLEASE                       = 0x401
+       F_GETLK                          = 0x5
+       F_GETLK64                        = 0xc
+       F_GETOWN                         = 0x9
+       F_GETOWN_EX                      = 0x10
+       F_GETPIPE_SZ                     = 0x408
+       F_GETSIG                         = 0xb
+       F_LOCK                           = 0x1
+       F_NOTIFY                         = 0x402
+       F_OK                             = 0x0
+       F_RDLCK                          = 0x0
+       F_SETFD                          = 0x2
+       F_SETFL                          = 0x4
+       F_SETLEASE                       = 0x400
+       F_SETLK                          = 0xd
+       F_SETLK64                        = 0xd
+       F_SETLKW                         = 0xe
+       F_SETLKW64                       = 0xe
+       F_SETOWN                         = 0x8
+       F_SETOWN_EX                      = 0xf
+       F_SETPIPE_SZ                     = 0x407
+       F_SETSIG                         = 0xa
+       F_SHLCK                          = 0x8
+       F_TEST                           = 0x3
+       F_TLOCK                          = 0x2
+       F_ULOCK                          = 0x0
+       F_UNLCK                          = 0x2
+       F_WRLCK                          = 0x1
+       HUPCL                            = 0x4000
+       ICANON                           = 0x100
+       ICMPV6_FILTER                    = 0x1
+       ICRNL                            = 0x100
+       IEXTEN                           = 0x400
+       IFA_F_DADFAILED                  = 0x8
+       IFA_F_DEPRECATED                 = 0x20
+       IFA_F_HOMEADDRESS                = 0x10
+       IFA_F_NODAD                      = 0x2
+       IFA_F_OPTIMISTIC                 = 0x4
+       IFA_F_PERMANENT                  = 0x80
+       IFA_F_SECONDARY                  = 0x1
+       IFA_F_TEMPORARY                  = 0x1
+       IFA_F_TENTATIVE                  = 0x40
+       IFA_MAX                          = 0x7
+       IFF_802_1Q_VLAN                  = 0x1
+       IFF_ALLMULTI                     = 0x200
+       IFF_ATTACH_QUEUE                 = 0x200
+       IFF_AUTOMEDIA                    = 0x4000
+       IFF_BONDING                      = 0x20
+       IFF_BRIDGE_PORT                  = 0x4000
+       IFF_BROADCAST                    = 0x2
+       IFF_DEBUG                        = 0x4
+       IFF_DETACH_QUEUE                 = 0x400
+       IFF_DISABLE_NETPOLL              = 0x1000
+       IFF_DONT_BRIDGE                  = 0x800
+       IFF_DORMANT                      = 0x20000
+       IFF_DYNAMIC                      = 0x8000
+       IFF_EBRIDGE                      = 0x2
+       IFF_ECHO                         = 0x40000
+       IFF_ISATAP                       = 0x80
+       IFF_LIVE_ADDR_CHANGE             = 0x100000
+       IFF_LOOPBACK                     = 0x8
+       IFF_LOWER_UP                     = 0x10000
+       IFF_MACVLAN                      = 0x200000
+       IFF_MACVLAN_PORT                 = 0x2000
+       IFF_MASTER                       = 0x400
+       IFF_MASTER_8023AD                = 0x8
+       IFF_MASTER_ALB                   = 0x10
+       IFF_MASTER_ARPMON                = 0x100
+       IFF_MULTICAST                    = 0x1000
+       IFF_MULTI_QUEUE                  = 0x100
+       IFF_NOARP                        = 0x80
+       IFF_NOFILTER                     = 0x1000
+       IFF_NOTRAILERS                   = 0x20
+       IFF_NO_PI                        = 0x1000
+       IFF_ONE_QUEUE                    = 0x2000
+       IFF_OVS_DATAPATH                 = 0x8000
+       IFF_PERSIST                      = 0x800
+       IFF_POINTOPOINT                  = 0x10
+       IFF_PORTSEL                      = 0x2000
+       IFF_PROMISC                      = 0x100
+       IFF_RUNNING                      = 0x40
+       IFF_SLAVE                        = 0x800
+       IFF_SLAVE_INACTIVE               = 0x4
+       IFF_SLAVE_NEEDARP                = 0x40
+       IFF_SUPP_NOFCS                   = 0x80000
+       IFF_TAP                          = 0x2
+       IFF_TEAM_PORT                    = 0x40000
+       IFF_TUN                          = 0x1
+       IFF_TUN_EXCL                     = 0x8000
+       IFF_TX_SKB_SHARING               = 0x10000
+       IFF_UNICAST_FLT                  = 0x20000
+       IFF_UP                           = 0x1
+       IFF_VNET_HDR                     = 0x4000
+       IFF_VOLATILE                     = 0x70c5a
+       IFF_WAN_HDLC                     = 0x200
+       IFF_XMIT_DST_RELEASE             = 0x400
+       IFNAMSIZ                         = 0x10
+       IGNBRK                           = 0x1
+       IGNCR                            = 0x80
+       IGNPAR                           = 0x4
+       IMAXBEL                          = 0x2000
+       INLCR                            = 0x40
+       INPCK                            = 0x10
+       IN_ACCESS                        = 0x1
+       IN_ALL_EVENTS                    = 0xfff
+       IN_ATTRIB                        = 0x4
+       IN_CLASSA_HOST                   = 0xffffff
+       IN_CLASSA_MAX                    = 0x80
+       IN_CLASSA_NET                    = 0xff000000
+       IN_CLASSA_NSHIFT                 = 0x18
+       IN_CLASSB_HOST                   = 0xffff
+       IN_CLASSB_MAX                    = 0x10000
+       IN_CLASSB_NET                    = 0xffff0000
+       IN_CLASSB_NSHIFT                 = 0x10
+       IN_CLASSC_HOST                   = 0xff
+       IN_CLASSC_NET                    = 0xffffff00
+       IN_CLASSC_NSHIFT                 = 0x8
+       IN_CLOEXEC                       = 0x80000
+       IN_CLOSE                         = 0x18
+       IN_CLOSE_NOWRITE                 = 0x10
+       IN_CLOSE_WRITE                   = 0x8
+       IN_CREATE                        = 0x100
+       IN_DELETE                        = 0x200
+       IN_DELETE_SELF                   = 0x400
+       IN_DONT_FOLLOW                   = 0x2000000
+       IN_EXCL_UNLINK                   = 0x4000000
+       IN_IGNORED                       = 0x8000
+       IN_ISDIR                         = 0x40000000
+       IN_LOOPBACKNET                   = 0x7f
+       IN_MASK_ADD                      = 0x20000000
+       IN_MODIFY                        = 0x2
+       IN_MOVE                          = 0xc0
+       IN_MOVED_FROM                    = 0x40
+       IN_MOVED_TO                      = 0x80
+       IN_MOVE_SELF                     = 0x800
+       IN_NONBLOCK                      = 0x800
+       IN_ONESHOT                       = 0x80000000
+       IN_ONLYDIR                       = 0x1000000
+       IN_OPEN                          = 0x20
+       IN_Q_OVERFLOW                    = 0x4000
+       IN_UNMOUNT                       = 0x2000
+       IPPROTO_AH                       = 0x33
+       IPPROTO_COMP                     = 0x6c
+       IPPROTO_DCCP                     = 0x21
+       IPPROTO_DSTOPTS                  = 0x3c
+       IPPROTO_EGP                      = 0x8
+       IPPROTO_ENCAP                    = 0x62
+       IPPROTO_ESP                      = 0x32
+       IPPROTO_FRAGMENT                 = 0x2c
+       IPPROTO_GRE                      = 0x2f
+       IPPROTO_HOPOPTS                  = 0x0
+       IPPROTO_ICMP                     = 0x1
+       IPPROTO_ICMPV6                   = 0x3a
+       IPPROTO_IDP                      = 0x16
+       IPPROTO_IGMP                     = 0x2
+       IPPROTO_IP                       = 0x0
+       IPPROTO_IPIP                     = 0x4
+       IPPROTO_IPV6                     = 0x29
+       IPPROTO_MTP                      = 0x5c
+       IPPROTO_NONE                     = 0x3b
+       IPPROTO_PIM                      = 0x67
+       IPPROTO_PUP                      = 0xc
+       IPPROTO_RAW                      = 0xff
+       IPPROTO_ROUTING                  = 0x2b
+       IPPROTO_RSVP                     = 0x2e
+       IPPROTO_SCTP                     = 0x84
+       IPPROTO_TCP                      = 0x6
+       IPPROTO_TP                       = 0x1d
+       IPPROTO_UDP                      = 0x11
+       IPPROTO_UDPLITE                  = 0x88
+       IPV6_2292DSTOPTS                 = 0x4
+       IPV6_2292HOPLIMIT                = 0x8
+       IPV6_2292HOPOPTS                 = 0x3
+       IPV6_2292PKTINFO                 = 0x2
+       IPV6_2292PKTOPTIONS              = 0x6
+       IPV6_2292RTHDR                   = 0x5
+       IPV6_ADDRFORM                    = 0x1
+       IPV6_ADD_MEMBERSHIP              = 0x14
+       IPV6_AUTHHDR                     = 0xa
+       IPV6_CHECKSUM                    = 0x7
+       IPV6_DROP_MEMBERSHIP             = 0x15
+       IPV6_DSTOPTS                     = 0x3b
+       IPV6_HOPLIMIT                    = 0x34
+       IPV6_HOPOPTS                     = 0x36
+       IPV6_IPSEC_POLICY                = 0x22
+       IPV6_JOIN_ANYCAST                = 0x1b
+       IPV6_JOIN_GROUP                  = 0x14
+       IPV6_LEAVE_ANYCAST               = 0x1c
+       IPV6_LEAVE_GROUP                 = 0x15
+       IPV6_MTU                         = 0x18
+       IPV6_MTU_DISCOVER                = 0x17
+       IPV6_MULTICAST_HOPS              = 0x12
+       IPV6_MULTICAST_IF                = 0x11
+       IPV6_MULTICAST_LOOP              = 0x13
+       IPV6_NEXTHOP                     = 0x9
+       IPV6_PKTINFO                     = 0x32
+       IPV6_PMTUDISC_DO                 = 0x2
+       IPV6_PMTUDISC_DONT               = 0x0
+       IPV6_PMTUDISC_PROBE              = 0x3
+       IPV6_PMTUDISC_WANT               = 0x1
+       IPV6_RECVDSTOPTS                 = 0x3a
+       IPV6_RECVERR                     = 0x19
+       IPV6_RECVHOPLIMIT                = 0x33
+       IPV6_RECVHOPOPTS                 = 0x35
+       IPV6_RECVPKTINFO                 = 0x31
+       IPV6_RECVRTHDR                   = 0x38
+       IPV6_RECVTCLASS                  = 0x42
+       IPV6_ROUTER_ALERT                = 0x16
+       IPV6_RTHDR                       = 0x39
+       IPV6_RTHDRDSTOPTS                = 0x37
+       IPV6_RTHDR_LOOSE                 = 0x0
+       IPV6_RTHDR_STRICT                = 0x1
+       IPV6_RTHDR_TYPE_0                = 0x0
+       IPV6_RXDSTOPTS                   = 0x3b
+       IPV6_RXHOPOPTS                   = 0x36
+       IPV6_TCLASS                      = 0x43
+       IPV6_UNICAST_HOPS                = 0x10
+       IPV6_V6ONLY                      = 0x1a
+       IPV6_XFRM_POLICY                 = 0x23
+       IP_ADD_MEMBERSHIP                = 0x23
+       IP_ADD_SOURCE_MEMBERSHIP         = 0x27
+       IP_BLOCK_SOURCE                  = 0x26
+       IP_DEFAULT_MULTICAST_LOOP        = 0x1
+       IP_DEFAULT_MULTICAST_TTL         = 0x1
+       IP_DF                            = 0x4000
+       IP_DROP_MEMBERSHIP               = 0x24
+       IP_DROP_SOURCE_MEMBERSHIP        = 0x28
+       IP_FREEBIND                      = 0xf
+       IP_HDRINCL                       = 0x3
+       IP_IPSEC_POLICY                  = 0x10
+       IP_MAXPACKET                     = 0xffff
+       IP_MAX_MEMBERSHIPS               = 0x14
+       IP_MF                            = 0x2000
+       IP_MINTTL                        = 0x15
+       IP_MSFILTER                      = 0x29
+       IP_MSS                           = 0x240
+       IP_MTU                           = 0xe
+       IP_MTU_DISCOVER                  = 0xa
+       IP_MULTICAST_ALL                 = 0x31
+       IP_MULTICAST_IF                  = 0x20
+       IP_MULTICAST_LOOP                = 0x22
+       IP_MULTICAST_TTL                 = 0x21
+       IP_OFFMASK                       = 0x1fff
+       IP_OPTIONS                       = 0x4
+       IP_ORIGDSTADDR                   = 0x14
+       IP_PASSSEC                       = 0x12
+       IP_PKTINFO                       = 0x8
+       IP_PKTOPTIONS                    = 0x9
+       IP_PMTUDISC                      = 0xa
+       IP_PMTUDISC_DO                   = 0x2
+       IP_PMTUDISC_DONT                 = 0x0
+       IP_PMTUDISC_PROBE                = 0x3
+       IP_PMTUDISC_WANT                 = 0x1
+       IP_RECVERR                       = 0xb
+       IP_RECVOPTS                      = 0x6
+       IP_RECVORIGDSTADDR               = 0x14
+       IP_RECVRETOPTS                   = 0x7
+       IP_RECVTOS                       = 0xd
+       IP_RECVTTL                       = 0xc
+       IP_RETOPTS                       = 0x7
+       IP_RF                            = 0x8000
+       IP_ROUTER_ALERT                  = 0x5
+       IP_TOS                           = 0x1
+       IP_TRANSPARENT                   = 0x13
+       IP_TTL                           = 0x2
+       IP_UNBLOCK_SOURCE                = 0x25
+       IP_UNICAST_IF                    = 0x32
+       IP_XFRM_POLICY                   = 0x11
+       ISIG                             = 0x80
+       ISTRIP                           = 0x20
+       IUTF8                            = 0x4000
+       IXANY                            = 0x800
+       IXOFF                            = 0x400
+       IXON                             = 0x200
+       LINUX_REBOOT_CMD_CAD_OFF         = 0x0
+       LINUX_REBOOT_CMD_CAD_ON          = 0x89abcdef
+       LINUX_REBOOT_CMD_HALT            = 0xcdef0123
+       LINUX_REBOOT_CMD_KEXEC           = 0x45584543
+       LINUX_REBOOT_CMD_POWER_OFF       = 0x4321fedc
+       LINUX_REBOOT_CMD_RESTART         = 0x1234567
+       LINUX_REBOOT_CMD_RESTART2        = 0xa1b2c3d4
+       LINUX_REBOOT_CMD_SW_SUSPEND      = 0xd000fce2
+       LINUX_REBOOT_MAGIC1              = 0xfee1dead
+       LINUX_REBOOT_MAGIC2              = 0x28121969
+       LOCK_EX                          = 0x2
+       LOCK_NB                          = 0x4
+       LOCK_SH                          = 0x1
+       LOCK_UN                          = 0x8
+       MADV_DODUMP                      = 0x11
+       MADV_DOFORK                      = 0xb
+       MADV_DONTDUMP                    = 0x10
+       MADV_DONTFORK                    = 0xa
+       MADV_DONTNEED                    = 0x4
+       MADV_HUGEPAGE                    = 0xe
+       MADV_HWPOISON                    = 0x64
+       MADV_MERGEABLE                   = 0xc
+       MADV_NOHUGEPAGE                  = 0xf
+       MADV_NORMAL                      = 0x0
+       MADV_RANDOM                      = 0x1
+       MADV_REMOVE                      = 0x9
+       MADV_SEQUENTIAL                  = 0x2
+       MADV_UNMERGEABLE                 = 0xd
+       MADV_WILLNEED                    = 0x3
+       MAP_ANON                         = 0x20
+       MAP_ANONYMOUS                    = 0x20
+       MAP_DENYWRITE                    = 0x800
+       MAP_EXECUTABLE                   = 0x1000
+       MAP_FILE                         = 0x0
+       MAP_FIXED                        = 0x10
+       MAP_GROWSDOWN                    = 0x100
+       MAP_HUGETLB                      = 0x40000
+       MAP_LOCKED                       = 0x80
+       MAP_NONBLOCK                     = 0x10000
+       MAP_NORESERVE                    = 0x40
+       MAP_POPULATE                     = 0x8000
+       MAP_PRIVATE                      = 0x2
+       MAP_SHARED                       = 0x1
+       MAP_STACK                        = 0x20000
+       MAP_TYPE                         = 0xf
+       MCL_CURRENT                      = 0x2000
+       MCL_FUTURE                       = 0x4000
+       MNT_DETACH                       = 0x2
+       MNT_EXPIRE                       = 0x4
+       MNT_FORCE                        = 0x1
+       MSG_CMSG_CLOEXEC                 = 0x40000000
+       MSG_CONFIRM                      = 0x800
+       MSG_CTRUNC                       = 0x8
+       MSG_DONTROUTE                    = 0x4
+       MSG_DONTWAIT                     = 0x40
+       MSG_EOR                          = 0x80
+       MSG_ERRQUEUE                     = 0x2000
+       MSG_FASTOPEN                     = 0x20000000
+       MSG_FIN                          = 0x200
+       MSG_MORE                         = 0x8000
+       MSG_NOSIGNAL                     = 0x4000
+       MSG_OOB                          = 0x1
+       MSG_PEEK                         = 0x2
+       MSG_PROXY                        = 0x10
+       MSG_RST                          = 0x1000
+       MSG_SYN                          = 0x400
+       MSG_TRUNC                        = 0x20
+       MSG_TRYHARD                      = 0x4
+       MSG_WAITALL                      = 0x100
+       MSG_WAITFORONE                   = 0x10000
+       MS_ACTIVE                        = 0x40000000
+       MS_ASYNC                         = 0x1
+       MS_BIND                          = 0x1000
+       MS_DIRSYNC                       = 0x80
+       MS_INVALIDATE                    = 0x2
+       MS_I_VERSION                     = 0x800000
+       MS_KERNMOUNT                     = 0x400000
+       MS_MANDLOCK                      = 0x40
+       MS_MGC_MSK                       = 0xffff0000
+       MS_MGC_VAL                       = 0xc0ed0000
+       MS_MOVE                          = 0x2000
+       MS_NOATIME                       = 0x400
+       MS_NODEV                         = 0x4
+       MS_NODIRATIME                    = 0x800
+       MS_NOEXEC                        = 0x8
+       MS_NOSUID                        = 0x2
+       MS_NOUSER                        = -0x80000000
+       MS_POSIXACL                      = 0x10000
+       MS_PRIVATE                       = 0x40000
+       MS_RDONLY                        = 0x1
+       MS_REC                           = 0x4000
+       MS_RELATIME                      = 0x200000
+       MS_REMOUNT                       = 0x20
+       MS_RMT_MASK                      = 0x800051
+       MS_SHARED                        = 0x100000
+       MS_SILENT                        = 0x8000
+       MS_SLAVE                         = 0x80000
+       MS_STRICTATIME                   = 0x1000000
+       MS_SYNC                          = 0x4
+       MS_SYNCHRONOUS                   = 0x10
+       MS_UNBINDABLE                    = 0x20000
+       NAME_MAX                         = 0xff
+       NETLINK_ADD_MEMBERSHIP           = 0x1
+       NETLINK_AUDIT                    = 0x9
+       NETLINK_BROADCAST_ERROR          = 0x4
+       NETLINK_CONNECTOR                = 0xb
+       NETLINK_CRYPTO                   = 0x15
+       NETLINK_DNRTMSG                  = 0xe
+       NETLINK_DROP_MEMBERSHIP          = 0x2
+       NETLINK_ECRYPTFS                 = 0x13
+       NETLINK_FIB_LOOKUP               = 0xa
+       NETLINK_FIREWALL                 = 0x3
+       NETLINK_GENERIC                  = 0x10
+       NETLINK_INET_DIAG                = 0x4
+       NETLINK_IP6_FW                   = 0xd
+       NETLINK_ISCSI                    = 0x8
+       NETLINK_KOBJECT_UEVENT           = 0xf
+       NETLINK_NETFILTER                = 0xc
+       NETLINK_NFLOG                    = 0x5
+       NETLINK_NO_ENOBUFS               = 0x5
+       NETLINK_PKTINFO                  = 0x3
+       NETLINK_RDMA                     = 0x14
+       NETLINK_ROUTE                    = 0x0
+       NETLINK_RX_RING                  = 0x6
+       NETLINK_SCSITRANSPORT            = 0x12
+       NETLINK_SELINUX                  = 0x7
+       NETLINK_SOCK_DIAG                = 0x4
+       NETLINK_TX_RING                  = 0x7
+       NETLINK_UNUSED                   = 0x1
+       NETLINK_USERSOCK                 = 0x2
+       NETLINK_XFRM                     = 0x6
+       NLA_ALIGNTO                      = 0x4
+       NLA_F_NESTED                     = 0x8000
+       NLA_F_NET_BYTEORDER              = 0x4000
+       NLA_HDRLEN                       = 0x4
+       NLMSG_ALIGNTO                    = 0x4
+       NLMSG_DONE                       = 0x3
+       NLMSG_ERROR                      = 0x2
+       NLMSG_HDRLEN                     = 0x10
+       NLMSG_MIN_TYPE                   = 0x10
+       NLMSG_NOOP                       = 0x1
+       NLMSG_OVERRUN                    = 0x4
+       NLM_F_ACK                        = 0x4
+       NLM_F_APPEND                     = 0x800
+       NLM_F_ATOMIC                     = 0x400
+       NLM_F_CREATE                     = 0x400
+       NLM_F_DUMP                       = 0x300
+       NLM_F_DUMP_INTR                  = 0x10
+       NLM_F_ECHO                       = 0x8
+       NLM_F_EXCL                       = 0x200
+       NLM_F_MATCH                      = 0x200
+       NLM_F_MULTI                      = 0x2
+       NLM_F_REPLACE                    = 0x100
+       NLM_F_REQUEST                    = 0x1
+       NLM_F_ROOT                       = 0x100
+       NOFLSH                           = 0x80000000
+       OCRNL                            = 0x8
+       OFDEL                            = 0x80
+       OFILL                            = 0x40
+       ONLCR                            = 0x2
+       ONLRET                           = 0x20
+       ONOCR                            = 0x10
+       OPOST                            = 0x1
+       O_ACCMODE                        = 0x3
+       O_APPEND                         = 0x400
+       O_ASYNC                          = 0x2000
+       O_CLOEXEC                        = 0x80000
+       O_CREAT                          = 0x40
+       O_DIRECT                         = 0x20000
+       O_DIRECTORY                      = 0x4000
+       O_DSYNC                          = 0x1000
+       O_EXCL                           = 0x80
+       O_FSYNC                          = 0x101000
+       O_LARGEFILE                      = 0x0
+       O_NDELAY                         = 0x800
+       O_NOATIME                        = 0x40000
+       O_NOCTTY                         = 0x100
+       O_NOFOLLOW                       = 0x8000
+       O_NONBLOCK                       = 0x800
+       O_PATH                           = 0x200000
+       O_RDONLY                         = 0x0
+       O_RDWR                           = 0x2
+       O_RSYNC                          = 0x101000
+       O_SYNC                           = 0x101000
+       O_TRUNC                          = 0x200
+       O_WRONLY                         = 0x1
+       PACKET_ADD_MEMBERSHIP            = 0x1
+       PACKET_AUXDATA                   = 0x8
+       PACKET_BROADCAST                 = 0x1
+       PACKET_COPY_THRESH               = 0x7
+       PACKET_DROP_MEMBERSHIP           = 0x2
+       PACKET_FANOUT                    = 0x12
+       PACKET_FANOUT_CPU                = 0x2
+       PACKET_FANOUT_FLAG_DEFRAG        = 0x8000
+       PACKET_FANOUT_FLAG_ROLLOVER      = 0x1000
+       PACKET_FANOUT_HASH               = 0x0
+       PACKET_FANOUT_LB                 = 0x1
+       PACKET_FANOUT_RND                = 0x4
+       PACKET_FANOUT_ROLLOVER           = 0x3
+       PACKET_FASTROUTE                 = 0x6
+       PACKET_HDRLEN                    = 0xb
+       PACKET_HOST                      = 0x0
+       PACKET_LOOPBACK                  = 0x5
+       PACKET_LOSS                      = 0xe
+       PACKET_MR_ALLMULTI               = 0x2
+       PACKET_MR_MULTICAST              = 0x0
+       PACKET_MR_PROMISC                = 0x1
+       PACKET_MR_UNICAST                = 0x3
+       PACKET_MULTICAST                 = 0x2
+       PACKET_ORIGDEV                   = 0x9
+       PACKET_OTHERHOST                 = 0x3
+       PACKET_OUTGOING                  = 0x4
+       PACKET_RECV_OUTPUT               = 0x3
+       PACKET_RESERVE                   = 0xc
+       PACKET_RX_RING                   = 0x5
+       PACKET_STATISTICS                = 0x6
+       PACKET_TIMESTAMP                 = 0x11
+       PACKET_TX_HAS_OFF                = 0x13
+       PACKET_TX_RING                   = 0xd
+       PACKET_TX_TIMESTAMP              = 0x10
+       PACKET_VERSION                   = 0xa
+       PACKET_VNET_HDR                  = 0xf
+       PARENB                           = 0x1000
+       PARITY_CRC16_PR0                 = 0x2
+       PARITY_CRC16_PR0_CCITT           = 0x4
+       PARITY_CRC16_PR1                 = 0x3
+       PARITY_CRC16_PR1_CCITT           = 0x5
+       PARITY_CRC32_PR0_CCITT           = 0x6
+       PARITY_CRC32_PR1_CCITT           = 0x7
+       PARITY_DEFAULT                   = 0x0
+       PARITY_NONE                      = 0x1
+       PARMRK                           = 0x8
+       PARODD                           = 0x2000
+       PENDIN                           = 0x20000000
+       PRIO_PGRP                        = 0x1
+       PRIO_PROCESS                     = 0x0
+       PRIO_USER                        = 0x2
+       PROT_EXEC                        = 0x4
+       PROT_GROWSDOWN                   = 0x1000000
+       PROT_GROWSUP                     = 0x2000000
+       PROT_NONE                        = 0x0
+       PROT_READ                        = 0x1
+       PROT_SAO                         = 0x10
+       PROT_WRITE                       = 0x2
+       PR_CAPBSET_DROP                  = 0x18
+       PR_CAPBSET_READ                  = 0x17
+       PR_ENDIAN_BIG                    = 0x0
+       PR_ENDIAN_LITTLE                 = 0x1
+       PR_ENDIAN_PPC_LITTLE             = 0x2
+       PR_FPEMU_NOPRINT                 = 0x1
+       PR_FPEMU_SIGFPE                  = 0x2
+       PR_FP_EXC_ASYNC                  = 0x2
+       PR_FP_EXC_DISABLED               = 0x0
+       PR_FP_EXC_DIV                    = 0x10000
+       PR_FP_EXC_INV                    = 0x100000
+       PR_FP_EXC_NONRECOV               = 0x1
+       PR_FP_EXC_OVF                    = 0x20000
+       PR_FP_EXC_PRECISE                = 0x3
+       PR_FP_EXC_RES                    = 0x80000
+       PR_FP_EXC_SW_ENABLE              = 0x80
+       PR_FP_EXC_UND                    = 0x40000
+       PR_GET_CHILD_SUBREAPER           = 0x25
+       PR_GET_DUMPABLE                  = 0x3
+       PR_GET_ENDIAN                    = 0x13
+       PR_GET_FPEMU                     = 0x9
+       PR_GET_FPEXC                     = 0xb
+       PR_GET_KEEPCAPS                  = 0x7
+       PR_GET_NAME                      = 0x10
+       PR_GET_NO_NEW_PRIVS              = 0x27
+       PR_GET_PDEATHSIG                 = 0x2
+       PR_GET_SECCOMP                   = 0x15
+       PR_GET_SECUREBITS                = 0x1b
+       PR_GET_TID_ADDRESS               = 0x28
+       PR_GET_TIMERSLACK                = 0x1e
+       PR_GET_TIMING                    = 0xd
+       PR_GET_TSC                       = 0x19
+       PR_GET_UNALIGN                   = 0x5
+       PR_MCE_KILL                      = 0x21
+       PR_MCE_KILL_CLEAR                = 0x0
+       PR_MCE_KILL_DEFAULT              = 0x2
+       PR_MCE_KILL_EARLY                = 0x1
+       PR_MCE_KILL_GET                  = 0x22
+       PR_MCE_KILL_LATE                 = 0x0
+       PR_MCE_KILL_SET                  = 0x1
+       PR_SET_CHILD_SUBREAPER           = 0x24
+       PR_SET_DUMPABLE                  = 0x4
+       PR_SET_ENDIAN                    = 0x14
+       PR_SET_FPEMU                     = 0xa
+       PR_SET_FPEXC                     = 0xc
+       PR_SET_KEEPCAPS                  = 0x8
+       PR_SET_MM                        = 0x23
+       PR_SET_MM_ARG_END                = 0x9
+       PR_SET_MM_ARG_START              = 0x8
+       PR_SET_MM_AUXV                   = 0xc
+       PR_SET_MM_BRK                    = 0x7
+       PR_SET_MM_END_CODE               = 0x2
+       PR_SET_MM_END_DATA               = 0x4
+       PR_SET_MM_ENV_END                = 0xb
+       PR_SET_MM_ENV_START              = 0xa
+       PR_SET_MM_EXE_FILE               = 0xd
+       PR_SET_MM_START_BRK              = 0x6
+       PR_SET_MM_START_CODE             = 0x1
+       PR_SET_MM_START_DATA             = 0x3
+       PR_SET_MM_START_STACK            = 0x5
+       PR_SET_NAME                      = 0xf
+       PR_SET_NO_NEW_PRIVS              = 0x26
+       PR_SET_PDEATHSIG                 = 0x1
+       PR_SET_PTRACER                   = 0x59616d61
+       PR_SET_PTRACER_ANY               = -0x1
+       PR_SET_SECCOMP                   = 0x16
+       PR_SET_SECUREBITS                = 0x1c
+       PR_SET_TIMERSLACK                = 0x1d
+       PR_SET_TIMING                    = 0xe
+       PR_SET_TSC                       = 0x1a
+       PR_SET_UNALIGN                   = 0x6
+       PR_TASK_PERF_EVENTS_DISABLE      = 0x1f
+       PR_TASK_PERF_EVENTS_ENABLE       = 0x20
+       PR_TIMING_STATISTICAL            = 0x0
+       PR_TIMING_TIMESTAMP              = 0x1
+       PR_TSC_ENABLE                    = 0x1
+       PR_TSC_SIGSEGV                   = 0x2
+       PR_UNALIGN_NOPRINT               = 0x1
+       PR_UNALIGN_SIGBUS                = 0x2
+       PTRACE_ATTACH                    = 0x10
+       PTRACE_CONT                      = 0x7
+       PTRACE_DETACH                    = 0x11
+       PTRACE_EVENT_CLONE               = 0x3
+       PTRACE_EVENT_EXEC                = 0x4
+       PTRACE_EVENT_EXIT                = 0x6
+       PTRACE_EVENT_FORK                = 0x1
+       PTRACE_EVENT_SECCOMP             = 0x7
+       PTRACE_EVENT_STOP                = 0x80
+       PTRACE_EVENT_VFORK               = 0x2
+       PTRACE_EVENT_VFORK_DONE          = 0x5
+       PTRACE_GETEVENTMSG               = 0x4201
+       PTRACE_GETEVRREGS                = 0x14
+       PTRACE_GETFPREGS                 = 0xe
+       PTRACE_GETREGS                   = 0xc
+       PTRACE_GETREGS64                 = 0x16
+       PTRACE_GETREGSET                 = 0x4204
+       PTRACE_GETSIGINFO                = 0x4202
+       PTRACE_GETSIGMASK                = 0x420a
+       PTRACE_GETVRREGS                 = 0x12
+       PTRACE_GETVSRREGS                = 0x1b
+       PTRACE_GET_DEBUGREG              = 0x19
+       PTRACE_INTERRUPT                 = 0x4207
+       PTRACE_KILL                      = 0x8
+       PTRACE_LISTEN                    = 0x4208
+       PTRACE_O_EXITKILL                = 0x100000
+       PTRACE_O_MASK                    = 0x1000ff
+       PTRACE_O_TRACECLONE              = 0x8
+       PTRACE_O_TRACEEXEC               = 0x10
+       PTRACE_O_TRACEEXIT               = 0x40
+       PTRACE_O_TRACEFORK               = 0x2
+       PTRACE_O_TRACESECCOMP            = 0x80
+       PTRACE_O_TRACESYSGOOD            = 0x1
+       PTRACE_O_TRACEVFORK              = 0x4
+       PTRACE_O_TRACEVFORKDONE          = 0x20
+       PTRACE_PEEKDATA                  = 0x2
+       PTRACE_PEEKSIGINFO               = 0x4209
+       PTRACE_PEEKSIGINFO_SHARED        = 0x1
+       PTRACE_PEEKTEXT                  = 0x1
+       PTRACE_PEEKUSR                   = 0x3
+       PTRACE_POKEDATA                  = 0x5
+       PTRACE_POKETEXT                  = 0x4
+       PTRACE_POKEUSR                   = 0x6
+       PTRACE_SEIZE                     = 0x4206
+       PTRACE_SETEVRREGS                = 0x15
+       PTRACE_SETFPREGS                 = 0xf
+       PTRACE_SETOPTIONS                = 0x4200
+       PTRACE_SETREGS                   = 0xd
+       PTRACE_SETREGS64                 = 0x17
+       PTRACE_SETREGSET                 = 0x4205
+       PTRACE_SETSIGINFO                = 0x4203
+       PTRACE_SETSIGMASK                = 0x420b
+       PTRACE_SETVRREGS                 = 0x13
+       PTRACE_SETVSRREGS                = 0x1c
+       PTRACE_SET_DEBUGREG              = 0x1a
+       PTRACE_SINGLEBLOCK               = 0x100
+       PTRACE_SINGLESTEP                = 0x9
+       PTRACE_SYSCALL                   = 0x18
+       PTRACE_TRACEME                   = 0x0
+       PT_CCR                           = 0x26
+       PT_CTR                           = 0x23
+       PT_DAR                           = 0x29
+       PT_DSCR                          = 0x2c
+       PT_DSISR                         = 0x2a
+       PT_FPR0                          = 0x30
+       PT_FPSCR                         = 0x50
+       PT_LNK                           = 0x24
+       PT_MSR                           = 0x21
+       PT_NIP                           = 0x20
+       PT_ORIG_R3                       = 0x22
+       PT_R0                            = 0x0
+       PT_R1                            = 0x1
+       PT_R10                           = 0xa
+       PT_R11                           = 0xb
+       PT_R12                           = 0xc
+       PT_R13                           = 0xd
+       PT_R14                           = 0xe
+       PT_R15                           = 0xf
+       PT_R16                           = 0x10
+       PT_R17                           = 0x11
+       PT_R18                           = 0x12
+       PT_R19                           = 0x13
+       PT_R2                            = 0x2
+       PT_R20                           = 0x14
+       PT_R21                           = 0x15
+       PT_R22                           = 0x16
+       PT_R23                           = 0x17
+       PT_R24                           = 0x18
+       PT_R25                           = 0x19
+       PT_R26                           = 0x1a
+       PT_R27                           = 0x1b
+       PT_R28                           = 0x1c
+       PT_R29                           = 0x1d
+       PT_R3                            = 0x3
+       PT_R30                           = 0x1e
+       PT_R31                           = 0x1f
+       PT_R4                            = 0x4
+       PT_R5                            = 0x5
+       PT_R6                            = 0x6
+       PT_R7                            = 0x7
+       PT_R8                            = 0x8
+       PT_R9                            = 0x9
+       PT_REGS_COUNT                    = 0x2c
+       PT_RESULT                        = 0x2b
+       PT_SOFTE                         = 0x27
+       PT_TRAP                          = 0x28
+       PT_VR0                           = 0x52
+       PT_VRSAVE                        = 0x94
+       PT_VSCR                          = 0x93
+       PT_VSR0                          = 0x96
+       PT_VSR31                         = 0xd4
+       PT_XER                           = 0x25
+       RLIMIT_AS                        = 0x9
+       RLIMIT_CORE                      = 0x4
+       RLIMIT_CPU                       = 0x0
+       RLIMIT_DATA                      = 0x2
+       RLIMIT_FSIZE                     = 0x1
+       RLIMIT_NOFILE                    = 0x7
+       RLIMIT_STACK                     = 0x3
+       RLIM_INFINITY                    = -0x1
+       RTAX_ADVMSS                      = 0x8
+       RTAX_CWND                        = 0x7
+       RTAX_FEATURES                    = 0xc
+       RTAX_FEATURE_ALLFRAG             = 0x8
+       RTAX_FEATURE_ECN                 = 0x1
+       RTAX_FEATURE_SACK                = 0x2
+       RTAX_FEATURE_TIMESTAMP           = 0x4
+       RTAX_HOPLIMIT                    = 0xa
+       RTAX_INITCWND                    = 0xb
+       RTAX_INITRWND                    = 0xe
+       RTAX_LOCK                        = 0x1
+       RTAX_MAX                         = 0xf
+       RTAX_MTU                         = 0x2
+       RTAX_QUICKACK                    = 0xf
+       RTAX_REORDERING                  = 0x9
+       RTAX_RTO_MIN                     = 0xd
+       RTAX_RTT                         = 0x4
+       RTAX_RTTVAR                      = 0x5
+       RTAX_SSTHRESH                    = 0x6
+       RTAX_UNSPEC                      = 0x0
+       RTAX_WINDOW                      = 0x3
+       RTA_ALIGNTO                      = 0x4
+       RTA_MAX                          = 0x11
+       RTCF_DIRECTSRC                   = 0x4000000
+       RTCF_DOREDIRECT                  = 0x1000000
+       RTCF_LOG                         = 0x2000000
+       RTCF_MASQ                        = 0x400000
+       RTCF_NAT                         = 0x800000
+       RTCF_VALVE                       = 0x200000
+       RTF_ADDRCLASSMASK                = 0xf8000000
+       RTF_ADDRCONF                     = 0x40000
+       RTF_ALLONLINK                    = 0x20000
+       RTF_BROADCAST                    = 0x10000000
+       RTF_CACHE                        = 0x1000000
+       RTF_DEFAULT                      = 0x10000
+       RTF_DYNAMIC                      = 0x10
+       RTF_FLOW                         = 0x2000000
+       RTF_GATEWAY                      = 0x2
+       RTF_HOST                         = 0x4
+       RTF_INTERFACE                    = 0x40000000
+       RTF_IRTT                         = 0x100
+       RTF_LINKRT                       = 0x100000
+       RTF_LOCAL                        = 0x80000000
+       RTF_MODIFIED                     = 0x20
+       RTF_MSS                          = 0x40
+       RTF_MTU                          = 0x40
+       RTF_MULTICAST                    = 0x20000000
+       RTF_NAT                          = 0x8000000
+       RTF_NOFORWARD                    = 0x1000
+       RTF_NONEXTHOP                    = 0x200000
+       RTF_NOPMTUDISC                   = 0x4000
+       RTF_POLICY                       = 0x4000000
+       RTF_REINSTATE                    = 0x8
+       RTF_REJECT                       = 0x200
+       RTF_STATIC                       = 0x400
+       RTF_THROW                        = 0x2000
+       RTF_UP                           = 0x1
+       RTF_WINDOW                       = 0x80
+       RTF_XRESOLVE                     = 0x800
+       RTM_BASE                         = 0x10
+       RTM_DELACTION                    = 0x31
+       RTM_DELADDR                      = 0x15
+       RTM_DELADDRLABEL                 = 0x49
+       RTM_DELLINK                      = 0x11
+       RTM_DELMDB                       = 0x55
+       RTM_DELNEIGH                     = 0x1d
+       RTM_DELQDISC                     = 0x25
+       RTM_DELROUTE                     = 0x19
+       RTM_DELRULE                      = 0x21
+       RTM_DELTCLASS                    = 0x29
+       RTM_DELTFILTER                   = 0x2d
+       RTM_F_CLONED                     = 0x200
+       RTM_F_EQUALIZE                   = 0x400
+       RTM_F_NOTIFY                     = 0x100
+       RTM_F_PREFIX                     = 0x800
+       RTM_GETACTION                    = 0x32
+       RTM_GETADDR                      = 0x16
+       RTM_GETADDRLABEL                 = 0x4a
+       RTM_GETANYCAST                   = 0x3e
+       RTM_GETDCB                       = 0x4e
+       RTM_GETLINK                      = 0x12
+       RTM_GETMDB                       = 0x56
+       RTM_GETMULTICAST                 = 0x3a
+       RTM_GETNEIGH                     = 0x1e
+       RTM_GETNEIGHTBL                  = 0x42
+       RTM_GETNETCONF                   = 0x52
+       RTM_GETQDISC                     = 0x26
+       RTM_GETROUTE                     = 0x1a
+       RTM_GETRULE                      = 0x22
+       RTM_GETTCLASS                    = 0x2a
+       RTM_GETTFILTER                   = 0x2e
+       RTM_MAX                          = 0x57
+       RTM_NEWACTION                    = 0x30
+       RTM_NEWADDR                      = 0x14
+       RTM_NEWADDRLABEL                 = 0x48
+       RTM_NEWLINK                      = 0x10
+       RTM_NEWMDB                       = 0x54
+       RTM_NEWNDUSEROPT                 = 0x44
+       RTM_NEWNEIGH                     = 0x1c
+       RTM_NEWNEIGHTBL                  = 0x40
+       RTM_NEWNETCONF                   = 0x50
+       RTM_NEWPREFIX                    = 0x34
+       RTM_NEWQDISC                     = 0x24
+       RTM_NEWROUTE                     = 0x18
+       RTM_NEWRULE                      = 0x20
+       RTM_NEWTCLASS                    = 0x28
+       RTM_NEWTFILTER                   = 0x2c
+       RTM_NR_FAMILIES                  = 0x12
+       RTM_NR_MSGTYPES                  = 0x48
+       RTM_SETDCB                       = 0x4f
+       RTM_SETLINK                      = 0x13
+       RTM_SETNEIGHTBL                  = 0x43
+       RTNH_ALIGNTO                     = 0x4
+       RTNH_F_DEAD                      = 0x1
+       RTNH_F_ONLINK                    = 0x4
+       RTNH_F_PERVASIVE                 = 0x2
+       RTN_MAX                          = 0xb
+       RTPROT_BIRD                      = 0xc
+       RTPROT_BOOT                      = 0x3
+       RTPROT_DHCP                      = 0x10
+       RTPROT_DNROUTED                  = 0xd
+       RTPROT_GATED                     = 0x8
+       RTPROT_KERNEL                    = 0x2
+       RTPROT_MROUTED                   = 0x11
+       RTPROT_MRT                       = 0xa
+       RTPROT_NTK                       = 0xf
+       RTPROT_RA                        = 0x9
+       RTPROT_REDIRECT                  = 0x1
+       RTPROT_STATIC                    = 0x4
+       RTPROT_UNSPEC                    = 0x0
+       RTPROT_XORP                      = 0xe
+       RTPROT_ZEBRA                     = 0xb
+       RT_CLASS_DEFAULT                 = 0xfd
+       RT_CLASS_LOCAL                   = 0xff
+       RT_CLASS_MAIN                    = 0xfe
+       RT_CLASS_MAX                     = 0xff
+       RT_CLASS_UNSPEC                  = 0x0
+       RUSAGE_CHILDREN                  = -0x1
+       RUSAGE_SELF                      = 0x0
+       RUSAGE_THREAD                    = 0x1
+       SCM_CREDENTIALS                  = 0x2
+       SCM_RIGHTS                       = 0x1
+       SCM_TIMESTAMP                    = 0x1d
+       SCM_TIMESTAMPING                 = 0x25
+       SCM_TIMESTAMPNS                  = 0x23
+       SCM_WIFI_STATUS                  = 0x29
+       SHUT_RD                          = 0x0
+       SHUT_RDWR                        = 0x2
+       SHUT_WR                          = 0x1
+       SIOCADDDLCI                      = 0x8980
+       SIOCADDMULTI                     = 0x8931
+       SIOCADDRT                        = 0x890b
+       SIOCATMARK                       = 0x8905
+       SIOCDARP                         = 0x8953
+       SIOCDELDLCI                      = 0x8981
+       SIOCDELMULTI                     = 0x8932
+       SIOCDELRT                        = 0x890c
+       SIOCDEVPRIVATE                   = 0x89f0
+       SIOCDIFADDR                      = 0x8936
+       SIOCDRARP                        = 0x8960
+       SIOCGARP                         = 0x8954
+       SIOCGIFADDR                      = 0x8915
+       SIOCGIFBR                        = 0x8940
+       SIOCGIFBRDADDR                   = 0x8919
+       SIOCGIFCONF                      = 0x8912
+       SIOCGIFCOUNT                     = 0x8938
+       SIOCGIFDSTADDR                   = 0x8917
+       SIOCGIFENCAP                     = 0x8925
+       SIOCGIFFLAGS                     = 0x8913
+       SIOCGIFHWADDR                    = 0x8927
+       SIOCGIFINDEX                     = 0x8933
+       SIOCGIFMAP                       = 0x8970
+       SIOCGIFMEM                       = 0x891f
+       SIOCGIFMETRIC                    = 0x891d
+       SIOCGIFMTU                       = 0x8921
+       SIOCGIFNAME                      = 0x8910
+       SIOCGIFNETMASK                   = 0x891b
+       SIOCGIFPFLAGS                    = 0x8935
+       SIOCGIFSLAVE                     = 0x8929
+       SIOCGIFTXQLEN                    = 0x8942
+       SIOCGPGRP                        = 0x8904
+       SIOCGRARP                        = 0x8961
+       SIOCGSTAMP                       = 0x8906
+       SIOCGSTAMPNS                     = 0x8907
+       SIOCPROTOPRIVATE                 = 0x89e0
+       SIOCRTMSG                        = 0x890d
+       SIOCSARP                         = 0x8955
+       SIOCSIFADDR                      = 0x8916
+       SIOCSIFBR                        = 0x8941
+       SIOCSIFBRDADDR                   = 0x891a
+       SIOCSIFDSTADDR                   = 0x8918
+       SIOCSIFENCAP                     = 0x8926
+       SIOCSIFFLAGS                     = 0x8914
+       SIOCSIFHWADDR                    = 0x8924
+       SIOCSIFHWBROADCAST               = 0x8937
+       SIOCSIFLINK                      = 0x8911
+       SIOCSIFMAP                       = 0x8971
+       SIOCSIFMEM                       = 0x8920
+       SIOCSIFMETRIC                    = 0x891e
+       SIOCSIFMTU                       = 0x8922
+       SIOCSIFNAME                      = 0x8923
+       SIOCSIFNETMASK                   = 0x891c
+       SIOCSIFPFLAGS                    = 0x8934
+       SIOCSIFSLAVE                     = 0x8930
+       SIOCSIFTXQLEN                    = 0x8943
+       SIOCSPGRP                        = 0x8902
+       SIOCSRARP                        = 0x8962
+       SOCK_CLOEXEC                     = 0x80000
+       SOCK_DCCP                        = 0x6
+       SOCK_DGRAM                       = 0x2
+       SOCK_NONBLOCK                    = 0x800
+       SOCK_PACKET                      = 0xa
+       SOCK_RAW                         = 0x3
+       SOCK_RDM                         = 0x4
+       SOCK_SEQPACKET                   = 0x5
+       SOCK_STREAM                      = 0x1
+       SOL_AAL                          = 0x109
+       SOL_ATM                          = 0x108
+       SOL_DECNET                       = 0x105
+       SOL_ICMPV6                       = 0x3a
+       SOL_IP                           = 0x0
+       SOL_IPV6                         = 0x29
+       SOL_IRDA                         = 0x10a
+       SOL_PACKET                       = 0x107
+       SOL_RAW                          = 0xff
+       SOL_SOCKET                       = 0x1
+       SOL_TCP                          = 0x6
+       SOL_X25                          = 0x106
+       SOMAXCONN                        = 0x80
+       SO_ACCEPTCONN                    = 0x1e
+       SO_ATTACH_FILTER                 = 0x1a
+       SO_BINDTODEVICE                  = 0x19
+       SO_BROADCAST                     = 0x6
+       SO_BSDCOMPAT                     = 0xe
+       SO_BUSY_POLL                     = 0x2e
+       SO_DEBUG                         = 0x1
+       SO_DETACH_FILTER                 = 0x1b
+       SO_DOMAIN                        = 0x27
+       SO_DONTROUTE                     = 0x5
+       SO_ERROR                         = 0x4
+       SO_GET_FILTER                    = 0x1a
+       SO_KEEPALIVE                     = 0x9
+       SO_LINGER                        = 0xd
+       SO_LOCK_FILTER                   = 0x2c
+       SO_MARK                          = 0x24
+       SO_MAX_PACING_RATE               = 0x2f
+       SO_NOFCS                         = 0x2b
+       SO_NO_CHECK                      = 0xb
+       SO_OOBINLINE                     = 0xa
+       SO_PASSCRED                      = 0x14
+       SO_PASSSEC                       = 0x22
+       SO_PEEK_OFF                      = 0x2a
+       SO_PEERCRED                      = 0x15
+       SO_PEERNAME                      = 0x1c
+       SO_PEERSEC                       = 0x1f
+       SO_PRIORITY                      = 0xc
+       SO_PROTOCOL                      = 0x26
+       SO_RCVBUF                        = 0x8
+       SO_RCVBUFFORCE                   = 0x21
+       SO_RCVLOWAT                      = 0x10
+       SO_RCVTIMEO                      = 0x12
+       SO_REUSEADDR                     = 0x2
+       SO_REUSEPORT                     = 0xf
+       SO_RXQ_OVFL                      = 0x28
+       SO_SECURITY_AUTHENTICATION       = 0x16
+       SO_SECURITY_ENCRYPTION_NETWORK   = 0x18
+       SO_SECURITY_ENCRYPTION_TRANSPORT = 0x17
+       SO_SELECT_ERR_QUEUE              = 0x2d
+       SO_SNDBUF                        = 0x7
+       SO_SNDBUFFORCE                   = 0x20
+       SO_SNDLOWAT                      = 0x11
+       SO_SNDTIMEO                      = 0x13
+       SO_TIMESTAMP                     = 0x1d
+       SO_TIMESTAMPING                  = 0x25
+       SO_TIMESTAMPNS                   = 0x23
+       SO_TYPE                          = 0x3
+       SO_WIFI_STATUS                   = 0x29
+       S_BLKSIZE                        = 0x200
+       S_IEXEC                          = 0x40
+       S_IFBLK                          = 0x6000
+       S_IFCHR                          = 0x2000
+       S_IFDIR                          = 0x4000
+       S_IFIFO                          = 0x1000
+       S_IFLNK                          = 0xa000
+       S_IFMT                           = 0xf000
+       S_IFREG                          = 0x8000
+       S_IFSOCK                         = 0xc000
+       S_IREAD                          = 0x100
+       S_IRGRP                          = 0x20
+       S_IROTH                          = 0x4
+       S_IRUSR                          = 0x100
+       S_IRWXG                          = 0x38
+       S_IRWXO                          = 0x7
+       S_IRWXU                          = 0x1c0
+       S_ISGID                          = 0x400
+       S_ISUID                          = 0x800
+       S_ISVTX                          = 0x200
+       S_IWGRP                          = 0x10
+       S_IWOTH                          = 0x2
+       S_IWRITE                         = 0x80
+       S_IWUSR                          = 0x80
+       S_IXGRP                          = 0x8
+       S_IXOTH                          = 0x1
+       S_IXUSR                          = 0x40
+       TCFLSH                           = 0x2000741f
+       TCIFLUSH                         = 0x0
+       TCIOFLUSH                        = 0x2
+       TCOFLUSH                         = 0x1
+       TCP_CONGESTION                   = 0xd
+       TCP_CORK                         = 0x3
+       TCP_DEFER_ACCEPT                 = 0x9
+       TCP_INFO                         = 0xb
+       TCP_KEEPCNT                      = 0x6
+       TCP_KEEPIDLE                     = 0x4
+       TCP_KEEPINTVL                    = 0x5
+       TCP_LINGER2                      = 0x8
+       TCP_MAXSEG                       = 0x2
+       TCP_MAXWIN                       = 0xffff
+       TCP_MAX_WINSHIFT                 = 0xe
+       TCP_MD5SIG                       = 0xe
+       TCP_MD5SIG_MAXKEYLEN             = 0x50
+       TCP_MSS                          = 0x200
+       TCP_NODELAY                      = 0x1
+       TCP_QUICKACK                     = 0xc
+       TCP_SYNCNT                       = 0x7
+       TCP_WINDOW_CLAMP                 = 0xa
+       TCSAFLUSH                        = 0x2
+       TIOCCBRK                         = 0x5428
+       TIOCCONS                         = 0x541d
+       TIOCEXCL                         = 0x540c
+       TIOCGDEV                         = 0x40045432
+       TIOCGETC                         = 0x40067412
+       TIOCGETD                         = 0x5424
+       TIOCGETP                         = 0x40067408
+       TIOCGEXCL                        = 0x40045440
+       TIOCGICOUNT                      = 0x545d
+       TIOCGLCKTRMIOS                   = 0x5456
+       TIOCGLTC                         = 0x40067474
+       TIOCGPGRP                        = 0x40047477
+       TIOCGPKT                         = 0x40045438
+       TIOCGPTLCK                       = 0x40045439
+       TIOCGPTN                         = 0x40045430
+       TIOCGRS485                       = 0x542e
+       TIOCGSERIAL                      = 0x541e
+       TIOCGSID                         = 0x5429
+       TIOCGSOFTCAR                     = 0x5419
+       TIOCGWINSZ                       = 0x40087468
+       TIOCINQ                          = 0x4004667f
+       TIOCLINUX                        = 0x541c
+       TIOCMBIC                         = 0x5417
+       TIOCMBIS                         = 0x5416
+       TIOCMGET                         = 0x5415
+       TIOCMIWAIT                       = 0x545c
+       TIOCMSET                         = 0x5418
+       TIOCM_CAR                        = 0x40
+       TIOCM_CD                         = 0x40
+       TIOCM_CTS                        = 0x20
+       TIOCM_DSR                        = 0x100
+       TIOCM_DTR                        = 0x2
+       TIOCM_LE                         = 0x1
+       TIOCM_LOOP                       = 0x8000
+       TIOCM_OUT1                       = 0x2000
+       TIOCM_OUT2                       = 0x4000
+       TIOCM_RI                         = 0x80
+       TIOCM_RNG                        = 0x80
+       TIOCM_RTS                        = 0x4
+       TIOCM_SR                         = 0x10
+       TIOCM_ST                         = 0x8
+       TIOCNOTTY                        = 0x5422
+       TIOCNXCL                         = 0x540d
+       TIOCOUTQ                         = 0x40047473
+       TIOCPKT                          = 0x5420
+       TIOCPKT_DATA                     = 0x0
+       TIOCPKT_DOSTOP                   = 0x20
+       TIOCPKT_FLUSHREAD                = 0x1
+       TIOCPKT_FLUSHWRITE               = 0x2
+       TIOCPKT_IOCTL                    = 0x40
+       TIOCPKT_NOSTOP                   = 0x10
+       TIOCPKT_START                    = 0x8
+       TIOCPKT_STOP                     = 0x4
+       TIOCSBRK                         = 0x5427
+       TIOCSCTTY                        = 0x540e
+       TIOCSERCONFIG                    = 0x5453
+       TIOCSERGETLSR                    = 0x5459
+       TIOCSERGETMULTI                  = 0x545a
+       TIOCSERGSTRUCT                   = 0x5458
+       TIOCSERGWILD                     = 0x5454
+       TIOCSERSETMULTI                  = 0x545b
+       TIOCSERSWILD                     = 0x5455
+       TIOCSER_TEMT                     = 0x1
+       TIOCSETC                         = 0x80067411
+       TIOCSETD                         = 0x5423
+       TIOCSETN                         = 0x8006740a
+       TIOCSETP                         = 0x80067409
+       TIOCSIG                          = 0x80045436
+       TIOCSLCKTRMIOS                   = 0x5457
+       TIOCSLTC                         = 0x80067475
+       TIOCSPGRP                        = 0x80047476
+       TIOCSPTLCK                       = 0x80045431
+       TIOCSRS485                       = 0x542f
+       TIOCSSERIAL                      = 0x541f
+       TIOCSSOFTCAR                     = 0x541a
+       TIOCSTART                        = 0x2000746e
+       TIOCSTI                          = 0x5412
+       TIOCSTOP                         = 0x2000746f
+       TIOCSWINSZ                       = 0x80087467
+       TIOCVHANGUP                      = 0x5437
+       TOSTOP                           = 0x400000
+       TUNATTACHFILTER                  = 0x801054d5
+       TUNDETACHFILTER                  = 0x801054d6
+       TUNGETFEATURES                   = 0x400454cf
+       TUNGETFILTER                     = 0x401054db
+       TUNGETIFF                        = 0x400454d2
+       TUNGETSNDBUF                     = 0x400454d3
+       TUNGETVNETHDRSZ                  = 0x400454d7
+       TUNSETDEBUG                      = 0x800454c9
+       TUNSETGROUP                      = 0x800454ce
+       TUNSETIFF                        = 0x800454ca
+       TUNSETIFINDEX                    = 0x800454da
+       TUNSETLINK                       = 0x800454cd
+       TUNSETNOCSUM                     = 0x800454c8
+       TUNSETOFFLOAD                    = 0x800454d0
+       TUNSETOWNER                      = 0x800454cc
+       TUNSETPERSIST                    = 0x800454cb
+       TUNSETQUEUE                      = 0x800454d9
+       TUNSETSNDBUF                     = 0x800454d4
+       TUNSETTXFILTER                   = 0x800454d1
+       TUNSETVNETHDRSZ                  = 0x800454d8
+       VDISCARD                         = 0x10
+       VEOF                             = 0x4
+       VEOL                             = 0x6
+       VEOL2                            = 0x8
+       VERASE                           = 0x2
+       VINTR                            = 0x0
+       VKILL                            = 0x3
+       VLNEXT                           = 0xf
+       VMIN                             = 0x5
+       VQUIT                            = 0x1
+       VREPRINT                         = 0xb
+       VSTART                           = 0xd
+       VSTOP                            = 0xe
+       VSUSP                            = 0xc
+       VSWTC                            = 0x9
+       VT0                              = 0x0
+       VT1                              = 0x10000
+       VTDLY                            = 0x10000
+       VTIME                            = 0x7
+       VWERASE                          = 0xa
+       WALL                             = 0x40000000
+       WCLONE                           = 0x80000000
+       WCONTINUED                       = 0x8
+       WEXITED                          = 0x4
+       WNOHANG                          = 0x1
+       WNOTHREAD                        = 0x20000000
+       WNOWAIT                          = 0x1000000
+       WORDSIZE                         = 0x40
+       WSTOPPED                         = 0x2
+       WUNTRACED                        = 0x2
+)
+
+// Errors
+const (
+       E2BIG           = Errno(0x7)
+       EACCES          = Errno(0xd)
+       EADDRINUSE      = Errno(0x62)
+       EADDRNOTAVAIL   = Errno(0x63)
+       EADV            = Errno(0x44)
+       EAFNOSUPPORT    = Errno(0x61)
+       EAGAIN          = Errno(0xb)
+       EALREADY        = Errno(0x72)
+       EBADE           = Errno(0x34)
+       EBADF           = Errno(0x9)
+       EBADFD          = Errno(0x4d)
+       EBADMSG         = Errno(0x4a)
+       EBADR           = Errno(0x35)
+       EBADRQC         = Errno(0x38)
+       EBADSLT         = Errno(0x39)
+       EBFONT          = Errno(0x3b)
+       EBUSY           = Errno(0x10)
+       ECANCELED       = Errno(0x7d)
+       ECHILD          = Errno(0xa)
+       ECHRNG          = Errno(0x2c)
+       ECOMM           = Errno(0x46)
+       ECONNABORTED    = Errno(0x67)
+       ECONNREFUSED    = Errno(0x6f)
+       ECONNRESET      = Errno(0x68)
+       EDEADLK         = Errno(0x23)
+       EDEADLOCK       = Errno(0x3a)
+       EDESTADDRREQ    = Errno(0x59)
+       EDOM            = Errno(0x21)
+       EDOTDOT         = Errno(0x49)
+       EDQUOT          = Errno(0x7a)
+       EEXIST          = Errno(0x11)
+       EFAULT          = Errno(0xe)
+       EFBIG           = Errno(0x1b)
+       EHOSTDOWN       = Errno(0x70)
+       EHOSTUNREACH    = Errno(0x71)
+       EHWPOISON       = Errno(0x85)
+       EIDRM           = Errno(0x2b)
+       EILSEQ          = Errno(0x54)
+       EINPROGRESS     = Errno(0x73)
+       EINTR           = Errno(0x4)
+       EINVAL          = Errno(0x16)
+       EIO             = Errno(0x5)
+       EISCONN         = Errno(0x6a)
+       EISDIR          = Errno(0x15)
+       EISNAM          = Errno(0x78)
+       EKEYEXPIRED     = Errno(0x7f)
+       EKEYREJECTED    = Errno(0x81)
+       EKEYREVOKED     = Errno(0x80)
+       EL2HLT          = Errno(0x33)
+       EL2NSYNC        = Errno(0x2d)
+       EL3HLT          = Errno(0x2e)
+       EL3RST          = Errno(0x2f)
+       ELIBACC         = Errno(0x4f)
+       ELIBBAD         = Errno(0x50)
+       ELIBEXEC        = Errno(0x53)
+       ELIBMAX         = Errno(0x52)
+       ELIBSCN         = Errno(0x51)
+       ELNRNG          = Errno(0x30)
+       ELOOP           = Errno(0x28)
+       EMEDIUMTYPE     = Errno(0x7c)
+       EMFILE          = Errno(0x18)
+       EMLINK          = Errno(0x1f)
+       EMSGSIZE        = Errno(0x5a)
+       EMULTIHOP       = Errno(0x48)
+       ENAMETOOLONG    = Errno(0x24)
+       ENAVAIL         = Errno(0x77)
+       ENETDOWN        = Errno(0x64)
+       ENETRESET       = Errno(0x66)
+       ENETUNREACH     = Errno(0x65)
+       ENFILE          = Errno(0x17)
+       ENOANO          = Errno(0x37)
+       ENOBUFS         = Errno(0x69)
+       ENOCSI          = Errno(0x32)
+       ENODATA         = Errno(0x3d)
+       ENODEV          = Errno(0x13)
+       ENOENT          = Errno(0x2)
+       ENOEXEC         = Errno(0x8)
+       ENOKEY          = Errno(0x7e)
+       ENOLCK          = Errno(0x25)
+       ENOLINK         = Errno(0x43)
+       ENOMEDIUM       = Errno(0x7b)
+       ENOMEM          = Errno(0xc)
+       ENOMSG          = Errno(0x2a)
+       ENONET          = Errno(0x40)
+       ENOPKG          = Errno(0x41)
+       ENOPROTOOPT     = Errno(0x5c)
+       ENOSPC          = Errno(0x1c)
+       ENOSR           = Errno(0x3f)
+       ENOSTR          = Errno(0x3c)
+       ENOSYS          = Errno(0x26)
+       ENOTBLK         = Errno(0xf)
+       ENOTCONN        = Errno(0x6b)
+       ENOTDIR         = Errno(0x14)
+       ENOTEMPTY       = Errno(0x27)
+       ENOTNAM         = Errno(0x76)
+       ENOTRECOVERABLE = Errno(0x83)
+       ENOTSOCK        = Errno(0x58)
+       ENOTSUP         = Errno(0x5f)
+       ENOTTY          = Errno(0x19)
+       ENOTUNIQ        = Errno(0x4c)
+       ENXIO           = Errno(0x6)
+       EOPNOTSUPP      = Errno(0x5f)
+       EOVERFLOW       = Errno(0x4b)
+       EOWNERDEAD      = Errno(0x82)
+       EPERM           = Errno(0x1)
+       EPFNOSUPPORT    = Errno(0x60)
+       EPIPE           = Errno(0x20)
+       EPROTO          = Errno(0x47)
+       EPROTONOSUPPORT = Errno(0x5d)
+       EPROTOTYPE      = Errno(0x5b)
+       ERANGE          = Errno(0x22)
+       EREMCHG         = Errno(0x4e)
+       EREMOTE         = Errno(0x42)
+       EREMOTEIO       = Errno(0x79)
+       ERESTART        = Errno(0x55)
+       ERFKILL         = Errno(0x84)
+       EROFS           = Errno(0x1e)
+       ESHUTDOWN       = Errno(0x6c)
+       ESOCKTNOSUPPORT = Errno(0x5e)
+       ESPIPE          = Errno(0x1d)
+       ESRCH           = Errno(0x3)
+       ESRMNT          = Errno(0x45)
+       ESTALE          = Errno(0x74)
+       ESTRPIPE        = Errno(0x56)
+       ETIME           = Errno(0x3e)
+       ETIMEDOUT       = Errno(0x6e)
+       ETOOMANYREFS    = Errno(0x6d)
+       ETXTBSY         = Errno(0x1a)
+       EUCLEAN         = Errno(0x75)
+       EUNATCH         = Errno(0x31)
+       EUSERS          = Errno(0x57)
+       EWOULDBLOCK     = Errno(0xb)
+       EXDEV           = Errno(0x12)
+       EXFULL          = Errno(0x36)
+)
+
+// Signals
+const (
+       SIGABRT   = Signal(0x6)
+       SIGALRM   = Signal(0xe)
+       SIGBUS    = Signal(0x7)
+       SIGCHLD   = Signal(0x11)
+       SIGCLD    = Signal(0x11)
+       SIGCONT   = Signal(0x12)
+       SIGFPE    = Signal(0x8)
+       SIGHUP    = Signal(0x1)
+       SIGILL    = Signal(0x4)
+       SIGINT    = Signal(0x2)
+       SIGIO     = Signal(0x1d)
+       SIGIOT    = Signal(0x6)
+       SIGKILL   = Signal(0x9)
+       SIGPIPE   = Signal(0xd)
+       SIGPOLL   = Signal(0x1d)
+       SIGPROF   = Signal(0x1b)
+       SIGPWR    = Signal(0x1e)
+       SIGQUIT   = Signal(0x3)
+       SIGSEGV   = Signal(0xb)
+       SIGSTKFLT = Signal(0x10)
+       SIGSTOP   = Signal(0x13)
+       SIGSYS    = Signal(0x1f)
+       SIGTERM   = Signal(0xf)
+       SIGTRAP   = Signal(0x5)
+       SIGTSTP   = Signal(0x14)
+       SIGTTIN   = Signal(0x15)
+       SIGTTOU   = Signal(0x16)
+       SIGUNUSED = Signal(0x1f)
+       SIGURG    = Signal(0x17)
+       SIGUSR1   = Signal(0xa)
+       SIGUSR2   = Signal(0xc)
+       SIGVTALRM = Signal(0x1a)
+       SIGWINCH  = Signal(0x1c)
+       SIGXCPU   = Signal(0x18)
+       SIGXFSZ   = Signal(0x19)
+)
+
+// Error table
+var errors = [...]string{
+       1:   "operation not permitted",
+       2:   "no such file or directory",
+       3:   "no such process",
+       4:   "interrupted system call",
+       5:   "input/output error",
+       6:   "no such device or address",
+       7:   "argument list too long",
+       8:   "exec format error",
+       9:   "bad file descriptor",
+       10:  "no child processes",
+       11:  "resource temporarily unavailable",
+       12:  "cannot allocate memory",
+       13:  "permission denied",
+       14:  "bad address",
+       15:  "block device required",
+       16:  "device or resource busy",
+       17:  "file exists",
+       18:  "invalid cross-device link",
+       19:  "no such device",
+       20:  "not a directory",
+       21:  "is a directory",
+       22:  "invalid argument",
+       23:  "too many open files in system",
+       24:  "too many open files",
+       25:  "inappropriate ioctl for device",
+       26:  "text file busy",
+       27:  "file too large",
+       28:  "no space left on device",
+       29:  "illegal seek",
+       30:  "read-only file system",
+       31:  "too many links",
+       32:  "broken pipe",
+       33:  "numerical argument out of domain",
+       34:  "numerical result out of range",
+       35:  "resource deadlock avoided",
+       36:  "file name too long",
+       37:  "no locks available",
+       38:  "function not implemented",
+       39:  "directory not empty",
+       40:  "too many levels of symbolic links",
+       42:  "no message of desired type",
+       43:  "identifier removed",
+       44:  "channel number out of range",
+       45:  "level 2 not synchronized",
+       46:  "level 3 halted",
+       47:  "level 3 reset",
+       48:  "link number out of range",
+       49:  "protocol driver not attached",
+       50:  "no CSI structure available",
+       51:  "level 2 halted",
+       52:  "invalid exchange",
+       53:  "invalid request descriptor",
+       54:  "exchange full",
+       55:  "no anode",
+       56:  "invalid request code",
+       57:  "invalid slot",
+       58:  "file locking deadlock error",
+       59:  "bad font file format",
+       60:  "device not a stream",
+       61:  "no data available",
+       62:  "timer expired",
+       63:  "out of streams resources",
+       64:  "machine is not on the network",
+       65:  "package not installed",
+       66:  "object is remote",
+       67:  "link has been severed",
+       68:  "advertise error",
+       69:  "srmount error",
+       70:  "communication error on send",
+       71:  "protocol error",
+       72:  "multihop attempted",
+       73:  "RFS specific error",
+       74:  "bad message",
+       75:  "value too large for defined data type",
+       76:  "name not unique on network",
+       77:  "file descriptor in bad state",
+       78:  "remote address changed",
+       79:  "can not access a needed shared library",
+       80:  "accessing a corrupted shared library",
+       81:  ".lib section in a.out corrupted",
+       82:  "attempting to link in too many shared libraries",
+       83:  "cannot exec a shared library directly",
+       84:  "invalid or incomplete multibyte or wide character",
+       85:  "interrupted system call should be restarted",
+       86:  "streams pipe error",
+       87:  "too many users",
+       88:  "socket operation on non-socket",
+       89:  "destination address required",
+       90:  "message too long",
+       91:  "protocol wrong type for socket",
+       92:  "protocol not available",
+       93:  "protocol not supported",
+       94:  "socket type not supported",
+       95:  "operation not supported",
+       96:  "protocol family not supported",
+       97:  "address family not supported by protocol",
+       98:  "address already in use",
+       99:  "cannot assign requested address",
+       100: "network is down",
+       101: "network is unreachable",
+       102: "network dropped connection on reset",
+       103: "software caused connection abort",
+       104: "connection reset by peer",
+       105: "no buffer space available",
+       106: "transport endpoint is already connected",
+       107: "transport endpoint is not connected",
+       108: "cannot send after transport endpoint shutdown",
+       109: "too many references: cannot splice",
+       110: "connection timed out",
+       111: "connection refused",
+       112: "host is down",
+       113: "no route to host",
+       114: "operation already in progress",
+       115: "operation now in progress",
+       116: "stale NFS file handle",
+       117: "structure needs cleaning",
+       118: "not a XENIX named type file",
+       119: "no XENIX semaphores available",
+       120: "is a named type file",
+       121: "remote I/O error",
+       122: "disk quota exceeded",
+       123: "no medium found",
+       124: "wrong medium type",
+       125: "operation canceled",
+       126: "required key not available",
+       127: "key has expired",
+       128: "key has been revoked",
+       129: "key was rejected by service",
+       130: "owner died",
+       131: "state not recoverable",
+       132: "operation not possible due to RF-kill",
+       133: "memory page has hardware error",
+}
+
+// Signal table
+var signals = [...]string{
+       1:  "hangup",
+       2:  "interrupt",
+       3:  "quit",
+       4:  "illegal instruction",
+       5:  "trace/breakpoint trap",
+       6:  "aborted",
+       7:  "bus error",
+       8:  "floating point exception",
+       9:  "killed",
+       10: "user defined signal 1",
+       11: "segmentation fault",
+       12: "user defined signal 2",
+       13: "broken pipe",
+       14: "alarm clock",
+       15: "terminated",
+       16: "stack fault",
+       17: "child exited",
+       18: "continued",
+       19: "stopped (signal)",
+       20: "stopped",
+       21: "stopped (tty input)",
+       22: "stopped (tty output)",
+       23: "urgent I/O condition",
+       24: "CPU time limit exceeded",
+       25: "file size limit exceeded",
+       26: "virtual timer expired",
+       27: "profiling timer expired",
+       28: "window changed",
+       29: "I/O possible",
+       30: "power failure",
+       31: "bad system call",
+}
diff --git a/src/syscall/zerrors_linux_power64le.go b/src/syscall/zerrors_linux_power64le.go
new file mode 100644 (file)
index 0000000..fdecdf2
--- /dev/null
@@ -0,0 +1,1902 @@
+// mkerrors.sh -m64
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs -- -m64 _const.go
+
+package syscall
+
+const (
+       AF_ALG                           = 0x26
+       AF_APPLETALK                     = 0x5
+       AF_ASH                           = 0x12
+       AF_ATMPVC                        = 0x8
+       AF_ATMSVC                        = 0x14
+       AF_AX25                          = 0x3
+       AF_BLUETOOTH                     = 0x1f
+       AF_BRIDGE                        = 0x7
+       AF_CAIF                          = 0x25
+       AF_CAN                           = 0x1d
+       AF_DECnet                        = 0xc
+       AF_ECONET                        = 0x13
+       AF_FILE                          = 0x1
+       AF_IEEE802154                    = 0x24
+       AF_INET                          = 0x2
+       AF_INET6                         = 0xa
+       AF_IPX                           = 0x4
+       AF_IRDA                          = 0x17
+       AF_ISDN                          = 0x22
+       AF_IUCV                          = 0x20
+       AF_KEY                           = 0xf
+       AF_LLC                           = 0x1a
+       AF_LOCAL                         = 0x1
+       AF_MAX                           = 0x29
+       AF_NETBEUI                       = 0xd
+       AF_NETLINK                       = 0x10
+       AF_NETROM                        = 0x6
+       AF_NFC                           = 0x27
+       AF_PACKET                        = 0x11
+       AF_PHONET                        = 0x23
+       AF_PPPOX                         = 0x18
+       AF_RDS                           = 0x15
+       AF_ROSE                          = 0xb
+       AF_ROUTE                         = 0x10
+       AF_RXRPC                         = 0x21
+       AF_SECURITY                      = 0xe
+       AF_SNA                           = 0x16
+       AF_TIPC                          = 0x1e
+       AF_UNIX                          = 0x1
+       AF_UNSPEC                        = 0x0
+       AF_VSOCK                         = 0x28
+       AF_WANPIPE                       = 0x19
+       AF_X25                           = 0x9
+       ARPHRD_ADAPT                     = 0x108
+       ARPHRD_APPLETLK                  = 0x8
+       ARPHRD_ARCNET                    = 0x7
+       ARPHRD_ASH                       = 0x30d
+       ARPHRD_ATM                       = 0x13
+       ARPHRD_AX25                      = 0x3
+       ARPHRD_BIF                       = 0x307
+       ARPHRD_CAIF                      = 0x336
+       ARPHRD_CAN                       = 0x118
+       ARPHRD_CHAOS                     = 0x5
+       ARPHRD_CISCO                     = 0x201
+       ARPHRD_CSLIP                     = 0x101
+       ARPHRD_CSLIP6                    = 0x103
+       ARPHRD_DDCMP                     = 0x205
+       ARPHRD_DLCI                      = 0xf
+       ARPHRD_ECONET                    = 0x30e
+       ARPHRD_EETHER                    = 0x2
+       ARPHRD_ETHER                     = 0x1
+       ARPHRD_EUI64                     = 0x1b
+       ARPHRD_FCAL                      = 0x311
+       ARPHRD_FCFABRIC                  = 0x313
+       ARPHRD_FCPL                      = 0x312
+       ARPHRD_FCPP                      = 0x310
+       ARPHRD_FDDI                      = 0x306
+       ARPHRD_FRAD                      = 0x302
+       ARPHRD_HDLC                      = 0x201
+       ARPHRD_HIPPI                     = 0x30c
+       ARPHRD_HWX25                     = 0x110
+       ARPHRD_IEEE1394                  = 0x18
+       ARPHRD_IEEE802                   = 0x6
+       ARPHRD_IEEE80211                 = 0x321
+       ARPHRD_IEEE80211_PRISM           = 0x322
+       ARPHRD_IEEE80211_RADIOTAP        = 0x323
+       ARPHRD_IEEE802154                = 0x324
+       ARPHRD_IEEE802154_MONITOR        = 0x325
+       ARPHRD_IEEE802_TR                = 0x320
+       ARPHRD_INFINIBAND                = 0x20
+       ARPHRD_IP6GRE                    = 0x337
+       ARPHRD_IPDDP                     = 0x309
+       ARPHRD_IPGRE                     = 0x30a
+       ARPHRD_IRDA                      = 0x30f
+       ARPHRD_LAPB                      = 0x204
+       ARPHRD_LOCALTLK                  = 0x305
+       ARPHRD_LOOPBACK                  = 0x304
+       ARPHRD_METRICOM                  = 0x17
+       ARPHRD_NETLINK                   = 0x338
+       ARPHRD_NETROM                    = 0x0
+       ARPHRD_NONE                      = 0xfffe
+       ARPHRD_PHONET                    = 0x334
+       ARPHRD_PHONET_PIPE               = 0x335
+       ARPHRD_PIMREG                    = 0x30b
+       ARPHRD_PPP                       = 0x200
+       ARPHRD_PRONET                    = 0x4
+       ARPHRD_RAWHDLC                   = 0x206
+       ARPHRD_ROSE                      = 0x10e
+       ARPHRD_RSRVD                     = 0x104
+       ARPHRD_SIT                       = 0x308
+       ARPHRD_SKIP                      = 0x303
+       ARPHRD_SLIP                      = 0x100
+       ARPHRD_SLIP6                     = 0x102
+       ARPHRD_TUNNEL                    = 0x300
+       ARPHRD_TUNNEL6                   = 0x301
+       ARPHRD_VOID                      = 0xffff
+       ARPHRD_X25                       = 0x10f
+       B0                               = 0x0
+       B1000000                         = 0x17
+       B110                             = 0x3
+       B115200                          = 0x11
+       B1152000                         = 0x18
+       B1200                            = 0x9
+       B134                             = 0x4
+       B150                             = 0x5
+       B1500000                         = 0x19
+       B1800                            = 0xa
+       B19200                           = 0xe
+       B200                             = 0x6
+       B2000000                         = 0x1a
+       B230400                          = 0x12
+       B2400                            = 0xb
+       B2500000                         = 0x1b
+       B300                             = 0x7
+       B3000000                         = 0x1c
+       B3500000                         = 0x1d
+       B38400                           = 0xf
+       B4000000                         = 0x1e
+       B460800                          = 0x13
+       B4800                            = 0xc
+       B50                              = 0x1
+       B500000                          = 0x14
+       B57600                           = 0x10
+       B576000                          = 0x15
+       B600                             = 0x8
+       B75                              = 0x2
+       B921600                          = 0x16
+       B9600                            = 0xd
+       BPF_A                            = 0x10
+       BPF_ABS                          = 0x20
+       BPF_ADD                          = 0x0
+       BPF_ALU                          = 0x4
+       BPF_AND                          = 0x50
+       BPF_B                            = 0x10
+       BPF_DIV                          = 0x30
+       BPF_H                            = 0x8
+       BPF_IMM                          = 0x0
+       BPF_IND                          = 0x40
+       BPF_JA                           = 0x0
+       BPF_JEQ                          = 0x10
+       BPF_JGE                          = 0x30
+       BPF_JGT                          = 0x20
+       BPF_JMP                          = 0x5
+       BPF_JSET                         = 0x40
+       BPF_K                            = 0x0
+       BPF_LD                           = 0x0
+       BPF_LDX                          = 0x1
+       BPF_LEN                          = 0x80
+       BPF_LSH                          = 0x60
+       BPF_MAJOR_VERSION                = 0x1
+       BPF_MAXINSNS                     = 0x1000
+       BPF_MEM                          = 0x60
+       BPF_MEMWORDS                     = 0x10
+       BPF_MINOR_VERSION                = 0x1
+       BPF_MISC                         = 0x7
+       BPF_MOD                          = 0x90
+       BPF_MSH                          = 0xa0
+       BPF_MUL                          = 0x20
+       BPF_NEG                          = 0x80
+       BPF_OR                           = 0x40
+       BPF_RET                          = 0x6
+       BPF_RSH                          = 0x70
+       BPF_ST                           = 0x2
+       BPF_STX                          = 0x3
+       BPF_SUB                          = 0x10
+       BPF_TAX                          = 0x0
+       BPF_TXA                          = 0x80
+       BPF_W                            = 0x0
+       BPF_X                            = 0x8
+       BPF_XOR                          = 0xa0
+       BRKINT                           = 0x2
+       CFLUSH                           = 0xf
+       CLOCAL                           = 0x8000
+       CLONE_CHILD_CLEARTID             = 0x200000
+       CLONE_CHILD_SETTID               = 0x1000000
+       CLONE_DETACHED                   = 0x400000
+       CLONE_FILES                      = 0x400
+       CLONE_FS                         = 0x200
+       CLONE_IO                         = 0x80000000
+       CLONE_NEWIPC                     = 0x8000000
+       CLONE_NEWNET                     = 0x40000000
+       CLONE_NEWNS                      = 0x20000
+       CLONE_NEWPID                     = 0x20000000
+       CLONE_NEWUSER                    = 0x10000000
+       CLONE_NEWUTS                     = 0x4000000
+       CLONE_PARENT                     = 0x8000
+       CLONE_PARENT_SETTID              = 0x100000
+       CLONE_PTRACE                     = 0x2000
+       CLONE_SETTLS                     = 0x80000
+       CLONE_SIGHAND                    = 0x800
+       CLONE_SYSVSEM                    = 0x40000
+       CLONE_THREAD                     = 0x10000
+       CLONE_UNTRACED                   = 0x800000
+       CLONE_VFORK                      = 0x4000
+       CLONE_VM                         = 0x100
+       CREAD                            = 0x800
+       CS5                              = 0x0
+       CS6                              = 0x100
+       CS7                              = 0x200
+       CS8                              = 0x300
+       CSIGNAL                          = 0xff
+       CSIZE                            = 0x300
+       CSTART                           = 0x11
+       CSTATUS                          = 0x0
+       CSTOP                            = 0x13
+       CSTOPB                           = 0x400
+       CSUSP                            = 0x1a
+       DT_BLK                           = 0x6
+       DT_CHR                           = 0x2
+       DT_DIR                           = 0x4
+       DT_FIFO                          = 0x1
+       DT_LNK                           = 0xa
+       DT_REG                           = 0x8
+       DT_SOCK                          = 0xc
+       DT_UNKNOWN                       = 0x0
+       DT_WHT                           = 0xe
+       ECHO                             = 0x8
+       ECHOCTL                          = 0x40
+       ECHOE                            = 0x2
+       ECHOK                            = 0x4
+       ECHOKE                           = 0x1
+       ECHONL                           = 0x10
+       ECHOPRT                          = 0x20
+       ENCODING_DEFAULT                 = 0x0
+       ENCODING_FM_MARK                 = 0x3
+       ENCODING_FM_SPACE                = 0x4
+       ENCODING_MANCHESTER              = 0x5
+       ENCODING_NRZ                     = 0x1
+       ENCODING_NRZI                    = 0x2
+       EPOLLERR                         = 0x8
+       EPOLLET                          = 0x80000000
+       EPOLLHUP                         = 0x10
+       EPOLLIN                          = 0x1
+       EPOLLMSG                         = 0x400
+       EPOLLONESHOT                     = 0x40000000
+       EPOLLOUT                         = 0x4
+       EPOLLPRI                         = 0x2
+       EPOLLRDBAND                      = 0x80
+       EPOLLRDHUP                       = 0x2000
+       EPOLLRDNORM                      = 0x40
+       EPOLLWAKEUP                      = 0x20000000
+       EPOLLWRBAND                      = 0x200
+       EPOLLWRNORM                      = 0x100
+       EPOLL_CLOEXEC                    = 0x80000
+       EPOLL_CTL_ADD                    = 0x1
+       EPOLL_CTL_DEL                    = 0x2
+       EPOLL_CTL_MOD                    = 0x3
+       ETH_P_1588                       = 0x88f7
+       ETH_P_8021AD                     = 0x88a8
+       ETH_P_8021AH                     = 0x88e7
+       ETH_P_8021Q                      = 0x8100
+       ETH_P_802_2                      = 0x4
+       ETH_P_802_3                      = 0x1
+       ETH_P_802_3_MIN                  = 0x600
+       ETH_P_802_EX1                    = 0x88b5
+       ETH_P_AARP                       = 0x80f3
+       ETH_P_AF_IUCV                    = 0xfbfb
+       ETH_P_ALL                        = 0x3
+       ETH_P_AOE                        = 0x88a2
+       ETH_P_ARCNET                     = 0x1a
+       ETH_P_ARP                        = 0x806
+       ETH_P_ATALK                      = 0x809b
+       ETH_P_ATMFATE                    = 0x8884
+       ETH_P_ATMMPOA                    = 0x884c
+       ETH_P_AX25                       = 0x2
+       ETH_P_BATMAN                     = 0x4305
+       ETH_P_BPQ                        = 0x8ff
+       ETH_P_CAIF                       = 0xf7
+       ETH_P_CAN                        = 0xc
+       ETH_P_CANFD                      = 0xd
+       ETH_P_CONTROL                    = 0x16
+       ETH_P_CUST                       = 0x6006
+       ETH_P_DDCMP                      = 0x6
+       ETH_P_DEC                        = 0x6000
+       ETH_P_DIAG                       = 0x6005
+       ETH_P_DNA_DL                     = 0x6001
+       ETH_P_DNA_RC                     = 0x6002
+       ETH_P_DNA_RT                     = 0x6003
+       ETH_P_DSA                        = 0x1b
+       ETH_P_ECONET                     = 0x18
+       ETH_P_EDSA                       = 0xdada
+       ETH_P_FCOE                       = 0x8906
+       ETH_P_FIP                        = 0x8914
+       ETH_P_HDLC                       = 0x19
+       ETH_P_IEEE802154                 = 0xf6
+       ETH_P_IEEEPUP                    = 0xa00
+       ETH_P_IEEEPUPAT                  = 0xa01
+       ETH_P_IP                         = 0x800
+       ETH_P_IPV6                       = 0x86dd
+       ETH_P_IPX                        = 0x8137
+       ETH_P_IRDA                       = 0x17
+       ETH_P_LAT                        = 0x6004
+       ETH_P_LINK_CTL                   = 0x886c
+       ETH_P_LOCALTALK                  = 0x9
+       ETH_P_LOOP                       = 0x60
+       ETH_P_MOBITEX                    = 0x15
+       ETH_P_MPLS_MC                    = 0x8848
+       ETH_P_MPLS_UC                    = 0x8847
+       ETH_P_MVRP                       = 0x88f5
+       ETH_P_PAE                        = 0x888e
+       ETH_P_PAUSE                      = 0x8808
+       ETH_P_PHONET                     = 0xf5
+       ETH_P_PPPTALK                    = 0x10
+       ETH_P_PPP_DISC                   = 0x8863
+       ETH_P_PPP_MP                     = 0x8
+       ETH_P_PPP_SES                    = 0x8864
+       ETH_P_PRP                        = 0x88fb
+       ETH_P_PUP                        = 0x200
+       ETH_P_PUPAT                      = 0x201
+       ETH_P_QINQ1                      = 0x9100
+       ETH_P_QINQ2                      = 0x9200
+       ETH_P_QINQ3                      = 0x9300
+       ETH_P_RARP                       = 0x8035
+       ETH_P_SCA                        = 0x6007
+       ETH_P_SLOW                       = 0x8809
+       ETH_P_SNAP                       = 0x5
+       ETH_P_TDLS                       = 0x890d
+       ETH_P_TEB                        = 0x6558
+       ETH_P_TIPC                       = 0x88ca
+       ETH_P_TRAILER                    = 0x1c
+       ETH_P_TR_802_2                   = 0x11
+       ETH_P_WAN_PPP                    = 0x7
+       ETH_P_WCCP                       = 0x883e
+       ETH_P_X25                        = 0x805
+       EXTA                             = 0xe
+       EXTB                             = 0xf
+       EXTPROC                          = 0x10000000
+       FD_CLOEXEC                       = 0x1
+       FD_SETSIZE                       = 0x400
+       FLUSHO                           = 0x800000
+       F_DUPFD                          = 0x0
+       F_DUPFD_CLOEXEC                  = 0x406
+       F_EXLCK                          = 0x4
+       F_GETFD                          = 0x1
+       F_GETFL                          = 0x3
+       F_GETLEASE                       = 0x401
+       F_GETLK                          = 0x5
+       F_GETLK64                        = 0xc
+       F_GETOWN                         = 0x9
+       F_GETOWN_EX                      = 0x10
+       F_GETPIPE_SZ                     = 0x408
+       F_GETSIG                         = 0xb
+       F_LOCK                           = 0x1
+       F_NOTIFY                         = 0x402
+       F_OK                             = 0x0
+       F_RDLCK                          = 0x0
+       F_SETFD                          = 0x2
+       F_SETFL                          = 0x4
+       F_SETLEASE                       = 0x400
+       F_SETLK                          = 0xd
+       F_SETLK64                        = 0xd
+       F_SETLKW                         = 0xe
+       F_SETLKW64                       = 0xe
+       F_SETOWN                         = 0x8
+       F_SETOWN_EX                      = 0xf
+       F_SETPIPE_SZ                     = 0x407
+       F_SETSIG                         = 0xa
+       F_SHLCK                          = 0x8
+       F_TEST                           = 0x3
+       F_TLOCK                          = 0x2
+       F_ULOCK                          = 0x0
+       F_UNLCK                          = 0x2
+       F_WRLCK                          = 0x1
+       HUPCL                            = 0x4000
+       ICANON                           = 0x100
+       ICMPV6_FILTER                    = 0x1
+       ICRNL                            = 0x100
+       IEXTEN                           = 0x400
+       IFA_F_DADFAILED                  = 0x8
+       IFA_F_DEPRECATED                 = 0x20
+       IFA_F_HOMEADDRESS                = 0x10
+       IFA_F_NODAD                      = 0x2
+       IFA_F_OPTIMISTIC                 = 0x4
+       IFA_F_PERMANENT                  = 0x80
+       IFA_F_SECONDARY                  = 0x1
+       IFA_F_TEMPORARY                  = 0x1
+       IFA_F_TENTATIVE                  = 0x40
+       IFA_MAX                          = 0x7
+       IFF_802_1Q_VLAN                  = 0x1
+       IFF_ALLMULTI                     = 0x200
+       IFF_ATTACH_QUEUE                 = 0x200
+       IFF_AUTOMEDIA                    = 0x4000
+       IFF_BONDING                      = 0x20
+       IFF_BRIDGE_PORT                  = 0x4000
+       IFF_BROADCAST                    = 0x2
+       IFF_DEBUG                        = 0x4
+       IFF_DETACH_QUEUE                 = 0x400
+       IFF_DISABLE_NETPOLL              = 0x1000
+       IFF_DONT_BRIDGE                  = 0x800
+       IFF_DORMANT                      = 0x20000
+       IFF_DYNAMIC                      = 0x8000
+       IFF_EBRIDGE                      = 0x2
+       IFF_ECHO                         = 0x40000
+       IFF_ISATAP                       = 0x80
+       IFF_LIVE_ADDR_CHANGE             = 0x100000
+       IFF_LOOPBACK                     = 0x8
+       IFF_LOWER_UP                     = 0x10000
+       IFF_MACVLAN                      = 0x200000
+       IFF_MACVLAN_PORT                 = 0x2000
+       IFF_MASTER                       = 0x400
+       IFF_MASTER_8023AD                = 0x8
+       IFF_MASTER_ALB                   = 0x10
+       IFF_MASTER_ARPMON                = 0x100
+       IFF_MULTICAST                    = 0x1000
+       IFF_MULTI_QUEUE                  = 0x100
+       IFF_NOARP                        = 0x80
+       IFF_NOFILTER                     = 0x1000
+       IFF_NOTRAILERS                   = 0x20
+       IFF_NO_PI                        = 0x1000
+       IFF_ONE_QUEUE                    = 0x2000
+       IFF_OVS_DATAPATH                 = 0x8000
+       IFF_PERSIST                      = 0x800
+       IFF_POINTOPOINT                  = 0x10
+       IFF_PORTSEL                      = 0x2000
+       IFF_PROMISC                      = 0x100
+       IFF_RUNNING                      = 0x40
+       IFF_SLAVE                        = 0x800
+       IFF_SLAVE_INACTIVE               = 0x4
+       IFF_SLAVE_NEEDARP                = 0x40
+       IFF_SUPP_NOFCS                   = 0x80000
+       IFF_TAP                          = 0x2
+       IFF_TEAM_PORT                    = 0x40000
+       IFF_TUN                          = 0x1
+       IFF_TUN_EXCL                     = 0x8000
+       IFF_TX_SKB_SHARING               = 0x10000
+       IFF_UNICAST_FLT                  = 0x20000
+       IFF_UP                           = 0x1
+       IFF_VNET_HDR                     = 0x4000
+       IFF_VOLATILE                     = 0x70c5a
+       IFF_WAN_HDLC                     = 0x200
+       IFF_XMIT_DST_RELEASE             = 0x400
+       IFNAMSIZ                         = 0x10
+       IGNBRK                           = 0x1
+       IGNCR                            = 0x80
+       IGNPAR                           = 0x4
+       IMAXBEL                          = 0x2000
+       INLCR                            = 0x40
+       INPCK                            = 0x10
+       IN_ACCESS                        = 0x1
+       IN_ALL_EVENTS                    = 0xfff
+       IN_ATTRIB                        = 0x4
+       IN_CLASSA_HOST                   = 0xffffff
+       IN_CLASSA_MAX                    = 0x80
+       IN_CLASSA_NET                    = 0xff000000
+       IN_CLASSA_NSHIFT                 = 0x18
+       IN_CLASSB_HOST                   = 0xffff
+       IN_CLASSB_MAX                    = 0x10000
+       IN_CLASSB_NET                    = 0xffff0000
+       IN_CLASSB_NSHIFT                 = 0x10
+       IN_CLASSC_HOST                   = 0xff
+       IN_CLASSC_NET                    = 0xffffff00
+       IN_CLASSC_NSHIFT                 = 0x8
+       IN_CLOEXEC                       = 0x80000
+       IN_CLOSE                         = 0x18
+       IN_CLOSE_NOWRITE                 = 0x10
+       IN_CLOSE_WRITE                   = 0x8
+       IN_CREATE                        = 0x100
+       IN_DELETE                        = 0x200
+       IN_DELETE_SELF                   = 0x400
+       IN_DONT_FOLLOW                   = 0x2000000
+       IN_EXCL_UNLINK                   = 0x4000000
+       IN_IGNORED                       = 0x8000
+       IN_ISDIR                         = 0x40000000
+       IN_LOOPBACKNET                   = 0x7f
+       IN_MASK_ADD                      = 0x20000000
+       IN_MODIFY                        = 0x2
+       IN_MOVE                          = 0xc0
+       IN_MOVED_FROM                    = 0x40
+       IN_MOVED_TO                      = 0x80
+       IN_MOVE_SELF                     = 0x800
+       IN_NONBLOCK                      = 0x800
+       IN_ONESHOT                       = 0x80000000
+       IN_ONLYDIR                       = 0x1000000
+       IN_OPEN                          = 0x20
+       IN_Q_OVERFLOW                    = 0x4000
+       IN_UNMOUNT                       = 0x2000
+       IPPROTO_AH                       = 0x33
+       IPPROTO_BEETPH                   = 0x5e
+       IPPROTO_COMP                     = 0x6c
+       IPPROTO_DCCP                     = 0x21
+       IPPROTO_DSTOPTS                  = 0x3c
+       IPPROTO_EGP                      = 0x8
+       IPPROTO_ENCAP                    = 0x62
+       IPPROTO_ESP                      = 0x32
+       IPPROTO_FRAGMENT                 = 0x2c
+       IPPROTO_GRE                      = 0x2f
+       IPPROTO_HOPOPTS                  = 0x0
+       IPPROTO_ICMP                     = 0x1
+       IPPROTO_ICMPV6                   = 0x3a
+       IPPROTO_IDP                      = 0x16
+       IPPROTO_IGMP                     = 0x2
+       IPPROTO_IP                       = 0x0
+       IPPROTO_IPIP                     = 0x4
+       IPPROTO_IPV6                     = 0x29
+       IPPROTO_MH                       = 0x87
+       IPPROTO_MTP                      = 0x5c
+       IPPROTO_NONE                     = 0x3b
+       IPPROTO_PIM                      = 0x67
+       IPPROTO_PUP                      = 0xc
+       IPPROTO_RAW                      = 0xff
+       IPPROTO_ROUTING                  = 0x2b
+       IPPROTO_RSVP                     = 0x2e
+       IPPROTO_SCTP                     = 0x84
+       IPPROTO_TCP                      = 0x6
+       IPPROTO_TP                       = 0x1d
+       IPPROTO_UDP                      = 0x11
+       IPPROTO_UDPLITE                  = 0x88
+       IPV6_2292DSTOPTS                 = 0x4
+       IPV6_2292HOPLIMIT                = 0x8
+       IPV6_2292HOPOPTS                 = 0x3
+       IPV6_2292PKTINFO                 = 0x2
+       IPV6_2292PKTOPTIONS              = 0x6
+       IPV6_2292RTHDR                   = 0x5
+       IPV6_ADDRFORM                    = 0x1
+       IPV6_ADD_MEMBERSHIP              = 0x14
+       IPV6_AUTHHDR                     = 0xa
+       IPV6_CHECKSUM                    = 0x7
+       IPV6_DROP_MEMBERSHIP             = 0x15
+       IPV6_DSTOPTS                     = 0x3b
+       IPV6_HOPLIMIT                    = 0x34
+       IPV6_HOPOPTS                     = 0x36
+       IPV6_IPSEC_POLICY                = 0x22
+       IPV6_JOIN_ANYCAST                = 0x1b
+       IPV6_JOIN_GROUP                  = 0x14
+       IPV6_LEAVE_ANYCAST               = 0x1c
+       IPV6_LEAVE_GROUP                 = 0x15
+       IPV6_MTU                         = 0x18
+       IPV6_MTU_DISCOVER                = 0x17
+       IPV6_MULTICAST_HOPS              = 0x12
+       IPV6_MULTICAST_IF                = 0x11
+       IPV6_MULTICAST_LOOP              = 0x13
+       IPV6_NEXTHOP                     = 0x9
+       IPV6_PKTINFO                     = 0x32
+       IPV6_PMTUDISC_DO                 = 0x2
+       IPV6_PMTUDISC_DONT               = 0x0
+       IPV6_PMTUDISC_PROBE              = 0x3
+       IPV6_PMTUDISC_WANT               = 0x1
+       IPV6_RECVDSTOPTS                 = 0x3a
+       IPV6_RECVERR                     = 0x19
+       IPV6_RECVHOPLIMIT                = 0x33
+       IPV6_RECVHOPOPTS                 = 0x35
+       IPV6_RECVPKTINFO                 = 0x31
+       IPV6_RECVRTHDR                   = 0x38
+       IPV6_RECVTCLASS                  = 0x42
+       IPV6_ROUTER_ALERT                = 0x16
+       IPV6_RTHDR                       = 0x39
+       IPV6_RTHDRDSTOPTS                = 0x37
+       IPV6_RTHDR_LOOSE                 = 0x0
+       IPV6_RTHDR_STRICT                = 0x1
+       IPV6_RTHDR_TYPE_0                = 0x0
+       IPV6_RXDSTOPTS                   = 0x3b
+       IPV6_RXHOPOPTS                   = 0x36
+       IPV6_TCLASS                      = 0x43
+       IPV6_UNICAST_HOPS                = 0x10
+       IPV6_V6ONLY                      = 0x1a
+       IPV6_XFRM_POLICY                 = 0x23
+       IP_ADD_MEMBERSHIP                = 0x23
+       IP_ADD_SOURCE_MEMBERSHIP         = 0x27
+       IP_BLOCK_SOURCE                  = 0x26
+       IP_DEFAULT_MULTICAST_LOOP        = 0x1
+       IP_DEFAULT_MULTICAST_TTL         = 0x1
+       IP_DF                            = 0x4000
+       IP_DROP_MEMBERSHIP               = 0x24
+       IP_DROP_SOURCE_MEMBERSHIP        = 0x28
+       IP_FREEBIND                      = 0xf
+       IP_HDRINCL                       = 0x3
+       IP_IPSEC_POLICY                  = 0x10
+       IP_MAXPACKET                     = 0xffff
+       IP_MAX_MEMBERSHIPS               = 0x14
+       IP_MF                            = 0x2000
+       IP_MINTTL                        = 0x15
+       IP_MSFILTER                      = 0x29
+       IP_MSS                           = 0x240
+       IP_MTU                           = 0xe
+       IP_MTU_DISCOVER                  = 0xa
+       IP_MULTICAST_ALL                 = 0x31
+       IP_MULTICAST_IF                  = 0x20
+       IP_MULTICAST_LOOP                = 0x22
+       IP_MULTICAST_TTL                 = 0x21
+       IP_OFFMASK                       = 0x1fff
+       IP_OPTIONS                       = 0x4
+       IP_ORIGDSTADDR                   = 0x14
+       IP_PASSSEC                       = 0x12
+       IP_PKTINFO                       = 0x8
+       IP_PKTOPTIONS                    = 0x9
+       IP_PMTUDISC                      = 0xa
+       IP_PMTUDISC_DO                   = 0x2
+       IP_PMTUDISC_DONT                 = 0x0
+       IP_PMTUDISC_PROBE                = 0x3
+       IP_PMTUDISC_WANT                 = 0x1
+       IP_RECVERR                       = 0xb
+       IP_RECVOPTS                      = 0x6
+       IP_RECVORIGDSTADDR               = 0x14
+       IP_RECVRETOPTS                   = 0x7
+       IP_RECVTOS                       = 0xd
+       IP_RECVTTL                       = 0xc
+       IP_RETOPTS                       = 0x7
+       IP_RF                            = 0x8000
+       IP_ROUTER_ALERT                  = 0x5
+       IP_TOS                           = 0x1
+       IP_TRANSPARENT                   = 0x13
+       IP_TTL                           = 0x2
+       IP_UNBLOCK_SOURCE                = 0x25
+       IP_UNICAST_IF                    = 0x32
+       IP_XFRM_POLICY                   = 0x11
+       ISIG                             = 0x80
+       ISTRIP                           = 0x20
+       IUTF8                            = 0x4000
+       IXANY                            = 0x800
+       IXOFF                            = 0x400
+       IXON                             = 0x200
+       LINUX_REBOOT_CMD_CAD_OFF         = 0x0
+       LINUX_REBOOT_CMD_CAD_ON          = 0x89abcdef
+       LINUX_REBOOT_CMD_HALT            = 0xcdef0123
+       LINUX_REBOOT_CMD_KEXEC           = 0x45584543
+       LINUX_REBOOT_CMD_POWER_OFF       = 0x4321fedc
+       LINUX_REBOOT_CMD_RESTART         = 0x1234567
+       LINUX_REBOOT_CMD_RESTART2        = 0xa1b2c3d4
+       LINUX_REBOOT_CMD_SW_SUSPEND      = 0xd000fce2
+       LINUX_REBOOT_MAGIC1              = 0xfee1dead
+       LINUX_REBOOT_MAGIC2              = 0x28121969
+       LOCK_EX                          = 0x2
+       LOCK_NB                          = 0x4
+       LOCK_SH                          = 0x1
+       LOCK_UN                          = 0x8
+       MADV_DODUMP                      = 0x11
+       MADV_DOFORK                      = 0xb
+       MADV_DONTDUMP                    = 0x10
+       MADV_DONTFORK                    = 0xa
+       MADV_DONTNEED                    = 0x4
+       MADV_HUGEPAGE                    = 0xe
+       MADV_HWPOISON                    = 0x64
+       MADV_MERGEABLE                   = 0xc
+       MADV_NOHUGEPAGE                  = 0xf
+       MADV_NORMAL                      = 0x0
+       MADV_RANDOM                      = 0x1
+       MADV_REMOVE                      = 0x9
+       MADV_SEQUENTIAL                  = 0x2
+       MADV_UNMERGEABLE                 = 0xd
+       MADV_WILLNEED                    = 0x3
+       MAP_ANON                         = 0x20
+       MAP_ANONYMOUS                    = 0x20
+       MAP_DENYWRITE                    = 0x800
+       MAP_EXECUTABLE                   = 0x1000
+       MAP_FILE                         = 0x0
+       MAP_FIXED                        = 0x10
+       MAP_GROWSDOWN                    = 0x100
+       MAP_HUGETLB                      = 0x40000
+       MAP_HUGE_MASK                    = 0x3f
+       MAP_HUGE_SHIFT                   = 0x1a
+       MAP_LOCKED                       = 0x80
+       MAP_NONBLOCK                     = 0x10000
+       MAP_NORESERVE                    = 0x40
+       MAP_POPULATE                     = 0x8000
+       MAP_PRIVATE                      = 0x2
+       MAP_SHARED                       = 0x1
+       MAP_STACK                        = 0x20000
+       MAP_TYPE                         = 0xf
+       MCL_CURRENT                      = 0x2000
+       MCL_FUTURE                       = 0x4000
+       MNT_DETACH                       = 0x2
+       MNT_EXPIRE                       = 0x4
+       MNT_FORCE                        = 0x1
+       MSG_CMSG_CLOEXEC                 = 0x40000000
+       MSG_CONFIRM                      = 0x800
+       MSG_CTRUNC                       = 0x8
+       MSG_DONTROUTE                    = 0x4
+       MSG_DONTWAIT                     = 0x40
+       MSG_EOR                          = 0x80
+       MSG_ERRQUEUE                     = 0x2000
+       MSG_FASTOPEN                     = 0x20000000
+       MSG_FIN                          = 0x200
+       MSG_MORE                         = 0x8000
+       MSG_NOSIGNAL                     = 0x4000
+       MSG_OOB                          = 0x1
+       MSG_PEEK                         = 0x2
+       MSG_PROXY                        = 0x10
+       MSG_RST                          = 0x1000
+       MSG_SYN                          = 0x400
+       MSG_TRUNC                        = 0x20
+       MSG_TRYHARD                      = 0x4
+       MSG_WAITALL                      = 0x100
+       MSG_WAITFORONE                   = 0x10000
+       MS_ACTIVE                        = 0x40000000
+       MS_ASYNC                         = 0x1
+       MS_BIND                          = 0x1000
+       MS_DIRSYNC                       = 0x80
+       MS_INVALIDATE                    = 0x2
+       MS_I_VERSION                     = 0x800000
+       MS_KERNMOUNT                     = 0x400000
+       MS_MANDLOCK                      = 0x40
+       MS_MGC_MSK                       = 0xffff0000
+       MS_MGC_VAL                       = 0xc0ed0000
+       MS_MOVE                          = 0x2000
+       MS_NOATIME                       = 0x400
+       MS_NODEV                         = 0x4
+       MS_NODIRATIME                    = 0x800
+       MS_NOEXEC                        = 0x8
+       MS_NOSUID                        = 0x2
+       MS_NOUSER                        = -0x80000000
+       MS_POSIXACL                      = 0x10000
+       MS_PRIVATE                       = 0x40000
+       MS_RDONLY                        = 0x1
+       MS_REC                           = 0x4000
+       MS_RELATIME                      = 0x200000
+       MS_REMOUNT                       = 0x20
+       MS_RMT_MASK                      = 0x800051
+       MS_SHARED                        = 0x100000
+       MS_SILENT                        = 0x8000
+       MS_SLAVE                         = 0x80000
+       MS_STRICTATIME                   = 0x1000000
+       MS_SYNC                          = 0x4
+       MS_SYNCHRONOUS                   = 0x10
+       MS_UNBINDABLE                    = 0x20000
+       NAME_MAX                         = 0xff
+       NETLINK_ADD_MEMBERSHIP           = 0x1
+       NETLINK_AUDIT                    = 0x9
+       NETLINK_BROADCAST_ERROR          = 0x4
+       NETLINK_CONNECTOR                = 0xb
+       NETLINK_CRYPTO                   = 0x15
+       NETLINK_DNRTMSG                  = 0xe
+       NETLINK_DROP_MEMBERSHIP          = 0x2
+       NETLINK_ECRYPTFS                 = 0x13
+       NETLINK_FIB_LOOKUP               = 0xa
+       NETLINK_FIREWALL                 = 0x3
+       NETLINK_GENERIC                  = 0x10
+       NETLINK_INET_DIAG                = 0x4
+       NETLINK_IP6_FW                   = 0xd
+       NETLINK_ISCSI                    = 0x8
+       NETLINK_KOBJECT_UEVENT           = 0xf
+       NETLINK_NETFILTER                = 0xc
+       NETLINK_NFLOG                    = 0x5
+       NETLINK_NO_ENOBUFS               = 0x5
+       NETLINK_PKTINFO                  = 0x3
+       NETLINK_RDMA                     = 0x14
+       NETLINK_ROUTE                    = 0x0
+       NETLINK_RX_RING                  = 0x6
+       NETLINK_SCSITRANSPORT            = 0x12
+       NETLINK_SELINUX                  = 0x7
+       NETLINK_SOCK_DIAG                = 0x4
+       NETLINK_TX_RING                  = 0x7
+       NETLINK_UNUSED                   = 0x1
+       NETLINK_USERSOCK                 = 0x2
+       NETLINK_XFRM                     = 0x6
+       NLA_ALIGNTO                      = 0x4
+       NLA_F_NESTED                     = 0x8000
+       NLA_F_NET_BYTEORDER              = 0x4000
+       NLA_HDRLEN                       = 0x4
+       NLMSG_ALIGNTO                    = 0x4
+       NLMSG_DONE                       = 0x3
+       NLMSG_ERROR                      = 0x2
+       NLMSG_HDRLEN                     = 0x10
+       NLMSG_MIN_TYPE                   = 0x10
+       NLMSG_NOOP                       = 0x1
+       NLMSG_OVERRUN                    = 0x4
+       NLM_F_ACK                        = 0x4
+       NLM_F_APPEND                     = 0x800
+       NLM_F_ATOMIC                     = 0x400
+       NLM_F_CREATE                     = 0x400
+       NLM_F_DUMP                       = 0x300
+       NLM_F_DUMP_INTR                  = 0x10
+       NLM_F_ECHO                       = 0x8
+       NLM_F_EXCL                       = 0x200
+       NLM_F_MATCH                      = 0x200
+       NLM_F_MULTI                      = 0x2
+       NLM_F_REPLACE                    = 0x100
+       NLM_F_REQUEST                    = 0x1
+       NLM_F_ROOT                       = 0x100
+       NOFLSH                           = 0x80000000
+       OCRNL                            = 0x8
+       OFDEL                            = 0x80
+       OFILL                            = 0x40
+       ONLCR                            = 0x2
+       ONLRET                           = 0x20
+       ONOCR                            = 0x10
+       OPOST                            = 0x1
+       O_ACCMODE                        = 0x3
+       O_APPEND                         = 0x400
+       O_ASYNC                          = 0x2000
+       O_CLOEXEC                        = 0x80000
+       O_CREAT                          = 0x40
+       O_DIRECT                         = 0x20000
+       O_DIRECTORY                      = 0x4000
+       O_DSYNC                          = 0x1000
+       O_EXCL                           = 0x80
+       O_FSYNC                          = 0x101000
+       O_LARGEFILE                      = 0x0
+       O_NDELAY                         = 0x800
+       O_NOATIME                        = 0x40000
+       O_NOCTTY                         = 0x100
+       O_NOFOLLOW                       = 0x8000
+       O_NONBLOCK                       = 0x800
+       O_PATH                           = 0x200000
+       O_RDONLY                         = 0x0
+       O_RDWR                           = 0x2
+       O_RSYNC                          = 0x101000
+       O_SYNC                           = 0x101000
+       O_TMPFILE                        = 0x410000
+       O_TRUNC                          = 0x200
+       O_WRONLY                         = 0x1
+       PACKET_ADD_MEMBERSHIP            = 0x1
+       PACKET_AUXDATA                   = 0x8
+       PACKET_BROADCAST                 = 0x1
+       PACKET_COPY_THRESH               = 0x7
+       PACKET_DROP_MEMBERSHIP           = 0x2
+       PACKET_FANOUT                    = 0x12
+       PACKET_FANOUT_CPU                = 0x2
+       PACKET_FANOUT_FLAG_DEFRAG        = 0x8000
+       PACKET_FANOUT_FLAG_ROLLOVER      = 0x1000
+       PACKET_FANOUT_HASH               = 0x0
+       PACKET_FANOUT_LB                 = 0x1
+       PACKET_FANOUT_RND                = 0x4
+       PACKET_FANOUT_ROLLOVER           = 0x3
+       PACKET_FASTROUTE                 = 0x6
+       PACKET_HDRLEN                    = 0xb
+       PACKET_HOST                      = 0x0
+       PACKET_LOOPBACK                  = 0x5
+       PACKET_LOSS                      = 0xe
+       PACKET_MR_ALLMULTI               = 0x2
+       PACKET_MR_MULTICAST              = 0x0
+       PACKET_MR_PROMISC                = 0x1
+       PACKET_MR_UNICAST                = 0x3
+       PACKET_MULTICAST                 = 0x2
+       PACKET_ORIGDEV                   = 0x9
+       PACKET_OTHERHOST                 = 0x3
+       PACKET_OUTGOING                  = 0x4
+       PACKET_RECV_OUTPUT               = 0x3
+       PACKET_RESERVE                   = 0xc
+       PACKET_RX_RING                   = 0x5
+       PACKET_STATISTICS                = 0x6
+       PACKET_TIMESTAMP                 = 0x11
+       PACKET_TX_HAS_OFF                = 0x13
+       PACKET_TX_RING                   = 0xd
+       PACKET_TX_TIMESTAMP              = 0x10
+       PACKET_VERSION                   = 0xa
+       PACKET_VNET_HDR                  = 0xf
+       PARENB                           = 0x1000
+       PARITY_CRC16_PR0                 = 0x2
+       PARITY_CRC16_PR0_CCITT           = 0x4
+       PARITY_CRC16_PR1                 = 0x3
+       PARITY_CRC16_PR1_CCITT           = 0x5
+       PARITY_CRC32_PR0_CCITT           = 0x6
+       PARITY_CRC32_PR1_CCITT           = 0x7
+       PARITY_DEFAULT                   = 0x0
+       PARITY_NONE                      = 0x1
+       PARMRK                           = 0x8
+       PARODD                           = 0x2000
+       PENDIN                           = 0x20000000
+       PRIO_PGRP                        = 0x1
+       PRIO_PROCESS                     = 0x0
+       PRIO_USER                        = 0x2
+       PROT_EXEC                        = 0x4
+       PROT_GROWSDOWN                   = 0x1000000
+       PROT_GROWSUP                     = 0x2000000
+       PROT_NONE                        = 0x0
+       PROT_READ                        = 0x1
+       PROT_SAO                         = 0x10
+       PROT_WRITE                       = 0x2
+       PR_CAPBSET_DROP                  = 0x18
+       PR_CAPBSET_READ                  = 0x17
+       PR_ENDIAN_BIG                    = 0x0
+       PR_ENDIAN_LITTLE                 = 0x1
+       PR_ENDIAN_PPC_LITTLE             = 0x2
+       PR_FPEMU_NOPRINT                 = 0x1
+       PR_FPEMU_SIGFPE                  = 0x2
+       PR_FP_EXC_ASYNC                  = 0x2
+       PR_FP_EXC_DISABLED               = 0x0
+       PR_FP_EXC_DIV                    = 0x10000
+       PR_FP_EXC_INV                    = 0x100000
+       PR_FP_EXC_NONRECOV               = 0x1
+       PR_FP_EXC_OVF                    = 0x20000
+       PR_FP_EXC_PRECISE                = 0x3
+       PR_FP_EXC_RES                    = 0x80000
+       PR_FP_EXC_SW_ENABLE              = 0x80
+       PR_FP_EXC_UND                    = 0x40000
+       PR_GET_CHILD_SUBREAPER           = 0x25
+       PR_GET_DUMPABLE                  = 0x3
+       PR_GET_ENDIAN                    = 0x13
+       PR_GET_FPEMU                     = 0x9
+       PR_GET_FPEXC                     = 0xb
+       PR_GET_KEEPCAPS                  = 0x7
+       PR_GET_NAME                      = 0x10
+       PR_GET_NO_NEW_PRIVS              = 0x27
+       PR_GET_PDEATHSIG                 = 0x2
+       PR_GET_SECCOMP                   = 0x15
+       PR_GET_SECUREBITS                = 0x1b
+       PR_GET_TID_ADDRESS               = 0x28
+       PR_GET_TIMERSLACK                = 0x1e
+       PR_GET_TIMING                    = 0xd
+       PR_GET_TSC                       = 0x19
+       PR_GET_UNALIGN                   = 0x5
+       PR_MCE_KILL                      = 0x21
+       PR_MCE_KILL_CLEAR                = 0x0
+       PR_MCE_KILL_DEFAULT              = 0x2
+       PR_MCE_KILL_EARLY                = 0x1
+       PR_MCE_KILL_GET                  = 0x22
+       PR_MCE_KILL_LATE                 = 0x0
+       PR_MCE_KILL_SET                  = 0x1
+       PR_SET_CHILD_SUBREAPER           = 0x24
+       PR_SET_DUMPABLE                  = 0x4
+       PR_SET_ENDIAN                    = 0x14
+       PR_SET_FPEMU                     = 0xa
+       PR_SET_FPEXC                     = 0xc
+       PR_SET_KEEPCAPS                  = 0x8
+       PR_SET_MM                        = 0x23
+       PR_SET_MM_ARG_END                = 0x9
+       PR_SET_MM_ARG_START              = 0x8
+       PR_SET_MM_AUXV                   = 0xc
+       PR_SET_MM_BRK                    = 0x7
+       PR_SET_MM_END_CODE               = 0x2
+       PR_SET_MM_END_DATA               = 0x4
+       PR_SET_MM_ENV_END                = 0xb
+       PR_SET_MM_ENV_START              = 0xa
+       PR_SET_MM_EXE_FILE               = 0xd
+       PR_SET_MM_START_BRK              = 0x6
+       PR_SET_MM_START_CODE             = 0x1
+       PR_SET_MM_START_DATA             = 0x3
+       PR_SET_MM_START_STACK            = 0x5
+       PR_SET_NAME                      = 0xf
+       PR_SET_NO_NEW_PRIVS              = 0x26
+       PR_SET_PDEATHSIG                 = 0x1
+       PR_SET_PTRACER                   = 0x59616d61
+       PR_SET_PTRACER_ANY               = -0x1
+       PR_SET_SECCOMP                   = 0x16
+       PR_SET_SECUREBITS                = 0x1c
+       PR_SET_TIMERSLACK                = 0x1d
+       PR_SET_TIMING                    = 0xe
+       PR_SET_TSC                       = 0x1a
+       PR_SET_UNALIGN                   = 0x6
+       PR_TASK_PERF_EVENTS_DISABLE      = 0x1f
+       PR_TASK_PERF_EVENTS_ENABLE       = 0x20
+       PR_TIMING_STATISTICAL            = 0x0
+       PR_TIMING_TIMESTAMP              = 0x1
+       PR_TSC_ENABLE                    = 0x1
+       PR_TSC_SIGSEGV                   = 0x2
+       PR_UNALIGN_NOPRINT               = 0x1
+       PR_UNALIGN_SIGBUS                = 0x2
+       PTRACE_ATTACH                    = 0x10
+       PTRACE_CONT                      = 0x7
+       PTRACE_DETACH                    = 0x11
+       PTRACE_EVENT_CLONE               = 0x3
+       PTRACE_EVENT_EXEC                = 0x4
+       PTRACE_EVENT_EXIT                = 0x6
+       PTRACE_EVENT_FORK                = 0x1
+       PTRACE_EVENT_SECCOMP             = 0x7
+       PTRACE_EVENT_STOP                = 0x80
+       PTRACE_EVENT_VFORK               = 0x2
+       PTRACE_EVENT_VFORK_DONE          = 0x5
+       PTRACE_GETEVENTMSG               = 0x4201
+       PTRACE_GETEVRREGS                = 0x14
+       PTRACE_GETFPREGS                 = 0xe
+       PTRACE_GETREGS                   = 0xc
+       PTRACE_GETREGS64                 = 0x16
+       PTRACE_GETREGSET                 = 0x4204
+       PTRACE_GETSIGINFO                = 0x4202
+       PTRACE_GETSIGMASK                = 0x420a
+       PTRACE_GETVRREGS                 = 0x12
+       PTRACE_GETVSRREGS                = 0x1b
+       PTRACE_GET_DEBUGREG              = 0x19
+       PTRACE_INTERRUPT                 = 0x4207
+       PTRACE_KILL                      = 0x8
+       PTRACE_LISTEN                    = 0x4208
+       PTRACE_O_EXITKILL                = 0x100000
+       PTRACE_O_MASK                    = 0x1000ff
+       PTRACE_O_TRACECLONE              = 0x8
+       PTRACE_O_TRACEEXEC               = 0x10
+       PTRACE_O_TRACEEXIT               = 0x40
+       PTRACE_O_TRACEFORK               = 0x2
+       PTRACE_O_TRACESECCOMP            = 0x80
+       PTRACE_O_TRACESYSGOOD            = 0x1
+       PTRACE_O_TRACEVFORK              = 0x4
+       PTRACE_O_TRACEVFORKDONE          = 0x20
+       PTRACE_PEEKDATA                  = 0x2
+       PTRACE_PEEKSIGINFO               = 0x4209
+       PTRACE_PEEKSIGINFO_SHARED        = 0x1
+       PTRACE_PEEKTEXT                  = 0x1
+       PTRACE_PEEKUSR                   = 0x3
+       PTRACE_POKEDATA                  = 0x5
+       PTRACE_POKETEXT                  = 0x4
+       PTRACE_POKEUSR                   = 0x6
+       PTRACE_SEIZE                     = 0x4206
+       PTRACE_SETEVRREGS                = 0x15
+       PTRACE_SETFPREGS                 = 0xf
+       PTRACE_SETOPTIONS                = 0x4200
+       PTRACE_SETREGS                   = 0xd
+       PTRACE_SETREGS64                 = 0x17
+       PTRACE_SETREGSET                 = 0x4205
+       PTRACE_SETSIGINFO                = 0x4203
+       PTRACE_SETSIGMASK                = 0x420b
+       PTRACE_SETVRREGS                 = 0x13
+       PTRACE_SETVSRREGS                = 0x1c
+       PTRACE_SET_DEBUGREG              = 0x1a
+       PTRACE_SINGLEBLOCK               = 0x100
+       PTRACE_SINGLESTEP                = 0x9
+       PTRACE_SYSCALL                   = 0x18
+       PTRACE_TRACEME                   = 0x0
+       PT_CCR                           = 0x26
+       PT_CTR                           = 0x23
+       PT_DAR                           = 0x29
+       PT_DSCR                          = 0x2c
+       PT_DSISR                         = 0x2a
+       PT_FPR0                          = 0x30
+       PT_FPSCR                         = 0x50
+       PT_LNK                           = 0x24
+       PT_MSR                           = 0x21
+       PT_NIP                           = 0x20
+       PT_ORIG_R3                       = 0x22
+       PT_R0                            = 0x0
+       PT_R1                            = 0x1
+       PT_R10                           = 0xa
+       PT_R11                           = 0xb
+       PT_R12                           = 0xc
+       PT_R13                           = 0xd
+       PT_R14                           = 0xe
+       PT_R15                           = 0xf
+       PT_R16                           = 0x10
+       PT_R17                           = 0x11
+       PT_R18                           = 0x12
+       PT_R19                           = 0x13
+       PT_R2                            = 0x2
+       PT_R20                           = 0x14
+       PT_R21                           = 0x15
+       PT_R22                           = 0x16
+       PT_R23                           = 0x17
+       PT_R24                           = 0x18
+       PT_R25                           = 0x19
+       PT_R26                           = 0x1a
+       PT_R27                           = 0x1b
+       PT_R28                           = 0x1c
+       PT_R29                           = 0x1d
+       PT_R3                            = 0x3
+       PT_R30                           = 0x1e
+       PT_R31                           = 0x1f
+       PT_R4                            = 0x4
+       PT_R5                            = 0x5
+       PT_R6                            = 0x6
+       PT_R7                            = 0x7
+       PT_R8                            = 0x8
+       PT_R9                            = 0x9
+       PT_REGS_COUNT                    = 0x2c
+       PT_RESULT                        = 0x2b
+       PT_SOFTE                         = 0x27
+       PT_TRAP                          = 0x28
+       PT_VR0                           = 0x52
+       PT_VRSAVE                        = 0x94
+       PT_VSCR                          = 0x93
+       PT_VSR0                          = 0x96
+       PT_VSR31                         = 0xd4
+       PT_XER                           = 0x25
+       RLIMIT_AS                        = 0x9
+       RLIMIT_CORE                      = 0x4
+       RLIMIT_CPU                       = 0x0
+       RLIMIT_DATA                      = 0x2
+       RLIMIT_FSIZE                     = 0x1
+       RLIMIT_NOFILE                    = 0x7
+       RLIMIT_STACK                     = 0x3
+       RLIM_INFINITY                    = -0x1
+       RTAX_ADVMSS                      = 0x8
+       RTAX_CWND                        = 0x7
+       RTAX_FEATURES                    = 0xc
+       RTAX_FEATURE_ALLFRAG             = 0x8
+       RTAX_FEATURE_ECN                 = 0x1
+       RTAX_FEATURE_SACK                = 0x2
+       RTAX_FEATURE_TIMESTAMP           = 0x4
+       RTAX_HOPLIMIT                    = 0xa
+       RTAX_INITCWND                    = 0xb
+       RTAX_INITRWND                    = 0xe
+       RTAX_LOCK                        = 0x1
+       RTAX_MAX                         = 0xf
+       RTAX_MTU                         = 0x2
+       RTAX_QUICKACK                    = 0xf
+       RTAX_REORDERING                  = 0x9
+       RTAX_RTO_MIN                     = 0xd
+       RTAX_RTT                         = 0x4
+       RTAX_RTTVAR                      = 0x5
+       RTAX_SSTHRESH                    = 0x6
+       RTAX_UNSPEC                      = 0x0
+       RTAX_WINDOW                      = 0x3
+       RTA_ALIGNTO                      = 0x4
+       RTA_MAX                          = 0x11
+       RTCF_DIRECTSRC                   = 0x4000000
+       RTCF_DOREDIRECT                  = 0x1000000
+       RTCF_LOG                         = 0x2000000
+       RTCF_MASQ                        = 0x400000
+       RTCF_NAT                         = 0x800000
+       RTCF_VALVE                       = 0x200000
+       RTF_ADDRCLASSMASK                = 0xf8000000
+       RTF_ADDRCONF                     = 0x40000
+       RTF_ALLONLINK                    = 0x20000
+       RTF_BROADCAST                    = 0x10000000
+       RTF_CACHE                        = 0x1000000
+       RTF_DEFAULT                      = 0x10000
+       RTF_DYNAMIC                      = 0x10
+       RTF_FLOW                         = 0x2000000
+       RTF_GATEWAY                      = 0x2
+       RTF_HOST                         = 0x4
+       RTF_INTERFACE                    = 0x40000000
+       RTF_IRTT                         = 0x100
+       RTF_LINKRT                       = 0x100000
+       RTF_LOCAL                        = 0x80000000
+       RTF_MODIFIED                     = 0x20
+       RTF_MSS                          = 0x40
+       RTF_MTU                          = 0x40
+       RTF_MULTICAST                    = 0x20000000
+       RTF_NAT                          = 0x8000000
+       RTF_NOFORWARD                    = 0x1000
+       RTF_NONEXTHOP                    = 0x200000
+       RTF_NOPMTUDISC                   = 0x4000
+       RTF_POLICY                       = 0x4000000
+       RTF_REINSTATE                    = 0x8
+       RTF_REJECT                       = 0x200
+       RTF_STATIC                       = 0x400
+       RTF_THROW                        = 0x2000
+       RTF_UP                           = 0x1
+       RTF_WINDOW                       = 0x80
+       RTF_XRESOLVE                     = 0x800
+       RTM_BASE                         = 0x10
+       RTM_DELACTION                    = 0x31
+       RTM_DELADDR                      = 0x15
+       RTM_DELADDRLABEL                 = 0x49
+       RTM_DELLINK                      = 0x11
+       RTM_DELMDB                       = 0x55
+       RTM_DELNEIGH                     = 0x1d
+       RTM_DELQDISC                     = 0x25
+       RTM_DELROUTE                     = 0x19
+       RTM_DELRULE                      = 0x21
+       RTM_DELTCLASS                    = 0x29
+       RTM_DELTFILTER                   = 0x2d
+       RTM_F_CLONED                     = 0x200
+       RTM_F_EQUALIZE                   = 0x400
+       RTM_F_NOTIFY                     = 0x100
+       RTM_F_PREFIX                     = 0x800
+       RTM_GETACTION                    = 0x32
+       RTM_GETADDR                      = 0x16
+       RTM_GETADDRLABEL                 = 0x4a
+       RTM_GETANYCAST                   = 0x3e
+       RTM_GETDCB                       = 0x4e
+       RTM_GETLINK                      = 0x12
+       RTM_GETMDB                       = 0x56
+       RTM_GETMULTICAST                 = 0x3a
+       RTM_GETNEIGH                     = 0x1e
+       RTM_GETNEIGHTBL                  = 0x42
+       RTM_GETNETCONF                   = 0x52
+       RTM_GETQDISC                     = 0x26
+       RTM_GETROUTE                     = 0x1a
+       RTM_GETRULE                      = 0x22
+       RTM_GETTCLASS                    = 0x2a
+       RTM_GETTFILTER                   = 0x2e
+       RTM_MAX                          = 0x57
+       RTM_NEWACTION                    = 0x30
+       RTM_NEWADDR                      = 0x14
+       RTM_NEWADDRLABEL                 = 0x48
+       RTM_NEWLINK                      = 0x10
+       RTM_NEWMDB                       = 0x54
+       RTM_NEWNDUSEROPT                 = 0x44
+       RTM_NEWNEIGH                     = 0x1c
+       RTM_NEWNEIGHTBL                  = 0x40
+       RTM_NEWNETCONF                   = 0x50
+       RTM_NEWPREFIX                    = 0x34
+       RTM_NEWQDISC                     = 0x24
+       RTM_NEWROUTE                     = 0x18
+       RTM_NEWRULE                      = 0x20
+       RTM_NEWTCLASS                    = 0x28
+       RTM_NEWTFILTER                   = 0x2c
+       RTM_NR_FAMILIES                  = 0x12
+       RTM_NR_MSGTYPES                  = 0x48
+       RTM_SETDCB                       = 0x4f
+       RTM_SETLINK                      = 0x13
+       RTM_SETNEIGHTBL                  = 0x43
+       RTNH_ALIGNTO                     = 0x4
+       RTNH_F_DEAD                      = 0x1
+       RTNH_F_ONLINK                    = 0x4
+       RTNH_F_PERVASIVE                 = 0x2
+       RTN_MAX                          = 0xb
+       RTPROT_BIRD                      = 0xc
+       RTPROT_BOOT                      = 0x3
+       RTPROT_DHCP                      = 0x10
+       RTPROT_DNROUTED                  = 0xd
+       RTPROT_GATED                     = 0x8
+       RTPROT_KERNEL                    = 0x2
+       RTPROT_MROUTED                   = 0x11
+       RTPROT_MRT                       = 0xa
+       RTPROT_NTK                       = 0xf
+       RTPROT_RA                        = 0x9
+       RTPROT_REDIRECT                  = 0x1
+       RTPROT_STATIC                    = 0x4
+       RTPROT_UNSPEC                    = 0x0
+       RTPROT_XORP                      = 0xe
+       RTPROT_ZEBRA                     = 0xb
+       RT_CLASS_DEFAULT                 = 0xfd
+       RT_CLASS_LOCAL                   = 0xff
+       RT_CLASS_MAIN                    = 0xfe
+       RT_CLASS_MAX                     = 0xff
+       RT_CLASS_UNSPEC                  = 0x0
+       RUSAGE_CHILDREN                  = -0x1
+       RUSAGE_SELF                      = 0x0
+       RUSAGE_THREAD                    = 0x1
+       SCM_CREDENTIALS                  = 0x2
+       SCM_RIGHTS                       = 0x1
+       SCM_TIMESTAMP                    = 0x1d
+       SCM_TIMESTAMPING                 = 0x25
+       SCM_TIMESTAMPNS                  = 0x23
+       SCM_WIFI_STATUS                  = 0x29
+       SHUT_RD                          = 0x0
+       SHUT_RDWR                        = 0x2
+       SHUT_WR                          = 0x1
+       SIOCADDDLCI                      = 0x8980
+       SIOCADDMULTI                     = 0x8931
+       SIOCADDRT                        = 0x890b
+       SIOCATMARK                       = 0x8905
+       SIOCDARP                         = 0x8953
+       SIOCDELDLCI                      = 0x8981
+       SIOCDELMULTI                     = 0x8932
+       SIOCDELRT                        = 0x890c
+       SIOCDEVPRIVATE                   = 0x89f0
+       SIOCDIFADDR                      = 0x8936
+       SIOCDRARP                        = 0x8960
+       SIOCGARP                         = 0x8954
+       SIOCGIFADDR                      = 0x8915
+       SIOCGIFBR                        = 0x8940
+       SIOCGIFBRDADDR                   = 0x8919
+       SIOCGIFCONF                      = 0x8912
+       SIOCGIFCOUNT                     = 0x8938
+       SIOCGIFDSTADDR                   = 0x8917
+       SIOCGIFENCAP                     = 0x8925
+       SIOCGIFFLAGS                     = 0x8913
+       SIOCGIFHWADDR                    = 0x8927
+       SIOCGIFINDEX                     = 0x8933
+       SIOCGIFMAP                       = 0x8970
+       SIOCGIFMEM                       = 0x891f
+       SIOCGIFMETRIC                    = 0x891d
+       SIOCGIFMTU                       = 0x8921
+       SIOCGIFNAME                      = 0x8910
+       SIOCGIFNETMASK                   = 0x891b
+       SIOCGIFPFLAGS                    = 0x8935
+       SIOCGIFSLAVE                     = 0x8929
+       SIOCGIFTXQLEN                    = 0x8942
+       SIOCGPGRP                        = 0x8904
+       SIOCGRARP                        = 0x8961
+       SIOCGSTAMP                       = 0x8906
+       SIOCGSTAMPNS                     = 0x8907
+       SIOCPROTOPRIVATE                 = 0x89e0
+       SIOCRTMSG                        = 0x890d
+       SIOCSARP                         = 0x8955
+       SIOCSIFADDR                      = 0x8916
+       SIOCSIFBR                        = 0x8941
+       SIOCSIFBRDADDR                   = 0x891a
+       SIOCSIFDSTADDR                   = 0x8918
+       SIOCSIFENCAP                     = 0x8926
+       SIOCSIFFLAGS                     = 0x8914
+       SIOCSIFHWADDR                    = 0x8924
+       SIOCSIFHWBROADCAST               = 0x8937
+       SIOCSIFLINK                      = 0x8911
+       SIOCSIFMAP                       = 0x8971
+       SIOCSIFMEM                       = 0x8920
+       SIOCSIFMETRIC                    = 0x891e
+       SIOCSIFMTU                       = 0x8922
+       SIOCSIFNAME                      = 0x8923
+       SIOCSIFNETMASK                   = 0x891c
+       SIOCSIFPFLAGS                    = 0x8934
+       SIOCSIFSLAVE                     = 0x8930
+       SIOCSIFTXQLEN                    = 0x8943
+       SIOCSPGRP                        = 0x8902
+       SIOCSRARP                        = 0x8962
+       SOCK_CLOEXEC                     = 0x80000
+       SOCK_DCCP                        = 0x6
+       SOCK_DGRAM                       = 0x2
+       SOCK_NONBLOCK                    = 0x800
+       SOCK_PACKET                      = 0xa
+       SOCK_RAW                         = 0x3
+       SOCK_RDM                         = 0x4
+       SOCK_SEQPACKET                   = 0x5
+       SOCK_STREAM                      = 0x1
+       SOL_AAL                          = 0x109
+       SOL_ATM                          = 0x108
+       SOL_DECNET                       = 0x105
+       SOL_ICMPV6                       = 0x3a
+       SOL_IP                           = 0x0
+       SOL_IPV6                         = 0x29
+       SOL_IRDA                         = 0x10a
+       SOL_PACKET                       = 0x107
+       SOL_RAW                          = 0xff
+       SOL_SOCKET                       = 0x1
+       SOL_TCP                          = 0x6
+       SOL_X25                          = 0x106
+       SOMAXCONN                        = 0x80
+       SO_ACCEPTCONN                    = 0x1e
+       SO_ATTACH_FILTER                 = 0x1a
+       SO_BINDTODEVICE                  = 0x19
+       SO_BROADCAST                     = 0x6
+       SO_BSDCOMPAT                     = 0xe
+       SO_BUSY_POLL                     = 0x2e
+       SO_DEBUG                         = 0x1
+       SO_DETACH_FILTER                 = 0x1b
+       SO_DOMAIN                        = 0x27
+       SO_DONTROUTE                     = 0x5
+       SO_ERROR                         = 0x4
+       SO_GET_FILTER                    = 0x1a
+       SO_KEEPALIVE                     = 0x9
+       SO_LINGER                        = 0xd
+       SO_LOCK_FILTER                   = 0x2c
+       SO_MARK                          = 0x24
+       SO_MAX_PACING_RATE               = 0x2f
+       SO_NOFCS                         = 0x2b
+       SO_NO_CHECK                      = 0xb
+       SO_OOBINLINE                     = 0xa
+       SO_PASSCRED                      = 0x14
+       SO_PASSSEC                       = 0x22
+       SO_PEEK_OFF                      = 0x2a
+       SO_PEERCRED                      = 0x15
+       SO_PEERNAME                      = 0x1c
+       SO_PEERSEC                       = 0x1f
+       SO_PRIORITY                      = 0xc
+       SO_PROTOCOL                      = 0x26
+       SO_RCVBUF                        = 0x8
+       SO_RCVBUFFORCE                   = 0x21
+       SO_RCVLOWAT                      = 0x10
+       SO_RCVTIMEO                      = 0x12
+       SO_REUSEADDR                     = 0x2
+       SO_REUSEPORT                     = 0xf
+       SO_RXQ_OVFL                      = 0x28
+       SO_SECURITY_AUTHENTICATION       = 0x16
+       SO_SECURITY_ENCRYPTION_NETWORK   = 0x18
+       SO_SECURITY_ENCRYPTION_TRANSPORT = 0x17
+       SO_SELECT_ERR_QUEUE              = 0x2d
+       SO_SNDBUF                        = 0x7
+       SO_SNDBUFFORCE                   = 0x20
+       SO_SNDLOWAT                      = 0x11
+       SO_SNDTIMEO                      = 0x13
+       SO_TIMESTAMP                     = 0x1d
+       SO_TIMESTAMPING                  = 0x25
+       SO_TIMESTAMPNS                   = 0x23
+       SO_TYPE                          = 0x3
+       SO_WIFI_STATUS                   = 0x29
+       S_BLKSIZE                        = 0x200
+       S_IEXEC                          = 0x40
+       S_IFBLK                          = 0x6000
+       S_IFCHR                          = 0x2000
+       S_IFDIR                          = 0x4000
+       S_IFIFO                          = 0x1000
+       S_IFLNK                          = 0xa000
+       S_IFMT                           = 0xf000
+       S_IFREG                          = 0x8000
+       S_IFSOCK                         = 0xc000
+       S_IREAD                          = 0x100
+       S_IRGRP                          = 0x20
+       S_IROTH                          = 0x4
+       S_IRUSR                          = 0x100
+       S_IRWXG                          = 0x38
+       S_IRWXO                          = 0x7
+       S_IRWXU                          = 0x1c0
+       S_ISGID                          = 0x400
+       S_ISUID                          = 0x800
+       S_ISVTX                          = 0x200
+       S_IWGRP                          = 0x10
+       S_IWOTH                          = 0x2
+       S_IWRITE                         = 0x80
+       S_IWUSR                          = 0x80
+       S_IXGRP                          = 0x8
+       S_IXOTH                          = 0x1
+       S_IXUSR                          = 0x40
+       TCFLSH                           = 0x2000741f
+       TCIFLUSH                         = 0x0
+       TCIOFLUSH                        = 0x2
+       TCOFLUSH                         = 0x1
+       TCP_CONGESTION                   = 0xd
+       TCP_COOKIE_IN_ALWAYS             = 0x1
+       TCP_COOKIE_MAX                   = 0x10
+       TCP_COOKIE_MIN                   = 0x8
+       TCP_COOKIE_OUT_NEVER             = 0x2
+       TCP_COOKIE_PAIR_SIZE             = 0x20
+       TCP_COOKIE_TRANSACTIONS          = 0xf
+       TCP_CORK                         = 0x3
+       TCP_DEFER_ACCEPT                 = 0x9
+       TCP_FASTOPEN                     = 0x17
+       TCP_INFO                         = 0xb
+       TCP_KEEPCNT                      = 0x6
+       TCP_KEEPIDLE                     = 0x4
+       TCP_KEEPINTVL                    = 0x5
+       TCP_LINGER2                      = 0x8
+       TCP_MAXSEG                       = 0x2
+       TCP_MAXWIN                       = 0xffff
+       TCP_MAX_WINSHIFT                 = 0xe
+       TCP_MD5SIG                       = 0xe
+       TCP_MD5SIG_MAXKEYLEN             = 0x50
+       TCP_MSS                          = 0x200
+       TCP_MSS_DEFAULT                  = 0x218
+       TCP_MSS_DESIRED                  = 0x4c4
+       TCP_NODELAY                      = 0x1
+       TCP_QUEUE_SEQ                    = 0x15
+       TCP_QUICKACK                     = 0xc
+       TCP_REPAIR                       = 0x13
+       TCP_REPAIR_OPTIONS               = 0x16
+       TCP_REPAIR_QUEUE                 = 0x14
+       TCP_SYNCNT                       = 0x7
+       TCP_S_DATA_IN                    = 0x4
+       TCP_S_DATA_OUT                   = 0x8
+       TCP_THIN_DUPACK                  = 0x11
+       TCP_THIN_LINEAR_TIMEOUTS         = 0x10
+       TCP_TIMESTAMP                    = 0x18
+       TCP_USER_TIMEOUT                 = 0x12
+       TCP_WINDOW_CLAMP                 = 0xa
+       TCSAFLUSH                        = 0x2
+       TIOCCBRK                         = 0x5428
+       TIOCCONS                         = 0x541d
+       TIOCEXCL                         = 0x540c
+       TIOCGDEV                         = 0x40045432
+       TIOCGETC                         = 0x40067412
+       TIOCGETD                         = 0x5424
+       TIOCGETP                         = 0x40067408
+       TIOCGEXCL                        = 0x40045440
+       TIOCGICOUNT                      = 0x545d
+       TIOCGLCKTRMIOS                   = 0x5456
+       TIOCGLTC                         = 0x40067474
+       TIOCGPGRP                        = 0x40047477
+       TIOCGPKT                         = 0x40045438
+       TIOCGPTLCK                       = 0x40045439
+       TIOCGPTN                         = 0x40045430
+       TIOCGRS485                       = 0x542e
+       TIOCGSERIAL                      = 0x541e
+       TIOCGSID                         = 0x5429
+       TIOCGSOFTCAR                     = 0x5419
+       TIOCGWINSZ                       = 0x40087468
+       TIOCINQ                          = 0x4004667f
+       TIOCLINUX                        = 0x541c
+       TIOCMBIC                         = 0x5417
+       TIOCMBIS                         = 0x5416
+       TIOCMGET                         = 0x5415
+       TIOCMIWAIT                       = 0x545c
+       TIOCMSET                         = 0x5418
+       TIOCM_CAR                        = 0x40
+       TIOCM_CD                         = 0x40
+       TIOCM_CTS                        = 0x20
+       TIOCM_DSR                        = 0x100
+       TIOCM_DTR                        = 0x2
+       TIOCM_LE                         = 0x1
+       TIOCM_LOOP                       = 0x8000
+       TIOCM_OUT1                       = 0x2000
+       TIOCM_OUT2                       = 0x4000
+       TIOCM_RI                         = 0x80
+       TIOCM_RNG                        = 0x80
+       TIOCM_RTS                        = 0x4
+       TIOCM_SR                         = 0x10
+       TIOCM_ST                         = 0x8
+       TIOCNOTTY                        = 0x5422
+       TIOCNXCL                         = 0x540d
+       TIOCOUTQ                         = 0x40047473
+       TIOCPKT                          = 0x5420
+       TIOCPKT_DATA                     = 0x0
+       TIOCPKT_DOSTOP                   = 0x20
+       TIOCPKT_FLUSHREAD                = 0x1
+       TIOCPKT_FLUSHWRITE               = 0x2
+       TIOCPKT_IOCTL                    = 0x40
+       TIOCPKT_NOSTOP                   = 0x10
+       TIOCPKT_START                    = 0x8
+       TIOCPKT_STOP                     = 0x4
+       TIOCSBRK                         = 0x5427
+       TIOCSCTTY                        = 0x540e
+       TIOCSERCONFIG                    = 0x5453
+       TIOCSERGETLSR                    = 0x5459
+       TIOCSERGETMULTI                  = 0x545a
+       TIOCSERGSTRUCT                   = 0x5458
+       TIOCSERGWILD                     = 0x5454
+       TIOCSERSETMULTI                  = 0x545b
+       TIOCSERSWILD                     = 0x5455
+       TIOCSER_TEMT                     = 0x1
+       TIOCSETC                         = 0x80067411
+       TIOCSETD                         = 0x5423
+       TIOCSETN                         = 0x8006740a
+       TIOCSETP                         = 0x80067409
+       TIOCSIG                          = 0x80045436
+       TIOCSLCKTRMIOS                   = 0x5457
+       TIOCSLTC                         = 0x80067475
+       TIOCSPGRP                        = 0x80047476
+       TIOCSPTLCK                       = 0x80045431
+       TIOCSRS485                       = 0x542f
+       TIOCSSERIAL                      = 0x541f
+       TIOCSSOFTCAR                     = 0x541a
+       TIOCSTART                        = 0x2000746e
+       TIOCSTI                          = 0x5412
+       TIOCSTOP                         = 0x2000746f
+       TIOCSWINSZ                       = 0x80087467
+       TIOCVHANGUP                      = 0x5437
+       TOSTOP                           = 0x400000
+       TUNATTACHFILTER                  = 0x801054d5
+       TUNDETACHFILTER                  = 0x801054d6
+       TUNGETFEATURES                   = 0x400454cf
+       TUNGETFILTER                     = 0x401054db
+       TUNGETIFF                        = 0x400454d2
+       TUNGETSNDBUF                     = 0x400454d3
+       TUNGETVNETHDRSZ                  = 0x400454d7
+       TUNSETDEBUG                      = 0x800454c9
+       TUNSETGROUP                      = 0x800454ce
+       TUNSETIFF                        = 0x800454ca
+       TUNSETIFINDEX                    = 0x800454da
+       TUNSETLINK                       = 0x800454cd
+       TUNSETNOCSUM                     = 0x800454c8
+       TUNSETOFFLOAD                    = 0x800454d0
+       TUNSETOWNER                      = 0x800454cc
+       TUNSETPERSIST                    = 0x800454cb
+       TUNSETQUEUE                      = 0x800454d9
+       TUNSETSNDBUF                     = 0x800454d4
+       TUNSETTXFILTER                   = 0x800454d1
+       TUNSETVNETHDRSZ                  = 0x800454d8
+       VDISCARD                         = 0x10
+       VEOF                             = 0x4
+       VEOL                             = 0x6
+       VEOL2                            = 0x8
+       VERASE                           = 0x2
+       VINTR                            = 0x0
+       VKILL                            = 0x3
+       VLNEXT                           = 0xf
+       VMIN                             = 0x5
+       VQUIT                            = 0x1
+       VREPRINT                         = 0xb
+       VSTART                           = 0xd
+       VSTOP                            = 0xe
+       VSUSP                            = 0xc
+       VSWTC                            = 0x9
+       VT0                              = 0x0
+       VT1                              = 0x10000
+       VTDLY                            = 0x10000
+       VTIME                            = 0x7
+       VWERASE                          = 0xa
+       WALL                             = 0x40000000
+       WCLONE                           = 0x80000000
+       WCONTINUED                       = 0x8
+       WEXITED                          = 0x4
+       WNOHANG                          = 0x1
+       WNOTHREAD                        = 0x20000000
+       WNOWAIT                          = 0x1000000
+       WORDSIZE                         = 0x40
+       WSTOPPED                         = 0x2
+       WUNTRACED                        = 0x2
+)
+
+// Errors
+const (
+       E2BIG           = Errno(0x7)
+       EACCES          = Errno(0xd)
+       EADDRINUSE      = Errno(0x62)
+       EADDRNOTAVAIL   = Errno(0x63)
+       EADV            = Errno(0x44)
+       EAFNOSUPPORT    = Errno(0x61)
+       EAGAIN          = Errno(0xb)
+       EALREADY        = Errno(0x72)
+       EBADE           = Errno(0x34)
+       EBADF           = Errno(0x9)
+       EBADFD          = Errno(0x4d)
+       EBADMSG         = Errno(0x4a)
+       EBADR           = Errno(0x35)
+       EBADRQC         = Errno(0x38)
+       EBADSLT         = Errno(0x39)
+       EBFONT          = Errno(0x3b)
+       EBUSY           = Errno(0x10)
+       ECANCELED       = Errno(0x7d)
+       ECHILD          = Errno(0xa)
+       ECHRNG          = Errno(0x2c)
+       ECOMM           = Errno(0x46)
+       ECONNABORTED    = Errno(0x67)
+       ECONNREFUSED    = Errno(0x6f)
+       ECONNRESET      = Errno(0x68)
+       EDEADLK         = Errno(0x23)
+       EDEADLOCK       = Errno(0x3a)
+       EDESTADDRREQ    = Errno(0x59)
+       EDOM            = Errno(0x21)
+       EDOTDOT         = Errno(0x49)
+       EDQUOT          = Errno(0x7a)
+       EEXIST          = Errno(0x11)
+       EFAULT          = Errno(0xe)
+       EFBIG           = Errno(0x1b)
+       EHOSTDOWN       = Errno(0x70)
+       EHOSTUNREACH    = Errno(0x71)
+       EHWPOISON       = Errno(0x85)
+       EIDRM           = Errno(0x2b)
+       EILSEQ          = Errno(0x54)
+       EINPROGRESS     = Errno(0x73)
+       EINTR           = Errno(0x4)
+       EINVAL          = Errno(0x16)
+       EIO             = Errno(0x5)
+       EISCONN         = Errno(0x6a)
+       EISDIR          = Errno(0x15)
+       EISNAM          = Errno(0x78)
+       EKEYEXPIRED     = Errno(0x7f)
+       EKEYREJECTED    = Errno(0x81)
+       EKEYREVOKED     = Errno(0x80)
+       EL2HLT          = Errno(0x33)
+       EL2NSYNC        = Errno(0x2d)
+       EL3HLT          = Errno(0x2e)
+       EL3RST          = Errno(0x2f)
+       ELIBACC         = Errno(0x4f)
+       ELIBBAD         = Errno(0x50)
+       ELIBEXEC        = Errno(0x53)
+       ELIBMAX         = Errno(0x52)
+       ELIBSCN         = Errno(0x51)
+       ELNRNG          = Errno(0x30)
+       ELOOP           = Errno(0x28)
+       EMEDIUMTYPE     = Errno(0x7c)
+       EMFILE          = Errno(0x18)
+       EMLINK          = Errno(0x1f)
+       EMSGSIZE        = Errno(0x5a)
+       EMULTIHOP       = Errno(0x48)
+       ENAMETOOLONG    = Errno(0x24)
+       ENAVAIL         = Errno(0x77)
+       ENETDOWN        = Errno(0x64)
+       ENETRESET       = Errno(0x66)
+       ENETUNREACH     = Errno(0x65)
+       ENFILE          = Errno(0x17)
+       ENOANO          = Errno(0x37)
+       ENOBUFS         = Errno(0x69)
+       ENOCSI          = Errno(0x32)
+       ENODATA         = Errno(0x3d)
+       ENODEV          = Errno(0x13)
+       ENOENT          = Errno(0x2)
+       ENOEXEC         = Errno(0x8)
+       ENOKEY          = Errno(0x7e)
+       ENOLCK          = Errno(0x25)
+       ENOLINK         = Errno(0x43)
+       ENOMEDIUM       = Errno(0x7b)
+       ENOMEM          = Errno(0xc)
+       ENOMSG          = Errno(0x2a)
+       ENONET          = Errno(0x40)
+       ENOPKG          = Errno(0x41)
+       ENOPROTOOPT     = Errno(0x5c)
+       ENOSPC          = Errno(0x1c)
+       ENOSR           = Errno(0x3f)
+       ENOSTR          = Errno(0x3c)
+       ENOSYS          = Errno(0x26)
+       ENOTBLK         = Errno(0xf)
+       ENOTCONN        = Errno(0x6b)
+       ENOTDIR         = Errno(0x14)
+       ENOTEMPTY       = Errno(0x27)
+       ENOTNAM         = Errno(0x76)
+       ENOTRECOVERABLE = Errno(0x83)
+       ENOTSOCK        = Errno(0x58)
+       ENOTSUP         = Errno(0x5f)
+       ENOTTY          = Errno(0x19)
+       ENOTUNIQ        = Errno(0x4c)
+       ENXIO           = Errno(0x6)
+       EOPNOTSUPP      = Errno(0x5f)
+       EOVERFLOW       = Errno(0x4b)
+       EOWNERDEAD      = Errno(0x82)
+       EPERM           = Errno(0x1)
+       EPFNOSUPPORT    = Errno(0x60)
+       EPIPE           = Errno(0x20)
+       EPROTO          = Errno(0x47)
+       EPROTONOSUPPORT = Errno(0x5d)
+       EPROTOTYPE      = Errno(0x5b)
+       ERANGE          = Errno(0x22)
+       EREMCHG         = Errno(0x4e)
+       EREMOTE         = Errno(0x42)
+       EREMOTEIO       = Errno(0x79)
+       ERESTART        = Errno(0x55)
+       ERFKILL         = Errno(0x84)
+       EROFS           = Errno(0x1e)
+       ESHUTDOWN       = Errno(0x6c)
+       ESOCKTNOSUPPORT = Errno(0x5e)
+       ESPIPE          = Errno(0x1d)
+       ESRCH           = Errno(0x3)
+       ESRMNT          = Errno(0x45)
+       ESTALE          = Errno(0x74)
+       ESTRPIPE        = Errno(0x56)
+       ETIME           = Errno(0x3e)
+       ETIMEDOUT       = Errno(0x6e)
+       ETOOMANYREFS    = Errno(0x6d)
+       ETXTBSY         = Errno(0x1a)
+       EUCLEAN         = Errno(0x75)
+       EUNATCH         = Errno(0x31)
+       EUSERS          = Errno(0x57)
+       EWOULDBLOCK     = Errno(0xb)
+       EXDEV           = Errno(0x12)
+       EXFULL          = Errno(0x36)
+)
+
+// Signals
+const (
+       SIGABRT   = Signal(0x6)
+       SIGALRM   = Signal(0xe)
+       SIGBUS    = Signal(0x7)
+       SIGCHLD   = Signal(0x11)
+       SIGCLD    = Signal(0x11)
+       SIGCONT   = Signal(0x12)
+       SIGFPE    = Signal(0x8)
+       SIGHUP    = Signal(0x1)
+       SIGILL    = Signal(0x4)
+       SIGINT    = Signal(0x2)
+       SIGIO     = Signal(0x1d)
+       SIGIOT    = Signal(0x6)
+       SIGKILL   = Signal(0x9)
+       SIGPIPE   = Signal(0xd)
+       SIGPOLL   = Signal(0x1d)
+       SIGPROF   = Signal(0x1b)
+       SIGPWR    = Signal(0x1e)
+       SIGQUIT   = Signal(0x3)
+       SIGSEGV   = Signal(0xb)
+       SIGSTKFLT = Signal(0x10)
+       SIGSTOP   = Signal(0x13)
+       SIGSYS    = Signal(0x1f)
+       SIGTERM   = Signal(0xf)
+       SIGTRAP   = Signal(0x5)
+       SIGTSTP   = Signal(0x14)
+       SIGTTIN   = Signal(0x15)
+       SIGTTOU   = Signal(0x16)
+       SIGUNUSED = Signal(0x1f)
+       SIGURG    = Signal(0x17)
+       SIGUSR1   = Signal(0xa)
+       SIGUSR2   = Signal(0xc)
+       SIGVTALRM = Signal(0x1a)
+       SIGWINCH  = Signal(0x1c)
+       SIGXCPU   = Signal(0x18)
+       SIGXFSZ   = Signal(0x19)
+)
+
+// Error table
+var errors = [...]string{
+       1:   "operation not permitted",
+       2:   "no such file or directory",
+       3:   "no such process",
+       4:   "interrupted system call",
+       5:   "input/output error",
+       6:   "no such device or address",
+       7:   "argument list too long",
+       8:   "exec format error",
+       9:   "bad file descriptor",
+       10:  "no child processes",
+       11:  "resource temporarily unavailable",
+       12:  "cannot allocate memory",
+       13:  "permission denied",
+       14:  "bad address",
+       15:  "block device required",
+       16:  "device or resource busy",
+       17:  "file exists",
+       18:  "invalid cross-device link",
+       19:  "no such device",
+       20:  "not a directory",
+       21:  "is a directory",
+       22:  "invalid argument",
+       23:  "too many open files in system",
+       24:  "too many open files",
+       25:  "inappropriate ioctl for device",
+       26:  "text file busy",
+       27:  "file too large",
+       28:  "no space left on device",
+       29:  "illegal seek",
+       30:  "read-only file system",
+       31:  "too many links",
+       32:  "broken pipe",
+       33:  "numerical argument out of domain",
+       34:  "numerical result out of range",
+       35:  "resource deadlock avoided",
+       36:  "file name too long",
+       37:  "no locks available",
+       38:  "function not implemented",
+       39:  "directory not empty",
+       40:  "too many levels of symbolic links",
+       42:  "no message of desired type",
+       43:  "identifier removed",
+       44:  "channel number out of range",
+       45:  "level 2 not synchronized",
+       46:  "level 3 halted",
+       47:  "level 3 reset",
+       48:  "link number out of range",
+       49:  "protocol driver not attached",
+       50:  "no CSI structure available",
+       51:  "level 2 halted",
+       52:  "invalid exchange",
+       53:  "invalid request descriptor",
+       54:  "exchange full",
+       55:  "no anode",
+       56:  "invalid request code",
+       57:  "invalid slot",
+       58:  "file locking deadlock error",
+       59:  "bad font file format",
+       60:  "device not a stream",
+       61:  "no data available",
+       62:  "timer expired",
+       63:  "out of streams resources",
+       64:  "machine is not on the network",
+       65:  "package not installed",
+       66:  "object is remote",
+       67:  "link has been severed",
+       68:  "advertise error",
+       69:  "srmount error",
+       70:  "communication error on send",
+       71:  "protocol error",
+       72:  "multihop attempted",
+       73:  "RFS specific error",
+       74:  "bad message",
+       75:  "value too large for defined data type",
+       76:  "name not unique on network",
+       77:  "file descriptor in bad state",
+       78:  "remote address changed",
+       79:  "can not access a needed shared library",
+       80:  "accessing a corrupted shared library",
+       81:  ".lib section in a.out corrupted",
+       82:  "attempting to link in too many shared libraries",
+       83:  "cannot exec a shared library directly",
+       84:  "invalid or incomplete multibyte or wide character",
+       85:  "interrupted system call should be restarted",
+       86:  "streams pipe error",
+       87:  "too many users",
+       88:  "socket operation on non-socket",
+       89:  "destination address required",
+       90:  "message too long",
+       91:  "protocol wrong type for socket",
+       92:  "protocol not available",
+       93:  "protocol not supported",
+       94:  "socket type not supported",
+       95:  "operation not supported",
+       96:  "protocol family not supported",
+       97:  "address family not supported by protocol",
+       98:  "address already in use",
+       99:  "cannot assign requested address",
+       100: "network is down",
+       101: "network is unreachable",
+       102: "network dropped connection on reset",
+       103: "software caused connection abort",
+       104: "connection reset by peer",
+       105: "no buffer space available",
+       106: "transport endpoint is already connected",
+       107: "transport endpoint is not connected",
+       108: "cannot send after transport endpoint shutdown",
+       109: "too many references: cannot splice",
+       110: "connection timed out",
+       111: "connection refused",
+       112: "host is down",
+       113: "no route to host",
+       114: "operation already in progress",
+       115: "operation now in progress",
+       116: "stale file handle",
+       117: "structure needs cleaning",
+       118: "not a XENIX named type file",
+       119: "no XENIX semaphores available",
+       120: "is a named type file",
+       121: "remote I/O error",
+       122: "disk quota exceeded",
+       123: "no medium found",
+       124: "wrong medium type",
+       125: "operation canceled",
+       126: "required key not available",
+       127: "key has expired",
+       128: "key has been revoked",
+       129: "key was rejected by service",
+       130: "owner died",
+       131: "state not recoverable",
+       132: "operation not possible due to RF-kill",
+       133: "memory page has hardware error",
+}
+
+// Signal table
+var signals = [...]string{
+       1:  "hangup",
+       2:  "interrupt",
+       3:  "quit",
+       4:  "illegal instruction",
+       5:  "trace/breakpoint trap",
+       6:  "aborted",
+       7:  "bus error",
+       8:  "floating point exception",
+       9:  "killed",
+       10: "user defined signal 1",
+       11: "segmentation fault",
+       12: "user defined signal 2",
+       13: "broken pipe",
+       14: "alarm clock",
+       15: "terminated",
+       16: "stack fault",
+       17: "child exited",
+       18: "continued",
+       19: "stopped (signal)",
+       20: "stopped",
+       21: "stopped (tty input)",
+       22: "stopped (tty output)",
+       23: "urgent I/O condition",
+       24: "CPU time limit exceeded",
+       25: "file size limit exceeded",
+       26: "virtual timer expired",
+       27: "profiling timer expired",
+       28: "window changed",
+       29: "I/O possible",
+       30: "power failure",
+       31: "bad system call",
+}
diff --git a/src/syscall/zsyscall_linux_power64.go b/src/syscall/zsyscall_linux_power64.go
new file mode 100644 (file)
index 0000000..7808059
--- /dev/null
@@ -0,0 +1,1931 @@
+// mksyscall.pl syscall_linux.go syscall_linux_power64x.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int, perm uint32) (fd int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+       _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+       _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, times *[2]Timeval) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) {
+       _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(buf) > 0 {
+               _p0 = unsafe.Pointer(&buf[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+       r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+       wpid = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+       _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(arg)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(source)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(target)
+       if err != nil {
+               return
+       }
+       var _p2 *byte
+       _p2, err = BytePtrFromString(fstype)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Acct(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtimex(buf *Timex) (state int, err error) {
+       r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
+       state = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+       _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Creat(path string, mode uint32) (fd int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       r0, _, e1 := Syscall(SYS_CREAT, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_DUP, uintptr(oldfd), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(oldfd int, newfd int) (err error) {
+       _, _, e1 := RawSyscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(oldfd int, newfd int, flags int) (err error) {
+       _, _, e1 := RawSyscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate(size int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate1(flag int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+       _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(events) > 0 {
+               _p0 = unsafe.Pointer(&events[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+       Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
+       _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+       _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+       _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+       r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+       val = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fdatasync(fd int) (err error) {
+       _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+       _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+       _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(buf) > 0 {
+               _p0 = unsafe.Pointer(&buf[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+       r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+       pgid = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pid int) {
+       r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+       pid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+       r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+       pid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+       r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+       ppid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+       r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+       prio = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettid() (tid int) {
+       r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0)
+       tid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(attr)
+       if err != nil {
+               return
+       }
+       var _p2 unsafe.Pointer
+       if len(dest) > 0 {
+               _p2 = unsafe.Pointer(&dest[0])
+       } else {
+               _p2 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
+       sz = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(pathname)
+       if err != nil {
+               return
+       }
+       r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
+       watchdesc = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit() (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit1(flags int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+       r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
+       success = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+       _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Klogctl(typ int, buf []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(buf) > 0 {
+               _p0 = unsafe.Pointer(&buf[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(oldpath string, newpath string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(oldpath)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(newpath)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listxattr(path string, dest []byte) (sz int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 unsafe.Pointer
+       if len(dest) > 0 {
+               _p1 = unsafe.Pointer(&dest[0])
+       } else {
+               _p1 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+       sz = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+       _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pause() (err error) {
+       _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func PivotRoot(newroot string, putold string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(newroot)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(putold)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) {
+       _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 unsafe.Pointer
+       if len(buf) > 0 {
+               _p1 = unsafe.Pointer(&buf[0])
+       } else {
+               _p1 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Removexattr(path string, attr string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(attr)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(oldpath string, newpath string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(oldpath)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(newpath)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(oldpath)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(newpath)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setdomainname(p []byte) (err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sethostname(p []byte) (err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+       r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+       pid = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tv *Timeval) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+       _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setxattr(path string, attr string, data []byte, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(attr)
+       if err != nil {
+               return
+       }
+       var _p2 unsafe.Pointer
+       if len(data) > 0 {
+               _p2 = unsafe.Pointer(&data[0])
+       } else {
+               _p2 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(oldpath string, newpath string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(oldpath)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(newpath)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() {
+       Syscall(SYS_SYNC, 0, 0, 0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sysinfo(info *Sysinfo_t) (err error) {
+       _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
+       r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
+       n = int64(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tgkill(tgid int, tid int, sig Signal) (err error) {
+       _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+       r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
+       ticks = uintptr(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(mask int) (oldmask int) {
+       r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0)
+       oldmask = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+       _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlinkat(dirfd int, path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(target string, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(target)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unshare(flags int) (err error) {
+       _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ustat(dev int, ubuf *Ustat_t) (err error) {
+       _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Utime(path string, buf *Utimbuf) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exitThread(code int) (err error) {
+       _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, p *byte, np int) (n int, err error) {
+       r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, p *byte, np int) (n int, err error) {
+       r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+       _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, advice int) (err error) {
+       var _p0 unsafe.Pointer
+       if len(b) > 0 {
+               _p0 = unsafe.Pointer(&b[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+       var _p0 unsafe.Pointer
+       if len(b) > 0 {
+               _p0 = unsafe.Pointer(&b[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+       var _p0 unsafe.Pointer
+       if len(b) > 0 {
+               _p0 = unsafe.Pointer(&b[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+       var _p0 unsafe.Pointer
+       if len(b) > 0 {
+               _p0 = unsafe.Pointer(&b[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+       _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+       _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+       _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+       _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, buf *Statfs_t) (err error) {
+       _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+       _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+       r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+       egid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+       r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+       euid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+       r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+       gid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+       _, _, e1 := RawSyscall(SYS_UGETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+       r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+       uid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ioperm(from int, num int, on int) (err error) {
+       _, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Iopl(level int) (err error) {
+       _, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+       _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (off int64, err error) {
+       r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+       off = int64(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+       r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+       r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
+       written = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsgid(gid int) (err error) {
+       _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsuid(uid int) (err error) {
+       _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(resource int, rlim *Rlimit) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(fd int, how int) (err error) {
+       _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
+       r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
+       n = int64(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, buf *Statfs_t) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
+       _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+       r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+       r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+       _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+       _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+       r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+       nn = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(n int, list *_Gid_t) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+       _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+       _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+       _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+       var _p0 unsafe.Pointer
+       if len(buf) > 0 {
+               _p0 = unsafe.Pointer(&buf[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+       r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+       r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
+       r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
+       xaddr = uintptr(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Time(t *Time_t) (tt Time_t, err error) {
+       r0, _, e1 := RawSyscall(SYS_TIME, uintptr(unsafe.Pointer(t)), 0, 0)
+       tt = Time_t(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
diff --git a/src/syscall/zsyscall_linux_power64le.go b/src/syscall/zsyscall_linux_power64le.go
new file mode 100644 (file)
index 0000000..7808059
--- /dev/null
@@ -0,0 +1,1931 @@
+// mksyscall.pl syscall_linux.go syscall_linux_power64x.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int, perm uint32) (fd int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+       _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+       _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, times *[2]Timeval) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) {
+       _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(buf) > 0 {
+               _p0 = unsafe.Pointer(&buf[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+       r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+       wpid = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+       _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(arg)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(source)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(target)
+       if err != nil {
+               return
+       }
+       var _p2 *byte
+       _p2, err = BytePtrFromString(fstype)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Acct(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtimex(buf *Timex) (state int, err error) {
+       r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
+       state = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+       _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Creat(path string, mode uint32) (fd int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       r0, _, e1 := Syscall(SYS_CREAT, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_DUP, uintptr(oldfd), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(oldfd int, newfd int) (err error) {
+       _, _, e1 := RawSyscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(oldfd int, newfd int, flags int) (err error) {
+       _, _, e1 := RawSyscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate(size int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate1(flag int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+       _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(events) > 0 {
+               _p0 = unsafe.Pointer(&events[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+       Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
+       _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+       _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+       _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+       r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+       val = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fdatasync(fd int) (err error) {
+       _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+       _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+       _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(buf) > 0 {
+               _p0 = unsafe.Pointer(&buf[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+       r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+       pgid = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pid int) {
+       r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+       pid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+       r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+       pid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+       r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+       ppid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+       r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+       prio = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettid() (tid int) {
+       r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0)
+       tid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(attr)
+       if err != nil {
+               return
+       }
+       var _p2 unsafe.Pointer
+       if len(dest) > 0 {
+               _p2 = unsafe.Pointer(&dest[0])
+       } else {
+               _p2 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
+       sz = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(pathname)
+       if err != nil {
+               return
+       }
+       r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
+       watchdesc = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit() (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit1(flags int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+       r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
+       success = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+       _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Klogctl(typ int, buf []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(buf) > 0 {
+               _p0 = unsafe.Pointer(&buf[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(oldpath string, newpath string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(oldpath)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(newpath)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listxattr(path string, dest []byte) (sz int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 unsafe.Pointer
+       if len(dest) > 0 {
+               _p1 = unsafe.Pointer(&dest[0])
+       } else {
+               _p1 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+       sz = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+       _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pause() (err error) {
+       _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func PivotRoot(newroot string, putold string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(newroot)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(putold)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) {
+       _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 unsafe.Pointer
+       if len(buf) > 0 {
+               _p1 = unsafe.Pointer(&buf[0])
+       } else {
+               _p1 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Removexattr(path string, attr string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(attr)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(oldpath string, newpath string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(oldpath)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(newpath)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(oldpath)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(newpath)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setdomainname(p []byte) (err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sethostname(p []byte) (err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+       r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+       pid = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tv *Timeval) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+       _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setxattr(path string, attr string, data []byte, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(attr)
+       if err != nil {
+               return
+       }
+       var _p2 unsafe.Pointer
+       if len(data) > 0 {
+               _p2 = unsafe.Pointer(&data[0])
+       } else {
+               _p2 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(oldpath string, newpath string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(oldpath)
+       if err != nil {
+               return
+       }
+       var _p1 *byte
+       _p1, err = BytePtrFromString(newpath)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() {
+       Syscall(SYS_SYNC, 0, 0, 0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sysinfo(info *Sysinfo_t) (err error) {
+       _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
+       r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
+       n = int64(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tgkill(tgid int, tid int, sig Signal) (err error) {
+       _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+       r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
+       ticks = uintptr(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(mask int) (oldmask int) {
+       r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0)
+       oldmask = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+       _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlinkat(dirfd int, path string) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(target string, flags int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(target)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unshare(flags int) (err error) {
+       _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ustat(dev int, ubuf *Ustat_t) (err error) {
+       _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Utime(path string, buf *Utimbuf) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exitThread(code int) (err error) {
+       _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, p *byte, np int) (n int, err error) {
+       r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, p *byte, np int) (n int, err error) {
+       r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+       _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, advice int) (err error) {
+       var _p0 unsafe.Pointer
+       if len(b) > 0 {
+               _p0 = unsafe.Pointer(&b[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+       var _p0 unsafe.Pointer
+       if len(b) > 0 {
+               _p0 = unsafe.Pointer(&b[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+       var _p0 unsafe.Pointer
+       if len(b) > 0 {
+               _p0 = unsafe.Pointer(&b[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+       var _p0 unsafe.Pointer
+       if len(b) > 0 {
+               _p0 = unsafe.Pointer(&b[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+       _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+       _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+       _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+       _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, buf *Statfs_t) (err error) {
+       _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+       _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+       r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+       egid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+       r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+       euid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+       r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+       gid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+       _, _, e1 := RawSyscall(SYS_UGETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+       r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+       uid = int(r0)
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ioperm(from int, num int, on int) (err error) {
+       _, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Iopl(level int) (err error) {
+       _, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+       _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (off int64, err error) {
+       r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+       off = int64(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+       r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+       r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
+       written = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsgid(gid int) (err error) {
+       _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsuid(uid int) (err error) {
+       _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(resource int, rlim *Rlimit) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(fd int, how int) (err error) {
+       _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
+       r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
+       n = int64(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, buf *Statfs_t) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
+       _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+       var _p0 *byte
+       _p0, err = BytePtrFromString(path)
+       if err != nil {
+               return
+       }
+       _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+       r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+       r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+       _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+       _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+       r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+       nn = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(n int, list *_Gid_t) (err error) {
+       _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+       _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+       _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+       fd = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+       _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+       var _p0 unsafe.Pointer
+       if len(p) > 0 {
+               _p0 = unsafe.Pointer(&p[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+       var _p0 unsafe.Pointer
+       if len(buf) > 0 {
+               _p0 = unsafe.Pointer(&buf[0])
+       } else {
+               _p0 = unsafe.Pointer(&_zero)
+       }
+       _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+       r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+       r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+       n = int(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
+       r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
+       xaddr = uintptr(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Time(t *Time_t) (tt Time_t, err error) {
+       r0, _, e1 := RawSyscall(SYS_TIME, uintptr(unsafe.Pointer(t)), 0, 0)
+       tt = Time_t(r0)
+       if e1 != 0 {
+               err = e1
+       }
+       return
+}
diff --git a/src/syscall/zsysnum_linux_power64.go b/src/syscall/zsysnum_linux_power64.go
new file mode 100644 (file)
index 0000000..0567fd0
--- /dev/null
@@ -0,0 +1,351 @@
+// mksysnum_linux.pl /usr/include/asm/unistd.h
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package syscall
+
+const (
+       SYS_RESTART_SYSCALL        = 0
+       SYS_EXIT                   = 1
+       SYS_FORK                   = 2
+       SYS_READ                   = 3
+       SYS_WRITE                  = 4
+       SYS_OPEN                   = 5
+       SYS_CLOSE                  = 6
+       SYS_WAITPID                = 7
+       SYS_CREAT                  = 8
+       SYS_LINK                   = 9
+       SYS_UNLINK                 = 10
+       SYS_EXECVE                 = 11
+       SYS_CHDIR                  = 12
+       SYS_TIME                   = 13
+       SYS_MKNOD                  = 14
+       SYS_CHMOD                  = 15
+       SYS_LCHOWN                 = 16
+       SYS_BREAK                  = 17
+       SYS_OLDSTAT                = 18
+       SYS_LSEEK                  = 19
+       SYS_GETPID                 = 20
+       SYS_MOUNT                  = 21
+       SYS_UMOUNT                 = 22
+       SYS_SETUID                 = 23
+       SYS_GETUID                 = 24
+       SYS_STIME                  = 25
+       SYS_PTRACE                 = 26
+       SYS_ALARM                  = 27
+       SYS_OLDFSTAT               = 28
+       SYS_PAUSE                  = 29
+       SYS_UTIME                  = 30
+       SYS_STTY                   = 31
+       SYS_GTTY                   = 32
+       SYS_ACCESS                 = 33
+       SYS_NICE                   = 34
+       SYS_FTIME                  = 35
+       SYS_SYNC                   = 36
+       SYS_KILL                   = 37
+       SYS_RENAME                 = 38
+       SYS_MKDIR                  = 39
+       SYS_RMDIR                  = 40
+       SYS_DUP                    = 41
+       SYS_PIPE                   = 42
+       SYS_TIMES                  = 43
+       SYS_PROF                   = 44
+       SYS_BRK                    = 45
+       SYS_SETGID                 = 46
+       SYS_GETGID                 = 47
+       SYS_SIGNAL                 = 48
+       SYS_GETEUID                = 49
+       SYS_GETEGID                = 50
+       SYS_ACCT                   = 51
+       SYS_UMOUNT2                = 52
+       SYS_LOCK                   = 53
+       SYS_IOCTL                  = 54
+       SYS_FCNTL                  = 55
+       SYS_MPX                    = 56
+       SYS_SETPGID                = 57
+       SYS_ULIMIT                 = 58
+       SYS_OLDOLDUNAME            = 59
+       SYS_UMASK                  = 60
+       SYS_CHROOT                 = 61
+       SYS_USTAT                  = 62
+       SYS_DUP2                   = 63
+       SYS_GETPPID                = 64
+       SYS_GETPGRP                = 65
+       SYS_SETSID                 = 66
+       SYS_SIGACTION              = 67
+       SYS_SGETMASK               = 68
+       SYS_SSETMASK               = 69
+       SYS_SETREUID               = 70
+       SYS_SETREGID               = 71
+       SYS_SIGSUSPEND             = 72
+       SYS_SIGPENDING             = 73
+       SYS_SETHOSTNAME            = 74
+       SYS_SETRLIMIT              = 75
+       SYS_GETRLIMIT              = 76
+       SYS_GETRUSAGE              = 77
+       SYS_GETTIMEOFDAY           = 78
+       SYS_SETTIMEOFDAY           = 79
+       SYS_GETGROUPS              = 80
+       SYS_SETGROUPS              = 81
+       SYS_SELECT                 = 82
+       SYS_SYMLINK                = 83
+       SYS_OLDLSTAT               = 84
+       SYS_READLINK               = 85
+       SYS_USELIB                 = 86
+       SYS_SWAPON                 = 87
+       SYS_REBOOT                 = 88
+       SYS_READDIR                = 89
+       SYS_MMAP                   = 90
+       SYS_MUNMAP                 = 91
+       SYS_TRUNCATE               = 92
+       SYS_FTRUNCATE              = 93
+       SYS_FCHMOD                 = 94
+       SYS_FCHOWN                 = 95
+       SYS_GETPRIORITY            = 96
+       SYS_SETPRIORITY            = 97
+       SYS_PROFIL                 = 98
+       SYS_STATFS                 = 99
+       SYS_FSTATFS                = 100
+       SYS_IOPERM                 = 101
+       SYS_SOCKETCALL             = 102
+       SYS_SYSLOG                 = 103
+       SYS_SETITIMER              = 104
+       SYS_GETITIMER              = 105
+       SYS_STAT                   = 106
+       SYS_LSTAT                  = 107
+       SYS_FSTAT                  = 108
+       SYS_OLDUNAME               = 109
+       SYS_IOPL                   = 110
+       SYS_VHANGUP                = 111
+       SYS_IDLE                   = 112
+       SYS_VM86                   = 113
+       SYS_WAIT4                  = 114
+       SYS_SWAPOFF                = 115
+       SYS_SYSINFO                = 116
+       SYS_IPC                    = 117
+       SYS_FSYNC                  = 118
+       SYS_SIGRETURN              = 119
+       SYS_CLONE                  = 120
+       SYS_SETDOMAINNAME          = 121
+       SYS_UNAME                  = 122
+       SYS_MODIFY_LDT             = 123
+       SYS_ADJTIMEX               = 124
+       SYS_MPROTECT               = 125
+       SYS_SIGPROCMASK            = 126
+       SYS_CREATE_MODULE          = 127
+       SYS_INIT_MODULE            = 128
+       SYS_DELETE_MODULE          = 129
+       SYS_GET_KERNEL_SYMS        = 130
+       SYS_QUOTACTL               = 131
+       SYS_GETPGID                = 132
+       SYS_FCHDIR                 = 133
+       SYS_BDFLUSH                = 134
+       SYS_SYSFS                  = 135
+       SYS_PERSONALITY            = 136
+       SYS_AFS_SYSCALL            = 137
+       SYS_SETFSUID               = 138
+       SYS_SETFSGID               = 139
+       SYS__LLSEEK                = 140
+       SYS_GETDENTS               = 141
+       SYS__NEWSELECT             = 142
+       SYS_FLOCK                  = 143
+       SYS_MSYNC                  = 144
+       SYS_READV                  = 145
+       SYS_WRITEV                 = 146
+       SYS_GETSID                 = 147
+       SYS_FDATASYNC              = 148
+       SYS__SYSCTL                = 149
+       SYS_MLOCK                  = 150
+       SYS_MUNLOCK                = 151
+       SYS_MLOCKALL               = 152
+       SYS_MUNLOCKALL             = 153
+       SYS_SCHED_SETPARAM         = 154
+       SYS_SCHED_GETPARAM         = 155
+       SYS_SCHED_SETSCHEDULER     = 156
+       SYS_SCHED_GETSCHEDULER     = 157
+       SYS_SCHED_YIELD            = 158
+       SYS_SCHED_GET_PRIORITY_MAX = 159
+       SYS_SCHED_GET_PRIORITY_MIN = 160
+       SYS_SCHED_RR_GET_INTERVAL  = 161
+       SYS_NANOSLEEP              = 162
+       SYS_MREMAP                 = 163
+       SYS_SETRESUID              = 164
+       SYS_GETRESUID              = 165
+       SYS_QUERY_MODULE           = 166
+       SYS_POLL                   = 167
+       SYS_NFSSERVCTL             = 168
+       SYS_SETRESGID              = 169
+       SYS_GETRESGID              = 170
+       SYS_PRCTL                  = 171
+       SYS_RT_SIGRETURN           = 172
+       SYS_RT_SIGACTION           = 173
+       SYS_RT_SIGPROCMASK         = 174
+       SYS_RT_SIGPENDING          = 175
+       SYS_RT_SIGTIMEDWAIT        = 176
+       SYS_RT_SIGQUEUEINFO        = 177
+       SYS_RT_SIGSUSPEND          = 178
+       SYS_PREAD64                = 179
+       SYS_PWRITE64               = 180
+       SYS_CHOWN                  = 181
+       SYS_GETCWD                 = 182
+       SYS_CAPGET                 = 183
+       SYS_CAPSET                 = 184
+       SYS_SIGALTSTACK            = 185
+       SYS_SENDFILE               = 186
+       SYS_GETPMSG                = 187
+       SYS_PUTPMSG                = 188
+       SYS_VFORK                  = 189
+       SYS_UGETRLIMIT             = 190
+       SYS_READAHEAD              = 191
+       SYS_PCICONFIG_READ         = 198
+       SYS_PCICONFIG_WRITE        = 199
+       SYS_PCICONFIG_IOBASE       = 200
+       SYS_MULTIPLEXER            = 201
+       SYS_GETDENTS64             = 202
+       SYS_PIVOT_ROOT             = 203
+       SYS_MADVISE                = 205
+       SYS_MINCORE                = 206
+       SYS_GETTID                 = 207
+       SYS_TKILL                  = 208
+       SYS_SETXATTR               = 209
+       SYS_LSETXATTR              = 210
+       SYS_FSETXATTR              = 211
+       SYS_GETXATTR               = 212
+       SYS_LGETXATTR              = 213
+       SYS_FGETXATTR              = 214
+       SYS_LISTXATTR              = 215
+       SYS_LLISTXATTR             = 216
+       SYS_FLISTXATTR             = 217
+       SYS_REMOVEXATTR            = 218
+       SYS_LREMOVEXATTR           = 219
+       SYS_FREMOVEXATTR           = 220
+       SYS_FUTEX                  = 221
+       SYS_SCHED_SETAFFINITY      = 222
+       SYS_SCHED_GETAFFINITY      = 223
+       SYS_TUXCALL                = 225
+       SYS_IO_SETUP               = 227
+       SYS_IO_DESTROY             = 228
+       SYS_IO_GETEVENTS           = 229
+       SYS_IO_SUBMIT              = 230
+       SYS_IO_CANCEL              = 231
+       SYS_SET_TID_ADDRESS        = 232
+       SYS_FADVISE64              = 233
+       SYS_EXIT_GROUP             = 234
+       SYS_LOOKUP_DCOOKIE         = 235
+       SYS_EPOLL_CREATE           = 236
+       SYS_EPOLL_CTL              = 237
+       SYS_EPOLL_WAIT             = 238
+       SYS_REMAP_FILE_PAGES       = 239
+       SYS_TIMER_CREATE           = 240
+       SYS_TIMER_SETTIME          = 241
+       SYS_TIMER_GETTIME          = 242
+       SYS_TIMER_GETOVERRUN       = 243
+       SYS_TIMER_DELETE           = 244
+       SYS_CLOCK_SETTIME          = 245
+       SYS_CLOCK_GETTIME          = 246
+       SYS_CLOCK_GETRES           = 247
+       SYS_CLOCK_NANOSLEEP        = 248
+       SYS_SWAPCONTEXT            = 249
+       SYS_TGKILL                 = 250
+       SYS_UTIMES                 = 251
+       SYS_STATFS64               = 252
+       SYS_FSTATFS64              = 253
+       SYS_RTAS                   = 255
+       SYS_SYS_DEBUG_SETCONTEXT   = 256
+       SYS_MIGRATE_PAGES          = 258
+       SYS_MBIND                  = 259
+       SYS_GET_MEMPOLICY          = 260
+       SYS_SET_MEMPOLICY          = 261
+       SYS_MQ_OPEN                = 262
+       SYS_MQ_UNLINK              = 263
+       SYS_MQ_TIMEDSEND           = 264
+       SYS_MQ_TIMEDRECEIVE        = 265
+       SYS_MQ_NOTIFY              = 266
+       SYS_MQ_GETSETATTR          = 267
+       SYS_KEXEC_LOAD             = 268
+       SYS_ADD_KEY                = 269
+       SYS_REQUEST_KEY            = 270
+       SYS_KEYCTL                 = 271
+       SYS_WAITID                 = 272
+       SYS_IOPRIO_SET             = 273
+       SYS_IOPRIO_GET             = 274
+       SYS_INOTIFY_INIT           = 275
+       SYS_INOTIFY_ADD_WATCH      = 276
+       SYS_INOTIFY_RM_WATCH       = 277
+       SYS_SPU_RUN                = 278
+       SYS_SPU_CREATE             = 279
+       SYS_PSELECT6               = 280
+       SYS_PPOLL                  = 281
+       SYS_UNSHARE                = 282
+       SYS_SPLICE                 = 283
+       SYS_TEE                    = 284
+       SYS_VMSPLICE               = 285
+       SYS_OPENAT                 = 286
+       SYS_MKDIRAT                = 287
+       SYS_MKNODAT                = 288
+       SYS_FCHOWNAT               = 289
+       SYS_FUTIMESAT              = 290
+       SYS_NEWFSTATAT             = 291
+       SYS_UNLINKAT               = 292
+       SYS_RENAMEAT               = 293
+       SYS_LINKAT                 = 294
+       SYS_SYMLINKAT              = 295
+       SYS_READLINKAT             = 296
+       SYS_FCHMODAT               = 297
+       SYS_FACCESSAT              = 298
+       SYS_GET_ROBUST_LIST        = 299
+       SYS_SET_ROBUST_LIST        = 300
+       SYS_MOVE_PAGES             = 301
+       SYS_GETCPU                 = 302
+       SYS_EPOLL_PWAIT            = 303
+       SYS_UTIMENSAT              = 304
+       SYS_SIGNALFD               = 305
+       SYS_TIMERFD_CREATE         = 306
+       SYS_EVENTFD                = 307
+       SYS_SYNC_FILE_RANGE2       = 308
+       SYS_FALLOCATE              = 309
+       SYS_SUBPAGE_PROT           = 310
+       SYS_TIMERFD_SETTIME        = 311
+       SYS_TIMERFD_GETTIME        = 312
+       SYS_SIGNALFD4              = 313
+       SYS_EVENTFD2               = 314
+       SYS_EPOLL_CREATE1          = 315
+       SYS_DUP3                   = 316
+       SYS_PIPE2                  = 317
+       SYS_INOTIFY_INIT1          = 318
+       SYS_PERF_EVENT_OPEN        = 319
+       SYS_PREADV                 = 320
+       SYS_PWRITEV                = 321
+       SYS_RT_TGSIGQUEUEINFO      = 322
+       SYS_FANOTIFY_INIT          = 323
+       SYS_FANOTIFY_MARK          = 324
+       SYS_PRLIMIT64              = 325
+       SYS_SOCKET                 = 326
+       SYS_BIND                   = 327
+       SYS_CONNECT                = 328
+       SYS_LISTEN                 = 329
+       SYS_ACCEPT                 = 330
+       SYS_GETSOCKNAME            = 331
+       SYS_GETPEERNAME            = 332
+       SYS_SOCKETPAIR             = 333
+       SYS_SEND                   = 334
+       SYS_SENDTO                 = 335
+       SYS_RECV                   = 336
+       SYS_RECVFROM               = 337
+       SYS_SHUTDOWN               = 338
+       SYS_SETSOCKOPT             = 339
+       SYS_GETSOCKOPT             = 340
+       SYS_SENDMSG                = 341
+       SYS_RECVMSG                = 342
+       SYS_RECVMMSG               = 343
+       SYS_ACCEPT4                = 344
+       SYS_NAME_TO_HANDLE_AT      = 345
+       SYS_OPEN_BY_HANDLE_AT      = 346
+       SYS_CLOCK_ADJTIME          = 347
+       SYS_SYNCFS                 = 348
+       SYS_SENDMMSG               = 349
+       SYS_SETNS                  = 350
+       SYS_PROCESS_VM_READV       = 351
+       SYS_PROCESS_VM_WRITEV      = 352
+       SYS_FINIT_MODULE           = 353
+       SYS_KCMP                   = 354
+)
diff --git a/src/syscall/zsysnum_linux_power64le.go b/src/syscall/zsysnum_linux_power64le.go
new file mode 100644 (file)
index 0000000..52c63e3
--- /dev/null
@@ -0,0 +1,351 @@
+// mksysnum_linux.pl /usr/include/powerpc64le-linux-gnu/asm/unistd.h
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package syscall
+
+const (
+       SYS_RESTART_SYSCALL        = 0
+       SYS_EXIT                   = 1
+       SYS_FORK                   = 2
+       SYS_READ                   = 3
+       SYS_WRITE                  = 4
+       SYS_OPEN                   = 5
+       SYS_CLOSE                  = 6
+       SYS_WAITPID                = 7
+       SYS_CREAT                  = 8
+       SYS_LINK                   = 9
+       SYS_UNLINK                 = 10
+       SYS_EXECVE                 = 11
+       SYS_CHDIR                  = 12
+       SYS_TIME                   = 13
+       SYS_MKNOD                  = 14
+       SYS_CHMOD                  = 15
+       SYS_LCHOWN                 = 16
+       SYS_BREAK                  = 17
+       SYS_OLDSTAT                = 18
+       SYS_LSEEK                  = 19
+       SYS_GETPID                 = 20
+       SYS_MOUNT                  = 21
+       SYS_UMOUNT                 = 22
+       SYS_SETUID                 = 23
+       SYS_GETUID                 = 24
+       SYS_STIME                  = 25
+       SYS_PTRACE                 = 26
+       SYS_ALARM                  = 27
+       SYS_OLDFSTAT               = 28
+       SYS_PAUSE                  = 29
+       SYS_UTIME                  = 30
+       SYS_STTY                   = 31
+       SYS_GTTY                   = 32
+       SYS_ACCESS                 = 33
+       SYS_NICE                   = 34
+       SYS_FTIME                  = 35
+       SYS_SYNC                   = 36
+       SYS_KILL                   = 37
+       SYS_RENAME                 = 38
+       SYS_MKDIR                  = 39
+       SYS_RMDIR                  = 40
+       SYS_DUP                    = 41
+       SYS_PIPE                   = 42
+       SYS_TIMES                  = 43
+       SYS_PROF                   = 44
+       SYS_BRK                    = 45
+       SYS_SETGID                 = 46
+       SYS_GETGID                 = 47
+       SYS_SIGNAL                 = 48
+       SYS_GETEUID                = 49
+       SYS_GETEGID                = 50
+       SYS_ACCT                   = 51
+       SYS_UMOUNT2                = 52
+       SYS_LOCK                   = 53
+       SYS_IOCTL                  = 54
+       SYS_FCNTL                  = 55
+       SYS_MPX                    = 56
+       SYS_SETPGID                = 57
+       SYS_ULIMIT                 = 58
+       SYS_OLDOLDUNAME            = 59
+       SYS_UMASK                  = 60
+       SYS_CHROOT                 = 61
+       SYS_USTAT                  = 62
+       SYS_DUP2                   = 63
+       SYS_GETPPID                = 64
+       SYS_GETPGRP                = 65
+       SYS_SETSID                 = 66
+       SYS_SIGACTION              = 67
+       SYS_SGETMASK               = 68
+       SYS_SSETMASK               = 69
+       SYS_SETREUID               = 70
+       SYS_SETREGID               = 71
+       SYS_SIGSUSPEND             = 72
+       SYS_SIGPENDING             = 73
+       SYS_SETHOSTNAME            = 74
+       SYS_SETRLIMIT              = 75
+       SYS_GETRLIMIT              = 76
+       SYS_GETRUSAGE              = 77
+       SYS_GETTIMEOFDAY           = 78
+       SYS_SETTIMEOFDAY           = 79
+       SYS_GETGROUPS              = 80
+       SYS_SETGROUPS              = 81
+       SYS_SELECT                 = 82
+       SYS_SYMLINK                = 83
+       SYS_OLDLSTAT               = 84
+       SYS_READLINK               = 85
+       SYS_USELIB                 = 86
+       SYS_SWAPON                 = 87
+       SYS_REBOOT                 = 88
+       SYS_READDIR                = 89
+       SYS_MMAP                   = 90
+       SYS_MUNMAP                 = 91
+       SYS_TRUNCATE               = 92
+       SYS_FTRUNCATE              = 93
+       SYS_FCHMOD                 = 94
+       SYS_FCHOWN                 = 95
+       SYS_GETPRIORITY            = 96
+       SYS_SETPRIORITY            = 97
+       SYS_PROFIL                 = 98
+       SYS_STATFS                 = 99
+       SYS_FSTATFS                = 100
+       SYS_IOPERM                 = 101
+       SYS_SOCKETCALL             = 102
+       SYS_SYSLOG                 = 103
+       SYS_SETITIMER              = 104
+       SYS_GETITIMER              = 105
+       SYS_STAT                   = 106
+       SYS_LSTAT                  = 107
+       SYS_FSTAT                  = 108
+       SYS_OLDUNAME               = 109
+       SYS_IOPL                   = 110
+       SYS_VHANGUP                = 111
+       SYS_IDLE                   = 112
+       SYS_VM86                   = 113
+       SYS_WAIT4                  = 114
+       SYS_SWAPOFF                = 115
+       SYS_SYSINFO                = 116
+       SYS_IPC                    = 117
+       SYS_FSYNC                  = 118
+       SYS_SIGRETURN              = 119
+       SYS_CLONE                  = 120
+       SYS_SETDOMAINNAME          = 121
+       SYS_UNAME                  = 122
+       SYS_MODIFY_LDT             = 123
+       SYS_ADJTIMEX               = 124
+       SYS_MPROTECT               = 125
+       SYS_SIGPROCMASK            = 126
+       SYS_CREATE_MODULE          = 127
+       SYS_INIT_MODULE            = 128
+       SYS_DELETE_MODULE          = 129
+       SYS_GET_KERNEL_SYMS        = 130
+       SYS_QUOTACTL               = 131
+       SYS_GETPGID                = 132
+       SYS_FCHDIR                 = 133
+       SYS_BDFLUSH                = 134
+       SYS_SYSFS                  = 135
+       SYS_PERSONALITY            = 136
+       SYS_AFS_SYSCALL            = 137
+       SYS_SETFSUID               = 138
+       SYS_SETFSGID               = 139
+       SYS__LLSEEK                = 140
+       SYS_GETDENTS               = 141
+       SYS__NEWSELECT             = 142
+       SYS_FLOCK                  = 143
+       SYS_MSYNC                  = 144
+       SYS_READV                  = 145
+       SYS_WRITEV                 = 146
+       SYS_GETSID                 = 147
+       SYS_FDATASYNC              = 148
+       SYS__SYSCTL                = 149
+       SYS_MLOCK                  = 150
+       SYS_MUNLOCK                = 151
+       SYS_MLOCKALL               = 152
+       SYS_MUNLOCKALL             = 153
+       SYS_SCHED_SETPARAM         = 154
+       SYS_SCHED_GETPARAM         = 155
+       SYS_SCHED_SETSCHEDULER     = 156
+       SYS_SCHED_GETSCHEDULER     = 157
+       SYS_SCHED_YIELD            = 158
+       SYS_SCHED_GET_PRIORITY_MAX = 159
+       SYS_SCHED_GET_PRIORITY_MIN = 160
+       SYS_SCHED_RR_GET_INTERVAL  = 161
+       SYS_NANOSLEEP              = 162
+       SYS_MREMAP                 = 163
+       SYS_SETRESUID              = 164
+       SYS_GETRESUID              = 165
+       SYS_QUERY_MODULE           = 166
+       SYS_POLL                   = 167
+       SYS_NFSSERVCTL             = 168
+       SYS_SETRESGID              = 169
+       SYS_GETRESGID              = 170
+       SYS_PRCTL                  = 171
+       SYS_RT_SIGRETURN           = 172
+       SYS_RT_SIGACTION           = 173
+       SYS_RT_SIGPROCMASK         = 174
+       SYS_RT_SIGPENDING          = 175
+       SYS_RT_SIGTIMEDWAIT        = 176
+       SYS_RT_SIGQUEUEINFO        = 177
+       SYS_RT_SIGSUSPEND          = 178
+       SYS_PREAD64                = 179
+       SYS_PWRITE64               = 180
+       SYS_CHOWN                  = 181
+       SYS_GETCWD                 = 182
+       SYS_CAPGET                 = 183
+       SYS_CAPSET                 = 184
+       SYS_SIGALTSTACK            = 185
+       SYS_SENDFILE               = 186
+       SYS_GETPMSG                = 187
+       SYS_PUTPMSG                = 188
+       SYS_VFORK                  = 189
+       SYS_UGETRLIMIT             = 190
+       SYS_READAHEAD              = 191
+       SYS_PCICONFIG_READ         = 198
+       SYS_PCICONFIG_WRITE        = 199
+       SYS_PCICONFIG_IOBASE       = 200
+       SYS_MULTIPLEXER            = 201
+       SYS_GETDENTS64             = 202
+       SYS_PIVOT_ROOT             = 203
+       SYS_MADVISE                = 205
+       SYS_MINCORE                = 206
+       SYS_GETTID                 = 207
+       SYS_TKILL                  = 208
+       SYS_SETXATTR               = 209
+       SYS_LSETXATTR              = 210
+       SYS_FSETXATTR              = 211
+       SYS_GETXATTR               = 212
+       SYS_LGETXATTR              = 213
+       SYS_FGETXATTR              = 214
+       SYS_LISTXATTR              = 215
+       SYS_LLISTXATTR             = 216
+       SYS_FLISTXATTR             = 217
+       SYS_REMOVEXATTR            = 218
+       SYS_LREMOVEXATTR           = 219
+       SYS_FREMOVEXATTR           = 220
+       SYS_FUTEX                  = 221
+       SYS_SCHED_SETAFFINITY      = 222
+       SYS_SCHED_GETAFFINITY      = 223
+       SYS_TUXCALL                = 225
+       SYS_IO_SETUP               = 227
+       SYS_IO_DESTROY             = 228
+       SYS_IO_GETEVENTS           = 229
+       SYS_IO_SUBMIT              = 230
+       SYS_IO_CANCEL              = 231
+       SYS_SET_TID_ADDRESS        = 232
+       SYS_FADVISE64              = 233
+       SYS_EXIT_GROUP             = 234
+       SYS_LOOKUP_DCOOKIE         = 235
+       SYS_EPOLL_CREATE           = 236
+       SYS_EPOLL_CTL              = 237
+       SYS_EPOLL_WAIT             = 238
+       SYS_REMAP_FILE_PAGES       = 239
+       SYS_TIMER_CREATE           = 240
+       SYS_TIMER_SETTIME          = 241
+       SYS_TIMER_GETTIME          = 242
+       SYS_TIMER_GETOVERRUN       = 243
+       SYS_TIMER_DELETE           = 244
+       SYS_CLOCK_SETTIME          = 245
+       SYS_CLOCK_GETTIME          = 246
+       SYS_CLOCK_GETRES           = 247
+       SYS_CLOCK_NANOSLEEP        = 248
+       SYS_SWAPCONTEXT            = 249
+       SYS_TGKILL                 = 250
+       SYS_UTIMES                 = 251
+       SYS_STATFS64               = 252
+       SYS_FSTATFS64              = 253
+       SYS_RTAS                   = 255
+       SYS_SYS_DEBUG_SETCONTEXT   = 256
+       SYS_MIGRATE_PAGES          = 258
+       SYS_MBIND                  = 259
+       SYS_GET_MEMPOLICY          = 260
+       SYS_SET_MEMPOLICY          = 261
+       SYS_MQ_OPEN                = 262
+       SYS_MQ_UNLINK              = 263
+       SYS_MQ_TIMEDSEND           = 264
+       SYS_MQ_TIMEDRECEIVE        = 265
+       SYS_MQ_NOTIFY              = 266
+       SYS_MQ_GETSETATTR          = 267
+       SYS_KEXEC_LOAD             = 268
+       SYS_ADD_KEY                = 269
+       SYS_REQUEST_KEY            = 270
+       SYS_KEYCTL                 = 271
+       SYS_WAITID                 = 272
+       SYS_IOPRIO_SET             = 273
+       SYS_IOPRIO_GET             = 274
+       SYS_INOTIFY_INIT           = 275
+       SYS_INOTIFY_ADD_WATCH      = 276
+       SYS_INOTIFY_RM_WATCH       = 277
+       SYS_SPU_RUN                = 278
+       SYS_SPU_CREATE             = 279
+       SYS_PSELECT6               = 280
+       SYS_PPOLL                  = 281
+       SYS_UNSHARE                = 282
+       SYS_SPLICE                 = 283
+       SYS_TEE                    = 284
+       SYS_VMSPLICE               = 285
+       SYS_OPENAT                 = 286
+       SYS_MKDIRAT                = 287
+       SYS_MKNODAT                = 288
+       SYS_FCHOWNAT               = 289
+       SYS_FUTIMESAT              = 290
+       SYS_NEWFSTATAT             = 291
+       SYS_UNLINKAT               = 292
+       SYS_RENAMEAT               = 293
+       SYS_LINKAT                 = 294
+       SYS_SYMLINKAT              = 295
+       SYS_READLINKAT             = 296
+       SYS_FCHMODAT               = 297
+       SYS_FACCESSAT              = 298
+       SYS_GET_ROBUST_LIST        = 299
+       SYS_SET_ROBUST_LIST        = 300
+       SYS_MOVE_PAGES             = 301
+       SYS_GETCPU                 = 302
+       SYS_EPOLL_PWAIT            = 303
+       SYS_UTIMENSAT              = 304
+       SYS_SIGNALFD               = 305
+       SYS_TIMERFD_CREATE         = 306
+       SYS_EVENTFD                = 307
+       SYS_SYNC_FILE_RANGE2       = 308
+       SYS_FALLOCATE              = 309
+       SYS_SUBPAGE_PROT           = 310
+       SYS_TIMERFD_SETTIME        = 311
+       SYS_TIMERFD_GETTIME        = 312
+       SYS_SIGNALFD4              = 313
+       SYS_EVENTFD2               = 314
+       SYS_EPOLL_CREATE1          = 315
+       SYS_DUP3                   = 316
+       SYS_PIPE2                  = 317
+       SYS_INOTIFY_INIT1          = 318
+       SYS_PERF_EVENT_OPEN        = 319
+       SYS_PREADV                 = 320
+       SYS_PWRITEV                = 321
+       SYS_RT_TGSIGQUEUEINFO      = 322
+       SYS_FANOTIFY_INIT          = 323
+       SYS_FANOTIFY_MARK          = 324
+       SYS_PRLIMIT64              = 325
+       SYS_SOCKET                 = 326
+       SYS_BIND                   = 327
+       SYS_CONNECT                = 328
+       SYS_LISTEN                 = 329
+       SYS_ACCEPT                 = 330
+       SYS_GETSOCKNAME            = 331
+       SYS_GETPEERNAME            = 332
+       SYS_SOCKETPAIR             = 333
+       SYS_SEND                   = 334
+       SYS_SENDTO                 = 335
+       SYS_RECV                   = 336
+       SYS_RECVFROM               = 337
+       SYS_SHUTDOWN               = 338
+       SYS_SETSOCKOPT             = 339
+       SYS_GETSOCKOPT             = 340
+       SYS_SENDMSG                = 341
+       SYS_RECVMSG                = 342
+       SYS_RECVMMSG               = 343
+       SYS_ACCEPT4                = 344
+       SYS_NAME_TO_HANDLE_AT      = 345
+       SYS_OPEN_BY_HANDLE_AT      = 346
+       SYS_CLOCK_ADJTIME          = 347
+       SYS_SYNCFS                 = 348
+       SYS_SENDMMSG               = 349
+       SYS_SETNS                  = 350
+       SYS_PROCESS_VM_READV       = 351
+       SYS_PROCESS_VM_WRITEV      = 352
+       SYS_FINIT_MODULE           = 353
+       SYS_KCMP                   = 354
+)
diff --git a/src/syscall/ztypes_linux_power64.go b/src/syscall/ztypes_linux_power64.go
new file mode 100644 (file)
index 0000000..204d806
--- /dev/null
@@ -0,0 +1,602 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_linux.go
+
+package syscall
+
+const (
+       sizeofPtr      = 0x8
+       sizeofShort    = 0x2
+       sizeofInt      = 0x4
+       sizeofLong     = 0x8
+       sizeofLongLong = 0x8
+       PathMax        = 0x1000
+)
+
+type (
+       _C_short     int16
+       _C_int       int32
+       _C_long      int64
+       _C_long_long int64
+)
+
+type Timespec struct {
+       Sec  int64
+       Nsec int64
+}
+
+type Timeval struct {
+       Sec  int64
+       Usec int64
+}
+
+type Timex struct {
+       Modes     uint32
+       Pad_cgo_0 [4]byte
+       Offset    int64
+       Freq      int64
+       Maxerror  int64
+       Esterror  int64
+       Status    int32
+       Pad_cgo_1 [4]byte
+       Constant  int64
+       Precision int64
+       Tolerance int64
+       Time      Timeval
+       Tick      int64
+       Ppsfreq   int64
+       Jitter    int64
+       Shift     int32
+       Pad_cgo_2 [4]byte
+       Stabil    int64
+       Jitcnt    int64
+       Calcnt    int64
+       Errcnt    int64
+       Stbcnt    int64
+       Tai       int32
+       Pad_cgo_3 [44]byte
+}
+
+type Time_t int64
+
+type Tms struct {
+       Utime  int64
+       Stime  int64
+       Cutime int64
+       Cstime int64
+}
+
+type Utimbuf struct {
+       Actime  int64
+       Modtime int64
+}
+
+type Rusage struct {
+       Utime    Timeval
+       Stime    Timeval
+       Maxrss   int64
+       Ixrss    int64
+       Idrss    int64
+       Isrss    int64
+       Minflt   int64
+       Majflt   int64
+       Nswap    int64
+       Inblock  int64
+       Oublock  int64
+       Msgsnd   int64
+       Msgrcv   int64
+       Nsignals int64
+       Nvcsw    int64
+       Nivcsw   int64
+}
+
+type Rlimit struct {
+       Cur uint64
+       Max uint64
+}
+
+type _Gid_t uint32
+
+type Stat_t struct {
+       Dev        uint64
+       Ino        uint64
+       Nlink      uint64
+       Mode       uint32
+       Uid        uint32
+       Gid        uint32
+       X__pad2    int32
+       Rdev       uint64
+       Size       int64
+       Blksize    int64
+       Blocks     int64
+       Atim       Timespec
+       Mtim       Timespec
+       Ctim       Timespec
+       X__unused4 uint64
+       X__unused5 uint64
+       X__unused6 uint64
+}
+
+type Statfs_t struct {
+       Type    int64
+       Bsize   int64
+       Blocks  uint64
+       Bfree   uint64
+       Bavail  uint64
+       Files   uint64
+       Ffree   uint64
+       Fsid    Fsid
+       Namelen int64
+       Frsize  int64
+       Flags   int64
+       Spare   [4]int64
+}
+
+type Dirent struct {
+       Ino       uint64
+       Off       int64
+       Reclen    uint16
+       Type      uint8
+       Name      [256]uint8
+       Pad_cgo_0 [5]byte
+}
+
+type Fsid struct {
+       X__val [2]int32
+}
+
+type Flock_t struct {
+       Type      int16
+       Whence    int16
+       Pad_cgo_0 [4]byte
+       Start     int64
+       Len       int64
+       Pid       int32
+       Pad_cgo_1 [4]byte
+}
+
+type RawSockaddrInet4 struct {
+       Family uint16
+       Port   uint16
+       Addr   [4]byte /* in_addr */
+       Zero   [8]uint8
+}
+
+type RawSockaddrInet6 struct {
+       Family   uint16
+       Port     uint16
+       Flowinfo uint32
+       Addr     [16]byte /* in6_addr */
+       Scope_id uint32
+}
+
+type RawSockaddrUnix struct {
+       Family uint16
+       Path   [108]int8
+}
+
+type RawSockaddrLinklayer struct {
+       Family   uint16
+       Protocol uint16
+       Ifindex  int32
+       Hatype   uint16
+       Pkttype  uint8
+       Halen    uint8
+       Addr     [8]uint8
+}
+
+type RawSockaddrNetlink struct {
+       Family uint16
+       Pad    uint16
+       Pid    uint32
+       Groups uint32
+}
+
+type RawSockaddr struct {
+       Family uint16
+       Data   [14]uint8
+}
+
+type RawSockaddrAny struct {
+       Addr RawSockaddr
+       Pad  [96]uint8
+}
+
+type _Socklen uint32
+
+type Linger struct {
+       Onoff  int32
+       Linger int32
+}
+
+type Iovec struct {
+       Base *byte
+       Len  uint64
+}
+
+type IPMreq struct {
+       Multiaddr [4]byte /* in_addr */
+       Interface [4]byte /* in_addr */
+}
+
+type IPMreqn struct {
+       Multiaddr [4]byte /* in_addr */
+       Address   [4]byte /* in_addr */
+       Ifindex   int32
+}
+
+type IPv6Mreq struct {
+       Multiaddr [16]byte /* in6_addr */
+       Interface uint32
+}
+
+type Msghdr struct {
+       Name       *byte
+       Namelen    uint32
+       Pad_cgo_0  [4]byte
+       Iov        *Iovec
+       Iovlen     uint64
+       Control    *byte
+       Controllen uint64
+       Flags      int32
+       Pad_cgo_1  [4]byte
+}
+
+type Cmsghdr struct {
+       Len          uint64
+       Level        int32
+       Type         int32
+       X__cmsg_data [0]uint8
+}
+
+type Inet4Pktinfo struct {
+       Ifindex  int32
+       Spec_dst [4]byte /* in_addr */
+       Addr     [4]byte /* in_addr */
+}
+
+type Inet6Pktinfo struct {
+       Addr    [16]byte /* in6_addr */
+       Ifindex uint32
+}
+
+type IPv6MTUInfo struct {
+       Addr RawSockaddrInet6
+       Mtu  uint32
+}
+
+type ICMPv6Filter struct {
+       Data [8]uint32
+}
+
+type Ucred struct {
+       Pid int32
+       Uid uint32
+       Gid uint32
+}
+
+type TCPInfo struct {
+       State          uint8
+       Ca_state       uint8
+       Retransmits    uint8
+       Probes         uint8
+       Backoff        uint8
+       Options        uint8
+       Pad_cgo_0      [2]byte
+       Rto            uint32
+       Ato            uint32
+       Snd_mss        uint32
+       Rcv_mss        uint32
+       Unacked        uint32
+       Sacked         uint32
+       Lost           uint32
+       Retrans        uint32
+       Fackets        uint32
+       Last_data_sent uint32
+       Last_ack_sent  uint32
+       Last_data_recv uint32
+       Last_ack_recv  uint32
+       Pmtu           uint32
+       Rcv_ssthresh   uint32
+       Rtt            uint32
+       Rttvar         uint32
+       Snd_ssthresh   uint32
+       Snd_cwnd       uint32
+       Advmss         uint32
+       Reordering     uint32
+       Rcv_rtt        uint32
+       Rcv_space      uint32
+       Total_retrans  uint32
+}
+
+const (
+       SizeofSockaddrInet4     = 0x10
+       SizeofSockaddrInet6     = 0x1c
+       SizeofSockaddrAny       = 0x70
+       SizeofSockaddrUnix      = 0x6e
+       SizeofSockaddrLinklayer = 0x14
+       SizeofSockaddrNetlink   = 0xc
+       SizeofLinger            = 0x8
+       SizeofIPMreq            = 0x8
+       SizeofIPMreqn           = 0xc
+       SizeofIPv6Mreq          = 0x14
+       SizeofMsghdr            = 0x38
+       SizeofCmsghdr           = 0x10
+       SizeofInet4Pktinfo      = 0xc
+       SizeofInet6Pktinfo      = 0x14
+       SizeofIPv6MTUInfo       = 0x20
+       SizeofICMPv6Filter      = 0x20
+       SizeofUcred             = 0xc
+       SizeofTCPInfo           = 0x68
+)
+
+const (
+       IFA_UNSPEC          = 0x0
+       IFA_ADDRESS         = 0x1
+       IFA_LOCAL           = 0x2
+       IFA_LABEL           = 0x3
+       IFA_BROADCAST       = 0x4
+       IFA_ANYCAST         = 0x5
+       IFA_CACHEINFO       = 0x6
+       IFA_MULTICAST       = 0x7
+       IFLA_UNSPEC         = 0x0
+       IFLA_ADDRESS        = 0x1
+       IFLA_BROADCAST      = 0x2
+       IFLA_IFNAME         = 0x3
+       IFLA_MTU            = 0x4
+       IFLA_LINK           = 0x5
+       IFLA_QDISC          = 0x6
+       IFLA_STATS          = 0x7
+       IFLA_COST           = 0x8
+       IFLA_PRIORITY       = 0x9
+       IFLA_MASTER         = 0xa
+       IFLA_WIRELESS       = 0xb
+       IFLA_PROTINFO       = 0xc
+       IFLA_TXQLEN         = 0xd
+       IFLA_MAP            = 0xe
+       IFLA_WEIGHT         = 0xf
+       IFLA_OPERSTATE      = 0x10
+       IFLA_LINKMODE       = 0x11
+       IFLA_LINKINFO       = 0x12
+       IFLA_NET_NS_PID     = 0x13
+       IFLA_IFALIAS        = 0x14
+       IFLA_MAX            = 0x22
+       RT_SCOPE_UNIVERSE   = 0x0
+       RT_SCOPE_SITE       = 0xc8
+       RT_SCOPE_LINK       = 0xfd
+       RT_SCOPE_HOST       = 0xfe
+       RT_SCOPE_NOWHERE    = 0xff
+       RT_TABLE_UNSPEC     = 0x0
+       RT_TABLE_COMPAT     = 0xfc
+       RT_TABLE_DEFAULT    = 0xfd
+       RT_TABLE_MAIN       = 0xfe
+       RT_TABLE_LOCAL      = 0xff
+       RT_TABLE_MAX        = 0xffffffff
+       RTA_UNSPEC          = 0x0
+       RTA_DST             = 0x1
+       RTA_SRC             = 0x2
+       RTA_IIF             = 0x3
+       RTA_OIF             = 0x4
+       RTA_GATEWAY         = 0x5
+       RTA_PRIORITY        = 0x6
+       RTA_PREFSRC         = 0x7
+       RTA_METRICS         = 0x8
+       RTA_MULTIPATH       = 0x9
+       RTA_FLOW            = 0xb
+       RTA_CACHEINFO       = 0xc
+       RTA_TABLE           = 0xf
+       RTN_UNSPEC          = 0x0
+       RTN_UNICAST         = 0x1
+       RTN_LOCAL           = 0x2
+       RTN_BROADCAST       = 0x3
+       RTN_ANYCAST         = 0x4
+       RTN_MULTICAST       = 0x5
+       RTN_BLACKHOLE       = 0x6
+       RTN_UNREACHABLE     = 0x7
+       RTN_PROHIBIT        = 0x8
+       RTN_THROW           = 0x9
+       RTN_NAT             = 0xa
+       RTN_XRESOLVE        = 0xb
+       RTNLGRP_NONE        = 0x0
+       RTNLGRP_LINK        = 0x1
+       RTNLGRP_NOTIFY      = 0x2
+       RTNLGRP_NEIGH       = 0x3
+       RTNLGRP_TC          = 0x4
+       RTNLGRP_IPV4_IFADDR = 0x5
+       RTNLGRP_IPV4_MROUTE = 0x6
+       RTNLGRP_IPV4_ROUTE  = 0x7
+       RTNLGRP_IPV4_RULE   = 0x8
+       RTNLGRP_IPV6_IFADDR = 0x9
+       RTNLGRP_IPV6_MROUTE = 0xa
+       RTNLGRP_IPV6_ROUTE  = 0xb
+       RTNLGRP_IPV6_IFINFO = 0xc
+       RTNLGRP_IPV6_PREFIX = 0x12
+       RTNLGRP_IPV6_RULE   = 0x13
+       RTNLGRP_ND_USEROPT  = 0x14
+       SizeofNlMsghdr      = 0x10
+       SizeofNlMsgerr      = 0x14
+       SizeofRtGenmsg      = 0x1
+       SizeofNlAttr        = 0x4
+       SizeofRtAttr        = 0x4
+       SizeofIfInfomsg     = 0x10
+       SizeofIfAddrmsg     = 0x8
+       SizeofRtMsg         = 0xc
+       SizeofRtNexthop     = 0x8
+)
+
+type NlMsghdr struct {
+       Len   uint32
+       Type  uint16
+       Flags uint16
+       Seq   uint32
+       Pid   uint32
+}
+
+type NlMsgerr struct {
+       Error int32
+       Msg   NlMsghdr
+}
+
+type RtGenmsg struct {
+       Family uint8
+}
+
+type NlAttr struct {
+       Len  uint16
+       Type uint16
+}
+
+type RtAttr struct {
+       Len  uint16
+       Type uint16
+}
+
+type IfInfomsg struct {
+       Family     uint8
+       X__ifi_pad uint8
+       Type       uint16
+       Index      int32
+       Flags      uint32
+       Change     uint32
+}
+
+type IfAddrmsg struct {
+       Family    uint8
+       Prefixlen uint8
+       Flags     uint8
+       Scope     uint8
+       Index     uint32
+}
+
+type RtMsg struct {
+       Family   uint8
+       Dst_len  uint8
+       Src_len  uint8
+       Tos      uint8
+       Table    uint8
+       Protocol uint8
+       Scope    uint8
+       Type     uint8
+       Flags    uint32
+}
+
+type RtNexthop struct {
+       Len     uint16
+       Flags   uint8
+       Hops    uint8
+       Ifindex int32
+}
+
+const (
+       SizeofSockFilter = 0x8
+       SizeofSockFprog  = 0x10
+)
+
+type SockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
+
+type SockFprog struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *SockFilter
+}
+
+type InotifyEvent struct {
+       Wd     int32
+       Mask   uint32
+       Cookie uint32
+       Len    uint32
+       Name   [0]uint8
+}
+
+const SizeofInotifyEvent = 0x10
+
+type PtraceRegs struct {
+       Gpr       [32]uint64
+       Nip       uint64
+       Msr       uint64
+       Orig_gpr3 uint64
+       Ctr       uint64
+       Link      uint64
+       Xer       uint64
+       Ccr       uint64
+       Softe     uint64
+       Trap      uint64
+       Dar       uint64
+       Dsisr     uint64
+       Result    uint64
+}
+
+type FdSet struct {
+       Bits [16]int64
+}
+
+type Sysinfo_t struct {
+       Uptime    int64
+       Loads     [3]uint64
+       Totalram  uint64
+       Freeram   uint64
+       Sharedram uint64
+       Bufferram uint64
+       Totalswap uint64
+       Freeswap  uint64
+       Procs     uint16
+       Pad       uint16
+       Pad_cgo_0 [4]byte
+       Totalhigh uint64
+       Freehigh  uint64
+       Unit      uint32
+       X_f       [0]byte
+       Pad_cgo_1 [4]byte
+}
+
+type Utsname struct {
+       Sysname    [65]uint8
+       Nodename   [65]uint8
+       Release    [65]uint8
+       Version    [65]uint8
+       Machine    [65]uint8
+       Domainname [65]uint8
+}
+
+type Ustat_t struct {
+       Tfree     int32
+       Pad_cgo_0 [4]byte
+       Tinode    uint64
+       Fname     [6]uint8
+       Fpack     [6]uint8
+       Pad_cgo_1 [4]byte
+}
+
+type EpollEvent struct {
+       Events uint32
+       Fd     int32
+       Pad    int32
+}
+
+const (
+       _AT_FDCWD = -0x64
+)
+
+type Termios struct {
+       Iflag     uint32
+       Oflag     uint32
+       Cflag     uint32
+       Lflag     uint32
+       Line      uint8
+       Cc        [32]uint8
+       Pad_cgo_0 [3]byte
+       Ispeed    uint32
+       Ospeed    uint32
+}
+
+const (
+       IUCLC  = 0x1000
+       OLCUC  = 0x4
+       TCGETS = 0x403c7413
+       TCSETS = 0x803c7414
+       XCASE  = 0x4000
+)
diff --git a/src/syscall/ztypes_linux_power64le.go b/src/syscall/ztypes_linux_power64le.go
new file mode 100644 (file)
index 0000000..df481f5
--- /dev/null
@@ -0,0 +1,602 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_linux.go
+
+package syscall
+
+const (
+       sizeofPtr      = 0x8
+       sizeofShort    = 0x2
+       sizeofInt      = 0x4
+       sizeofLong     = 0x8
+       sizeofLongLong = 0x8
+       PathMax        = 0x1000
+)
+
+type (
+       _C_short     int16
+       _C_int       int32
+       _C_long      int64
+       _C_long_long int64
+)
+
+type Timespec struct {
+       Sec  int64
+       Nsec int64
+}
+
+type Timeval struct {
+       Sec  int64
+       Usec int64
+}
+
+type Timex struct {
+       Modes     uint32
+       Pad_cgo_0 [4]byte
+       Offset    int64
+       Freq      int64
+       Maxerror  int64
+       Esterror  int64
+       Status    int32
+       Pad_cgo_1 [4]byte
+       Constant  int64
+       Precision int64
+       Tolerance int64
+       Time      Timeval
+       Tick      int64
+       Ppsfreq   int64
+       Jitter    int64
+       Shift     int32
+       Pad_cgo_2 [4]byte
+       Stabil    int64
+       Jitcnt    int64
+       Calcnt    int64
+       Errcnt    int64
+       Stbcnt    int64
+       Tai       int32
+       Pad_cgo_3 [44]byte
+}
+
+type Time_t int64
+
+type Tms struct {
+       Utime  int64
+       Stime  int64
+       Cutime int64
+       Cstime int64
+}
+
+type Utimbuf struct {
+       Actime  int64
+       Modtime int64
+}
+
+type Rusage struct {
+       Utime    Timeval
+       Stime    Timeval
+       Maxrss   int64
+       Ixrss    int64
+       Idrss    int64
+       Isrss    int64
+       Minflt   int64
+       Majflt   int64
+       Nswap    int64
+       Inblock  int64
+       Oublock  int64
+       Msgsnd   int64
+       Msgrcv   int64
+       Nsignals int64
+       Nvcsw    int64
+       Nivcsw   int64
+}
+
+type Rlimit struct {
+       Cur uint64
+       Max uint64
+}
+
+type _Gid_t uint32
+
+type Stat_t struct {
+       Dev                uint64
+       Ino                uint64
+       Nlink              uint64
+       Mode               uint32
+       Uid                uint32
+       Gid                uint32
+       X__pad2            int32
+       Rdev               uint64
+       Size               int64
+       Blksize            int64
+       Blocks             int64
+       Atim               Timespec
+       Mtim               Timespec
+       Ctim               Timespec
+       X__glibc_reserved4 uint64
+       X__glibc_reserved5 uint64
+       X__glibc_reserved6 uint64
+}
+
+type Statfs_t struct {
+       Type    int64
+       Bsize   int64
+       Blocks  uint64
+       Bfree   uint64
+       Bavail  uint64
+       Files   uint64
+       Ffree   uint64
+       Fsid    Fsid
+       Namelen int64
+       Frsize  int64
+       Flags   int64
+       Spare   [4]int64
+}
+
+type Dirent struct {
+       Ino       uint64
+       Off       int64
+       Reclen    uint16
+       Type      uint8
+       Name      [256]uint8
+       Pad_cgo_0 [5]byte
+}
+
+type Fsid struct {
+       X__val [2]int32
+}
+
+type Flock_t struct {
+       Type      int16
+       Whence    int16
+       Pad_cgo_0 [4]byte
+       Start     int64
+       Len       int64
+       Pid       int32
+       Pad_cgo_1 [4]byte
+}
+
+type RawSockaddrInet4 struct {
+       Family uint16
+       Port   uint16
+       Addr   [4]byte /* in_addr */
+       Zero   [8]uint8
+}
+
+type RawSockaddrInet6 struct {
+       Family   uint16
+       Port     uint16
+       Flowinfo uint32
+       Addr     [16]byte /* in6_addr */
+       Scope_id uint32
+}
+
+type RawSockaddrUnix struct {
+       Family uint16
+       Path   [108]int8
+}
+
+type RawSockaddrLinklayer struct {
+       Family   uint16
+       Protocol uint16
+       Ifindex  int32
+       Hatype   uint16
+       Pkttype  uint8
+       Halen    uint8
+       Addr     [8]uint8
+}
+
+type RawSockaddrNetlink struct {
+       Family uint16
+       Pad    uint16
+       Pid    uint32
+       Groups uint32
+}
+
+type RawSockaddr struct {
+       Family uint16
+       Data   [14]uint8
+}
+
+type RawSockaddrAny struct {
+       Addr RawSockaddr
+       Pad  [96]uint8
+}
+
+type _Socklen uint32
+
+type Linger struct {
+       Onoff  int32
+       Linger int32
+}
+
+type Iovec struct {
+       Base *byte
+       Len  uint64
+}
+
+type IPMreq struct {
+       Multiaddr [4]byte /* in_addr */
+       Interface [4]byte /* in_addr */
+}
+
+type IPMreqn struct {
+       Multiaddr [4]byte /* in_addr */
+       Address   [4]byte /* in_addr */
+       Ifindex   int32
+}
+
+type IPv6Mreq struct {
+       Multiaddr [16]byte /* in6_addr */
+       Interface uint32
+}
+
+type Msghdr struct {
+       Name       *byte
+       Namelen    uint32
+       Pad_cgo_0  [4]byte
+       Iov        *Iovec
+       Iovlen     uint64
+       Control    *byte
+       Controllen uint64
+       Flags      int32
+       Pad_cgo_1  [4]byte
+}
+
+type Cmsghdr struct {
+       Len          uint64
+       Level        int32
+       Type         int32
+       X__cmsg_data [0]uint8
+}
+
+type Inet4Pktinfo struct {
+       Ifindex  int32
+       Spec_dst [4]byte /* in_addr */
+       Addr     [4]byte /* in_addr */
+}
+
+type Inet6Pktinfo struct {
+       Addr    [16]byte /* in6_addr */
+       Ifindex uint32
+}
+
+type IPv6MTUInfo struct {
+       Addr RawSockaddrInet6
+       Mtu  uint32
+}
+
+type ICMPv6Filter struct {
+       Data [8]uint32
+}
+
+type Ucred struct {
+       Pid int32
+       Uid uint32
+       Gid uint32
+}
+
+type TCPInfo struct {
+       State          uint8
+       Ca_state       uint8
+       Retransmits    uint8
+       Probes         uint8
+       Backoff        uint8
+       Options        uint8
+       Pad_cgo_0      [2]byte
+       Rto            uint32
+       Ato            uint32
+       Snd_mss        uint32
+       Rcv_mss        uint32
+       Unacked        uint32
+       Sacked         uint32
+       Lost           uint32
+       Retrans        uint32
+       Fackets        uint32
+       Last_data_sent uint32
+       Last_ack_sent  uint32
+       Last_data_recv uint32
+       Last_ack_recv  uint32
+       Pmtu           uint32
+       Rcv_ssthresh   uint32
+       Rtt            uint32
+       Rttvar         uint32
+       Snd_ssthresh   uint32
+       Snd_cwnd       uint32
+       Advmss         uint32
+       Reordering     uint32
+       Rcv_rtt        uint32
+       Rcv_space      uint32
+       Total_retrans  uint32
+}
+
+const (
+       SizeofSockaddrInet4     = 0x10
+       SizeofSockaddrInet6     = 0x1c
+       SizeofSockaddrAny       = 0x70
+       SizeofSockaddrUnix      = 0x6e
+       SizeofSockaddrLinklayer = 0x14
+       SizeofSockaddrNetlink   = 0xc
+       SizeofLinger            = 0x8
+       SizeofIPMreq            = 0x8
+       SizeofIPMreqn           = 0xc
+       SizeofIPv6Mreq          = 0x14
+       SizeofMsghdr            = 0x38
+       SizeofCmsghdr           = 0x10
+       SizeofInet4Pktinfo      = 0xc
+       SizeofInet6Pktinfo      = 0x14
+       SizeofIPv6MTUInfo       = 0x20
+       SizeofICMPv6Filter      = 0x20
+       SizeofUcred             = 0xc
+       SizeofTCPInfo           = 0x68
+)
+
+const (
+       IFA_UNSPEC          = 0x0
+       IFA_ADDRESS         = 0x1
+       IFA_LOCAL           = 0x2
+       IFA_LABEL           = 0x3
+       IFA_BROADCAST       = 0x4
+       IFA_ANYCAST         = 0x5
+       IFA_CACHEINFO       = 0x6
+       IFA_MULTICAST       = 0x7
+       IFLA_UNSPEC         = 0x0
+       IFLA_ADDRESS        = 0x1
+       IFLA_BROADCAST      = 0x2
+       IFLA_IFNAME         = 0x3
+       IFLA_MTU            = 0x4
+       IFLA_LINK           = 0x5
+       IFLA_QDISC          = 0x6
+       IFLA_STATS          = 0x7
+       IFLA_COST           = 0x8
+       IFLA_PRIORITY       = 0x9
+       IFLA_MASTER         = 0xa
+       IFLA_WIRELESS       = 0xb
+       IFLA_PROTINFO       = 0xc
+       IFLA_TXQLEN         = 0xd
+       IFLA_MAP            = 0xe
+       IFLA_WEIGHT         = 0xf
+       IFLA_OPERSTATE      = 0x10
+       IFLA_LINKMODE       = 0x11
+       IFLA_LINKINFO       = 0x12
+       IFLA_NET_NS_PID     = 0x13
+       IFLA_IFALIAS        = 0x14
+       IFLA_MAX            = 0x22
+       RT_SCOPE_UNIVERSE   = 0x0
+       RT_SCOPE_SITE       = 0xc8
+       RT_SCOPE_LINK       = 0xfd
+       RT_SCOPE_HOST       = 0xfe
+       RT_SCOPE_NOWHERE    = 0xff
+       RT_TABLE_UNSPEC     = 0x0
+       RT_TABLE_COMPAT     = 0xfc
+       RT_TABLE_DEFAULT    = 0xfd
+       RT_TABLE_MAIN       = 0xfe
+       RT_TABLE_LOCAL      = 0xff
+       RT_TABLE_MAX        = 0xffffffff
+       RTA_UNSPEC          = 0x0
+       RTA_DST             = 0x1
+       RTA_SRC             = 0x2
+       RTA_IIF             = 0x3
+       RTA_OIF             = 0x4
+       RTA_GATEWAY         = 0x5
+       RTA_PRIORITY        = 0x6
+       RTA_PREFSRC         = 0x7
+       RTA_METRICS         = 0x8
+       RTA_MULTIPATH       = 0x9
+       RTA_FLOW            = 0xb
+       RTA_CACHEINFO       = 0xc
+       RTA_TABLE           = 0xf
+       RTN_UNSPEC          = 0x0
+       RTN_UNICAST         = 0x1
+       RTN_LOCAL           = 0x2
+       RTN_BROADCAST       = 0x3
+       RTN_ANYCAST         = 0x4
+       RTN_MULTICAST       = 0x5
+       RTN_BLACKHOLE       = 0x6
+       RTN_UNREACHABLE     = 0x7
+       RTN_PROHIBIT        = 0x8
+       RTN_THROW           = 0x9
+       RTN_NAT             = 0xa
+       RTN_XRESOLVE        = 0xb
+       RTNLGRP_NONE        = 0x0
+       RTNLGRP_LINK        = 0x1
+       RTNLGRP_NOTIFY      = 0x2
+       RTNLGRP_NEIGH       = 0x3
+       RTNLGRP_TC          = 0x4
+       RTNLGRP_IPV4_IFADDR = 0x5
+       RTNLGRP_IPV4_MROUTE = 0x6
+       RTNLGRP_IPV4_ROUTE  = 0x7
+       RTNLGRP_IPV4_RULE   = 0x8
+       RTNLGRP_IPV6_IFADDR = 0x9
+       RTNLGRP_IPV6_MROUTE = 0xa
+       RTNLGRP_IPV6_ROUTE  = 0xb
+       RTNLGRP_IPV6_IFINFO = 0xc
+       RTNLGRP_IPV6_PREFIX = 0x12
+       RTNLGRP_IPV6_RULE   = 0x13
+       RTNLGRP_ND_USEROPT  = 0x14
+       SizeofNlMsghdr      = 0x10
+       SizeofNlMsgerr      = 0x14
+       SizeofRtGenmsg      = 0x1
+       SizeofNlAttr        = 0x4
+       SizeofRtAttr        = 0x4
+       SizeofIfInfomsg     = 0x10
+       SizeofIfAddrmsg     = 0x8
+       SizeofRtMsg         = 0xc
+       SizeofRtNexthop     = 0x8
+)
+
+type NlMsghdr struct {
+       Len   uint32
+       Type  uint16
+       Flags uint16
+       Seq   uint32
+       Pid   uint32
+}
+
+type NlMsgerr struct {
+       Error int32
+       Msg   NlMsghdr
+}
+
+type RtGenmsg struct {
+       Family uint8
+}
+
+type NlAttr struct {
+       Len  uint16
+       Type uint16
+}
+
+type RtAttr struct {
+       Len  uint16
+       Type uint16
+}
+
+type IfInfomsg struct {
+       Family     uint8
+       X__ifi_pad uint8
+       Type       uint16
+       Index      int32
+       Flags      uint32
+       Change     uint32
+}
+
+type IfAddrmsg struct {
+       Family    uint8
+       Prefixlen uint8
+       Flags     uint8
+       Scope     uint8
+       Index     uint32
+}
+
+type RtMsg struct {
+       Family   uint8
+       Dst_len  uint8
+       Src_len  uint8
+       Tos      uint8
+       Table    uint8
+       Protocol uint8
+       Scope    uint8
+       Type     uint8
+       Flags    uint32
+}
+
+type RtNexthop struct {
+       Len     uint16
+       Flags   uint8
+       Hops    uint8
+       Ifindex int32
+}
+
+const (
+       SizeofSockFilter = 0x8
+       SizeofSockFprog  = 0x10
+)
+
+type SockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
+
+type SockFprog struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *SockFilter
+}
+
+type InotifyEvent struct {
+       Wd     int32
+       Mask   uint32
+       Cookie uint32
+       Len    uint32
+       Name   [0]uint8
+}
+
+const SizeofInotifyEvent = 0x10
+
+type PtraceRegs struct {
+       Gpr       [32]uint64
+       Nip       uint64
+       Msr       uint64
+       Orig_gpr3 uint64
+       Ctr       uint64
+       Link      uint64
+       Xer       uint64
+       Ccr       uint64
+       Softe     uint64
+       Trap      uint64
+       Dar       uint64
+       Dsisr     uint64
+       Result    uint64
+}
+
+type FdSet struct {
+       Bits [16]int64
+}
+
+type Sysinfo_t struct {
+       Uptime    int64
+       Loads     [3]uint64
+       Totalram  uint64
+       Freeram   uint64
+       Sharedram uint64
+       Bufferram uint64
+       Totalswap uint64
+       Freeswap  uint64
+       Procs     uint16
+       Pad       uint16
+       Pad_cgo_0 [4]byte
+       Totalhigh uint64
+       Freehigh  uint64
+       Unit      uint32
+       X_f       [0]byte
+       Pad_cgo_1 [4]byte
+}
+
+type Utsname struct {
+       Sysname    [65]uint8
+       Nodename   [65]uint8
+       Release    [65]uint8
+       Version    [65]uint8
+       Machine    [65]uint8
+       Domainname [65]uint8
+}
+
+type Ustat_t struct {
+       Tfree     int32
+       Pad_cgo_0 [4]byte
+       Tinode    uint64
+       Fname     [6]uint8
+       Fpack     [6]uint8
+       Pad_cgo_1 [4]byte
+}
+
+type EpollEvent struct {
+       Events uint32
+       Fd     int32
+       Pad    int32
+}
+
+const (
+       _AT_FDCWD = -0x64
+)
+
+type Termios struct {
+       Iflag     uint32
+       Oflag     uint32
+       Cflag     uint32
+       Lflag     uint32
+       Line      uint8
+       Cc        [32]uint8
+       Pad_cgo_0 [3]byte
+       Ispeed    uint32
+       Ospeed    uint32
+}
+
+const (
+       IUCLC  = 0x1000
+       OLCUC  = 0x4
+       TCGETS = 0x403c7413
+       TCSETS = 0x803c7414
+       XCASE  = 0x4000
+)
index 953a5bf0a61b627745f5c70fe632885eaa77d95c..3a63e8731d92ba14c777032484804499bca5ea86 100644 (file)
@@ -127,8 +127,9 @@ main 136 nosplit; REJECT
 # Calling a nosplit function from a nosplit function requires
 # having room for the saved caller PC and the called frame.
 # Because ARM doesn't save LR in the leaf, it gets an extra 4 bytes.
+# Because Power64 doesn't save LR in the leaf, it gets an extra 8 bytes.
 main 112 nosplit call f; f 0 nosplit
-main 116 nosplit call f; f 0 nosplit; REJECT amd64
+main 116 nosplit call f; f 0 nosplit
 main 120 nosplit call f; f 0 nosplit; REJECT amd64
 main 124 nosplit call f; f 0 nosplit; REJECT amd64 386
 main 128 nosplit call f; f 0 nosplit; REJECT
@@ -137,8 +138,8 @@ main 136 nosplit call f; f 0 nosplit; REJECT
 
 # Calling a splitting function from a nosplit function requires
 # having room for the saved caller PC of the call but also the
-# saved caller PC for the call to morestack. Again the ARM works
-# in less space.
+# saved caller PC for the call to morestack.
+# Again the ARM and Power64 work in less space.
 main 104 nosplit call f; f 0 call f
 main 108 nosplit call f; f 0 call f
 main 112 nosplit call f; f 0 call f; REJECT amd64
@@ -234,9 +235,17 @@ TestCases:
                fmt.Fprintf(&gobuf, "package main\n")
 
                var buf bytes.Buffer
-               if goarch == "arm" {
+               ptrSize := 4
+               switch goarch {
+               case "power64", "power64le":
+                       ptrSize = 8
+                       fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (CTR)\n#define RET RETURN\n")
+               case "arm":
                        fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")
-               } else {
+               case "amd64":
+                       ptrSize = 8
+                       fmt.Fprintf(&buf, "#define REGISTER AX\n")
+               default:
                        fmt.Fprintf(&buf, "#define REGISTER AX\n")
                }
 
@@ -266,7 +275,7 @@ TestCases:
                                        size += 384 - 128
                                }
 
-                               if goarch == "amd64" && size%8 == 4 {
+                               if size%ptrSize == 4 {
                                        continue TestCases
                                }
                                nosplit := m[3]