From c7b3ad174881c5c88bbcbd6476e42f277eb51872 Mon Sep 17 00:00:00 2001 From: Markku Rossi Date: Thu, 25 Jul 2024 10:09:02 +0200 Subject: [PATCH] The builtin copy implemented as AST node. --- README.md | 2 +- compiler/ast/builtin.go | 111 ---------------------------------- testsuite/lang/copy_make.mpcl | 17 ++++++ 3 files changed, 18 insertions(+), 112 deletions(-) create mode 100644 testsuite/lang/copy_make.mpcl diff --git a/README.md b/README.md index 83e6756..3d29058 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ The MPCL runtime defines the following builtin functions: - [ ] SSA aliasing is 1:1 but `amov` has 2:1 relation - [ ] variable liveness analysis for templates - [ ] BitShift - - [ ] `copy()` does not work on arrays which have been `make()`:ed + - [x] `copy()` does not work on arrays which have been `make()`:ed - [ ] `&base[pos][i]` returns the address of the first element - [ ] reading from `*[32]int32` returns invalid values - [x] Pointer handling diff --git a/compiler/ast/builtin.go b/compiler/ast/builtin.go index e1f1bc6..6f0c2e9 100644 --- a/compiler/ast/builtin.go +++ b/compiler/ast/builtin.go @@ -33,9 +33,6 @@ type Eval func(args []AST, env *Env, ctx *Codegen, gen *ssa.Generator, // Predeclared identifiers. var builtins = map[string]Builtin{ - "copy": { - SSA: copySSA, - }, "floorPow2": { SSA: floorPow2SSA, Eval: floorPow2Eval, @@ -57,114 +54,6 @@ var builtins = map[string]Builtin{ }, } -func copySSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator, - args []ssa.Value, loc utils.Point) (*ssa.Block, []ssa.Value, error) { - - if len(args) != 2 { - return nil, nil, ctx.Errorf(loc, - "invalid amount of arguments in call to copy") - } - dst := args[0] - src := args[1] - - var baseName string - var baseType types.Info - var baseScope ssa.Scope - var baseBindings *ssa.Bindings - var base ssa.Value - - var dstOffset types.Size - var elementType types.Info - - switch dst.Type.Type { - case types.TArray, types.TSlice: - baseName = dst.Name - baseType = dst.Type - baseScope = dst.Scope - baseBindings = block.Bindings - - dstOffset = 0 - elementType = *dst.Type.ElementType - base = dst - - case types.TPtr: - elementType = *dst.Type.ElementType - if !elementType.Type.Array() { - return nil, nil, ctx.Errorf(loc, "setting elements of non-array %s", - elementType) - } - baseName = dst.PtrInfo.Name - baseType = dst.PtrInfo.ContainerType - baseScope = dst.PtrInfo.Scope - baseBindings = dst.PtrInfo.Bindings - - dstOffset = dst.PtrInfo.Offset - elementType = *elementType.ElementType - - b, ok := baseBindings.Get(baseName) - if !ok { - return nil, nil, ctx.Errorf(loc, "undefined: %s", baseName) - } - base = b.Value(block, gen) - - default: - return nil, nil, ctx.Errorf(loc, - "arguments to copy must be slices; have %s, %s", - dst.Type.Type, src.Type.Type) - } - - var srcType types.Info - if src.Type.Type == types.TPtr { - srcType = *src.Type.ElementType - } else { - srcType = src.Type - } - - if !srcType.Type.Array() { - return nil, nil, ctx.Errorf(loc, - "second argument to copy should be slice or array (%v)", src.Type) - } - if !elementType.Equal(*srcType.ElementType) { - return nil, nil, ctx.Errorf(loc, - "arguments to copy have different element types: %s and %s", - baseType.ElementType, src.Type.ElementType) - } - - dstBits := dst.Type.Bits - srcBits := src.Type.Bits - - var copied types.Size - if srcBits > dstBits { - fromConst := gen.Constant(int64(0), types.Undefined) - toConst := gen.Constant(int64(dstBits), types.Undefined) - - tmp := gen.AnonVal(dst.Type) - block.AddInstr(ssa.NewSliceInstr(src, fromConst, toConst, tmp)) - src = tmp - srcBits = dstBits - - copied = dst.Type.ArraySize - } else { - copied = src.Type.ArraySize - } - - lValue := gen.NewVal(baseName, baseType, baseScope) - - fromConst := gen.Constant(int64(dstOffset), types.Undefined) - toConst := gen.Constant(int64(dstOffset+srcBits), types.Undefined) - - block.AddInstr(ssa.NewAmovInstr(src, base, fromConst, toConst, lValue)) - err := baseBindings.Set(lValue, nil) - if err != nil { - return nil, nil, ctx.Error(loc, err.Error()) - } - - v := gen.Constant(int64(copied), types.Undefined) - gen.AddConstant(v) - - return block, []ssa.Value{v}, nil -} - func floorPow2SSA(block *ssa.Block, ctx *Codegen, gen *ssa.Generator, args []ssa.Value, loc utils.Point) (*ssa.Block, []ssa.Value, error) { return nil, nil, ctx.Errorf(loc, "floorPow2SSA not implemented") diff --git a/testsuite/lang/copy_make.mpcl b/testsuite/lang/copy_make.mpcl new file mode 100644 index 0000000..a7f41ec --- /dev/null +++ b/testsuite/lang/copy_make.mpcl @@ -0,0 +1,17 @@ +// -*- go -*- + +package main + +// @Hex +// @LSB +// @Test 0x11223344 0xaabb = 0x11223344aa 0x11223344aa 5 +func main(g, e []byte) ([]byte, []byte, int) { + buf := make([]byte, 5) + n := copy(buf, g) + m := copy(buf[n:], e) + + buf2 := make([]byte, 5) + copy(buf2, buf) + + return buf, buf2, n + m +}