Ejemplo n.º 1
0
func (v *GEP) Type() types.Type {
	typ := v.value.Type()

	for i, index := range v.indexes {
		switch styp := typ.(type) {
		case *types.Pointer:
			if i != 0 {
				return types.NewVoid() // only the first index can dereference a pointer
			}

			typ = styp.Element()

		case *types.Array:
			typ = styp.Element()

		case *types.Struct:
			lit, ok := index.(*IntLiteral)
			if !ok {
				return types.NewVoid()
			}

			if int(lit.value) >= len(styp.Fields()) {
				return types.NewVoid()
			}

			typ = styp.Fields()[lit.value]

		default:
			return types.NewVoid()
		}
	}

	return types.NewPointer(typ)
}
Ejemplo n.º 2
0
func (v Load) Type() types.Type {
	ptr, ok := v.location.Type().(*types.Pointer)
	if !ok {
		return types.NewVoid()
	}

	return ptr.Element()
}
Ejemplo n.º 3
0
func test() {
	mod := ssa.NewModule("mod")

	strLit := ssa.NewStringLiteral("%2d: %lld\n", true)
	strGlob := mod.NewGlobal(strLit.Type(), ssa.NewLiteralInitialiser(strLit), "str")

	failLit := ssa.NewStringLiteral("Please supply number as argument\n", true)
	failGlob := mod.NewGlobal(failLit.Type(), ssa.NewLiteralInitialiser(failLit), "str")

	i8ptr := types.NewPointer(types.NewInt(8))
	i32 := types.NewInt(32)
	i64 := types.NewInt(64)

	printf := mod.NewFunction(types.NewSignature([]types.Type{i8ptr}, types.NewVoid(), true), "printf")
	atol := mod.NewFunction(types.NewSignature([]types.Type{i8ptr}, i64, false), "atol")

	mainFnSig := types.NewSignature([]types.Type{i32, types.NewPointer(i8ptr)}, i32, false)
	mainFn := mod.NewFunction(mainFnSig, "main")
	entry := mainFn.AddBlockAtEnd("entry")
	getMax := mainFn.AddBlockAtEnd("getMax")
	fail := mainFn.AddBlockAtEnd("fail")
	builder := ssa.NewBuilder()

	builder.SetInsertAtBlockStart(entry)
	builder.CreateCondBr(builder.CreateICmp(mainFn.Parameters()[0], ssa.NewIntLiteral(2, i32), ssa.IntSGE, "cmp"), getMax, fail)

	builder.SetInsertAtBlockStart(fail)
	builder.CreateCall(printf, []ssa.Value{builder.CreateConvert(failGlob, i8ptr, ssa.ConvertBitcast, "")}, "")
	builder.CreateRet(ssa.NewIntLiteral(1, i32))

	builder.SetInsertAtBlockStart(getMax)
	secondArg := builder.CreateLoad(builder.CreateGEP(mainFn.Parameters()[1], []ssa.Value{ssa.NewIntLiteral(1, i32)}, ""), "")
	maxorig := builder.CreateCall(atol, []ssa.Value{secondArg}, "max")
	location := builder.CreateAlloc(maxorig.Type(), "")
	builder.CreateStore(location, maxorig)
	max := builder.CreateLoad(location, "")

	mid := mainFn.AddBlockAtEnd("mid")
	exit := mainFn.AddBlockAtEnd("exit")
	builder.CreateBr(mid)
	builder.SetInsertAtBlockStart(mid)

	phi := builder.CreatePhi(i64, "phi")
	phi.AddIncoming(ssa.NewIntLiteral(0, i64), getMax)

	aphi := builder.CreatePhi(i64, "aphi")
	bphi := builder.CreatePhi(i64, "bphi")
	bphi.AddIncoming(ssa.NewIntLiteral(1, i64), getMax)
	aphi.AddIncoming(ssa.NewIntLiteral(0, i64), getMax)
	aphi.AddIncoming(bphi, mid)

	add := builder.CreateBinOp(phi, ssa.NewIntLiteral(1, i64), ssa.BinOpAdd, "add")

	addfib := builder.CreateBinOp(aphi, bphi, ssa.BinOpAdd, "addfib")
	bphi.AddIncoming(addfib, mid)

	builder.CreateCall(printf,
		[]ssa.Value{
			builder.CreateConvert(strGlob, i8ptr, ssa.ConvertBitcast, ""),
			add,
			aphi},
		"")

	phi.AddIncoming(add, mid)
	cmp := builder.CreateICmp(add, max, ssa.IntSGE, "cmp")
	builder.CreateCondBr(cmp, exit, mid)

	builder.SetInsertAtBlockStart(exit)
	builder.CreateRet(builder.CreateConvert(ssa.NewIntLiteral(0, types.NewInt(8)), i32, ssa.ConvertSExt, ""))

	fmt.Println(mod)

	fmt.Println("")

	//analysis.PrintValues(mod, os.Stdout)

	err := validate.Validate(mod)
	if err != nil {
		log.Fatal(err)
	}

	blockCFG := analysis.NewBlockCFG(mainFn)
	err = blockCFG.SaveImage("cfg.svg")
	if err != nil {
		fmt.Println(err)
	}

	domTree := analysis.NewBlockDominatorTree(blockCFG)
	err = domTree.SaveImage("dom.svg")
	if err != nil {
		fmt.Println(err)
	}

	file, err := os.OpenFile("out.s", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	t := amd64.Target{
		Platform: platform.Windows,
	}

	err = t.Generate(file, mod)
	if err != nil {
		log.Fatal(err)
	}
}