mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-17 03:03:27 +00:00
all: use less magic in memory-mapped IO
Don't store addresses in the values of registers, this leads to problems with char arrays (among others). Instead, do it like it's done in C with raw addresses cast to struct pointers. This commit also splits gen-device.py, as AVR and ARM have very different ideas of what a register is. It's easier to just keep them separate.
This commit is contained in:
+7
-16
@@ -1421,15 +1421,12 @@ func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
store := c.builder.CreateStore(llvmVal, llvmAddr)
|
||||
valType := instr.Addr.Type().(*types.Pointer).Elem()
|
||||
if valType, ok := valType.(*types.Named); ok && valType.Obj().Name() == "__reg" {
|
||||
// Magic type name to transform this store to a register store.
|
||||
registerAddr := c.builder.CreateLoad(llvmAddr, "")
|
||||
ptr := c.builder.CreateIntToPtr(registerAddr, llvmAddr.Type(), "")
|
||||
store := c.builder.CreateStore(llvmVal, ptr)
|
||||
// Magic type name to make this store volatile, for memory-mapped
|
||||
// registers.
|
||||
store.SetVolatile(true)
|
||||
} else {
|
||||
c.builder.CreateStore(llvmVal, llvmAddr)
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
@@ -2739,19 +2736,13 @@ func (c *Compiler) parseUnOp(frame *Frame, unop *ssa.UnOp) (llvm.Value, error) {
|
||||
}
|
||||
case token.MUL: // *x, dereference pointer
|
||||
valType := unop.X.Type().(*types.Pointer).Elem()
|
||||
load := c.builder.CreateLoad(x, "")
|
||||
if valType, ok := valType.(*types.Named); ok && valType.Obj().Name() == "__reg" {
|
||||
// Magic type name: treat the value as a register pointer.
|
||||
register := unop.X.(*ssa.FieldAddr)
|
||||
global := register.X.(*ssa.Global)
|
||||
llvmGlobal := c.ir.GetGlobal(global).llvmGlobal
|
||||
llvmAddr := c.builder.CreateExtractValue(llvmGlobal.Initializer(), register.Field, "")
|
||||
ptr := llvm.ConstIntToPtr(llvmAddr, x.Type())
|
||||
load := c.builder.CreateLoad(ptr, "")
|
||||
// Magic type name to make this load volatile, for memory-mapped
|
||||
// registers.
|
||||
load.SetVolatile(true)
|
||||
return load, nil
|
||||
} else {
|
||||
return c.builder.CreateLoad(x, ""), nil
|
||||
}
|
||||
return load, nil
|
||||
case token.XOR: // ^x, toggle all bits in integer
|
||||
return c.builder.CreateXor(x, llvm.ConstInt(x.Type(), ^uint64(0), false), ""), nil
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user