Implement printing of int8/uint8/pointers
Этот коммит содержится в:
родитель
e171f32493
коммит
320c583221
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
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))
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче