mirror of
https://github.com/golang/go.git
synced 2025-11-01 01:00:56 +00:00
[dev.garbage] all: merge dev.power64 (5ad5e85cfb99) into dev.garbage
The goal here is to get the big-endian fixes so that in some upcoming code movement for write barriers I don't make them unmergeable. LGTM=rlh R=rlh CC=golang-codereviews https://golang.org/cl/166890043
This commit is contained in:
commit
d6f4e5020b
158 changed files with 39414 additions and 2818 deletions
|
|
@ -2,13 +2,13 @@ syntax:glob
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.git
|
.git
|
||||||
.gitignore
|
.gitignore
|
||||||
*.[568ao]
|
*.[5689ao]
|
||||||
*.a[568o]
|
*.a[5689o]
|
||||||
*.so
|
*.so
|
||||||
*.pyc
|
*.pyc
|
||||||
._*
|
._*
|
||||||
.nfs.*
|
.nfs.*
|
||||||
[568a].out
|
[5689a].out
|
||||||
*~
|
*~
|
||||||
*.orig
|
*.orig
|
||||||
*.rej
|
*.rej
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,9 @@ struct Addr
|
||||||
short type;
|
short type;
|
||||||
uint8 index;
|
uint8 index;
|
||||||
int8 scale;
|
int8 scale;
|
||||||
int8 reg; // for 5l
|
int8 reg; // for 5l, 9l
|
||||||
int8 name; // for 5l
|
int8 name; // for 5l, 9l
|
||||||
int8 class; // for 5l
|
int8 class; // for 5l, 9l
|
||||||
uint8 etype; // for 5g, 6g, 8g
|
uint8 etype; // for 5g, 6g, 8g
|
||||||
int32 offset2; // for 5l, 8l
|
int32 offset2; // for 5l, 8l
|
||||||
struct Node* node; // for 5g, 6g, 8g
|
struct Node* node; // for 5g, 6g, 8g
|
||||||
|
|
@ -89,9 +89,10 @@ struct Prog
|
||||||
int32 lineno;
|
int32 lineno;
|
||||||
Prog* link;
|
Prog* link;
|
||||||
short as;
|
short as;
|
||||||
uchar reg; // arm only
|
uchar reg; // arm, power64 only
|
||||||
uchar scond; // arm only
|
uchar scond; // arm only
|
||||||
Addr from;
|
Addr from;
|
||||||
|
Addr from3; // power64 only, fma and rlwm
|
||||||
Addr to;
|
Addr to;
|
||||||
|
|
||||||
// for 5g, 6g, 8g internal use
|
// for 5g, 6g, 8g internal use
|
||||||
|
|
@ -103,11 +104,11 @@ struct Prog
|
||||||
Prog* comefrom; // 6l, 8l
|
Prog* comefrom; // 6l, 8l
|
||||||
Prog* pcrel; // 5l
|
Prog* pcrel; // 5l
|
||||||
int32 spadj;
|
int32 spadj;
|
||||||
uchar mark;
|
uint16 mark;
|
||||||
|
uint16 optab; // 5l, 9l
|
||||||
uchar back; // 6l, 8l
|
uchar back; // 6l, 8l
|
||||||
uchar ft; /* 6l, 8l oclass cache */
|
uchar ft; /* 6l, 8l oclass cache */
|
||||||
uchar tt; // 6l, 8l
|
uchar tt; // 6l, 8l
|
||||||
uint16 optab; // 5l
|
|
||||||
uchar isize; // 6l, 8l
|
uchar isize; // 6l, 8l
|
||||||
|
|
||||||
char width; /* fake for DATA */
|
char width; /* fake for DATA */
|
||||||
|
|
@ -233,10 +234,12 @@ enum
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
R_ADDR = 1,
|
R_ADDR = 1,
|
||||||
|
R_ADDRPOWER, // relocation for loading 31-bit address using addis and addi/ld/st for Power
|
||||||
R_SIZE,
|
R_SIZE,
|
||||||
R_CALL, // relocation for direct PC-relative call
|
R_CALL, // relocation for direct PC-relative call
|
||||||
R_CALLARM, // relocation for ARM direct call
|
R_CALLARM, // relocation for ARM direct call
|
||||||
R_CALLIND, // marker for indirect call (no actual relocating necessary)
|
R_CALLIND, // marker for indirect call (no actual relocating necessary)
|
||||||
|
R_CALLPOWER, // relocation for Power direct call
|
||||||
R_CONST,
|
R_CONST,
|
||||||
R_PCREL,
|
R_PCREL,
|
||||||
R_TLS,
|
R_TLS,
|
||||||
|
|
@ -529,6 +532,9 @@ void span6(Link *ctxt, LSym *s);
|
||||||
// asm8.c
|
// asm8.c
|
||||||
void span8(Link *ctxt, LSym *s);
|
void span8(Link *ctxt, LSym *s);
|
||||||
|
|
||||||
|
// asm9.c
|
||||||
|
void span9(Link *ctxt, LSym *s);
|
||||||
|
|
||||||
// data.c
|
// data.c
|
||||||
vlong addaddr(Link *ctxt, LSym *s, LSym *t);
|
vlong addaddr(Link *ctxt, LSym *s, LSym *t);
|
||||||
vlong addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add);
|
vlong addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add);
|
||||||
|
|
@ -576,10 +582,11 @@ Prog* copyp(Link*, Prog*);
|
||||||
Prog* appendp(Link*, Prog*);
|
Prog* appendp(Link*, Prog*);
|
||||||
vlong atolwhex(char*);
|
vlong atolwhex(char*);
|
||||||
|
|
||||||
// list[568].c
|
// list[5689].c
|
||||||
void listinit5(void);
|
void listinit5(void);
|
||||||
void listinit6(void);
|
void listinit6(void);
|
||||||
void listinit8(void);
|
void listinit8(void);
|
||||||
|
void listinit9(void);
|
||||||
|
|
||||||
// obj.c
|
// obj.c
|
||||||
int linklinefmt(Link *ctxt, Fmt *fp);
|
int linklinefmt(Link *ctxt, Fmt *fp);
|
||||||
|
|
@ -611,20 +618,24 @@ char* headstr(int);
|
||||||
extern char* anames5[];
|
extern char* anames5[];
|
||||||
extern char* anames6[];
|
extern char* anames6[];
|
||||||
extern char* anames8[];
|
extern char* anames8[];
|
||||||
|
extern char* anames9[];
|
||||||
|
|
||||||
extern char* cnames5[];
|
extern char* cnames5[];
|
||||||
|
extern char* cnames9[];
|
||||||
|
|
||||||
extern LinkArch link386;
|
extern LinkArch link386;
|
||||||
extern LinkArch linkamd64;
|
extern LinkArch linkamd64;
|
||||||
extern LinkArch linkamd64p32;
|
extern LinkArch linkamd64p32;
|
||||||
extern LinkArch linkarm;
|
extern LinkArch linkarm;
|
||||||
|
extern LinkArch linkpower64;
|
||||||
|
extern LinkArch linkpower64le;
|
||||||
|
|
||||||
#pragma varargck type "A" int
|
#pragma varargck type "A" int
|
||||||
#pragma varargck type "D" Addr*
|
#pragma varargck type "D" Addr*
|
||||||
#pragma varargck type "lD" Addr*
|
#pragma varargck type "lD" Addr*
|
||||||
#pragma varargck type "P" Prog*
|
#pragma varargck type "P" Prog*
|
||||||
#pragma varargck type "R" int
|
#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.
|
// TODO(ality): remove this workaround.
|
||||||
// It's here because Pconv in liblink/list?.c references %L.
|
// It's here because Pconv in liblink/list?.c references %L.
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
defaultcc: golang-codereviews@googlegroups.com
|
defaultcc: golang-codereviews@googlegroups.com
|
||||||
|
contributors: http://go.googlecode.com/hg/CONTRIBUTORS
|
||||||
|
|
|
||||||
|
|
@ -3603,11 +3603,17 @@ class MercurialVCS(VersionControlSystem):
|
||||||
if use_hg_shell:
|
if use_hg_shell:
|
||||||
base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], silent_ok=True)
|
base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], silent_ok=True)
|
||||||
else:
|
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
|
is_binary = "\0" in base_content # Mercurial's heuristic
|
||||||
if status != "R":
|
if status != "R":
|
||||||
new_content = open(relpath, "rb").read()
|
try:
|
||||||
is_binary = is_binary or "\0" in new_content
|
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:
|
if is_binary and base_content and use_hg_shell:
|
||||||
# Fetch again without converting newlines
|
# Fetch again without converting newlines
|
||||||
base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath],
|
base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath],
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ struct Sym
|
||||||
int32 value;
|
int32 value;
|
||||||
ushort type;
|
ushort type;
|
||||||
char *name;
|
char *name;
|
||||||
|
char* labelname;
|
||||||
char sym;
|
char sym;
|
||||||
};
|
};
|
||||||
#define S ((Sym*)0)
|
#define S ((Sym*)0)
|
||||||
|
|
@ -136,6 +137,8 @@ void newio(void);
|
||||||
void newfile(char*, int);
|
void newfile(char*, int);
|
||||||
Sym* slookup(char*);
|
Sym* slookup(char*);
|
||||||
Sym* lookup(void);
|
Sym* lookup(void);
|
||||||
|
Sym* labellookup(Sym*);
|
||||||
|
void settext(LSym*);
|
||||||
void syminit(Sym*);
|
void syminit(Sym*);
|
||||||
int32 yylex(void);
|
int32 yylex(void);
|
||||||
int getc(void);
|
int getc(void);
|
||||||
|
|
|
||||||
|
|
@ -73,15 +73,11 @@ prog:
|
||||||
line
|
line
|
||||||
|
|
||||||
line:
|
line:
|
||||||
LLAB ':'
|
LNAME ':'
|
||||||
{
|
|
||||||
if($1->value != pc)
|
|
||||||
yyerror("redeclaration of %s", $1->name);
|
|
||||||
$1->value = pc;
|
|
||||||
}
|
|
||||||
line
|
|
||||||
| LNAME ':'
|
|
||||||
{
|
{
|
||||||
|
$1 = labellookup($1);
|
||||||
|
if($1->type == LLAB && $1->value != pc)
|
||||||
|
yyerror("redeclaration of %s", $1->labelname);
|
||||||
$1->type = LLAB;
|
$1->type = LLAB;
|
||||||
$1->value = pc;
|
$1->value = pc;
|
||||||
}
|
}
|
||||||
|
|
@ -218,18 +214,21 @@ inst:
|
||||||
*/
|
*/
|
||||||
| LTYPEB name ',' imm
|
| LTYPEB name ',' imm
|
||||||
{
|
{
|
||||||
|
settext($2.sym);
|
||||||
$4.type = D_CONST2;
|
$4.type = D_CONST2;
|
||||||
$4.offset2 = ArgsSizeUnknown;
|
$4.offset2 = ArgsSizeUnknown;
|
||||||
outcode($1, Always, &$2, 0, &$4);
|
outcode($1, Always, &$2, 0, &$4);
|
||||||
}
|
}
|
||||||
| LTYPEB name ',' con ',' imm
|
| LTYPEB name ',' con ',' imm
|
||||||
{
|
{
|
||||||
|
settext($2.sym);
|
||||||
$6.type = D_CONST2;
|
$6.type = D_CONST2;
|
||||||
$6.offset2 = ArgsSizeUnknown;
|
$6.offset2 = ArgsSizeUnknown;
|
||||||
outcode($1, Always, &$2, $4, &$6);
|
outcode($1, Always, &$2, $4, &$6);
|
||||||
}
|
}
|
||||||
| LTYPEB name ',' con ',' imm '-' con
|
| LTYPEB name ',' con ',' imm '-' con
|
||||||
{
|
{
|
||||||
|
settext($2.sym);
|
||||||
$6.type = D_CONST2;
|
$6.type = D_CONST2;
|
||||||
$6.offset2 = $8;
|
$6.offset2 = $8;
|
||||||
outcode($1, Always, &$2, $4, &$6);
|
outcode($1, Always, &$2, $4, &$6);
|
||||||
|
|
@ -373,15 +372,10 @@ rel:
|
||||||
}
|
}
|
||||||
| LNAME offset
|
| LNAME offset
|
||||||
{
|
{
|
||||||
|
$1 = labellookup($1);
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
if(pass == 2)
|
if(pass == 2 && $1->type != LLAB)
|
||||||
yyerror("undefined label: %s", $1->name);
|
yyerror("undefined label: %s", $1->labelname);
|
||||||
$$.type = D_BRANCH;
|
|
||||||
$$.offset = $2;
|
|
||||||
}
|
|
||||||
| LLAB offset
|
|
||||||
{
|
|
||||||
$$ = nullgen;
|
|
||||||
$$.type = D_BRANCH;
|
$$.type = D_BRANCH;
|
||||||
$$.offset = $1->value + $2;
|
$$.offset = $1->value + $2;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2093
src/cmd/5a/y.tab.c
2093
src/cmd/5a/y.tab.c
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
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
|
|
||||||
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
(at your option) any later version.
|
any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
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
|
/* As a special exception, you may create a larger work that contains
|
||||||
part or all of the Bison parser skeleton and distribute that work
|
part or all of the Bison parser skeleton and distribute that work
|
||||||
|
|
@ -26,20 +29,10 @@
|
||||||
special exception, which will cause the skeleton and the resulting
|
special exception, which will cause the skeleton and the resulting
|
||||||
Bison output files to be licensed under the GNU General Public
|
Bison output files to be licensed under the GNU General Public
|
||||||
License without this special exception.
|
License without this special exception.
|
||||||
|
|
||||||
This special exception was added by the Free Software Foundation in
|
This special exception was added by the Free Software Foundation in
|
||||||
version 2.2 of Bison. */
|
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. */
|
/* Tokens. */
|
||||||
#ifndef YYTOKENTYPE
|
#ifndef YYTOKENTYPE
|
||||||
# define YYTOKENTYPE
|
# define YYTOKENTYPE
|
||||||
|
|
@ -148,41 +141,24 @@ extern int yydebug;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
typedef union YYSTYPE
|
typedef union YYSTYPE
|
||||||
{
|
|
||||||
/* Line 2053 of yacc.c */
|
|
||||||
#line 39 "a.y"
|
#line 39 "a.y"
|
||||||
|
{
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
int32 lval;
|
int32 lval;
|
||||||
double dval;
|
double dval;
|
||||||
char sval[8];
|
char sval[8];
|
||||||
Addr addr;
|
Addr addr;
|
||||||
|
}
|
||||||
|
/* Line 1529 of yacc.c. */
|
||||||
/* Line 2053 of yacc.c */
|
#line 157 "y.tab.h"
|
||||||
#line 166 "y.tab.h"
|
YYSTYPE;
|
||||||
} YYSTYPE;
|
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern YYSTYPE yylval;
|
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 */
|
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ struct Sym
|
||||||
vlong value;
|
vlong value;
|
||||||
ushort type;
|
ushort type;
|
||||||
char *name;
|
char *name;
|
||||||
|
char* labelname;
|
||||||
char sym;
|
char sym;
|
||||||
};
|
};
|
||||||
#define S ((Sym*)0)
|
#define S ((Sym*)0)
|
||||||
|
|
@ -148,6 +149,8 @@ void newio(void);
|
||||||
void newfile(char*, int);
|
void newfile(char*, int);
|
||||||
Sym* slookup(char*);
|
Sym* slookup(char*);
|
||||||
Sym* lookup(void);
|
Sym* lookup(void);
|
||||||
|
Sym* labellookup(Sym*);
|
||||||
|
void settext(LSym*);
|
||||||
void syminit(Sym*);
|
void syminit(Sym*);
|
||||||
int32 yylex(void);
|
int32 yylex(void);
|
||||||
int getc(void);
|
int getc(void);
|
||||||
|
|
|
||||||
|
|
@ -71,15 +71,11 @@ prog:
|
||||||
line
|
line
|
||||||
|
|
||||||
line:
|
line:
|
||||||
LLAB ':'
|
LNAME ':'
|
||||||
{
|
|
||||||
if($1->value != pc)
|
|
||||||
yyerror("redeclaration of %s", $1->name);
|
|
||||||
$1->value = pc;
|
|
||||||
}
|
|
||||||
line
|
|
||||||
| LNAME ':'
|
|
||||||
{
|
{
|
||||||
|
$1 = labellookup($1);
|
||||||
|
if($1->type == LLAB && $1->value != pc)
|
||||||
|
yyerror("redeclaration of %s (%s)", $1->labelname, $1->name);
|
||||||
$1->type = LLAB;
|
$1->type = LLAB;
|
||||||
$1->value = pc;
|
$1->value = pc;
|
||||||
}
|
}
|
||||||
|
|
@ -197,11 +193,13 @@ spec1: /* DATA */
|
||||||
spec2: /* TEXT */
|
spec2: /* TEXT */
|
||||||
mem ',' imm2
|
mem ',' imm2
|
||||||
{
|
{
|
||||||
|
settext($1.sym);
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
}
|
}
|
||||||
| mem ',' con ',' imm2
|
| mem ',' con ',' imm2
|
||||||
{
|
{
|
||||||
|
settext($1.sym);
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.from.scale = $3;
|
$$.from.scale = $3;
|
||||||
$$.to = $5;
|
$$.to = $5;
|
||||||
|
|
@ -363,15 +361,10 @@ rel:
|
||||||
}
|
}
|
||||||
| LNAME offset
|
| LNAME offset
|
||||||
{
|
{
|
||||||
|
$1 = labellookup($1);
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
if(pass == 2)
|
if(pass == 2 && $1->type != LLAB)
|
||||||
yyerror("undefined label: %s", $1->name);
|
yyerror("undefined label: %s", $1->labelname);
|
||||||
$$.type = D_BRANCH;
|
|
||||||
$$.offset = $2;
|
|
||||||
}
|
|
||||||
| LLAB offset
|
|
||||||
{
|
|
||||||
$$ = nullgen;
|
|
||||||
$$.type = D_BRANCH;
|
$$.type = D_BRANCH;
|
||||||
$$.offset = $1->value + $2;
|
$$.offset = $1->value + $2;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1152
src/cmd/6a/y.tab.c
1152
src/cmd/6a/y.tab.c
File diff suppressed because it is too large
Load diff
|
|
@ -70,6 +70,7 @@ struct Sym
|
||||||
int32 value;
|
int32 value;
|
||||||
ushort type;
|
ushort type;
|
||||||
char *name;
|
char *name;
|
||||||
|
char* labelname;
|
||||||
char sym;
|
char sym;
|
||||||
};
|
};
|
||||||
#define S ((Sym*)0)
|
#define S ((Sym*)0)
|
||||||
|
|
@ -148,6 +149,8 @@ void newio(void);
|
||||||
void newfile(char*, int);
|
void newfile(char*, int);
|
||||||
Sym* slookup(char*);
|
Sym* slookup(char*);
|
||||||
Sym* lookup(void);
|
Sym* lookup(void);
|
||||||
|
Sym* labellookup(Sym*);
|
||||||
|
void settext(LSym*);
|
||||||
void syminit(Sym*);
|
void syminit(Sym*);
|
||||||
int32 yylex(void);
|
int32 yylex(void);
|
||||||
int getc(void);
|
int getc(void);
|
||||||
|
|
|
||||||
|
|
@ -74,15 +74,11 @@ prog:
|
||||||
line
|
line
|
||||||
|
|
||||||
line:
|
line:
|
||||||
LLAB ':'
|
LNAME ':'
|
||||||
{
|
|
||||||
if($1->value != pc)
|
|
||||||
yyerror("redeclaration of %s", $1->name);
|
|
||||||
$1->value = pc;
|
|
||||||
}
|
|
||||||
line
|
|
||||||
| LNAME ':'
|
|
||||||
{
|
{
|
||||||
|
$1 = labellookup($1);
|
||||||
|
if($1->type == LLAB && $1->value != pc)
|
||||||
|
yyerror("redeclaration of %s", $1->labelname);
|
||||||
$1->type = LLAB;
|
$1->type = LLAB;
|
||||||
$1->value = pc;
|
$1->value = pc;
|
||||||
}
|
}
|
||||||
|
|
@ -199,11 +195,13 @@ spec1: /* DATA */
|
||||||
spec2: /* TEXT */
|
spec2: /* TEXT */
|
||||||
mem ',' imm2
|
mem ',' imm2
|
||||||
{
|
{
|
||||||
|
settext($1.sym);
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
}
|
}
|
||||||
| mem ',' con ',' imm2
|
| mem ',' con ',' imm2
|
||||||
{
|
{
|
||||||
|
settext($1.sym);
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.from.scale = $3;
|
$$.from.scale = $3;
|
||||||
$$.to = $5;
|
$$.to = $5;
|
||||||
|
|
@ -362,15 +360,10 @@ rel:
|
||||||
}
|
}
|
||||||
| LNAME offset
|
| LNAME offset
|
||||||
{
|
{
|
||||||
|
$1 = labellookup($1);
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
if(pass == 2)
|
if(pass == 2 && $1->type != LLAB)
|
||||||
yyerror("undefined label: %s", $1->name);
|
yyerror("undefined label: %s", $1->labelname);
|
||||||
$$.type = D_BRANCH;
|
|
||||||
$$.offset = $2;
|
|
||||||
}
|
|
||||||
| LLAB offset
|
|
||||||
{
|
|
||||||
$$ = nullgen;
|
|
||||||
$$.type = D_BRANCH;
|
$$.type = D_BRANCH;
|
||||||
$$.offset = $1->value + $2;
|
$$.offset = $1->value + $2;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1166
src/cmd/8a/y.tab.c
1166
src/cmd/8a/y.tab.c
File diff suppressed because it is too large
Load diff
10
src/cmd/9a/Makefile
Normal file
10
src/cmd/9a/Makefile
Normal file
|
|
@ -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
|
||||||
170
src/cmd/9a/a.h
Normal file
170
src/cmd/9a/a.h
Normal file
|
|
@ -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*);
|
||||||
991
src/cmd/9a/a.y
Normal file
991
src/cmd/9a/a.y
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
21
src/cmd/9a/doc.go
Normal file
21
src/cmd/9a/doc.go
Normal file
|
|
@ -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
|
||||||
725
src/cmd/9a/lex.c
Normal file
725
src/cmd/9a/lex.c
Normal file
|
|
@ -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"
|
||||||
3398
src/cmd/9a/y.tab.c
Normal file
3398
src/cmd/9a/y.tab.c
Normal file
File diff suppressed because it is too large
Load diff
188
src/cmd/9a/y.tab.h
Normal file
188
src/cmd/9a/y.tab.h
Normal file
|
|
@ -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;
|
||||||
|
|
||||||
5
src/cmd/9c/Makefile
Normal file
5
src/cmd/9c/Makefile
Normal file
|
|
@ -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
|
||||||
14
src/cmd/9c/Notes
Normal file
14
src/cmd/9c/Notes
Normal file
|
|
@ -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
|
||||||
1147
src/cmd/9c/cgen.c
Normal file
1147
src/cmd/9c/cgen.c
Normal file
File diff suppressed because it is too large
Load diff
17
src/cmd/9c/doc.go
Normal file
17
src/cmd/9c/doc.go
Normal file
|
|
@ -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
|
||||||
350
src/cmd/9c/gc.h
Normal file
350
src/cmd/9c/gc.h
Normal file
|
|
@ -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*
|
||||||
37
src/cmd/9c/list.c
Normal file
37
src/cmd/9c/list.c
Normal file
|
|
@ -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();
|
||||||
|
}
|
||||||
105
src/cmd/9c/machcap.c
Normal file
105
src/cmd/9c/machcap.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
638
src/cmd/9c/mul.c
Normal file
638
src/cmd/9c/mul.c
Normal file
|
|
@ -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);
|
||||||
1076
src/cmd/9c/peep.c
Normal file
1076
src/cmd/9c/peep.c
Normal file
File diff suppressed because it is too large
Load diff
1163
src/cmd/9c/reg.c
Normal file
1163
src/cmd/9c/reg.c
Normal file
File diff suppressed because it is too large
Load diff
291
src/cmd/9c/sgen.c
Normal file
291
src/cmd/9c/sgen.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
407
src/cmd/9c/swt.c
Normal file
407
src/cmd/9c/swt.c
Normal file
|
|
@ -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, ®node, 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;
|
||||||
|
}
|
||||||
1537
src/cmd/9c/txt.c
Normal file
1537
src/cmd/9c/txt.c
Normal file
File diff suppressed because it is too large
Load diff
1763
src/cmd/9g/cgen.c
Normal file
1763
src/cmd/9g/cgen.c
Normal file
File diff suppressed because it is too large
Load diff
16
src/cmd/9g/doc.go
Normal file
16
src/cmd/9g/doc.go
Normal file
|
|
@ -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
|
||||||
54
src/cmd/9g/galign.c
Normal file
54
src/cmd/9g/galign.c
Normal file
|
|
@ -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();
|
||||||
|
}
|
||||||
117
src/cmd/9g/gg.h
Normal file
117
src/cmd/9g/gg.h
Normal file
|
|
@ -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);
|
||||||
1034
src/cmd/9g/ggen.c
Normal file
1034
src/cmd/9g/ggen.c
Normal file
File diff suppressed because it is too large
Load diff
240
src/cmd/9g/gobj.c
Normal file
240
src/cmd/9g/gobj.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
1705
src/cmd/9g/gsubr.c
Normal file
1705
src/cmd/9g/gsubr.c
Normal file
File diff suppressed because it is too large
Load diff
219
src/cmd/9g/opt.h
Normal file
219
src/cmd/9g/opt.h
Normal file
|
|
@ -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,
|
||||||
|
};
|
||||||
94
src/cmd/9g/peep.c
Normal file
94
src/cmd/9g/peep.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
138
src/cmd/9g/prog.c
Normal file
138
src/cmd/9g/prog.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
161
src/cmd/9g/reg.c
Normal file
161
src/cmd/9g/reg.c
Normal file
|
|
@ -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");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
514
src/cmd/9l/9.out.h
Normal file
514
src/cmd/9l/9.out.h
Normal file
|
|
@ -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"
|
||||||
5
src/cmd/9l/Makefile
Normal file
5
src/cmd/9l/Makefile
Normal file
|
|
@ -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
|
||||||
338
src/cmd/9l/asm.c
Normal file
338
src/cmd/9l/asm.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
16
src/cmd/9l/doc.go
Normal file
16
src/cmd/9l/doc.go
Normal file
|
|
@ -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
|
||||||
100
src/cmd/9l/l.h
Normal file
100
src/cmd/9l/l.h
Normal file
|
|
@ -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
|
||||||
|
};
|
||||||
40
src/cmd/9l/list.c
Normal file
40
src/cmd/9l/list.c
Normal file
|
|
@ -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();
|
||||||
|
}
|
||||||
108
src/cmd/9l/obj.c
Normal file
108
src/cmd/9l/obj.c
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -220,6 +220,31 @@ slookup(char *s)
|
||||||
return lookup();
|
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*
|
Sym*
|
||||||
lookup(void)
|
lookup(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -65,14 +65,14 @@ argsize(int doret)
|
||||||
}
|
}
|
||||||
//print(" %d %T\n", s, t);
|
//print(" %d %T\n", s, t);
|
||||||
}
|
}
|
||||||
if(thechar == '6')
|
if(thechar == '6' || thechar == '9')
|
||||||
s = (s+7) & ~7;
|
s = (s+7) & ~7;
|
||||||
else
|
else
|
||||||
s = (s+3) & ~3;
|
s = (s+3) & ~3;
|
||||||
if(doret && thisfn->link->etype != TVOID) {
|
if(doret && thisfn->link->etype != TVOID) {
|
||||||
s = align(s, thisfn->link, Aarg1, nil);
|
s = align(s, thisfn->link, Aarg1, nil);
|
||||||
s = align(s, thisfn->link, Aarg2, nil);
|
s = align(s, thisfn->link, Aarg2, nil);
|
||||||
if(thechar == '6')
|
if(thechar == '6' || thechar == '9')
|
||||||
s = (s+7) & ~7;
|
s = (s+7) & ~7;
|
||||||
else
|
else
|
||||||
s = (s+3) & ~3;
|
s = (s+3) & ~3;
|
||||||
|
|
|
||||||
|
|
@ -130,15 +130,23 @@ func usage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var ptrSizeMap = map[string]int64{
|
var ptrSizeMap = map[string]int64{
|
||||||
"386": 4,
|
"386": 4,
|
||||||
"amd64": 8,
|
"amd64": 8,
|
||||||
"arm": 4,
|
"arm": 4,
|
||||||
|
"ppc64": 8,
|
||||||
|
"ppc64le": 8,
|
||||||
|
"power64": 8,
|
||||||
|
"power64le": 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
var intSizeMap = map[string]int64{
|
var intSizeMap = map[string]int64{
|
||||||
"386": 4,
|
"386": 4,
|
||||||
"amd64": 8,
|
"amd64": 8,
|
||||||
"arm": 4,
|
"arm": 4,
|
||||||
|
"ppc64": 8,
|
||||||
|
"ppc64le": 8,
|
||||||
|
"power64": 8,
|
||||||
|
"power64le": 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
var cPrefix string
|
var cPrefix string
|
||||||
|
|
|
||||||
49
src/cmd/dist/build.c
vendored
49
src/cmd/dist/build.c
vendored
|
|
@ -39,7 +39,7 @@ static void dopack(char*, char*, char**, int);
|
||||||
static char *findgoversion(void);
|
static char *findgoversion(void);
|
||||||
|
|
||||||
// The known architecture letters.
|
// The known architecture letters.
|
||||||
static char *gochars = "5668";
|
static char *gochars = "566899";
|
||||||
|
|
||||||
// The known architectures.
|
// The known architectures.
|
||||||
static char *okgoarch[] = {
|
static char *okgoarch[] = {
|
||||||
|
|
@ -48,6 +48,8 @@ static char *okgoarch[] = {
|
||||||
"amd64",
|
"amd64",
|
||||||
"amd64p32",
|
"amd64p32",
|
||||||
"386",
|
"386",
|
||||||
|
"power64",
|
||||||
|
"power64le",
|
||||||
};
|
};
|
||||||
|
|
||||||
// The known operating systems.
|
// The known operating systems.
|
||||||
|
|
@ -344,6 +346,7 @@ static char *oldtool[] = {
|
||||||
"5a", "5c", "5g", "5l",
|
"5a", "5c", "5g", "5l",
|
||||||
"6a", "6c", "6g", "6l",
|
"6a", "6c", "6g", "6l",
|
||||||
"8a", "8c", "8g", "8l",
|
"8a", "8c", "8g", "8l",
|
||||||
|
"9a", "9c", "9g", "9l",
|
||||||
"6cov",
|
"6cov",
|
||||||
"6nm",
|
"6nm",
|
||||||
"6prof",
|
"6prof",
|
||||||
|
|
@ -521,6 +524,7 @@ static struct {
|
||||||
"anames5.c",
|
"anames5.c",
|
||||||
"anames6.c",
|
"anames6.c",
|
||||||
"anames8.c",
|
"anames8.c",
|
||||||
|
"anames9.c",
|
||||||
}},
|
}},
|
||||||
{"cmd/cc", {
|
{"cmd/cc", {
|
||||||
"-pgen.c",
|
"-pgen.c",
|
||||||
|
|
@ -549,6 +553,11 @@ static struct {
|
||||||
"../cc/pswt.c",
|
"../cc/pswt.c",
|
||||||
"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
|
"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
|
||||||
}},
|
}},
|
||||||
|
{"cmd/9c", {
|
||||||
|
"../cc/pgen.c",
|
||||||
|
"../cc/pswt.c",
|
||||||
|
"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
|
||||||
|
}},
|
||||||
{"cmd/5g", {
|
{"cmd/5g", {
|
||||||
"../gc/cplx.c",
|
"../gc/cplx.c",
|
||||||
"../gc/pgen.c",
|
"../gc/pgen.c",
|
||||||
|
|
@ -573,6 +582,14 @@ static struct {
|
||||||
"../gc/popt.h",
|
"../gc/popt.h",
|
||||||
"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
|
"$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", {
|
{"cmd/5l", {
|
||||||
"../ld/*",
|
"../ld/*",
|
||||||
}},
|
}},
|
||||||
|
|
@ -582,6 +599,9 @@ static struct {
|
||||||
{"cmd/8l", {
|
{"cmd/8l", {
|
||||||
"../ld/*",
|
"../ld/*",
|
||||||
}},
|
}},
|
||||||
|
{"cmd/9l", {
|
||||||
|
"../ld/*",
|
||||||
|
}},
|
||||||
{"cmd/go", {
|
{"cmd/go", {
|
||||||
"zdefaultcc.go",
|
"zdefaultcc.go",
|
||||||
}},
|
}},
|
||||||
|
|
@ -618,6 +638,7 @@ static struct {
|
||||||
{"anames5.c", mkanames},
|
{"anames5.c", mkanames},
|
||||||
{"anames6.c", mkanames},
|
{"anames6.c", mkanames},
|
||||||
{"anames8.c", mkanames},
|
{"anames8.c", mkanames},
|
||||||
|
{"anames9.c", mkanames},
|
||||||
{"zasm_", mkzasm},
|
{"zasm_", mkzasm},
|
||||||
{"zdefaultcc.go", mkzdefaultcc},
|
{"zdefaultcc.go", mkzdefaultcc},
|
||||||
{"zsys_", mkzsys},
|
{"zsys_", mkzsys},
|
||||||
|
|
@ -1163,12 +1184,26 @@ shouldbuild(char *file, char *dir)
|
||||||
|
|
||||||
// Check file name for GOOS or GOARCH.
|
// Check file name for GOOS or GOARCH.
|
||||||
name = lastelem(file);
|
name = lastelem(file);
|
||||||
for(i=0; i<nelem(okgoos); i++)
|
for(i=0; i<nelem(okgoos); i++) {
|
||||||
if(contains(name, okgoos[i]) && !streq(okgoos[i], goos))
|
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;
|
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;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Omit test files.
|
// Omit test files.
|
||||||
if(contains(name, "_test"))
|
if(contains(name, "_test"))
|
||||||
|
|
@ -1367,6 +1402,10 @@ static char *cleantab[] = {
|
||||||
"cmd/8c",
|
"cmd/8c",
|
||||||
"cmd/8g",
|
"cmd/8g",
|
||||||
"cmd/8l",
|
"cmd/8l",
|
||||||
|
"cmd/9a",
|
||||||
|
"cmd/9c",
|
||||||
|
"cmd/9g",
|
||||||
|
"cmd/9l",
|
||||||
"cmd/cc",
|
"cmd/cc",
|
||||||
"cmd/gc",
|
"cmd/gc",
|
||||||
"cmd/go",
|
"cmd/go",
|
||||||
|
|
|
||||||
2
src/cmd/dist/buildgc.c
vendored
2
src/cmd/dist/buildgc.c
vendored
|
|
@ -63,7 +63,7 @@ gcopnames(char *dir, char *file)
|
||||||
vfree(&fields);
|
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.
|
// The format is much the same as the Go opcodes above.
|
||||||
// it also writes out cnames array for C_* constants.
|
// it also writes out cnames array for C_* constants.
|
||||||
void
|
void
|
||||||
|
|
|
||||||
7
src/cmd/dist/buildruntime.c
vendored
7
src/cmd/dist/buildruntime.c
vendored
|
|
@ -148,6 +148,13 @@ static struct {
|
||||||
{"arm", "",
|
{"arm", "",
|
||||||
"#define LR R14\n"
|
"#define LR R14\n"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{"power64", "",
|
||||||
|
"#define g R30\n"
|
||||||
|
},
|
||||||
|
{"power64le", "",
|
||||||
|
"#define g R30\n"
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAXWINCB 2000 /* maximum number of windows callbacks allowed */
|
#define MAXWINCB 2000 /* maximum number of windows callbacks allowed */
|
||||||
|
|
|
||||||
4
src/cmd/dist/unix.c
vendored
4
src/cmd/dist/unix.c
vendored
|
|
@ -708,6 +708,10 @@ main(int argc, char **argv)
|
||||||
gohostarch = "386";
|
gohostarch = "386";
|
||||||
else if(contains(u.machine, "arm"))
|
else if(contains(u.machine, "arm"))
|
||||||
gohostarch = "arm";
|
gohostarch = "arm";
|
||||||
|
else if(contains(u.machine, "ppc64le"))
|
||||||
|
gohostarch = "power64le";
|
||||||
|
else if(contains(u.machine, "ppc64"))
|
||||||
|
gohostarch = "power64";
|
||||||
else
|
else
|
||||||
fatal("unknown architecture: %s", u.machine);
|
fatal("unknown architecture: %s", u.machine);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -471,7 +471,7 @@ allocauto(Prog* ptxt)
|
||||||
stksize = rnd(stksize, n->type->align);
|
stksize = rnd(stksize, n->type->align);
|
||||||
if(haspointers(n->type))
|
if(haspointers(n->type))
|
||||||
stkptrsize = stksize;
|
stkptrsize = stksize;
|
||||||
if(thechar == '5')
|
if(thechar == '5' || thechar == '9')
|
||||||
stksize = rnd(stksize, widthptr);
|
stksize = rnd(stksize, widthptr);
|
||||||
if(stksize >= (1ULL<<31)) {
|
if(stksize >= (1ULL<<31)) {
|
||||||
setlineno(curfn);
|
setlineno(curfn);
|
||||||
|
|
@ -528,7 +528,7 @@ cgen_checknil(Node *n)
|
||||||
dump("checknil", n);
|
dump("checknil", n);
|
||||||
fatal("bad checknil");
|
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(®, types[tptr], n);
|
regalloc(®, types[tptr], n);
|
||||||
cgen(n, ®);
|
cgen(n, ®);
|
||||||
gins(ACHECKNIL, ®, N);
|
gins(ACHECKNIL, ®, N);
|
||||||
|
|
|
||||||
|
|
@ -847,6 +847,10 @@ nilopt(Prog *firstp)
|
||||||
Graph *g;
|
Graph *g;
|
||||||
int ncheck, nkill;
|
int ncheck, nkill;
|
||||||
|
|
||||||
|
// TODO(minux): nilopt on power64 throw away seemly random segment of code.
|
||||||
|
if(thechar == '9')
|
||||||
|
return;
|
||||||
|
|
||||||
g = flowstart(firstp, sizeof(NilFlow));
|
g = flowstart(firstp, sizeof(NilFlow));
|
||||||
if(g == nil)
|
if(g == nil)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -3301,6 +3301,9 @@ walkrotate(Node **np)
|
||||||
int w, sl, sr, s;
|
int w, sl, sr, s;
|
||||||
Node *l, *r;
|
Node *l, *r;
|
||||||
Node *n;
|
Node *n;
|
||||||
|
|
||||||
|
if(thechar == '9')
|
||||||
|
return;
|
||||||
|
|
||||||
n = *np;
|
n = *np;
|
||||||
|
|
||||||
|
|
@ -3426,6 +3429,10 @@ walkdiv(Node **np, NodeList **init)
|
||||||
Type *twide;
|
Type *twide;
|
||||||
Magic m;
|
Magic m;
|
||||||
|
|
||||||
|
// TODO(minux)
|
||||||
|
if(thechar == '9')
|
||||||
|
return;
|
||||||
|
|
||||||
n = *np;
|
n = *np;
|
||||||
if(n->right->op != OLITERAL)
|
if(n->right->op != OLITERAL)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -445,11 +445,11 @@ blk(LSym *start, int64 addr, int64 size)
|
||||||
continue;
|
continue;
|
||||||
if(sym->value >= eaddr)
|
if(sym->value >= eaddr)
|
||||||
break;
|
break;
|
||||||
|
ctxt->cursym = sym;
|
||||||
if(sym->value < addr) {
|
if(sym->value < addr) {
|
||||||
diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type);
|
diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type);
|
||||||
errorexit();
|
errorexit();
|
||||||
}
|
}
|
||||||
ctxt->cursym = sym;
|
|
||||||
for(; addr < sym->value; addr++)
|
for(; addr < sym->value; addr++)
|
||||||
cput(0);
|
cput(0);
|
||||||
p = sym->p;
|
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);
|
diag("phase error: addr=%#llx value+size=%#llx", (vlong)addr, (vlong)sym->value+sym->size);
|
||||||
errorexit();
|
errorexit();
|
||||||
}
|
}
|
||||||
|
if(sym->value+sym->size >= eaddr)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(; addr < eaddr; addr++)
|
for(; addr < eaddr; addr++)
|
||||||
|
|
|
||||||
|
|
@ -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
|
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
|
It reads object files (.5, .6, .8, .9 files) and writes a binary named for the
|
||||||
architecture (5.out, 6.out, 8.out) by default (if $GOOS is windows, a .exe suffix
|
architecture (5.out, 6.out, 8.out, 9.out) by default (if $GOOS is windows, a .exe suffix
|
||||||
will be appended).
|
will be appended).
|
||||||
|
|
||||||
Major changes include:
|
Major changes include:
|
||||||
|
|
@ -22,7 +22,7 @@ Original options are listed on the manual page linked above.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
go tool 6l [flags] mainObj
|
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:
|
Options new in this version:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2189,7 +2189,7 @@ dwarfaddshstrings(LSym *shstrtab)
|
||||||
elfstrdbg[ElfStrDebugStr] = addstring(shstrtab, ".debug_str");
|
elfstrdbg[ElfStrDebugStr] = addstring(shstrtab, ".debug_str");
|
||||||
elfstrdbg[ElfStrGDBScripts] = addstring(shstrtab, ".debug_gdb_scripts");
|
elfstrdbg[ElfStrGDBScripts] = addstring(shstrtab, ".debug_gdb_scripts");
|
||||||
if(linkmode == LinkExternal) {
|
if(linkmode == LinkExternal) {
|
||||||
if(thechar == '6') {
|
if(thechar == '6' || thechar == '9') {
|
||||||
elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
|
elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
|
||||||
elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
|
elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
|
||||||
elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
|
elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
|
||||||
|
|
@ -2244,7 +2244,7 @@ dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
|
||||||
ElfShdr *sh;
|
ElfShdr *sh;
|
||||||
|
|
||||||
sh = newElfShdr(elfstrdbg[elfstr]);
|
sh = newElfShdr(elfstrdbg[elfstr]);
|
||||||
if(thechar == '6') {
|
if(thechar == '6' || thechar == '9') {
|
||||||
sh->type = SHT_RELA;
|
sh->type = SHT_RELA;
|
||||||
} else {
|
} else {
|
||||||
sh->type = SHT_REL;
|
sh->type = SHT_REL;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ elfinit(void)
|
||||||
switch(thechar) {
|
switch(thechar) {
|
||||||
// 64-bit architectures
|
// 64-bit architectures
|
||||||
case '6':
|
case '6':
|
||||||
|
case '9':
|
||||||
elf64 = 1;
|
elf64 = 1;
|
||||||
hdr.phoff = ELF64HDRSIZE; /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
|
hdr.phoff = ELF64HDRSIZE; /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
|
||||||
hdr.shoff = ELF64HDRSIZE; /* Will move as we add PHeaders */
|
hdr.shoff = ELF64HDRSIZE; /* Will move as we add PHeaders */
|
||||||
|
|
@ -678,7 +679,7 @@ elfdynhash(void)
|
||||||
elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0));
|
elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thechar == '6') {
|
if(thechar == '6' || thechar == '9') {
|
||||||
sy = linklookup(ctxt, ".rela.plt", 0);
|
sy = linklookup(ctxt, ".rela.plt", 0);
|
||||||
if(sy->size > 0) {
|
if(sy->size > 0) {
|
||||||
elfwritedynent(s, DT_PLTREL, DT_RELA);
|
elfwritedynent(s, DT_PLTREL, DT_RELA);
|
||||||
|
|
@ -804,7 +805,7 @@ elfshreloc(Section *sect)
|
||||||
if(strcmp(sect->name, ".shstrtab") == 0 || strcmp(sect->name, ".tbss") == 0)
|
if(strcmp(sect->name, ".shstrtab") == 0 || strcmp(sect->name, ".tbss") == 0)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
if(thechar == '6') {
|
if(thechar == '6' || thechar == '9') {
|
||||||
prefix = ".rela";
|
prefix = ".rela";
|
||||||
typ = SHT_RELA;
|
typ = SHT_RELA;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -931,7 +932,7 @@ doelf(void)
|
||||||
debug['s'] = 0;
|
debug['s'] = 0;
|
||||||
debug['d'] = 1;
|
debug['d'] = 1;
|
||||||
|
|
||||||
if(thechar == '6') {
|
if(thechar == '6' || thechar == '9') {
|
||||||
addstring(shstrtab, ".rela.text");
|
addstring(shstrtab, ".rela.text");
|
||||||
addstring(shstrtab, ".rela.rodata");
|
addstring(shstrtab, ".rela.rodata");
|
||||||
addstring(shstrtab, ".rela.typelink");
|
addstring(shstrtab, ".rela.typelink");
|
||||||
|
|
@ -954,7 +955,7 @@ doelf(void)
|
||||||
|
|
||||||
if(flag_shared) {
|
if(flag_shared) {
|
||||||
addstring(shstrtab, ".init_array");
|
addstring(shstrtab, ".init_array");
|
||||||
if(thechar == '6')
|
if(thechar == '6' || thechar == '9')
|
||||||
addstring(shstrtab, ".rela.init_array");
|
addstring(shstrtab, ".rela.init_array");
|
||||||
else
|
else
|
||||||
addstring(shstrtab, ".rel.init_array");
|
addstring(shstrtab, ".rel.init_array");
|
||||||
|
|
@ -975,7 +976,7 @@ doelf(void)
|
||||||
addstring(shstrtab, ".dynamic");
|
addstring(shstrtab, ".dynamic");
|
||||||
addstring(shstrtab, ".dynsym");
|
addstring(shstrtab, ".dynsym");
|
||||||
addstring(shstrtab, ".dynstr");
|
addstring(shstrtab, ".dynstr");
|
||||||
if(thechar == '6') {
|
if(thechar == '6' || thechar == '9') {
|
||||||
addstring(shstrtab, ".rela");
|
addstring(shstrtab, ".rela");
|
||||||
addstring(shstrtab, ".rela.plt");
|
addstring(shstrtab, ".rela.plt");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -990,7 +991,7 @@ doelf(void)
|
||||||
s = linklookup(ctxt, ".dynsym", 0);
|
s = linklookup(ctxt, ".dynsym", 0);
|
||||||
s->type = SELFROSECT;
|
s->type = SELFROSECT;
|
||||||
s->reachable = 1;
|
s->reachable = 1;
|
||||||
if(thechar == '6')
|
if(thechar == '6' || thechar == '9')
|
||||||
s->size += ELF64SYMSIZE;
|
s->size += ELF64SYMSIZE;
|
||||||
else
|
else
|
||||||
s->size += ELF32SYMSIZE;
|
s->size += ELF32SYMSIZE;
|
||||||
|
|
@ -1004,7 +1005,7 @@ doelf(void)
|
||||||
dynstr = s;
|
dynstr = s;
|
||||||
|
|
||||||
/* relocation table */
|
/* relocation table */
|
||||||
if(thechar == '6')
|
if(thechar == '6' || thechar == '9')
|
||||||
s = linklookup(ctxt, ".rela", 0);
|
s = linklookup(ctxt, ".rela", 0);
|
||||||
else
|
else
|
||||||
s = linklookup(ctxt, ".rel", 0);
|
s = linklookup(ctxt, ".rel", 0);
|
||||||
|
|
@ -1031,7 +1032,7 @@ doelf(void)
|
||||||
|
|
||||||
elfsetupplt();
|
elfsetupplt();
|
||||||
|
|
||||||
if(thechar == '6')
|
if(thechar == '6' || thechar == '9')
|
||||||
s = linklookup(ctxt, ".rela.plt", 0);
|
s = linklookup(ctxt, ".rela.plt", 0);
|
||||||
else
|
else
|
||||||
s = linklookup(ctxt, ".rel.plt", 0);
|
s = linklookup(ctxt, ".rel.plt", 0);
|
||||||
|
|
@ -1056,13 +1057,13 @@ doelf(void)
|
||||||
*/
|
*/
|
||||||
elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0));
|
elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0));
|
||||||
elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0));
|
elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0));
|
||||||
if(thechar == '6')
|
if(thechar == '6' || thechar == '9')
|
||||||
elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE);
|
elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE);
|
||||||
else
|
else
|
||||||
elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
|
elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
|
||||||
elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0));
|
elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0));
|
||||||
elfwritedynentsymsize(s, DT_STRSZ, 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));
|
elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0));
|
||||||
elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0));
|
elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0));
|
||||||
elfwritedynent(s, DT_RELAENT, ELF64RELASIZE);
|
elfwritedynent(s, DT_RELAENT, ELF64RELASIZE);
|
||||||
|
|
@ -1148,6 +1149,9 @@ asmbelf(vlong symo)
|
||||||
case '8':
|
case '8':
|
||||||
eh->machine = EM_386;
|
eh->machine = EM_386;
|
||||||
break;
|
break;
|
||||||
|
case '9':
|
||||||
|
eh->machine = EM_PPC64;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
startva = INITTEXT - HEADR;
|
startva = INITTEXT - HEADR;
|
||||||
|
|
@ -1488,7 +1492,10 @@ elfobj:
|
||||||
eh->ident[EI_CLASS] = ELFCLASS64;
|
eh->ident[EI_CLASS] = ELFCLASS64;
|
||||||
else
|
else
|
||||||
eh->ident[EI_CLASS] = ELFCLASS32;
|
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;
|
eh->ident[EI_VERSION] = EV_CURRENT;
|
||||||
|
|
||||||
if(linkmode == LinkExternal)
|
if(linkmode == LinkExternal)
|
||||||
|
|
|
||||||
|
|
@ -436,6 +436,12 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
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.
|
// load section list into memory.
|
||||||
|
|
|
||||||
|
|
@ -594,6 +594,7 @@ hostlink(void)
|
||||||
argv[argc++] = "-m32";
|
argv[argc++] = "-m32";
|
||||||
break;
|
break;
|
||||||
case '6':
|
case '6':
|
||||||
|
case '9':
|
||||||
argv[argc++] = "-m64";
|
argv[argc++] = "-m64";
|
||||||
break;
|
break;
|
||||||
case '5':
|
case '5':
|
||||||
|
|
@ -1033,7 +1034,7 @@ static LSym *newstack;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
HasLinkRegister = (thechar == '5'),
|
HasLinkRegister = (thechar == '5' || thechar == '9'),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Record enough information in new object files to
|
// TODO: Record enough information in new object files to
|
||||||
|
|
@ -1042,7 +1043,7 @@ enum
|
||||||
static int
|
static int
|
||||||
callsize(void)
|
callsize(void)
|
||||||
{
|
{
|
||||||
if(thechar == '5')
|
if(HasLinkRegister)
|
||||||
return 0;
|
return 0;
|
||||||
return RegSize;
|
return RegSize;
|
||||||
}
|
}
|
||||||
|
|
@ -1052,7 +1053,7 @@ dostkcheck(void)
|
||||||
{
|
{
|
||||||
Chain ch;
|
Chain ch;
|
||||||
LSym *s;
|
LSym *s;
|
||||||
|
|
||||||
morestack = linklookup(ctxt, "runtime.morestack", 0);
|
morestack = linklookup(ctxt, "runtime.morestack", 0);
|
||||||
newstack = linklookup(ctxt, "runtime.newstack", 0);
|
newstack = linklookup(ctxt, "runtime.newstack", 0);
|
||||||
|
|
||||||
|
|
@ -1076,19 +1077,19 @@ dostkcheck(void)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(s->nosplit) {
|
if(s->nosplit) {
|
||||||
ctxt->cursym = s;
|
ctxt->cursym = s;
|
||||||
ch.sym = s;
|
ch.sym = s;
|
||||||
stkcheck(&ch, 0);
|
stkcheck(&ch, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(s = ctxt->textp; s != nil; s = s->next) {
|
for(s = ctxt->textp; s != nil; s = s->next) {
|
||||||
if(!s->nosplit) {
|
if(!s->nosplit) {
|
||||||
ctxt->cursym = s;
|
ctxt->cursym = s;
|
||||||
ch.sym = s;
|
ch.sym = s;
|
||||||
stkcheck(&ch, 0);
|
stkcheck(&ch, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
stkcheck(Chain *up, int depth)
|
stkcheck(Chain *up, int depth)
|
||||||
|
|
@ -1106,7 +1107,7 @@ stkcheck(Chain *up, int depth)
|
||||||
// function at top of safe zone once.
|
// function at top of safe zone once.
|
||||||
if(limit == StackLimit-callsize()) {
|
if(limit == StackLimit-callsize()) {
|
||||||
if(s->stkcheck)
|
if(s->stkcheck)
|
||||||
return 0;
|
return 0;
|
||||||
s->stkcheck = 1;
|
s->stkcheck = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1154,6 +1155,7 @@ stkcheck(Chain *up, int depth)
|
||||||
switch(r->type) {
|
switch(r->type) {
|
||||||
case R_CALL:
|
case R_CALL:
|
||||||
case R_CALLARM:
|
case R_CALLARM:
|
||||||
|
case R_CALLPOWER:
|
||||||
// Direct call.
|
// Direct call.
|
||||||
ch.limit = limit - pcsp.value - callsize();
|
ch.limit = limit - pcsp.value - callsize();
|
||||||
ch.sym = r->sym;
|
ch.sym = r->sym;
|
||||||
|
|
@ -1164,8 +1166,8 @@ stkcheck(Chain *up, int depth)
|
||||||
// to StackLimit beyond the frame size.
|
// to StackLimit beyond the frame size.
|
||||||
if(strncmp(r->sym->name, "runtime.morestack", 17) == 0) {
|
if(strncmp(r->sym->name, "runtime.morestack", 17) == 0) {
|
||||||
limit = StackLimit + s->locals;
|
limit = StackLimit + s->locals;
|
||||||
if(thechar == '5')
|
if(HasLinkRegister)
|
||||||
limit += 4; // saved LR
|
limit += RegSize;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1184,7 +1186,7 @@ stkcheck(Chain *up, int depth)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1213,7 +1215,7 @@ stkprint(Chain *ch, int limit)
|
||||||
else
|
else
|
||||||
print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
|
print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
|
||||||
} else {
|
} else {
|
||||||
stkprint(ch->up, ch->limit + (!HasLinkRegister)*PtrSize);
|
stkprint(ch->up, ch->limit + (!HasLinkRegister)*RegSize);
|
||||||
if(!HasLinkRegister)
|
if(!HasLinkRegister)
|
||||||
print("\t%d\ton entry to %s\n", ch->limit, name);
|
print("\t%d\ton entry to %s\n", ch->limit, name);
|
||||||
}
|
}
|
||||||
|
|
@ -1533,7 +1535,7 @@ callgraph(void)
|
||||||
r = &s->r[i];
|
r = &s->r[i];
|
||||||
if(r->sym == nil)
|
if(r->sym == nil)
|
||||||
continue;
|
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);
|
Bprint(&bso, "%s calls %s\n", s->name, r->sym->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ machoinit(void)
|
||||||
switch(thechar) {
|
switch(thechar) {
|
||||||
// 64-bit architectures
|
// 64-bit architectures
|
||||||
case '6':
|
case '6':
|
||||||
|
case '9':
|
||||||
macho64 = 1;
|
macho64 = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other)
|
||||||
{
|
{
|
||||||
switch(thechar) {
|
switch(thechar) {
|
||||||
case '6':
|
case '6':
|
||||||
|
case '9':
|
||||||
LPUT(off);
|
LPUT(off);
|
||||||
cput(info);
|
cput(info);
|
||||||
cput(other);
|
cput(other);
|
||||||
|
|
|
||||||
|
|
@ -1414,6 +1414,184 @@ var rppcStrings = []intName{
|
||||||
func (i R_PPC) String() string { return stringName(uint32(i), rppcStrings, false) }
|
func (i R_PPC) String() string { return stringName(uint32(i), rppcStrings, false) }
|
||||||
func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
|
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.
|
// Relocation types for SPARC.
|
||||||
type R_SPARC int
|
type R_SPARC int
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -532,6 +532,9 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {
|
||||||
if f.Class == ELFCLASS64 && f.Machine == EM_AARCH64 {
|
if f.Class == ELFCLASS64 && f.Machine == EM_AARCH64 {
|
||||||
return f.applyRelocationsARM64(dst, rels)
|
return f.applyRelocationsARM64(dst, rels)
|
||||||
}
|
}
|
||||||
|
if f.Class == ELFCLASS64 && f.Machine == EM_PPC64 {
|
||||||
|
return f.applyRelocationsPPC64(dst, rels)
|
||||||
|
}
|
||||||
|
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
@ -671,6 +674,51 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
|
||||||
return nil
|
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) {
|
func (f *File) DWARF() (*dwarf.Data, error) {
|
||||||
// There are many other DWARF sections, but these
|
// There are many other DWARF sections, but these
|
||||||
// are the required ones, and the debug/dwarf package
|
// 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
|
// 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.
|
// now otherwise the data in .debug_info is invalid for x86-64 objects.
|
||||||
rela := f.Section(".rela.debug_info")
|
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()
|
data, err := rela.Data()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -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)}}}},
|
{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",
|
"testdata/go-relocation-test-clang-x86.obj",
|
||||||
[]relocationTestEntry{
|
[]relocationTestEntry{
|
||||||
|
|
|
||||||
BIN
src/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj
vendored
Normal file
BIN
src/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj
vendored
Normal file
Binary file not shown.
|
|
@ -1384,6 +1384,8 @@ func ArchChar(goarch string) (string, error) {
|
||||||
return "6", nil
|
return "6", nil
|
||||||
case "arm":
|
case "arm":
|
||||||
return "5", nil
|
return "5", nil
|
||||||
|
case "power64", "power64le":
|
||||||
|
return "9", nil
|
||||||
}
|
}
|
||||||
return "", errors.New("unsupported GOARCH " + goarch)
|
return "", errors.New("unsupported GOARCH " + goarch)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,4 @@
|
||||||
package build
|
package build
|
||||||
|
|
||||||
const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows "
|
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 "
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build 386 arm
|
// +build 386 arm power64 power64le
|
||||||
|
|
||||||
package crc32
|
package crc32
|
||||||
|
|
||||||
|
|
|
||||||
2784
src/liblink/asm9.c
Normal file
2784
src/liblink/asm9.c
Normal file
File diff suppressed because it is too large
Load diff
409
src/liblink/list9.c
Normal file
409
src/liblink/list9.c
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
1086
src/liblink/obj9.c
Normal file
1086
src/liblink/obj9.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -142,6 +142,8 @@ writeobj(Link *ctxt, Biobuf *b)
|
||||||
edata = nil;
|
edata = nil;
|
||||||
for(pl = ctxt->plist; pl != nil; pl = pl->link) {
|
for(pl = ctxt->plist; pl != nil; pl = pl->link) {
|
||||||
for(p = pl->firstpc; p != nil; p = plink) {
|
for(p = pl->firstpc; p != nil; p = plink) {
|
||||||
|
if(ctxt->debugasm && ctxt->debugvlog)
|
||||||
|
print("obj: %p %P\n", p, p);
|
||||||
plink = p->link;
|
plink = p->link;
|
||||||
p->link = nil;
|
p->link = nil;
|
||||||
|
|
||||||
|
|
@ -365,7 +367,10 @@ writesym(Link *ctxt, Biobuf *b, LSym *s)
|
||||||
name = "";
|
name = "";
|
||||||
if(r->sym != nil)
|
if(r->sym != nil)
|
||||||
name = r->sym->name;
|
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;
|
s->type = SRODATA;
|
||||||
adduint32(ctxt, s, i32);
|
adduint32(ctxt, s, i32);
|
||||||
s->reachable = 0;
|
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;
|
int64 i64;
|
||||||
i64 = strtoull(s->name+5, nil, 16);
|
i64 = strtoull(s->name+5, nil, 16);
|
||||||
s->type = SRODATA;
|
s->type = SRODATA;
|
||||||
|
|
|
||||||
835
src/liblink/sched9.c
Normal file
835
src/liblink/sched9.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/math/abs_power64x.s
Normal file
14
src/math/abs_power64x.s
Normal file
|
|
@ -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
|
||||||
46
src/math/big/arith_power64x.s
Normal file
46
src/math/big/arith_power64x.s
Normal file
|
|
@ -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)
|
||||||
91
src/math/stubs_power64x.s
Normal file
91
src/math/stubs_power64x.s
Normal file
|
|
@ -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)
|
||||||
|
|
@ -4,13 +4,19 @@
|
||||||
|
|
||||||
// Assembly to get into package runtime without using exported symbols.
|
// 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"
|
#include "textflag.h"
|
||||||
|
|
||||||
#ifdef GOARCH_arm
|
#ifdef GOARCH_arm
|
||||||
#define JMP B
|
#define JMP B
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef GOARCH_power64
|
||||||
|
#define JMP BR
|
||||||
|
#endif
|
||||||
|
#ifdef GOARCH_power64le
|
||||||
|
#define JMP BR
|
||||||
|
#endif
|
||||||
|
|
||||||
TEXT ·signal_disable(SB),NOSPLIT,$0
|
TEXT ·signal_disable(SB),NOSPLIT,$0
|
||||||
JMP runtime·signal_disable(SB)
|
JMP runtime·signal_disable(SB)
|
||||||
|
|
|
||||||
|
|
@ -1052,6 +1052,11 @@ func TestChan(t *testing.T) {
|
||||||
ok = cv.TrySend(ValueOf(6))
|
ok = cv.TrySend(ValueOf(6))
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("TrySend on empty chan failed")
|
t.Errorf("TrySend on empty chan failed")
|
||||||
|
select {
|
||||||
|
case x := <-c:
|
||||||
|
t.Errorf("TrySend failed but it did send %d", x)
|
||||||
|
default:
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if i = <-c; i != 6 {
|
if i = <-c; i != 6 {
|
||||||
t.Errorf("TrySend 6, recv %d", i)
|
t.Errorf("TrySend 6, recv %d", i)
|
||||||
|
|
|
||||||
29
src/reflect/asm_power64x.s
Normal file
29
src/reflect/asm_power64x.s
Normal file
|
|
@ -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
|
||||||
8
src/runtime/arch_power64.go
Normal file
8
src/runtime/arch_power64.go
Normal file
|
|
@ -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
|
||||||
14
src/runtime/arch_power64.h
Normal file
14
src/runtime/arch_power64.h
Normal file
|
|
@ -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
|
||||||
|
};
|
||||||
|
|
||||||
8
src/runtime/arch_power64le.go
Normal file
8
src/runtime/arch_power64le.go
Normal file
|
|
@ -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
|
||||||
14
src/runtime/arch_power64le.h
Normal file
14
src/runtime/arch_power64le.h
Normal file
|
|
@ -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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -486,11 +486,11 @@ TEXT runtime·cas64(SB), NOSPLIT, $0-21
|
||||||
MOVL new_hi+16(FP), CX
|
MOVL new_hi+16(FP), CX
|
||||||
LOCK
|
LOCK
|
||||||
CMPXCHG8B 0(BP)
|
CMPXCHG8B 0(BP)
|
||||||
JNZ cas64_fail
|
JNZ fail
|
||||||
MOVL $1, AX
|
MOVL $1, AX
|
||||||
MOVB AX, ret+20(FP)
|
MOVB AX, ret+20(FP)
|
||||||
RET
|
RET
|
||||||
cas64_fail:
|
fail:
|
||||||
MOVL $0, AX
|
MOVL $0, AX
|
||||||
MOVB AX, ret+20(FP)
|
MOVB AX, ret+20(FP)
|
||||||
RET
|
RET
|
||||||
|
|
@ -1356,29 +1356,29 @@ TEXT strings·IndexByte(SB),NOSPLIT,$0
|
||||||
// AX = 1/0/-1
|
// AX = 1/0/-1
|
||||||
TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
|
TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
|
||||||
CMPL SI, DI
|
CMPL SI, DI
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
CMPL BX, DX
|
CMPL BX, DX
|
||||||
MOVL DX, BP
|
MOVL DX, BP
|
||||||
CMOVLLT BX, BP // BP = min(alen, blen)
|
CMOVLLT BX, BP // BP = min(alen, blen)
|
||||||
CMPL BP, $4
|
CMPL BP, $4
|
||||||
JB cmp_small
|
JB small
|
||||||
TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
|
TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
|
||||||
JE cmp_mediumloop
|
JE mediumloop
|
||||||
cmp_largeloop:
|
largeloop:
|
||||||
CMPL BP, $16
|
CMPL BP, $16
|
||||||
JB cmp_mediumloop
|
JB mediumloop
|
||||||
MOVOU (SI), X0
|
MOVOU (SI), X0
|
||||||
MOVOU (DI), X1
|
MOVOU (DI), X1
|
||||||
PCMPEQB X0, X1
|
PCMPEQB X0, X1
|
||||||
PMOVMSKB X1, AX
|
PMOVMSKB X1, AX
|
||||||
XORL $0xffff, AX // convert EQ to NE
|
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, SI
|
||||||
ADDL $16, DI
|
ADDL $16, DI
|
||||||
SUBL $16, BP
|
SUBL $16, BP
|
||||||
JMP cmp_largeloop
|
JMP largeloop
|
||||||
|
|
||||||
cmp_diff16:
|
diff16:
|
||||||
BSFL AX, BX // index of first byte that differs
|
BSFL AX, BX // index of first byte that differs
|
||||||
XORL AX, AX
|
XORL AX, AX
|
||||||
MOVB (SI)(BX*1), CX
|
MOVB (SI)(BX*1), CX
|
||||||
|
|
@ -1387,25 +1387,25 @@ cmp_diff16:
|
||||||
LEAL -1(AX*2), AX // convert 1/0 to +1/-1
|
LEAL -1(AX*2), AX // convert 1/0 to +1/-1
|
||||||
RET
|
RET
|
||||||
|
|
||||||
cmp_mediumloop:
|
mediumloop:
|
||||||
CMPL BP, $4
|
CMPL BP, $4
|
||||||
JBE cmp_0through4
|
JBE _0through4
|
||||||
MOVL (SI), AX
|
MOVL (SI), AX
|
||||||
MOVL (DI), CX
|
MOVL (DI), CX
|
||||||
CMPL AX, CX
|
CMPL AX, CX
|
||||||
JNE cmp_diff4
|
JNE diff4
|
||||||
ADDL $4, SI
|
ADDL $4, SI
|
||||||
ADDL $4, DI
|
ADDL $4, DI
|
||||||
SUBL $4, BP
|
SUBL $4, BP
|
||||||
JMP cmp_mediumloop
|
JMP mediumloop
|
||||||
|
|
||||||
cmp_0through4:
|
_0through4:
|
||||||
MOVL -4(SI)(BP*1), AX
|
MOVL -4(SI)(BP*1), AX
|
||||||
MOVL -4(DI)(BP*1), CX
|
MOVL -4(DI)(BP*1), CX
|
||||||
CMPL AX, CX
|
CMPL AX, CX
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
|
|
||||||
cmp_diff4:
|
diff4:
|
||||||
BSWAPL AX // reverse order of bytes
|
BSWAPL AX // reverse order of bytes
|
||||||
BSWAPL CX
|
BSWAPL CX
|
||||||
XORL AX, CX // find bit differences
|
XORL AX, CX // find bit differences
|
||||||
|
|
@ -1416,37 +1416,37 @@ cmp_diff4:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// 0-3 bytes in common
|
// 0-3 bytes in common
|
||||||
cmp_small:
|
small:
|
||||||
LEAL (BP*8), CX
|
LEAL (BP*8), CX
|
||||||
NEGL CX
|
NEGL CX
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
|
|
||||||
// load si
|
// load si
|
||||||
CMPB SI, $0xfc
|
CMPB SI, $0xfc
|
||||||
JA cmp_si_high
|
JA si_high
|
||||||
MOVL (SI), SI
|
MOVL (SI), SI
|
||||||
JMP cmp_si_finish
|
JMP si_finish
|
||||||
cmp_si_high:
|
si_high:
|
||||||
MOVL -4(SI)(BP*1), SI
|
MOVL -4(SI)(BP*1), SI
|
||||||
SHRL CX, SI
|
SHRL CX, SI
|
||||||
cmp_si_finish:
|
si_finish:
|
||||||
SHLL CX, SI
|
SHLL CX, SI
|
||||||
|
|
||||||
// same for di
|
// same for di
|
||||||
CMPB DI, $0xfc
|
CMPB DI, $0xfc
|
||||||
JA cmp_di_high
|
JA di_high
|
||||||
MOVL (DI), DI
|
MOVL (DI), DI
|
||||||
JMP cmp_di_finish
|
JMP di_finish
|
||||||
cmp_di_high:
|
di_high:
|
||||||
MOVL -4(DI)(BP*1), DI
|
MOVL -4(DI)(BP*1), DI
|
||||||
SHRL CX, DI
|
SHRL CX, DI
|
||||||
cmp_di_finish:
|
di_finish:
|
||||||
SHLL CX, DI
|
SHLL CX, DI
|
||||||
|
|
||||||
BSWAPL SI // reverse order of bytes
|
BSWAPL SI // reverse order of bytes
|
||||||
BSWAPL DI
|
BSWAPL DI
|
||||||
XORL SI, DI // find bit differences
|
XORL SI, DI // find bit differences
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
BSRL DI, CX // index of highest bit difference
|
BSRL DI, CX // index of highest bit difference
|
||||||
SHRL CX, SI // move a's bit to bottom
|
SHRL CX, SI // move a's bit to bottom
|
||||||
ANDL $1, SI // mask bit
|
ANDL $1, SI // mask bit
|
||||||
|
|
@ -1455,7 +1455,7 @@ cmp_di_finish:
|
||||||
|
|
||||||
// all the bytes in common are the same, so we just need
|
// all the bytes in common are the same, so we just need
|
||||||
// to compare the lengths.
|
// to compare the lengths.
|
||||||
cmp_allsame:
|
allsame:
|
||||||
XORL AX, AX
|
XORL AX, AX
|
||||||
XORL CX, CX
|
XORL CX, CX
|
||||||
CMPL BX, DX
|
CMPL BX, DX
|
||||||
|
|
|
||||||
|
|
@ -461,11 +461,11 @@ TEXT runtime·cas64(SB), NOSPLIT, $0-25
|
||||||
MOVQ new+16(FP), CX
|
MOVQ new+16(FP), CX
|
||||||
LOCK
|
LOCK
|
||||||
CMPXCHGQ CX, 0(BX)
|
CMPXCHGQ CX, 0(BX)
|
||||||
JNZ cas64_fail
|
JNZ fail
|
||||||
MOVL $1, AX
|
MOVL $1, AX
|
||||||
MOVB AX, ret+24(FP)
|
MOVB AX, ret+24(FP)
|
||||||
RET
|
RET
|
||||||
cas64_fail:
|
fail:
|
||||||
MOVL $0, AX
|
MOVL $0, AX
|
||||||
MOVB AX, ret+24(FP)
|
MOVB AX, ret+24(FP)
|
||||||
RET
|
RET
|
||||||
|
|
@ -890,24 +890,24 @@ TEXT runtime·aeshashbody(SB),NOSPLIT,$0-32
|
||||||
MOVO runtime·aeskeysched+0(SB), X2
|
MOVO runtime·aeskeysched+0(SB), X2
|
||||||
MOVO runtime·aeskeysched+16(SB), X3
|
MOVO runtime·aeskeysched+16(SB), X3
|
||||||
CMPQ CX, $16
|
CMPQ CX, $16
|
||||||
JB aessmall
|
JB small
|
||||||
aesloop:
|
loop:
|
||||||
CMPQ CX, $16
|
CMPQ CX, $16
|
||||||
JBE aesloopend
|
JBE loopend
|
||||||
MOVOU (AX), X1
|
MOVOU (AX), X1
|
||||||
AESENC X2, X0
|
AESENC X2, X0
|
||||||
AESENC X1, X0
|
AESENC X1, X0
|
||||||
SUBQ $16, CX
|
SUBQ $16, CX
|
||||||
ADDQ $16, AX
|
ADDQ $16, AX
|
||||||
JMP aesloop
|
JMP loop
|
||||||
// 1-16 bytes remaining
|
// 1-16 bytes remaining
|
||||||
aesloopend:
|
loopend:
|
||||||
// This load may overlap with the previous load above.
|
// This load may overlap with the previous load above.
|
||||||
// We'll hash some bytes twice, but that's ok.
|
// We'll hash some bytes twice, but that's ok.
|
||||||
MOVOU -16(AX)(CX*1), X1
|
MOVOU -16(AX)(CX*1), X1
|
||||||
JMP partial
|
JMP partial
|
||||||
// 0-15 bytes
|
// 0-15 bytes
|
||||||
aessmall:
|
small:
|
||||||
TESTQ CX, CX
|
TESTQ CX, CX
|
||||||
JE finalize // 0 bytes
|
JE finalize // 0 bytes
|
||||||
|
|
||||||
|
|
@ -1050,18 +1050,18 @@ TEXT runtime·eqstring(SB),NOSPLIT,$0-33
|
||||||
MOVQ s1len+8(FP), AX
|
MOVQ s1len+8(FP), AX
|
||||||
MOVQ s2len+24(FP), BX
|
MOVQ s2len+24(FP), BX
|
||||||
CMPQ AX, BX
|
CMPQ AX, BX
|
||||||
JNE different
|
JNE noteq
|
||||||
MOVQ s1str+0(FP), SI
|
MOVQ s1str+0(FP), SI
|
||||||
MOVQ s2str+16(FP), DI
|
MOVQ s2str+16(FP), DI
|
||||||
CMPQ SI, DI
|
CMPQ SI, DI
|
||||||
JEQ same
|
JEQ eq
|
||||||
CALL runtime·memeqbody(SB)
|
CALL runtime·memeqbody(SB)
|
||||||
MOVB AX, v+32(FP)
|
MOVB AX, v+32(FP)
|
||||||
RET
|
RET
|
||||||
same:
|
eq:
|
||||||
MOVB $1, v+32(FP)
|
MOVB $1, v+32(FP)
|
||||||
RET
|
RET
|
||||||
different:
|
noteq:
|
||||||
MOVB $0, v+32(FP)
|
MOVB $0, v+32(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
|
@ -1184,29 +1184,29 @@ TEXT runtime·cmpbytes(SB),NOSPLIT,$0-56
|
||||||
// AX = 1/0/-1
|
// AX = 1/0/-1
|
||||||
TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
|
TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
|
||||||
CMPQ SI, DI
|
CMPQ SI, DI
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
CMPQ BX, DX
|
CMPQ BX, DX
|
||||||
MOVQ DX, BP
|
MOVQ DX, BP
|
||||||
CMOVQLT BX, BP // BP = min(alen, blen) = # of bytes to compare
|
CMOVQLT BX, BP // BP = min(alen, blen) = # of bytes to compare
|
||||||
CMPQ BP, $8
|
CMPQ BP, $8
|
||||||
JB cmp_small
|
JB small
|
||||||
|
|
||||||
cmp_loop:
|
loop:
|
||||||
CMPQ BP, $16
|
CMPQ BP, $16
|
||||||
JBE cmp_0through16
|
JBE _0through16
|
||||||
MOVOU (SI), X0
|
MOVOU (SI), X0
|
||||||
MOVOU (DI), X1
|
MOVOU (DI), X1
|
||||||
PCMPEQB X0, X1
|
PCMPEQB X0, X1
|
||||||
PMOVMSKB X1, AX
|
PMOVMSKB X1, AX
|
||||||
XORQ $0xffff, AX // convert EQ to NE
|
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, SI
|
||||||
ADDQ $16, DI
|
ADDQ $16, DI
|
||||||
SUBQ $16, BP
|
SUBQ $16, BP
|
||||||
JMP cmp_loop
|
JMP loop
|
||||||
|
|
||||||
// AX = bit mask of differences
|
// AX = bit mask of differences
|
||||||
cmp_diff16:
|
diff16:
|
||||||
BSFQ AX, BX // index of first byte that differs
|
BSFQ AX, BX // index of first byte that differs
|
||||||
XORQ AX, AX
|
XORQ AX, AX
|
||||||
MOVB (SI)(BX*1), CX
|
MOVB (SI)(BX*1), CX
|
||||||
|
|
@ -1216,21 +1216,21 @@ cmp_diff16:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// 0 through 16 bytes left, alen>=8, blen>=8
|
// 0 through 16 bytes left, alen>=8, blen>=8
|
||||||
cmp_0through16:
|
_0through16:
|
||||||
CMPQ BP, $8
|
CMPQ BP, $8
|
||||||
JBE cmp_0through8
|
JBE _0through8
|
||||||
MOVQ (SI), AX
|
MOVQ (SI), AX
|
||||||
MOVQ (DI), CX
|
MOVQ (DI), CX
|
||||||
CMPQ AX, CX
|
CMPQ AX, CX
|
||||||
JNE cmp_diff8
|
JNE diff8
|
||||||
cmp_0through8:
|
_0through8:
|
||||||
MOVQ -8(SI)(BP*1), AX
|
MOVQ -8(SI)(BP*1), AX
|
||||||
MOVQ -8(DI)(BP*1), CX
|
MOVQ -8(DI)(BP*1), CX
|
||||||
CMPQ AX, CX
|
CMPQ AX, CX
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
|
|
||||||
// AX and CX contain parts of a and b that differ.
|
// AX and CX contain parts of a and b that differ.
|
||||||
cmp_diff8:
|
diff8:
|
||||||
BSWAPQ AX // reverse order of bytes
|
BSWAPQ AX // reverse order of bytes
|
||||||
BSWAPQ CX
|
BSWAPQ CX
|
||||||
XORQ AX, CX
|
XORQ AX, CX
|
||||||
|
|
@ -1241,44 +1241,44 @@ cmp_diff8:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// 0-7 bytes in common
|
// 0-7 bytes in common
|
||||||
cmp_small:
|
small:
|
||||||
LEAQ (BP*8), CX // bytes left -> bits left
|
LEAQ (BP*8), CX // bytes left -> bits left
|
||||||
NEGQ CX // - bits lift (== 64 - bits left mod 64)
|
NEGQ CX // - bits lift (== 64 - bits left mod 64)
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
|
|
||||||
// load bytes of a into high bytes of AX
|
// load bytes of a into high bytes of AX
|
||||||
CMPB SI, $0xf8
|
CMPB SI, $0xf8
|
||||||
JA cmp_si_high
|
JA si_high
|
||||||
MOVQ (SI), SI
|
MOVQ (SI), SI
|
||||||
JMP cmp_si_finish
|
JMP si_finish
|
||||||
cmp_si_high:
|
si_high:
|
||||||
MOVQ -8(SI)(BP*1), SI
|
MOVQ -8(SI)(BP*1), SI
|
||||||
SHRQ CX, SI
|
SHRQ CX, SI
|
||||||
cmp_si_finish:
|
si_finish:
|
||||||
SHLQ CX, SI
|
SHLQ CX, SI
|
||||||
|
|
||||||
// load bytes of b in to high bytes of BX
|
// load bytes of b in to high bytes of BX
|
||||||
CMPB DI, $0xf8
|
CMPB DI, $0xf8
|
||||||
JA cmp_di_high
|
JA di_high
|
||||||
MOVQ (DI), DI
|
MOVQ (DI), DI
|
||||||
JMP cmp_di_finish
|
JMP di_finish
|
||||||
cmp_di_high:
|
di_high:
|
||||||
MOVQ -8(DI)(BP*1), DI
|
MOVQ -8(DI)(BP*1), DI
|
||||||
SHRQ CX, DI
|
SHRQ CX, DI
|
||||||
cmp_di_finish:
|
di_finish:
|
||||||
SHLQ CX, DI
|
SHLQ CX, DI
|
||||||
|
|
||||||
BSWAPQ SI // reverse order of bytes
|
BSWAPQ SI // reverse order of bytes
|
||||||
BSWAPQ DI
|
BSWAPQ DI
|
||||||
XORQ SI, DI // find bit differences
|
XORQ SI, DI // find bit differences
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
BSRQ DI, CX // index of highest bit difference
|
BSRQ DI, CX // index of highest bit difference
|
||||||
SHRQ CX, SI // move a's bit to bottom
|
SHRQ CX, SI // move a's bit to bottom
|
||||||
ANDQ $1, SI // mask bit
|
ANDQ $1, SI // mask bit
|
||||||
LEAQ -1(SI*2), AX // 1/0 => +1/-1
|
LEAQ -1(SI*2), AX // 1/0 => +1/-1
|
||||||
RET
|
RET
|
||||||
|
|
||||||
cmp_allsame:
|
allsame:
|
||||||
XORQ AX, AX
|
XORQ AX, AX
|
||||||
XORQ CX, CX
|
XORQ CX, CX
|
||||||
CMPQ BX, DX
|
CMPQ BX, DX
|
||||||
|
|
@ -1313,7 +1313,7 @@ TEXT runtime·indexbytebody(SB),NOSPLIT,$0
|
||||||
MOVQ SI, DI
|
MOVQ SI, DI
|
||||||
|
|
||||||
CMPQ BX, $16
|
CMPQ BX, $16
|
||||||
JLT indexbyte_small
|
JLT small
|
||||||
|
|
||||||
// round up to first 16-byte boundary
|
// round up to first 16-byte boundary
|
||||||
TESTQ $15, SI
|
TESTQ $15, SI
|
||||||
|
|
@ -1371,7 +1371,7 @@ failure:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// handle for lengths < 16
|
// handle for lengths < 16
|
||||||
indexbyte_small:
|
small:
|
||||||
MOVQ BX, CX
|
MOVQ BX, CX
|
||||||
REPN; SCASB
|
REPN; SCASB
|
||||||
JZ success
|
JZ success
|
||||||
|
|
|
||||||
|
|
@ -444,11 +444,11 @@ TEXT runtime·cas64(SB), NOSPLIT, $0-25
|
||||||
MOVQ new+16(FP), CX
|
MOVQ new+16(FP), CX
|
||||||
LOCK
|
LOCK
|
||||||
CMPXCHGQ CX, 0(BX)
|
CMPXCHGQ CX, 0(BX)
|
||||||
JNZ cas64_fail
|
JNZ fail
|
||||||
MOVL $1, AX
|
MOVL $1, AX
|
||||||
MOVB AX, ret+24(FP)
|
MOVB AX, ret+24(FP)
|
||||||
RET
|
RET
|
||||||
cas64_fail:
|
fail:
|
||||||
MOVL $0, AX
|
MOVL $0, AX
|
||||||
MOVB AX, ret+24(FP)
|
MOVB AX, ret+24(FP)
|
||||||
RET
|
RET
|
||||||
|
|
@ -834,29 +834,29 @@ TEXT runtime·cmpbytes(SB),NOSPLIT,$0-28
|
||||||
// AX = 1/0/-1
|
// AX = 1/0/-1
|
||||||
TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
|
TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
|
||||||
CMPQ SI, DI
|
CMPQ SI, DI
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
CMPQ BX, DX
|
CMPQ BX, DX
|
||||||
MOVQ DX, R8
|
MOVQ DX, R8
|
||||||
CMOVQLT BX, R8 // R8 = min(alen, blen) = # of bytes to compare
|
CMOVQLT BX, R8 // R8 = min(alen, blen) = # of bytes to compare
|
||||||
CMPQ R8, $8
|
CMPQ R8, $8
|
||||||
JB cmp_small
|
JB small
|
||||||
|
|
||||||
cmp_loop:
|
loop:
|
||||||
CMPQ R8, $16
|
CMPQ R8, $16
|
||||||
JBE cmp_0through16
|
JBE _0through16
|
||||||
MOVOU (SI), X0
|
MOVOU (SI), X0
|
||||||
MOVOU (DI), X1
|
MOVOU (DI), X1
|
||||||
PCMPEQB X0, X1
|
PCMPEQB X0, X1
|
||||||
PMOVMSKB X1, AX
|
PMOVMSKB X1, AX
|
||||||
XORQ $0xffff, AX // convert EQ to NE
|
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, SI
|
||||||
ADDQ $16, DI
|
ADDQ $16, DI
|
||||||
SUBQ $16, R8
|
SUBQ $16, R8
|
||||||
JMP cmp_loop
|
JMP loop
|
||||||
|
|
||||||
// AX = bit mask of differences
|
// AX = bit mask of differences
|
||||||
cmp_diff16:
|
diff16:
|
||||||
BSFQ AX, BX // index of first byte that differs
|
BSFQ AX, BX // index of first byte that differs
|
||||||
XORQ AX, AX
|
XORQ AX, AX
|
||||||
ADDQ BX, SI
|
ADDQ BX, SI
|
||||||
|
|
@ -868,23 +868,23 @@ cmp_diff16:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// 0 through 16 bytes left, alen>=8, blen>=8
|
// 0 through 16 bytes left, alen>=8, blen>=8
|
||||||
cmp_0through16:
|
_0through16:
|
||||||
CMPQ R8, $8
|
CMPQ R8, $8
|
||||||
JBE cmp_0through8
|
JBE _0through8
|
||||||
MOVQ (SI), AX
|
MOVQ (SI), AX
|
||||||
MOVQ (DI), CX
|
MOVQ (DI), CX
|
||||||
CMPQ AX, CX
|
CMPQ AX, CX
|
||||||
JNE cmp_diff8
|
JNE diff8
|
||||||
cmp_0through8:
|
_0through8:
|
||||||
ADDQ R8, SI
|
ADDQ R8, SI
|
||||||
ADDQ R8, DI
|
ADDQ R8, DI
|
||||||
MOVQ -8(SI), AX
|
MOVQ -8(SI), AX
|
||||||
MOVQ -8(DI), CX
|
MOVQ -8(DI), CX
|
||||||
CMPQ AX, CX
|
CMPQ AX, CX
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
|
|
||||||
// AX and CX contain parts of a and b that differ.
|
// AX and CX contain parts of a and b that differ.
|
||||||
cmp_diff8:
|
diff8:
|
||||||
BSWAPQ AX // reverse order of bytes
|
BSWAPQ AX // reverse order of bytes
|
||||||
BSWAPQ CX
|
BSWAPQ CX
|
||||||
XORQ AX, CX
|
XORQ AX, CX
|
||||||
|
|
@ -895,46 +895,46 @@ cmp_diff8:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// 0-7 bytes in common
|
// 0-7 bytes in common
|
||||||
cmp_small:
|
small:
|
||||||
LEAQ (R8*8), CX // bytes left -> bits left
|
LEAQ (R8*8), CX // bytes left -> bits left
|
||||||
NEGQ CX // - bits lift (== 64 - bits left mod 64)
|
NEGQ CX // - bits lift (== 64 - bits left mod 64)
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
|
|
||||||
// load bytes of a into high bytes of AX
|
// load bytes of a into high bytes of AX
|
||||||
CMPB SI, $0xf8
|
CMPB SI, $0xf8
|
||||||
JA cmp_si_high
|
JA si_high
|
||||||
MOVQ (SI), SI
|
MOVQ (SI), SI
|
||||||
JMP cmp_si_finish
|
JMP si_finish
|
||||||
cmp_si_high:
|
si_high:
|
||||||
ADDQ R8, SI
|
ADDQ R8, SI
|
||||||
MOVQ -8(SI), SI
|
MOVQ -8(SI), SI
|
||||||
SHRQ CX, SI
|
SHRQ CX, SI
|
||||||
cmp_si_finish:
|
si_finish:
|
||||||
SHLQ CX, SI
|
SHLQ CX, SI
|
||||||
|
|
||||||
// load bytes of b in to high bytes of BX
|
// load bytes of b in to high bytes of BX
|
||||||
CMPB DI, $0xf8
|
CMPB DI, $0xf8
|
||||||
JA cmp_di_high
|
JA di_high
|
||||||
MOVQ (DI), DI
|
MOVQ (DI), DI
|
||||||
JMP cmp_di_finish
|
JMP di_finish
|
||||||
cmp_di_high:
|
di_high:
|
||||||
ADDQ R8, DI
|
ADDQ R8, DI
|
||||||
MOVQ -8(DI), DI
|
MOVQ -8(DI), DI
|
||||||
SHRQ CX, DI
|
SHRQ CX, DI
|
||||||
cmp_di_finish:
|
di_finish:
|
||||||
SHLQ CX, DI
|
SHLQ CX, DI
|
||||||
|
|
||||||
BSWAPQ SI // reverse order of bytes
|
BSWAPQ SI // reverse order of bytes
|
||||||
BSWAPQ DI
|
BSWAPQ DI
|
||||||
XORQ SI, DI // find bit differences
|
XORQ SI, DI // find bit differences
|
||||||
JEQ cmp_allsame
|
JEQ allsame
|
||||||
BSRQ DI, CX // index of highest bit difference
|
BSRQ DI, CX // index of highest bit difference
|
||||||
SHRQ CX, SI // move a's bit to bottom
|
SHRQ CX, SI // move a's bit to bottom
|
||||||
ANDQ $1, SI // mask bit
|
ANDQ $1, SI // mask bit
|
||||||
LEAQ -1(SI*2), AX // 1/0 => +1/-1
|
LEAQ -1(SI*2), AX // 1/0 => +1/-1
|
||||||
RET
|
RET
|
||||||
|
|
||||||
cmp_allsame:
|
allsame:
|
||||||
XORQ AX, AX
|
XORQ AX, AX
|
||||||
XORQ CX, CX
|
XORQ CX, CX
|
||||||
CMPQ BX, DX
|
CMPQ BX, DX
|
||||||
|
|
@ -969,7 +969,7 @@ TEXT runtime·indexbytebody(SB),NOSPLIT,$0
|
||||||
MOVL SI, DI
|
MOVL SI, DI
|
||||||
|
|
||||||
CMPL BX, $16
|
CMPL BX, $16
|
||||||
JLT indexbyte_small
|
JLT small
|
||||||
|
|
||||||
// round up to first 16-byte boundary
|
// round up to first 16-byte boundary
|
||||||
TESTL $15, SI
|
TESTL $15, SI
|
||||||
|
|
@ -1027,7 +1027,7 @@ failure:
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// handle for lengths < 16
|
// handle for lengths < 16
|
||||||
indexbyte_small:
|
small:
|
||||||
MOVL BX, CX
|
MOVL BX, CX
|
||||||
REPN; SCASB
|
REPN; SCASB
|
||||||
JZ success
|
JZ success
|
||||||
|
|
|
||||||
|
|
@ -492,7 +492,7 @@ TEXT asmcgocall<>(SB),NOSPLIT,$0-0
|
||||||
MOVW g_m(g), R8
|
MOVW g_m(g), R8
|
||||||
MOVW m_g0(R8), R3
|
MOVW m_g0(R8), R3
|
||||||
CMP R3, g
|
CMP R3, g
|
||||||
BEQ asmcgocall_g0
|
BEQ g0
|
||||||
BL gosave<>(SB)
|
BL gosave<>(SB)
|
||||||
MOVW R0, R5
|
MOVW R0, R5
|
||||||
MOVW R3, R0
|
MOVW R3, R0
|
||||||
|
|
@ -501,7 +501,7 @@ TEXT asmcgocall<>(SB),NOSPLIT,$0-0
|
||||||
MOVW (g_sched+gobuf_sp)(g), R13
|
MOVW (g_sched+gobuf_sp)(g), R13
|
||||||
|
|
||||||
// Now on a scheduling stack (a pthread-created stack).
|
// Now on a scheduling stack (a pthread-created stack).
|
||||||
asmcgocall_g0:
|
g0:
|
||||||
SUB $24, R13
|
SUB $24, R13
|
||||||
BIC $0x7, R13 // alignment for gcc ABI
|
BIC $0x7, R13 // alignment for gcc ABI
|
||||||
MOVW R4, 20(R13) // save old g
|
MOVW R4, 20(R13) // save old g
|
||||||
|
|
@ -751,13 +751,13 @@ TEXT runtime·memeq(SB),NOSPLIT,$-4-13
|
||||||
ADD R1, R3, R6
|
ADD R1, R3, R6
|
||||||
MOVW $1, R0
|
MOVW $1, R0
|
||||||
MOVB R0, ret+12(FP)
|
MOVB R0, ret+12(FP)
|
||||||
_next2:
|
loop:
|
||||||
CMP R1, R6
|
CMP R1, R6
|
||||||
RET.EQ
|
RET.EQ
|
||||||
MOVBU.P 1(R1), R4
|
MOVBU.P 1(R1), R4
|
||||||
MOVBU.P 1(R2), R5
|
MOVBU.P 1(R2), R5
|
||||||
CMP R4, R5
|
CMP R4, R5
|
||||||
BEQ _next2
|
BEQ loop
|
||||||
|
|
||||||
MOVW $0, R0
|
MOVW $0, R0
|
||||||
MOVB R0, ret+12(FP)
|
MOVB R0, ret+12(FP)
|
||||||
|
|
@ -780,13 +780,13 @@ TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
|
||||||
CMP R2, R3
|
CMP R2, R3
|
||||||
RET.EQ
|
RET.EQ
|
||||||
ADD R2, R0, R6
|
ADD R2, R0, R6
|
||||||
_eqnext:
|
loop:
|
||||||
CMP R2, R6
|
CMP R2, R6
|
||||||
RET.EQ
|
RET.EQ
|
||||||
MOVBU.P 1(R2), R4
|
MOVBU.P 1(R2), R4
|
||||||
MOVBU.P 1(R3), R5
|
MOVBU.P 1(R3), R5
|
||||||
CMP R4, R5
|
CMP R4, R5
|
||||||
BEQ _eqnext
|
BEQ loop
|
||||||
MOVB R7, v+16(FP)
|
MOVB R7, v+16(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
|
@ -801,26 +801,26 @@ TEXT bytes·Equal(SB),NOSPLIT,$0
|
||||||
MOVW b_len+16(FP), R3
|
MOVW b_len+16(FP), R3
|
||||||
|
|
||||||
CMP R1, R3 // unequal lengths are not equal
|
CMP R1, R3 // unequal lengths are not equal
|
||||||
B.NE _notequal
|
B.NE notequal
|
||||||
|
|
||||||
MOVW a+0(FP), R0
|
MOVW a+0(FP), R0
|
||||||
MOVW b+12(FP), R2
|
MOVW b+12(FP), R2
|
||||||
ADD R0, R1 // end
|
ADD R0, R1 // end
|
||||||
|
|
||||||
_byteseq_next:
|
loop:
|
||||||
CMP R0, R1
|
CMP R0, R1
|
||||||
B.EQ _equal // reached the end
|
B.EQ equal // reached the end
|
||||||
MOVBU.P 1(R0), R4
|
MOVBU.P 1(R0), R4
|
||||||
MOVBU.P 1(R2), R5
|
MOVBU.P 1(R2), R5
|
||||||
CMP R4, R5
|
CMP R4, R5
|
||||||
B.EQ _byteseq_next
|
B.EQ loop
|
||||||
|
|
||||||
_notequal:
|
notequal:
|
||||||
MOVW $0, R0
|
MOVW $0, R0
|
||||||
MOVBU R0, ret+24(FP)
|
MOVBU R0, ret+24(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
_equal:
|
equal:
|
||||||
MOVW $1, R0
|
MOVW $1, R0
|
||||||
MOVBU R0, ret+24(FP)
|
MOVBU R0, ret+24(FP)
|
||||||
RET
|
RET
|
||||||
|
|
|
||||||
981
src/runtime/asm_power64x.s
Normal file
981
src/runtime/asm_power64x.s
Normal file
|
|
@ -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)
|
||||||
40
src/runtime/atomic_power64x.s
Normal file
40
src/runtime/atomic_power64x.s
Normal file
|
|
@ -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
|
||||||
|
|
@ -7,6 +7,12 @@
|
||||||
#ifdef GOARCH_arm
|
#ifdef GOARCH_arm
|
||||||
#define JMP B
|
#define JMP B
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef GOARCH_power64
|
||||||
|
#define JMP BR
|
||||||
|
#endif
|
||||||
|
#ifdef GOARCH_power64le
|
||||||
|
#define JMP BR
|
||||||
|
#endif
|
||||||
|
|
||||||
TEXT ·setMaxStack(SB),NOSPLIT,$0-0
|
TEXT ·setMaxStack(SB),NOSPLIT,$0-0
|
||||||
JMP runtime·setMaxStack(SB)
|
JMP runtime·setMaxStack(SB)
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,14 @@ package runtime
|
||||||
/*
|
/*
|
||||||
#include <ucontext.h>
|
#include <ucontext.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <asm/signal.h>
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
O_RDONLY = C.O_RDONLY
|
O_RDONLY = C.O_RDONLY
|
||||||
O_CLOEXEC = C.O_CLOEXEC
|
O_CLOEXEC = C.O_CLOEXEC
|
||||||
|
SA_RESTORER = C.SA_RESTORER
|
||||||
)
|
)
|
||||||
|
|
||||||
type Usigset C.__sigset_t
|
type Usigset C.__sigset_t
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue