From 7be746e2f3b891371e8b1ffab0c25c522b5a1c36 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 13 Apr 2018 00:14:16 +0200 Subject: [PATCH] Make 'int' platform-dependent Or rather, provide abstraction to make this feature easy to add in the future. --- runtime/runtime.c | 4 ++-- runtime/runtime.h | 3 +-- tgo.go | 16 +++++++++++----- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index 1d548d40..37c03c42 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -10,7 +10,7 @@ void __go_printstring(string_t *str) { write(STDOUT_FILENO, str->buf, str->len); } -void __go_printint(int32_t n) { +void __go_printint(intgo_t n) { // Print integer in signed big-endian base-10 notation, for humans to // read. // TODO: don't recurse, but still be compact (and don't divide/mod @@ -19,7 +19,7 @@ void __go_printint(int32_t n) { print("-", 1); n = -n; } - int32_t prevdigits = n / 10; + intgo_t prevdigits = n / 10; if (prevdigits != 0) { __go_printint(prevdigits); } diff --git a/runtime/runtime.h b/runtime/runtime.h index 69f420a7..44640175 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -8,5 +8,4 @@ typedef struct { uint8_t buf[]; // variable size } string_t; -void __go_printstring(string_t *str); -void __go_printnl(); +typedef int32_t intgo_t; // may be 64-bit diff --git a/tgo.go b/tgo.go index a2c383e4..662941e5 100644 --- a/tgo.go +++ b/tgo.go @@ -29,6 +29,8 @@ type Compiler struct { ctx llvm.Context builder llvm.Builder machine llvm.TargetMachine + intType llvm.Type + stringLenType llvm.Type stringType llvm.Type stringPtrType llvm.Type printstringFunc llvm.Value @@ -50,13 +52,17 @@ func NewCompiler(path, triple string) (*Compiler, error) { c.ctx = c.mod.Context() c.builder = c.ctx.NewBuilder() + // Depends on platform (32bit or 64bit), but fix it here for now. + c.intType = llvm.Int32Type() + c.stringLenType = llvm.Int32Type() + // Length-prefixed string. - c.stringType = llvm.StructType([]llvm.Type{llvm.Int32Type(), llvm.ArrayType(llvm.Int8Type(), 0)}, false) + c.stringType = llvm.StructType([]llvm.Type{c.stringLenType, llvm.ArrayType(llvm.Int8Type(), 0)}, false) c.stringPtrType = llvm.PointerType(c.stringType, 0) printstringType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.stringPtrType}, false) c.printstringFunc = llvm.AddFunction(c.mod, "__go_printstring", printstringType) - printintType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{llvm.Int32Type()}, false) + printintType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.intType}, false) c.printintFunc = llvm.AddFunction(c.mod, "__go_printint", printintType) printspaceType := llvm.FunctionType(llvm.VoidType(), nil, false) c.printspaceFunc = llvm.AddFunction(c.mod, "__go_printspace", printspaceType) @@ -192,7 +198,7 @@ func (c *Compiler) parseBuiltin(instr *ssa.CallCommon, call *ssa.Builtin) error switch expr.Type() { case c.stringPtrType: c.builder.CreateCall(c.printstringFunc, []llvm.Value{*expr}, "") - case llvm.Int32Type(): + case c.intType: c.builder.CreateCall(c.printintFunc, []llvm.Value{*expr}, "") default: return errors.New("unknown arg type") @@ -252,7 +258,7 @@ func (c *Compiler) parseExpr(expr ssa.Value) (*llvm.Value, error) { case constant.String: str := constant.StringVal(expr.Value) strVal := c.ctx.ConstString(str, false) - strLen := llvm.ConstInt(llvm.Int32Type(), uint64(len(str)), false) + strLen := llvm.ConstInt(c.stringLenType, uint64(len(str)), false) strObj := llvm.ConstStruct([]llvm.Value{strLen, strVal}, false) ptr := llvm.AddGlobal(c.mod, strObj.Type(), ".str") ptr.SetInitializer(strObj) @@ -261,7 +267,7 @@ func (c *Compiler) parseExpr(expr ssa.Value) (*llvm.Value, error) { return &ptrCast, nil case constant.Int: n, _ := constant.Int64Val(expr.Value) // TODO: do something with the 'exact' return value? - val := llvm.ConstInt(llvm.Int32Type(), uint64(n), true) + val := llvm.ConstInt(c.intType, uint64(n), true) return &val, nil default: return nil, errors.New("todo: unknown constant")