"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"
OCMPIFACE, OCMPSTR,
OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT,
OCONV, OCONVNOP, OCONVIFACE, OCONVSLICE,
+ OCOPY,
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
ODOTTYPE,
"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,
case OCAP:
case OCLOSE:
case OCLOSED:
+ case OCOPY:
case OLEN:
case OMAKE:
case ONEW:
case OCLOSE:
case OCLOSED:
case OLEN:
+ case OCOPY:
case OMAKE:
case ONEW:
case OPANIC:
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)
[OCLOSE] = "close",
[OCOM] = "^",
[OCONTINUE] = "continue",
+ [OCOPY] = "copy",
[ODEC] = "--",
[ODEFER] = "defer",
[ODIV] = "/",
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;
case OAS2MAPR:
case OCLOSE:
case OCLOSED:
+ case OCOPY:
case OCALLMETH:
case OCALLINTER:
case OCALL:
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);
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:
sys.$O\
thread.$O\
traceback.$O\
+ memmove_$(GOARCH).$O\
$(OFILES_$(GOARCH))\
HFILES=\
--- /dev/null
+ 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
--- /dev/null
+ 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
}
}
+// 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)
{