Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:mewmew/uc into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
sangisos committed Jun 14, 2016
2 parents 9c6bb3d + ab782ce commit e20eda0
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 14 deletions.
88 changes: 77 additions & 11 deletions irgen/irgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,17 @@ func (gen *generator) createVar(n *ast.VarDecl) error {
return errutil.Err(err)
}
} else {
// Ignore tentative definitions.
if isTentativeVarDef(n) {
log.Printf("ignoring tentative global variable definition of %v", n.Name())
return nil
}
// Global values are compile time constant, no need for ssa.
if err := gen.createGlobal(n); err != nil {
global, err := gen.createGlobal(n)
if err != nil {
return errutil.Err(err)
}
gen.module.Globals = append(gen.module.Globals, global)
}
return nil
}
Expand Down Expand Up @@ -564,17 +571,76 @@ func (gen *generator) createLocal(n *ast.VarDecl) error {
}

// createGlobal creates the instructions for a global variable declaration.
func (gen *generator) createGlobal(n *ast.VarDecl) error {
// Ignore tentative definitions.
if isTentativeVarDef(n) {
log.Printf("ignoring tentative global variable definition of %v", n.Name())
return nil
func (gen *generator) createGlobal(n *ast.VarDecl) (*ir.GlobalDecl, error) {
name := n.Name().Name
log.Printf("create global variable %q", name)
typ := toIrType(n.Type())
var val value.Value
var err error
switch {
case n.Val != nil:
val, err = gen.createConstant(n.Val)
if err != nil {
return nil, errutil.Err(err)
}
case irtypes.IsInt(typ):
val, err = constant.NewInt(typ, "0")
if err != nil {
return nil, errutil.Err(err)
}
default:
val, err = constant.NewZeroInitializer(typ)
if err != nil {
return nil, errutil.Err(err)
}
}
// TODO: Implement
log.Printf("create global variable %v", n)
var gv *ir.GlobalDecl
gen.module.Globals = append(gen.module.Globals, gv)
return nil
global := ir.NewGlobalDef(name, val, false)
return global, nil
}

// createConstant converts the given uC expression to an LLVM IR constant
// expression.
func (gen *generator) createConstant(expr ast.Expr) (constant.Constant, error) {
typ := gen.typeOf(expr)
switch expr := expr.(type) {
case *ast.BasicLit:
switch expr.Kind {
case token.CharLit:
s, err := strconv.Unquote(expr.Val)
if err != nil {
return nil, errutil.Err(err)
}
val, err := constant.NewInt(typ, s)
if err != nil {
return nil, errutil.Err(err)
}
return val, nil
case token.IntLit:
val, err := constant.NewInt(typ, expr.Val)
if err != nil {
return nil, errutil.Err(err)
}
return val, nil
default:
panic(fmt.Sprintf("support for basic literal kind %v not yet implemented", expr.Kind))
}
//case *ast.BinaryExpr:
//case *ast.CallExpr:
//case *ast.Ident:
//case *ast.IndexExpr:
//case *ast.ParenExpr:
//case *ast.UnaryExpr:
default:
panic(fmt.Sprintf("support for type %T not yet implemented", expr))
}
}

// typeOf returns the LLVM IR type of the given expression.
func (gen *generator) typeOf(expr ast.Expr) irtypes.Type {
if typ, ok := gen.info.Types[expr]; ok {
return toIrType(typ)
}
panic(fmt.Sprintf("unable to locate type for expression %v", expr))
}

// isTentative reports whether the given global variable declaration is a
Expand Down
9 changes: 7 additions & 2 deletions irgen/irgen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ func TestGen(t *testing.T) {
path: "../testdata/extra/irgen/tentative_def.c",
want: "../testdata/extra/irgen/tentative_def.ll",
},
{
path: "../testdata/extra/irgen/function.c",
want: "../testdata/extra/irgen/function.ll",
},
}

for _, g := range golden {
Expand All @@ -46,13 +50,14 @@ func TestGen(t *testing.T) {
file := f.(*ast.File)

// Verify input.
if err := sem.Check(file); err != nil {
info, err := sem.Check(file)
if err != nil {
t.Errorf("%q: semantic analysis error: %v", g.path, err)
continue
}

// Generate IR.
module, err := irgen.Gen(file)
module, err := irgen.Gen(file, info)
if err != nil {
t.Errorf("%q: unable to generate IR: %v", g.path, err)
continue
Expand Down
7 changes: 6 additions & 1 deletion testdata/extra/irgen/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
CFILES = $(wildcard *.c)
LLFILES = $(CFILES:.c=.ll)

all: $(LLFILES)
all: $(LLFILES) post_strip

%.ll: %.c
clang -S -emit-llvm -o $@ $<
./strip.sh $@

post_strip:
./post_strip.sh

.PHONY: post_strip
3 changes: 3 additions & 0 deletions testdata/extra/irgen/function.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int main() {
return 42;
}
4 changes: 4 additions & 0 deletions testdata/extra/irgen/function.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
define i32 @main() {
0:
ret i32 42
}

0 comments on commit e20eda0

Please sign in to comment.