Implement printing of int8/uint8/pointers

Этот коммит содержится в:
Ayke van Laethem 2018-06-03 16:39:24 +02:00
родитель e171f32493
коммит 320c583221
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
3 изменённых файлов: 80 добавлений и 6 удалений

Просмотреть файл

@ -1,12 +1,40 @@
package runtime
import (
"unsafe"
)
func printstring(s string) {
for i := 0; i < len(s); i++ {
putchar(s[i])
}
}
func printuint8(n uint8) {
if TargetBits >= 32 {
printuint32(uint32(n))
} else {
prevdigits := n / 10
if prevdigits != 0 {
printuint8(prevdigits)
}
putchar(byte((n % 10) + '0'))
}
}
func printint8(n int8) {
if TargetBits >= 32 {
printint32(int32(n))
} else {
if n < 0 {
putchar('-')
n = -n
}
printuint8(uint8(n))
}
}
func printuint32(n uint32) {
// TODO: don't recurse, but still be compact (and don't divide/mod
// more than necessary).
@ -64,3 +92,17 @@ func printitf(msg interface{}) {
print("???")
}
}
func printptr(ptr uintptr) {
putchar('0')
putchar('x')
for i := 0; i < int(unsafe.Sizeof(ptr)) * 2; i++ {
nibble := byte(ptr >> (unsafe.Sizeof(ptr) * 8 - 4))
if nibble < 10 {
putchar(nibble + '0')
} else {
putchar(nibble - 10 + 'a')
}
ptr <<= 4
}
}

Просмотреть файл

@ -3,6 +3,9 @@ package runtime
const Compiler = "tgo"
// The bitness of the CPU (e.g. 8, 32, 64). Set by the compiler as a constant.
var TargetBits uint8
func _panic(message interface{}) {
printstring("panic: ")
printitf(message)

33
tgo.go
Просмотреть файл

@ -113,7 +113,12 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
tripleSplit := strings.Split(c.triple, "-")
config := loader.Config {
// TODO: TypeChecker.Sizes
TypeChecker: types.Config{
Sizes: &types.StdSizes{
int64(c.targetData.PointerSize()),
int64(c.targetData.PrefTypeAlignment(c.i8ptrType)),
},
},
Build: &build.Context {
GOARCH: tripleSplit[0],
GOOS: tripleSplit[2],
@ -390,12 +395,26 @@ func (c *Compiler) parsePackage(program *ssa.Program, pkg *ssa.Package) error {
global := llvm.AddGlobal(c.mod, llvmType, c.getGlobalName(member))
if !strings.HasPrefix(member.Name(), "_extern_") {
global.SetLinkage(llvm.PrivateLinkage)
if c.getGlobalName(member) == "runtime.TargetBits" {
bitness := c.targetData.PointerSize()
if bitness < 32 {
// Only 8 and 32+ architectures supported at the moment.
// On 8 bit architectures, pointers are normally bigger
// than 8 bits to do anything meaningful.
// TODO: clean up this hack to support 16-bit
// architectures.
bitness = 8
}
global.SetInitializer(llvm.ConstInt(llvm.Int8Type(), uint64(bitness), false))
global.SetGlobalConstant(true)
} else {
initializer, err := c.getZeroValue(llvmType)
if err != nil {
return err
}
global.SetInitializer(initializer)
}
}
case *ssa.Type:
ms := program.MethodSets.MethodSet(member.Type())
for i := 0; i < ms.Len(); i++ {
@ -714,8 +733,10 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
switch typ := typ.(type) {
case *types.Basic:
switch typ.Kind() {
case types.Int8:
c.builder.CreateCall(c.mod.NamedFunction("runtime.printint8"), []llvm.Value{value}, "")
case types.Uint8:
c.builder.CreateCall(c.mod.NamedFunction("runtime.printbyte"), []llvm.Value{value}, "")
c.builder.CreateCall(c.mod.NamedFunction("runtime.printuint8"), []llvm.Value{value}, "")
case types.Int, types.Int32: // TODO: assumes a 32-bit int type
c.builder.CreateCall(c.mod.NamedFunction("runtime.printint32"), []llvm.Value{value}, "")
case types.Uint, types.Uint32:
@ -726,9 +747,17 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
c.builder.CreateCall(c.mod.NamedFunction("runtime.printuint64"), []llvm.Value{value}, "")
case types.String:
c.builder.CreateCall(c.mod.NamedFunction("runtime.printstring"), []llvm.Value{value}, "")
case types.Uintptr:
c.builder.CreateCall(c.mod.NamedFunction("runtime.printptr"), []llvm.Value{value}, "")
case types.UnsafePointer:
ptrValue := c.builder.CreatePtrToInt(value, c.uintptrType, "")
c.builder.CreateCall(c.mod.NamedFunction("runtime.printptr"), []llvm.Value{ptrValue}, "")
default:
return llvm.Value{}, errors.New("unknown basic arg type: " + fmt.Sprintf("%#v", typ))
}
case *types.Pointer:
ptrValue := c.builder.CreatePtrToInt(value, c.uintptrType, "")
c.builder.CreateCall(c.mod.NamedFunction("runtime.printptr"), []llvm.Value{ptrValue}, "")
default:
return llvm.Value{}, errors.New("unknown arg type: " + fmt.Sprintf("%#v", typ))
}