Этот коммит содержится в:
Ayke van Laethem 2018-08-17 23:21:47 +02:00
родитель 574c7ec047
коммит 62c4c5e90b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
19 изменённых файлов: 28 добавлений и 45 удалений

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

@ -1,9 +1,7 @@
package main package main
import ( import (
"go/types" "go/types"
"golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa"
) )

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

@ -33,6 +33,7 @@ type __reg uint32
type RegValue = __reg type RegValue = __reg
type __asm string type __asm string
func Asm(s __asm) func Asm(s __asm)
const ( const (

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

@ -1,4 +1,3 @@
package main package main
import ( import (

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

@ -1,4 +1,3 @@
package main package main
type Thing struct { type Thing struct {
@ -84,7 +83,7 @@ func fib(n int) int {
if n <= 2 { if n <= 2 {
return 1 return 1
} }
return fib(n - 1) + fib(n - 2) return fib(n-1) + fib(n-2)
} }
func sumrange(n int) int { func sumrange(n int) int {

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

@ -1,4 +1,3 @@
package machine package machine
type GPIOConfig struct { type GPIOConfig struct {

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

@ -1,4 +1,3 @@
// +build avr // +build avr
package machine package machine
@ -10,7 +9,7 @@ import (
type GPIOMode uint8 type GPIOMode uint8
const ( const (
GPIO_INPUT = iota GPIO_INPUT = iota
GPIO_OUTPUT GPIO_OUTPUT
) )

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

@ -1,4 +1,3 @@
// +build !avr,!nrf // +build !avr,!nrf
package machine package machine
@ -8,7 +7,7 @@ package machine
type GPIOMode uint8 type GPIOMode uint8
const ( const (
GPIO_INPUT = iota GPIO_INPUT = iota
GPIO_OUTPUT GPIO_OUTPUT
) )

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

@ -1,4 +1,3 @@
// +build nrf // +build nrf
package machine package machine

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

@ -1,4 +1,3 @@
// +build !linux // +build !linux
package runtime package runtime

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

@ -1,4 +1,3 @@
package runtime package runtime
import ( import (
@ -96,8 +95,8 @@ func printitf(msg interface{}) {
func printptr(ptr uintptr) { func printptr(ptr uintptr) {
putchar('0') putchar('0')
putchar('x') putchar('x')
for i := 0; i < int(unsafe.Sizeof(ptr)) * 2; i++ { for i := 0; i < int(unsafe.Sizeof(ptr))*2; i++ {
nibble := byte(ptr >> (unsafe.Sizeof(ptr) * 8 - 4)) nibble := byte(ptr >> (unsafe.Sizeof(ptr)*8 - 4))
if nibble < 10 { if nibble < 10 {
putchar(nibble + '0') putchar(nibble + '0')
} else { } else {

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

@ -1,4 +1,3 @@
package runtime package runtime
const Compiler = "tgo" const Compiler = "tgo"

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

@ -1,4 +1,3 @@
// +build avr // +build avr
package runtime package runtime

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

@ -1,4 +1,3 @@
// +build nrf // +build nrf
package runtime package runtime
@ -20,16 +19,17 @@ func init() {
} }
func initUART() { func initUART() {
nrf.UART0.ENABLE = nrf.UART0_ENABLE_ENABLE_Enabled nrf.UART0.ENABLE = nrf.UART0_ENABLE_ENABLE_Enabled
nrf.UART0.BAUDRATE = nrf.UART0_BAUDRATE_BAUDRATE_Baud115200 nrf.UART0.BAUDRATE = nrf.UART0_BAUDRATE_BAUDRATE_Baud115200
nrf.UART0.TASKS_STARTTX = 1 nrf.UART0.TASKS_STARTTX = 1
nrf.UART0.PSELTXD = 6 // pin 6 for NRF52840-DK nrf.UART0.PSELTXD = 6 // pin 6 for NRF52840-DK
} }
func initLFCLK() { func initLFCLK() {
nrf.CLOCK.LFCLKSRC = nrf.CLOCK_LFCLKSTAT_SRC_Xtal nrf.CLOCK.LFCLKSRC = nrf.CLOCK_LFCLKSTAT_SRC_Xtal
nrf.CLOCK.TASKS_LFCLKSTART = 1 nrf.CLOCK.TASKS_LFCLKSTART = 1
for nrf.CLOCK.EVENTS_LFCLKSTARTED == 0 {} for nrf.CLOCK.EVENTS_LFCLKSTARTED == 0 {
}
nrf.CLOCK.EVENTS_LFCLKSTARTED = 0 nrf.CLOCK.EVENTS_LFCLKSTARTED = 0
} }
@ -41,16 +41,17 @@ func initRTC() {
func putchar(c byte) { func putchar(c byte) {
nrf.UART0.TXD = nrf.RegValue(c) nrf.UART0.TXD = nrf.RegValue(c)
for nrf.UART0.EVENTS_TXDRDY == 0 {} for nrf.UART0.EVENTS_TXDRDY == 0 {
}
nrf.UART0.EVENTS_TXDRDY = 0 nrf.UART0.EVENTS_TXDRDY = 0
} }
func sleep(d Duration) { func sleep(d Duration) {
ticks64 := d / 32 ticks64 := d / 32
for ticks64 != 0 { for ticks64 != 0 {
monotime() // update timestamp monotime() // update timestamp
ticks := uint32(ticks64) & 0x7fffff // 23 bits (to be on the safe side) ticks := uint32(ticks64) & 0x7fffff // 23 bits (to be on the safe side)
C.rtc_sleep(C.uint32_t(ticks)) // TODO: not accurate (must be d / 30.5175...) C.rtc_sleep(C.uint32_t(ticks)) // TODO: not accurate (must be d / 30.5175...)
ticks64 -= Duration(ticks) ticks64 -= Duration(ticks)
} }
} }

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

@ -1,4 +1,3 @@
// +build linux // +build linux
package runtime package runtime
@ -30,7 +29,7 @@ func sleep(d Duration) {
func monotime() uint64 { func monotime() uint64 {
var ts C.struct_timespec var ts C.struct_timespec
C.clock_gettime(C.CLOCK_MONOTONIC, &ts) C.clock_gettime(C.CLOCK_MONOTONIC, &ts)
return uint64(ts.tv_sec) * 1000 * 1000 + uint64(ts.tv_nsec) / 1000 return uint64(ts.tv_sec)*1000*1000 + uint64(ts.tv_nsec)/1000
} }
func abort() { func abort() {

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

@ -1,4 +1,3 @@
package runtime package runtime
// This file implements the Go scheduler using coroutines. // This file implements the Go scheduler using coroutines.
@ -212,7 +211,7 @@ func scheduler(main taskInstance) {
// Add tasks that are done sleeping to the end of the runqueue so they // Add tasks that are done sleeping to the end of the runqueue so they
// will be executed soon. // will be executed soon.
if sleepQueue != nil && now - sleepQueueBaseTime >= uint64(taskPromise(sleepQueue).data) { if sleepQueue != nil && now-sleepQueueBaseTime >= uint64(taskPromise(sleepQueue).data) {
scheduleLog(" run <- sleep") scheduleLog(" run <- sleep")
t := sleepQueue t := sleepQueue
promise := taskPromise(t) promise := taskPromise(t)

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

@ -1,4 +1,3 @@
package runtime package runtime
// TODO: use the time package for this. // TODO: use the time package for this.

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

@ -1,4 +1,3 @@
package syscall package syscall
// dummy // dummy

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

@ -1,4 +1,3 @@
package unsafe package unsafe
// dummy // dummy

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

@ -1,4 +1,3 @@
package main package main
import ( import (
@ -127,14 +126,14 @@ func NewCompiler(pkgName, triple string, dumpSSA bool) (*Compiler, error) {
func (c *Compiler) Parse(mainPath string, buildTags []string) error { func (c *Compiler) Parse(mainPath string, buildTags []string) error {
tripleSplit := strings.Split(c.triple, "-") tripleSplit := strings.Split(c.triple, "-")
config := loader.Config { config := loader.Config{
TypeChecker: types.Config{ TypeChecker: types.Config{
Sizes: &types.StdSizes{ Sizes: &types.StdSizes{
int64(c.targetData.PointerSize()), int64(c.targetData.PointerSize()),
int64(c.targetData.PrefTypeAlignment(c.i8ptrType)), int64(c.targetData.PrefTypeAlignment(c.i8ptrType)),
}, },
}, },
Build: &build.Context { Build: &build.Context{
GOARCH: tripleSplit[0], GOARCH: tripleSplit[0],
GOOS: tripleSplit[2], GOOS: tripleSplit[2],
GOROOT: ".", GOROOT: ".",
@ -159,7 +158,7 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
} }
} }
c.program = ssautil.CreateProgram(lprogram, ssa.SanityCheckFunctions | ssa.BareInits) c.program = ssautil.CreateProgram(lprogram, ssa.SanityCheckFunctions|ssa.BareInits)
c.program.Build() c.program.Build()
c.mainPkg = c.program.ImportedPackage(mainPath) c.mainPkg = c.program.ImportedPackage(mainPath)
@ -1219,7 +1218,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
if !boundsCheck.IsNil() { if !boundsCheck.IsNil() {
constZero := llvm.ConstInt(c.intType, 0, false) constZero := llvm.ConstInt(c.intType, 0, false)
isNegative := c.builder.CreateICmp(llvm.IntSLT, index, constZero, "") // index < 0 isNegative := c.builder.CreateICmp(llvm.IntSLT, index, constZero, "") // index < 0
isTooBig := c.builder.CreateICmp(llvm.IntSGE, index, buflen, "") // index >= len(value) isTooBig := c.builder.CreateICmp(llvm.IntSGE, index, buflen, "") // index >= len(value)
isOverflow := c.builder.CreateOr(isNegative, isTooBig, "") isOverflow := c.builder.CreateOr(isNegative, isTooBig, "")
c.builder.CreateCall(boundsCheck, []llvm.Value{isOverflow}, "") c.builder.CreateCall(boundsCheck, []llvm.Value{isOverflow}, "")
} }
@ -1382,7 +1381,7 @@ func (c *Compiler) parseBinOp(frame *Frame, binop *ssa.BinOp) (llvm.Value, error
if typNamed, ok := typ.(*types.Named); ok { if typNamed, ok := typ.(*types.Named); ok {
typ = typNamed.Underlying() typ = typNamed.Underlying()
} }
signed := typ.(*types.Basic).Info() & types.IsUnsigned == 0 signed := typ.(*types.Basic).Info()&types.IsUnsigned == 0
switch binop.Op { switch binop.Op {
case token.ADD: // + case token.ADD: // +
return c.builder.CreateAdd(x, y, ""), nil return c.builder.CreateAdd(x, y, ""), nil
@ -1404,7 +1403,7 @@ func (c *Compiler) parseBinOp(frame *Frame, binop *ssa.BinOp) (llvm.Value, error
} }
case token.AND: // & case token.AND: // &
return c.builder.CreateAnd(x, y, ""), nil return c.builder.CreateAnd(x, y, ""), nil
case token.OR: // | case token.OR: // |
return c.builder.CreateOr(x, y, ""), nil return c.builder.CreateOr(x, y, ""), nil
case token.XOR: // ^ case token.XOR: // ^
return c.builder.CreateXor(x, y, ""), nil return c.builder.CreateXor(x, y, ""), nil
@ -1487,10 +1486,10 @@ func (c *Compiler) parseConst(expr *ssa.Const) (llvm.Value, error) {
return llvm.Value{}, errors.New("todo: non-null constant pointer") return llvm.Value{}, errors.New("todo: non-null constant pointer")
} }
return llvm.ConstNull(c.i8ptrType), nil return llvm.ConstNull(c.i8ptrType), nil
} else if typ.Info() & types.IsUnsigned != 0 { } else if typ.Info()&types.IsUnsigned != 0 {
n, _ := constant.Uint64Val(expr.Value) n, _ := constant.Uint64Val(expr.Value)
return llvm.ConstInt(llvmType, n, false), nil return llvm.ConstInt(llvmType, n, false), nil
} else if typ.Info() & types.IsInteger != 0 { // signed } else if typ.Info()&types.IsInteger != 0 { // signed
n, _ := constant.Int64Val(expr.Value) n, _ := constant.Int64Val(expr.Value)
return llvm.ConstInt(llvmType, uint64(n), true), nil return llvm.ConstInt(llvmType, uint64(n), true), nil
} else { } else {
@ -1532,13 +1531,13 @@ func (c *Compiler) parseConvert(frame *Frame, typeTo types.Type, x ssa.Value) (l
return c.builder.CreateBitCast(value, llvmTypeTo, ""), nil return c.builder.CreateBitCast(value, llvmTypeTo, ""), nil
} }
if typeTo.Info() & types.IsInteger == 0 { // if not integer if typeTo.Info()&types.IsInteger == 0 { // if not integer
return llvm.Value{}, errors.New("todo: convert: extend non-integer type") return llvm.Value{}, errors.New("todo: convert: extend non-integer type")
} }
if sizeFrom > sizeTo { if sizeFrom > sizeTo {
return c.builder.CreateTrunc(value, llvmTypeTo, ""), nil return c.builder.CreateTrunc(value, llvmTypeTo, ""), nil
} else if typeTo.Info() & types.IsUnsigned != 0 { // if unsigned } else if typeTo.Info()&types.IsUnsigned != 0 { // if unsigned
return c.builder.CreateZExt(value, llvmTypeTo, ""), nil return c.builder.CreateZExt(value, llvmTypeTo, ""), nil
} else { // if signed } else { // if signed
return c.builder.CreateSExt(value, llvmTypeTo, ""), nil return c.builder.CreateSExt(value, llvmTypeTo, ""), nil
@ -1718,7 +1717,6 @@ func Compile(pkgName, runtimePath, outpath, target string, printIR, dumpSSA bool
return nil return nil
} }
func main() { func main() {
outpath := flag.String("o", "", "output filename") outpath := flag.String("o", "", "output filename")
printIR := flag.Bool("printir", false, "print LLVM IR") printIR := flag.Bool("printir", false, "print LLVM IR")
@ -1734,7 +1732,7 @@ func main() {
return return
} }
os.Setenv("CC", "clang -target=" + *target) os.Setenv("CC", "clang -target="+*target)
err := Compile(flag.Args()[0], *runtime, *outpath, *target, *printIR, *dumpSSA) err := Compile(flag.Args()[0], *runtime, *outpath, *target, *printIR, *dumpSSA)
if err != nil { if err != nil {