Commit b9c52302 authored by Russ Cox's avatar Russ Cox

all: merge dev.cc (81884b89bd88) into default

With this change, default now contains Go 1.5 work.
Any future bug fixes for Go 1.4 in the compilers or
the runtime will have to be made directly to the
release branch.
parents 41c6b843 829b286f
...@@ -2,13 +2,13 @@ syntax:glob ...@@ -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
......
...@@ -54,7 +54,7 @@ struct Addr ...@@ -54,7 +54,7 @@ struct Addr
{ {
char sval[8]; char sval[8];
float64 dval; float64 dval;
Prog* branch; // for 5g, 6g, 8g Prog* branch; // for 5g, 6g, 8g, 9g
} u; } u;
LSym* sym; LSym* sym;
...@@ -62,9 +62,9 @@ struct Addr ...@@ -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; GPRs and FPRs both start at 0
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,14 @@ struct Prog ...@@ -89,9 +89,14 @@ struct Prog
int32 lineno; int32 lineno;
Prog* link; Prog* link;
short as; short as;
uchar reg; // arm only uchar scond; // arm only; condition codes
uchar scond; // arm only
// operands
Addr from; Addr from;
uchar reg; // arm, power64 only (e.g., ADD from, reg, to);
// starts at 0 for both GPRs and FPRs;
// also used for ADATA width on arm, power64
Addr from3; // power64 only (e.g., RLWM/FMADD from, reg, from3, to)
Addr to; Addr to;
// for 5g, 6g, 8g internal use // for 5g, 6g, 8g internal use
...@@ -103,11 +108,11 @@ struct Prog ...@@ -103,11 +108,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 +238,12 @@ enum ...@@ -233,10 +238,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 +536,9 @@ void span6(Link *ctxt, LSym *s); ...@@ -529,6 +536,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 +586,11 @@ Prog* copyp(Link*, Prog*); ...@@ -576,10 +586,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 +622,30 @@ char* headstr(int); ...@@ -611,20 +622,30 @@ 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 char* dnames5[];
extern char* dnames6[];
extern char* dnames8[];
extern char* dnames9[];
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 "E" uint
#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.
......
defaultcc: golang-codereviews@googlegroups.com defaultcc: golang-codereviews@googlegroups.com
contributors: http://go.googlecode.com/hg/CONTRIBUTORS
...@@ -3604,11 +3604,17 @@ class MercurialVCS(VersionControlSystem): ...@@ -3604,11 +3604,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 ...@@ -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); ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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;
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/* 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 @@ ...@@ -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; ...@@ -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 */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Inferno utils/5c/sgen.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/sgen.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 "gc.h"
Prog*
gtext(Sym *s, int32 stkoff)
{
int32 a;
a = argsize(1);
if((textflag & NOSPLIT) != 0 && stkoff >= 128)
yyerror("stack frame too large for NOSPLIT function");
gpseudo(ATEXT, s, nodconst(stkoff));
p->to.type = D_CONST2;
p->to.offset2 = a;
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 t;
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 OASLMUL:
case OASMUL:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OASASHL;
r->vconst = t;
r->type = types[TINT];
}
break;
case OMUL:
case OLMUL:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OASHL;
r->vconst = t;
r->type = types[TINT];
}
t = vlog(l);
if(t >= 0) {
n->op = OASHL;
n->left = r;
n->right = l;
r = l;
l = n->left;
r->vconst = t;
r->type = types[TINT];
}
break;
case OASLDIV:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OASLSHR;
r->vconst = t;
r->type = types[TINT];
}
break;
case OLDIV:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OLSHR;
r->vconst = t;
r->type = types[TINT];
}
break;
case OASLMOD:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OASAND;
r->vconst--;
}
break;
case OLMOD:
xcom(l);
xcom(r);
t = vlog(r);
if(t >= 0) {
n->op = OAND;
r->vconst--;
}
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 OADD:
case OXOR:
case OAND:
case OOR:
case OEQ:
case ONE:
/*
* immediate operators, make const on right
*/
if(l->op == OCONST) {
n->left = r;
n->right = l;
}
break;
}
}
// Inferno utils/5c/swt.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/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 "gc.h"
void
swit1(C1 *q, int nc, int32 def, Node *n)
{
Node nreg;
if(typev[n->type->etype]) {
regsalloc(&nreg, n);
nreg.type = types[TVLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
return;
}
regalloc(&nreg, n, Z);
nreg.type = types[TLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
regfree(&nreg);
}
void
swit2(C1 *q, int nc, int32 def, Node *n)
{
C1 *r;
int i;
int32 v;
Prog *sp;
if(nc >= 3) {
i = (q+nc-1)->val - (q+0)->val;
if(!nacl && i > 0 && i < nc*2)
goto direct;
}
if(nc < 5) {
for(i=0; i<nc; i++) {
if(debug['W'])
print("case = %.8ux\n", q->val);
gopcode(OEQ, nodconst(q->val), n, Z);
patch(p, q->label);
q++;
}
gbranch(OGOTO);
patch(p, def);
return;
}
i = nc / 2;
r = q+i;
if(debug['W'])
print("case > %.8ux\n", r->val);
gopcode(OGT, nodconst(r->val), n, Z);
sp = p;
gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */
patch(p, r->label);
swit2(q, i, def, n);
if(debug['W'])
print("case < %.8ux\n", r->val);
patch(sp, pc);
swit2(r+1, nc-i-1, def, n);
return;
direct:
v = q->val;
if(v != 0)
gopcode(OSUB, nodconst(v), Z, n);
gopcode(OCASE, nodconst((q+nc-1)->val - v), n, Z);
patch(p, def);
for(i=0; i<nc; i++) {
if(debug['W'])
print("case = %.8ux\n", q->val);
while(q->val != v) {
nextpc();
p->as = ABCASE;
patch(p, def);
v++;
}
nextpc();
p->as = ABCASE;
patch(p, q->label);
q++;
v++;
}
gbranch(OGOTO); /* so that regopt() won't be confused */
patch(p, def);
}
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, vs;
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(v);
if(!m) {
if(debug['M'])
print("%L multiply table: %lld\n", n->lineno, r->vconst);
return 0;
}
if(debug['M'] && debug['v'])
print("%L multiply: %d\n", n->lineno, v);
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);
vs = v;
regalloc(&nod2, n, Z);
loop:
switch(*p) {
case 0:
regfree(&nod2);
if(vs < 0) {
gopcode(OAS, &nod1, Z, &nod1);
gopcode(OSUB, &nod1, nodconst(0), nn);
} else
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)
{
if(a->op == OCONST && typev[a->type->etype]) {
if(isbigendian)
gpseudo(ADATA, s, nod32const(a->vconst>>32));
else
gpseudo(ADATA, s, nod32const(a->vconst));
p->from.offset += o;
p->reg = 4;
if(isbigendian)
gpseudo(ADATA, s, nod32const(a->vconst));
else
gpseudo(ADATA, s, nod32const(a->vconst>>32));
p->from.offset += o + 4;
p->reg = 4;
return;
}
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 = P;
}
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 align 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 == 8)
w = 4;
}
if(w < 1 || w > SZ_LONG)
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(typesuv[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_LONG) {
w = SZ_LONG;
break;
}
w = 1; /* little endian no adjustment */
break;
case Aarg2: /* width of a parameter */
o += t->width;
w = t->width;
if(w > SZ_LONG)
w = SZ_LONG;
break;
case Aaut3: /* total align of automatic */
o = align(o, t, Ael2, nil);
o = align(o, t, Ael1, nil);
w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */
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 != nil && *maxalign < w)
*maxalign = w;
if(debug['A'])
print("align %s %d %T = %d\n", bnames[op], i, t, o);
return o;
}
int32
maxround(int32 max, int32 v)
{
v = xround(v, SZ_LONG);
if(v > max)
return v;
return max;
}
This diff is collapsed.
...@@ -86,7 +86,7 @@ datagostring(Strlit *sval, Addr *a) ...@@ -86,7 +86,7 @@ datagostring(Strlit *sval, Addr *a)
sym = stringsym(sval->s, sval->len); sym = stringsym(sval->s, sval->len);
a->type = D_OREG; a->type = D_OREG;
a->name = D_EXTERN; a->name = D_EXTERN;
a->etype = TINT32; a->etype = TSTRING;
a->offset = 0; // header a->offset = 0; // header
a->reg = NREG; a->reg = NREG;
a->sym = linksym(sym); a->sym = linksym(sym);
......
...@@ -1353,9 +1353,10 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1353,9 +1353,10 @@ naddr(Node *n, Addr *a, int canemitcode)
case OITAB: case OITAB:
// itable of interface value // itable of interface value
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
a->etype = TINT32; a->etype = simtype[tptr];
if(a->type == D_CONST && a->offset == 0) if(a->type == D_CONST && a->offset == 0)
break; // len(nil) break; // len(nil)
a->width = widthptr;
break; break;
case OSPTR: case OSPTR:
......
...@@ -63,8 +63,8 @@ enum ...@@ -63,8 +63,8 @@ enum
uint32 BLOAD(Reg*); uint32 BLOAD(Reg*);
uint32 BSTORE(Reg*); uint32 BSTORE(Reg*);
uint32 LOAD(Reg*); uint64 LOAD(Reg*);
uint32 STORE(Reg*); uint64 STORE(Reg*);
*/ */
// A Reg is a wrapper around a single Prog (one instruction) that holds // A Reg is a wrapper around a single Prog (one instruction) that holds
...@@ -75,12 +75,18 @@ struct Reg ...@@ -75,12 +75,18 @@ struct Reg
{ {
Flow f; Flow f;
Bits set; // variables written by this instruction. Bits set; // regopt variables written by this instruction.
Bits use1; // variables read by prog->from. Bits use1; // regopt variables read by prog->from.
Bits use2; // variables read by prog->to. Bits use2; // regopt variables read by prog->to.
// refahead/refbehind are the regopt variables whose current
// value may be used in the following/preceding instructions
// up to a CALL (or the value is clobbered).
Bits refbehind; Bits refbehind;
Bits refahead; Bits refahead;
// calahead/calbehind are similar, but for variables in
// instructions that are reachable after hitting at least one
// CALL.
Bits calbehind; Bits calbehind;
Bits calahead; Bits calahead;
Bits regdiff; Bits regdiff;
...@@ -93,6 +99,16 @@ struct Reg ...@@ -93,6 +99,16 @@ struct Reg
#define NRGN 600 #define NRGN 600
/*c2go enum { NRGN = 600 }; */ /*c2go enum { NRGN = 600 }; */
// A Rgn represents a single regopt variable over a region of code
// where a register could potentially be dedicated to that variable.
// The code encompassed by a Rgn is defined by the flow graph,
// starting at enter, flood-filling forward while varno is refahead
// and backward while varno is refbehind, and following branches. A
// single variable may be represented by multiple disjoint Rgns and
// each Rgn may choose a different register for that variable.
// Registers are allocated to regions greedily in order of descending
// cost.
struct Rgn struct Rgn
{ {
Reg* enter; Reg* enter;
...@@ -144,8 +160,8 @@ void prop(Reg*, Bits, Bits); ...@@ -144,8 +160,8 @@ void prop(Reg*, Bits, Bits);
void synch(Reg*, Bits); void synch(Reg*, Bits);
uint32 allreg(uint32, Rgn*); uint32 allreg(uint32, Rgn*);
void paint1(Reg*, int); void paint1(Reg*, int);
uint32 paint2(Reg*, int); uint32 paint2(Reg*, int, int);
void paint3(Reg*, int, int32, int); void paint3(Reg*, int, uint32, int);
void addreg(Adr*, int); void addreg(Adr*, int);
void dumpit(char *str, Flow *r0, int); void dumpit(char *str, Flow *r0, int);
...@@ -156,10 +172,10 @@ void peep(Prog*); ...@@ -156,10 +172,10 @@ void peep(Prog*);
void excise(Flow*); void excise(Flow*);
int copyu(Prog*, Adr*, Adr*); int copyu(Prog*, Adr*, Adr*);
int32 RtoB(int); uint32 RtoB(int);
int32 FtoB(int); uint32 FtoB(int);
int BtoR(int32); int BtoR(uint32);
int BtoF(int32); int BtoF(uint32);
/* /*
* prog.c * prog.c
...@@ -187,16 +203,16 @@ enum ...@@ -187,16 +203,16 @@ enum
SizeF = 1<<7, // float aka float32 SizeF = 1<<7, // float aka float32
SizeD = 1<<8, // double aka float64 SizeD = 1<<8, // double aka float64
// Left side: address taken, read, write. // Left side (Prog.from): address taken, read, write.
LeftAddr = 1<<9, LeftAddr = 1<<9,
LeftRead = 1<<10, LeftRead = 1<<10,
LeftWrite = 1<<11, LeftWrite = 1<<11,
// Register in middle; never written. // Register in middle (Prog.reg); only ever read.
RegRead = 1<<12, RegRead = 1<<12,
CanRegRead = 1<<13, CanRegRead = 1<<13,
// Right side: address taken, read, write. // Right side (Prog.to): address taken, read, write.
RightAddr = 1<<14, RightAddr = 1<<14,
RightRead = 1<<15, RightRead = 1<<15,
RightWrite = 1<<16, RightWrite = 1<<16,
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include "opt.h" #include "opt.h"
#define NREGVAR 32 #define NREGVAR 32
#define REGBITS ((uint32)0xffffffff) #define REGBITS ((uint64)0xffffffffull)
/*c2go enum { /*c2go enum {
NREGVAR = 32, NREGVAR = 32,
REGBITS = 0xffffffff, REGBITS = 0xffffffff,
...@@ -86,7 +86,7 @@ setaddrs(Bits bit) ...@@ -86,7 +86,7 @@ setaddrs(Bits bit)
i = bnum(bit); i = bnum(bit);
node = var[i].node; node = var[i].node;
n = var[i].name; n = var[i].name;
bit.b[i/32] &= ~(1L<<(i%32)); biclr(&bit, i);
// disable all pieces of that variable // disable all pieces of that variable
for(i=0; i<nvar; i++) { for(i=0; i<nvar; i++) {
...@@ -393,7 +393,7 @@ loop2: ...@@ -393,7 +393,7 @@ loop2:
for(z=0; z<BITS; z++) for(z=0; z<BITS; z++)
bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]); ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
if(bany(&bit) & !r->f.refset) { if(bany(&bit) && !r->f.refset) {
// should never happen - all variables are preset // should never happen - all variables are preset
if(debug['w']) if(debug['w'])
print("%L: used and not set: %Q\n", r->f.prog->lineno, bit); print("%L: used and not set: %Q\n", r->f.prog->lineno, bit);
...@@ -425,7 +425,7 @@ loop2: ...@@ -425,7 +425,7 @@ loop2:
if(debug['R'] > 1) if(debug['R'] > 1)
print("\n"); print("\n");
paint1(r, i); paint1(r, i);
bit.b[i/32] &= ~(1L<<(i%32)); biclr(&bit, i);
if(change <= 0) { if(change <= 0) {
if(debug['R']) if(debug['R'])
print("%L $%d: %Q\n", print("%L $%d: %Q\n",
...@@ -454,9 +454,13 @@ brk: ...@@ -454,9 +454,13 @@ brk:
* replace code (paint3) * replace code (paint3)
*/ */
rgp = region; rgp = region;
if(debug['R'] && debug['v'])
print("\nregisterizing\n");
for(i=0; i<nregion; i++) { for(i=0; i<nregion; i++) {
if(debug['R'] && debug['v'])
print("region %d: cost %d varno %d enter %lld\n", i, rgp->cost, rgp->varno, rgp->enter->f.prog->pc);
bit = blsh(rgp->varno); bit = blsh(rgp->varno);
vreg = paint2(rgp->enter, rgp->varno); vreg = paint2(rgp->enter, rgp->varno, 0);
vreg = allreg(vreg, rgp); vreg = allreg(vreg, rgp);
if(debug['R']) { if(debug['R']) {
if(rgp->regno >= NREG) if(rgp->regno >= NREG)
...@@ -477,9 +481,6 @@ brk: ...@@ -477,9 +481,6 @@ brk:
rgp++; rgp++;
} }
if(debug['R'] && debug['v'])
dumpit("pass6", &firstr->f, 1);
/* /*
* free aux structures. peep allocates new ones. * free aux structures. peep allocates new ones.
*/ */
...@@ -488,6 +489,15 @@ brk: ...@@ -488,6 +489,15 @@ brk:
flowend(g); flowend(g);
firstr = R; firstr = R;
if(debug['R'] && debug['v']) {
// Rebuild flow graph, since we inserted instructions
g = flowstart(firstp, sizeof(Reg));
firstr = (Reg*)g->start;
dumpit("pass6", &firstr->f, 1);
flowend(g);
firstr = R;
}
/* /*
* pass 7 * pass 7
* peep-hole on basic block * peep-hole on basic block
...@@ -570,7 +580,7 @@ walkvardef(Node *n, Reg *r, int active) ...@@ -570,7 +580,7 @@ walkvardef(Node *n, Reg *r, int active)
break; break;
for(v=n->opt; v!=nil; v=v->nextinnode) { for(v=n->opt; v!=nil; v=v->nextinnode) {
bn = v - var; bn = v - var;
r1->act.b[bn/32] |= 1L << (bn%32); biset(&r1->act, bn);
} }
if(r1->f.prog->as == ABL) if(r1->f.prog->as == ABL)
break; break;
...@@ -606,7 +616,7 @@ addsplits(void) ...@@ -606,7 +616,7 @@ addsplits(void)
~(r->calahead.b[z] & addrs.b[z]); ~(r->calahead.b[z] & addrs.b[z]);
while(bany(&bit)) { while(bany(&bit)) {
i = bnum(bit); i = bnum(bit);
bit.b[i/32] &= ~(1L << (i%32)); biclr(&bit, i);
} }
} }
} }
...@@ -972,10 +982,10 @@ prop(Reg *r, Bits ref, Bits cal) ...@@ -972,10 +982,10 @@ prop(Reg *r, Bits ref, Bits cal)
for(z=0; z<BITS; z++) { for(z=0; z<BITS; z++) {
if(cal.b[z] == 0) if(cal.b[z] == 0)
continue; continue;
for(i=0; i<32; i++) { for(i=0; i<64; i++) {
if(z*32+i >= nvar || ((cal.b[z]>>i)&1) == 0) if(z*64+i >= nvar || ((cal.b[z]>>i)&1) == 0)
continue; continue;
v = var+z*32+i; v = var+z*64+i;
if(v->node->opt == nil) // v represents fixed register, not Go variable if(v->node->opt == nil) // v represents fixed register, not Go variable
continue; continue;
...@@ -991,10 +1001,10 @@ prop(Reg *r, Bits ref, Bits cal) ...@@ -991,10 +1001,10 @@ prop(Reg *r, Bits ref, Bits cal)
// This will set the bits at most twice, keeping the overall loop linear. // This will set the bits at most twice, keeping the overall loop linear.
v1 = v->node->opt; v1 = v->node->opt;
j = v1 - var; j = v1 - var;
if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) { if(v == v1 || !btest(&cal, j)) {
for(; v1 != nil; v1 = v1->nextinnode) { for(; v1 != nil; v1 = v1->nextinnode) {
j = v1 - var; j = v1 - var;
cal.b[j/32] |= 1<<(j&31); biset(&cal, j);
} }
} }
} }
...@@ -1115,10 +1125,10 @@ paint1(Reg *r, int bn) ...@@ -1115,10 +1125,10 @@ paint1(Reg *r, int bn)
Reg *r1; Reg *r1;
Prog *p; Prog *p;
int z; int z;
uint32 bb; uint64 bb;
z = bn/32; z = bn/64;
bb = 1L<<(bn%32); bb = 1LL<<(bn%64);
if(r->act.b[z] & bb) if(r->act.b[z] & bb)
return; return;
for(;;) { for(;;) {
...@@ -1189,14 +1199,14 @@ paint1(Reg *r, int bn) ...@@ -1189,14 +1199,14 @@ paint1(Reg *r, int bn)
} }
uint32 uint32
paint2(Reg *r, int bn) paint2(Reg *r, int bn, int depth)
{ {
Reg *r1; Reg *r1;
int z; int z;
uint32 bb, vreg; uint64 bb, vreg;
z = bn/32; z = bn/64;
bb = 1L << (bn%32); bb = 1LL << (bn%64);
vreg = regbits; vreg = regbits;
if(!(r->act.b[z] & bb)) if(!(r->act.b[z] & bb))
return vreg; return vreg;
...@@ -1213,6 +1223,9 @@ paint2(Reg *r, int bn) ...@@ -1213,6 +1223,9 @@ paint2(Reg *r, int bn)
r = r1; r = r1;
} }
for(;;) { for(;;) {
if(debug['R'] && debug['v'])
print(" paint2 %d %P\n", depth, r->f.prog);
r->act.b[z] &= ~bb; r->act.b[z] &= ~bb;
vreg |= r->regu; vreg |= r->regu;
...@@ -1220,14 +1233,14 @@ paint2(Reg *r, int bn) ...@@ -1220,14 +1233,14 @@ paint2(Reg *r, int bn)
if(r->refbehind.b[z] & bb) if(r->refbehind.b[z] & bb)
for(r1 = (Reg*)r->f.p2; r1 != R; r1 = (Reg*)r1->f.p2link) for(r1 = (Reg*)r->f.p2; r1 != R; r1 = (Reg*)r1->f.p2link)
if(r1->refahead.b[z] & bb) if(r1->refahead.b[z] & bb)
vreg |= paint2(r1, bn); vreg |= paint2(r1, bn, depth+1);
if(!(r->refahead.b[z] & bb)) if(!(r->refahead.b[z] & bb))
break; break;
r1 = (Reg*)r->f.s2; r1 = (Reg*)r->f.s2;
if(r1 != R) if(r1 != R)
if(r1->refbehind.b[z] & bb) if(r1->refbehind.b[z] & bb)
vreg |= paint2(r1, bn); vreg |= paint2(r1, bn, depth+1);
r = (Reg*)r->f.s1; r = (Reg*)r->f.s1;
if(r == R) if(r == R)
break; break;
...@@ -1240,15 +1253,15 @@ paint2(Reg *r, int bn) ...@@ -1240,15 +1253,15 @@ paint2(Reg *r, int bn)
} }
void void
paint3(Reg *r, int bn, int32 rb, int rn) paint3(Reg *r, int bn, uint32 rb, int rn)
{ {
Reg *r1; Reg *r1;
Prog *p; Prog *p;
int z; int z;
uint32 bb; uint64 bb;
z = bn/32; z = bn/64;
bb = 1L << (bn%32); bb = 1LL << (bn%64);
if(r->act.b[z] & bb) if(r->act.b[z] & bb)
return; return;
for(;;) { for(;;) {
...@@ -1333,7 +1346,7 @@ addreg(Adr *a, int rn) ...@@ -1333,7 +1346,7 @@ addreg(Adr *a, int rn)
* 10 R10 * 10 R10
* 12 R12 * 12 R12
*/ */
int32 uint32
RtoB(int r) RtoB(int r)
{ {
if(r >= REGTMP-2 && r != 12) // excluded R9 and R10 for m and g, but not R12 if(r >= REGTMP-2 && r != 12) // excluded R9 and R10 for m and g, but not R12
...@@ -1342,8 +1355,10 @@ RtoB(int r) ...@@ -1342,8 +1355,10 @@ RtoB(int r)
} }
int int
BtoR(int32 b) BtoR(uint32 b)
{ {
// TODO Allow R0 and R1, but be careful with a 0 return
// TODO Allow R9. Only R10 is reserved now (just g, not m).
b &= 0x11fcL; // excluded R9 and R10 for m and g, but not R12 b &= 0x11fcL; // excluded R9 and R10 for m and g, but not R12
if(b == 0) if(b == 0)
return 0; return 0;
...@@ -1357,7 +1372,7 @@ BtoR(int32 b) ...@@ -1357,7 +1372,7 @@ BtoR(int32 b)
* ... ... * ... ...
* 31 F15 * 31 F15
*/ */
int32 uint32
FtoB(int f) FtoB(int f)
{ {
...@@ -1367,7 +1382,7 @@ FtoB(int f) ...@@ -1367,7 +1382,7 @@ FtoB(int f)
} }
int int
BtoF(int32 b) BtoF(uint32 b)
{ {
b &= 0xfffc0000L; b &= 0xfffc0000L;
...@@ -1442,12 +1457,14 @@ dumpit(char *str, Flow *r0, int isreg) ...@@ -1442,12 +1457,14 @@ dumpit(char *str, Flow *r0, int isreg)
print(" (only)"); print(" (only)");
print("\n"); print("\n");
} }
// r1 = r->s1; // Print successors if it's not just the next one
// if(r1 != nil) { if(r->s1 != r->link || r->s2 != nil) {
// print(" succ:"); print(" succ:");
// for(; r1 != R; r1 = r1->s1) if(r->s1 != nil)
// print(" %.4ud", (int)r1->prog->pc); print(" %.4ud", (int)r->s1->prog->pc);
// print("\n"); if(r->s2 != nil)
// } print(" %.4ud", (int)r->s2->prog->pc);
print("\n");
}
} }
} }
...@@ -338,6 +338,8 @@ enum ...@@ -338,6 +338,8 @@ enum
D_STATIC = (D_NONE+4), D_STATIC = (D_NONE+4),
D_AUTO = (D_NONE+5), D_AUTO = (D_NONE+5),
D_PARAM = (D_NONE+6), D_PARAM = (D_NONE+6),
D_LAST = (D_NONE+26),
}; };
/* /*
......
...@@ -70,6 +70,7 @@ struct Sym ...@@ -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); ...@@ -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: ...@@ -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 */ ...@@ -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: ...@@ -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;
} }
......
This diff is collapsed.
# 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
This diff is collapsed.
// Inferno utils/6c/div.c
// http://code.google.com/p/inferno-os/source/browse/utils/6c/div.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 "gc.h"
/*
* Based on: Granlund, T.; Montgomery, P.L.
* "Division by Invariant Integers using Multiplication".
* SIGPLAN Notices, Vol. 29, June 1994, page 61.
*/
#define TN(n) ((uvlong)1 << (n))
#define T31 TN(31)
#define T32 TN(32)
int
multiplier(uint32 d, int p, uvlong *mp)
{
int l;
uvlong mlo, mhi, tlo, thi;
l = topbit(d - 1) + 1;
mlo = (((TN(l) - d) << 32) / d) + T32;
if(l + p == 64)
mhi = (((TN(l) + 1 - d) << 32) / d) + T32;
else
mhi = (TN(32 + l) + TN(32 + l - p)) / d;
/*assert(mlo < mhi);*/
while(l > 0) {
tlo = mlo >> 1;
thi = mhi >> 1;
if(tlo == thi)
break;
mlo = tlo;
mhi = thi;
l--;
}
*mp = mhi;
return l;
}
int
sdiv(uint32 d, uint32 *mp, int *sp)
{
int s;
uvlong m;
s = multiplier(d, 32 - 1, &m);
*mp = m;
*sp = s;
if(m >= T31)
return 1;
else
return 0;
}
int
udiv(uint32 d, uint32 *mp, int *sp, int *pp)
{
int p, s;
uvlong m;
s = multiplier(d, 32, &m);
p = 0;
if(m >= T32) {
while((d & 1) == 0) {
d >>= 1;
p++;
}
s = multiplier(d, 32 - p, &m);
}
*mp = m;
*pp = p;
if(m >= T32) {
/*assert(p == 0);*/
*sp = s - 1;
return 1;
}
else {
*sp = s;
return 0;
}
}
void
sdivgen(Node *l, Node *r, Node *ax, Node *dx)
{
int a, s;
uint32 m;
vlong c;
c = r->vconst;
if(c < 0)
c = -c;
a = sdiv(c, &m, &s);
//print("a=%d i=%d s=%d m=%ux\n", a, (long)r->vconst, s, m);
gins(AMOVL, nodconst(m), ax);
gins(AIMULL, l, Z);
gins(AMOVL, l, ax);
if(a)
gins(AADDL, ax, dx);
gins(ASHRL, nodconst(31), ax);
gins(ASARL, nodconst(s), dx);
gins(AADDL, ax, dx);
if(r->vconst < 0)
gins(ANEGL, Z, dx);
}
void
udivgen(Node *l, Node *r, Node *ax, Node *dx)
{
int a, s, t;
uint32 m;
Node nod;
a = udiv(r->vconst, &m, &s, &t);
//print("a=%ud i=%d p=%d s=%d m=%ux\n", a, (long)r->vconst, t, s, m);
if(t != 0) {
gins(AMOVL, l, ax);
gins(ASHRL, nodconst(t), ax);
gins(AMOVL, nodconst(m), dx);
gins(AMULL, dx, Z);
}
else if(a) {
if(l->op != OREGISTER) {
regalloc(&nod, l, Z);
gins(AMOVL, l, &nod);
l = &nod;
}
gins(AMOVL, nodconst(m), ax);
gins(AMULL, l, Z);
gins(AADDL, l, dx);
gins(ARCRL, nodconst(1), dx);
if(l == &nod)
regfree(l);
}
else {
gins(AMOVL, nodconst(m), ax);
gins(AMULL, l, Z);
}
if(s != 0)
gins(ASHRL, nodconst(s), dx);
}
void
sext(Node *d, Node *s, Node *l)
{
if(s->reg == D_AX && !nodreg(d, Z, D_DX)) {
reg[D_DX]++;
gins(ACDQ, Z, Z);
}
else {
regalloc(d, l, Z);
gins(AMOVL, s, d);
gins(ASARL, nodconst(31), d);
}
}
void
sdiv2(int32 c, int v, Node *l, Node *n)
{
Node nod;
if(v > 0) {
if(v > 1) {
sext(&nod, n, l);
gins(AANDL, nodconst((1 << v) - 1), &nod);
gins(AADDL, &nod, n);
regfree(&nod);
}
else {
gins(ACMPL, n, nodconst(0x80000000));
gins(ASBBL, nodconst(-1), n);
}
gins(ASARL, nodconst(v), n);
}
if(c < 0)
gins(ANEGL, Z, n);
}
void
smod2(int32 c, int v, Node *l, Node *n)
{
Node nod;
if(c == 1) {
zeroregm(n);
return;
}
sext(&nod, n, l);
if(v == 0) {
zeroregm(n);
gins(AXORL, &nod, n);
gins(ASUBL, &nod, n);
}
else if(v > 1) {
gins(AANDL, nodconst((1 << v) - 1), &nod);
gins(AADDL, &nod, n);
gins(AANDL, nodconst((1 << v) - 1), n);
gins(ASUBL, &nod, n);
}
else {
gins(AANDL, nodconst(1), n);
gins(AXORL, &nod, n);
gins(ASUBL, &nod, n);
}
regfree(&nod);
}
This diff is collapsed.
// Inferno utils/6c/list.c
// http://code.google.com/p/inferno-os/source/browse/utils/6c/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.
#define EXTERN
#include "gc.h"
void
listinit(void)
{
listinit6();
}
// Inferno utils/6c/machcap.c
// http://code.google.com/p/inferno-os/source/browse/utils/6c/machcap.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 "gc.h"
int
machcap(Node *n)
{
if(n == Z)
return 1; /* test */
switch(n->op) {
case OMUL:
case OLMUL:
case OASMUL:
case OASLMUL:
if(typechl[n->type->etype])
return 1;
if(typev[n->type->etype])
return 1;
break;
case OCOM:
case ONEG:
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;
}
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -81,7 +81,7 @@ datagostring(Strlit *sval, Addr *a) ...@@ -81,7 +81,7 @@ datagostring(Strlit *sval, Addr *a)
a->sym = linksym(sym); a->sym = linksym(sym);
a->node = sym->def; a->node = sym->def;
a->offset = 0; // header a->offset = 0; // header
a->etype = TINT32; a->etype = TSTRING;
} }
void void
......
This diff is collapsed.
This diff is collapsed.
...@@ -865,6 +865,8 @@ enum ...@@ -865,6 +865,8 @@ enum
D_INDIR, /* additive */ D_INDIR, /* additive */
D_LAST,
T_TYPE = 1<<0, T_TYPE = 1<<0,
T_INDEX = 1<<1, T_INDEX = 1<<1,
T_OFFSET = 1<<2, T_OFFSET = 1<<2,
......
...@@ -70,6 +70,7 @@ struct Sym ...@@ -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); ...@@ -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);
......
This diff is collapsed.
This diff is collapsed.
# 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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -81,7 +81,7 @@ datagostring(Strlit *sval, Addr *a) ...@@ -81,7 +81,7 @@ datagostring(Strlit *sval, Addr *a)
a->sym = linksym(sym); a->sym = linksym(sym);
a->node = sym->def; a->node = sym->def;
a->offset = 0; // header a->offset = 0; // header
a->etype = TINT32; a->etype = TSTRING;
} }
void void
......
This diff is collapsed.
This diff is collapsed.
...@@ -654,6 +654,8 @@ enum ...@@ -654,6 +654,8 @@ enum
D_CONST2 = D_INDIR+D_INDIR, D_CONST2 = D_INDIR+D_INDIR,
D_LAST,
T_TYPE = 1<<0, T_TYPE = 1<<0,
T_INDEX = 1<<1, T_INDEX = 1<<1,
T_OFFSET = 1<<2, T_OFFSET = 1<<2,
......
# Copyright 2012 The Go Authors. All rights reserved. # Copyright 2012 The Go Authors. All rights reserved.
# 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.
...@@ -6,5 +6,5 @@ include ../../Make.dist ...@@ -6,5 +6,5 @@ include ../../Make.dist
install: y.tab.h install: y.tab.h
y.tab.h: cc.y y.tab.h: a.y
LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y cc.y LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment