install copy predefined

did not test 386, but should work
shouldnt matter if copy is not used

R=rsc
https://golang.org/cl/156055
This commit is contained in:
Ken Thompson 2009-11-17 20:41:44 -08:00
parent a8ba40823c
commit c4606d05da
12 changed files with 209 additions and 1 deletions

View File

@ -25,6 +25,7 @@ char *runtimeimport =
"func runtime.sliceinttostring (? []int) (? string)\n"
"func runtime.stringiter (? string, ? int) (? int)\n"
"func runtime.stringiter2 (? string, ? int) (retk int, retv int)\n"
"func runtime.slicecopy (to any, fr any, wid uint32) (? int)\n"
"func runtime.ifaceI2E (iface any) (ret any)\n"
"func runtime.ifaceE2I (typ *uint8, iface any) (ret any)\n"
"func runtime.ifaceT2E (typ *uint8, elem any) (ret any)\n"

View File

@ -346,6 +346,7 @@ enum
OCMPIFACE, OCMPSTR,
OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT,
OCONV, OCONVNOP, OCONVIFACE, OCONVSLICE,
OCOPY,
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
ODOTTYPE,

View File

@ -1245,6 +1245,7 @@ static struct
"cap", LNAME, Txxx, OCAP,
"close", LNAME, Txxx, OCLOSE,
"closed", LNAME, Txxx, OCLOSED,
"copy", LNAME, Txxx, OCOPY,
"len", LNAME, Txxx, OLEN,
"make", LNAME, Txxx, OMAKE,
"new", LNAME, Txxx, ONEW,

View File

@ -44,6 +44,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case OCAP:
case OCLOSE:
case OCLOSED:
case OCOPY:
case OLEN:
case OMAKE:
case ONEW:
@ -305,6 +306,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case OCLOSE:
case OCLOSED:
case OLEN:
case OCOPY:
case OMAKE:
case ONEW:
case OPANIC:

View File

@ -33,6 +33,7 @@ func slicebytetostring([]byte) string
func sliceinttostring([]int) string
func stringiter(string, int) int
func stringiter2(string, int) (retk int, retv int)
func slicecopy(to any, fr any, wid uint32) int
func ifaceI2E(iface any) (ret any)
func ifaceE2I(typ *byte, iface any) (ret any)

View File

@ -746,6 +746,7 @@ goopnames[] =
[OCLOSE] = "close",
[OCOM] = "^",
[OCONTINUE] = "continue",
[OCOPY] = "copy",
[ODEC] = "--",
[ODEFER] = "defer",
[ODIV] = "/",

View File

@ -761,6 +761,32 @@ reswitch:
ok |= Etop;
goto ret;
case OCOPY:
ok |= Erv;
args = n->list;
if(args == nil || args->next == nil) {
yyerror("missing arguments to copy");
goto error;
}
if(args->next->next != nil) {
yyerror("too many arguments to copy");
goto error;
}
typecheck(&args->n, Erv);
typecheck(&args->next->n, Erv);
if(!isslice(args->n->type) || !isslice(args->next->n->type)) {
yyerror("arguments to copy must be slices");
goto error;
}
if(!eqtype(args->n->type, args->next->n->type)) {
yyerror("arguments to copy must be slices of the same type");
goto error;
}
n->left = args->n;
n->right = args->next->n;
n->type = types[TINT];
goto ret;
case OCONV:
doconv:
ok |= Erv;

View File

@ -307,6 +307,7 @@ walkstmt(Node **np)
case OAS2MAPR:
case OCLOSE:
case OCLOSED:
case OCOPY:
case OCALLMETH:
case OCALLINTER:
case OCALL:
@ -904,6 +905,15 @@ walkexpr(Node **np, NodeList **init)
conv(n->right, types[TINT]));
goto ret;
case OCOPY:
fn = syslook("slicecopy", 1);
argtype(fn, n->left->type);
argtype(fn, n->right->type);
n = mkcall1(fn, n->type, init,
n->left, n->right,
nodintconst(n->left->type->width));
goto ret;
case OCLOSE:
// cannot use chanfn - closechan takes any, not chan any
fn = syslook("closechan", 1);
@ -950,7 +960,8 @@ walkexpr(Node **np, NodeList **init)
case ORUNESTR:
// sys_intstring(v)
n = mkcall("intstring", n->type, init, conv(n->left, types[TINT64])); // TODO(rsc): int64?!
n = mkcall("intstring", n->type, init,
conv(n->left, types[TINT64])); // TODO(rsc): int64?!
goto ret;
case OARRAYBYTESTR:

