]> Cypherpunks repositories - gostls13.git/commitdiff
install copy predefined
authorKen Thompson <ken@golang.org>
Wed, 18 Nov 2009 04:41:44 +0000 (20:41 -0800)
committerKen Thompson <ken@golang.org>
Wed, 18 Nov 2009 04:41:44 +0000 (20:41 -0800)
did not test 386, but should work
shouldnt matter if copy is not used

R=rsc
https://golang.org/cl/156055

12 files changed:
src/cmd/gc/builtin.c.boot
src/cmd/gc/go.h
src/cmd/gc/lex.c
src/cmd/gc/print.c
src/cmd/gc/runtime.go
src/cmd/gc/subr.c
src/cmd/gc/typecheck.c
src/cmd/gc/walk.c
src/pkg/runtime/Makefile
src/pkg/runtime/memmove_386.s [new file with mode: 0644]
src/pkg/runtime/memmove_amd64.s [new file with mode: 0644]
src/pkg/runtime/slice.c

index fc8a6d1f60f7bea2299c0efa49f928a6f80e8c39..8b794efdb82bb1f5fd26baab7ad335e7ee0ad05a 100644 (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"
index f5b88ff593d125bc08511399b172b035a7c60024..7702efbf7437a96286f8deb3afeeb05b293e9f55 100644 (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,
index 14500dc75a2325ee720247782a268deeeb1dbdea..f858aa95ec9559727761800c9db2ff916dca5507 100644 (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,
index ce4f721aed9188539a6b27efaffbdf8a3330ed9d..bbb7b0fbd2e98f6eb7d7a2bb1ba79bc356de265e 100644 (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:
index 5e363292093836950c8afb0bad79a20d109578bb..1f078f2da814cd53505e321a5162e67ff73ff143 100644 (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)
index 75ece477d26e0ef25b3fe610ee5fcad0354038bb..22e59c5c807ecea30e56a90a3ed786cc710a0240 100644 (file)
@@ -746,6 +746,7 @@ goopnames[] =
        [OCLOSE]        = "close",
        [OCOM]          = "^",
        [OCONTINUE]     = "continue",
+       [OCOPY]         = "copy",
        [ODEC]          = "--",
        [ODEFER]        = "defer",
        [ODIV]          = "/",
index 108a2d3e9bffbe3044d3f19c57da09120d02a4ad..86633b86d9602a91ce3fdbe8b09976c4e219c03f 100644 (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;
index 6aa23783f58e246efbaee4278e443faaf679507e..bb100b9716a2b1b9678c6823a999df3ef4810e94 100644 (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:
index 08bf278ef40d4e19222023e553172e42113124f5..3c97c495f6732a1c1228c8d3857f6caaa4adcf70 100644 (file)
@@ -68,6 +68,7 @@ OFILES=\
        sys.$O\
        thread.$O\
        traceback.$O\
+       memmove_$(GOARCH).$O\
        $(OFILES_$(GOARCH))\
 
 HFILES=\
diff --git a/src/pkg/runtime/memmove_386.s b/src/pkg/runtime/memmove_386.s
new file mode 100644 (file)
index 0000000..f7bc402
--- /dev/null
@@ -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
diff --git a/src/pkg/runtime/memmove_amd64.s b/src/pkg/runtime/memmove_amd64.s
new file mode 100644 (file)
index 0000000..7444d3b
--- /dev/null
@@ -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
index 722802c004cd8a459a8b753ec5e44c89a753e1cf..00d9724fbe62345d247a596a45ac347cdf2cb565 100644 (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)
 {