Exemple #1
0
// Will panic if the module is invalid!
// Can be called on multiple modules in parallel.
func (v PassList) Run(mod *ssa.Module) {
	if err := validate.Validate(mod); err != nil {
		panic(err)
	}

	for _, pass := range v.passes {
		pass.Run(mod)

		if err := validate.Validate(mod); err != nil {
			panic("Pass `" + pass.String() + "` caused validation error: " + err.Error())
		}
	}
}
Exemple #2
0
func (v Target) Generate(out io.Writer, mod *ssa.Module) (err error) {
	if err := validate.Validate(mod); err != nil {
		return err
	}

	mod.UpdateNames()

	/*defer func() {
		rec := recover()
		if rec != nil {
			err = errors.New(fmt.Sprintf("amd64: %s", rec))
		}
	}()*/

	v.out = out
	v.mod = mod
	v.gen()

	return nil
}
Exemple #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)
	}
}