View File

@ -68,6 +68,7 @@ OFILES=\
sys.$O\
thread.$O\
traceback.$O\
memmove_$(GOARCH).$O\
$(OFILES_$(GOARCH))\
HFILES=\

View File

@ -0,0 +1,65 @@
TEXT memmove(SB), $0
MOVL to+0(FP), DI
MOVL fr+4(FP), SI
MOVL n+8(FP), BX
JLT fault
/*
* check and set for backwards
* should we look closer for overlap?
*/
CMPL SI, DI
JLS back
/*
* foreward copy loop
*/
MOVL BX, CX
SHRL $2, CX
ANDL $3, BX
REP; MOVSL
MOVL BX, CX
REP; MOVSB
MOVL to+0(FP),AX
RET
/*
* whole thing backwards has
* adjusted addresses
*/
back:
ADDL BX, DI
ADDL BX, SI
STD
/*
* copy
*/
MOVL BX, CX
SHRL $2, CX
ANDL $3, BX
SUBL $4, DI
SUBL $4, SI
REP; MOVSL
ADDL $3, DI
ADDL $3, SI
MOVL BX, CX
REP; MOVSB
CLD
MOVL to+0(FP),AX
RET
/*
* if called with negative count,
* treat as error rather than
* rotating all of memory
*/
fault:
MOVL $0,SI
MOVL 0(SI), AX
RET

View File

@ -0,0 +1,65 @@
TEXT memmove(SB), $0
MOVQ to+0(FP), DI
MOVQ fr+8(FP), SI
MOVLQSX n+16(FP), BX
JLT fault
/*
* check and set for backwards
* should we look closer for overlap?
*/
CMPQ SI, DI
JLS back
/*
* foreward copy loop
*/
MOVQ BX, CX
SHRQ $3, CX
ANDQ $7, BX
REP; MOVSQ
MOVQ BX, CX
REP; MOVSB
MOVQ to+0(FP),AX
RET
/*
* whole thing backwards has
* adjusted addresses
*/
back:
ADDQ BX, DI
ADDQ BX, SI
STD
/*
* copy
*/
MOVQ BX, CX
SHRQ $3, CX
ANDQ $7, BX
SUBQ $8, DI
SUBQ $8, SI
REP; MOVSQ
ADDQ $7, DI
ADDQ $7, SI
MOVQ BX, CX
REP; MOVSB
CLD
MOVQ to+0(FP),AX
RET
/*
* if called with negative count,
* treat as error rather than
* rotating all of memory
*/
fault:
MOVQ $0,SI
MOVQ 0(SI), AX
RET

View File

@ -177,6 +177,39 @@ runtime·arraytoslice(byte* old, uint32 nel, Slice ret)
}
}
// slicecopy(to any, fr any, wid uint32) int
void
runtime·slicecopy(Slice to, Slice fm, uintptr width, int32 ret)
{
if(fm.array == nil || fm.len == 0 ||
to.array == nil || to.len == 0 ||
width == 0) {
ret = 0;
goto out;
}
ret = fm.len;
if(to.len > ret)
ret = to.len;
memmove(to.array, fm.array, ret*width);
out:
FLUSH(&ret);
if(debug) {
prints("main·copy: to=");
runtime·printslice(to);
prints("; fm=");
runtime·printslice(fm);
prints("; width=");
runtime·printint(width);
prints("; ret=");
runtime·printint(ret);
prints("\n");
}
}
void
runtime·printslice(Slice a)
{