예제 #1
0
파일: irx.go 프로젝트: llir/llvm
// NewCallInst returns a new call instruction based on the given function return
// type, function name and function arguments.
func NewCallInst(result, gname, args interface{}) (*instruction.Call, error) {
	name, err := getGlobalName(gname)
	if err != nil {
		return nil, errutil.Err(err)
	}
	if result, ok := result.(types.Type); ok {
		switch args := args.(type) {
		case []value.Value:
			return instruction.NewCall(result, name, args)
		case nil:
			return instruction.NewCall(result, name, nil)
		default:
			return nil, errutil.Newf("invalid function arguments type; expected []value.Value, got %T", args)
		}
	}
	return nil, errutil.Newf("invalid function return type; expected types.Type, got %T", result)
}
예제 #2
0
파일: lower.go 프로젝트: mewmew/uc
// callExpr lowers the given identifier to LLVM IR, emitting code to f.
func (m *Module) callExpr(f *Function, callExpr *ast.CallExpr) value.Value {
	typ := toIrType(callExpr.Name.Decl.Type())
	sig, ok := typ.(*irtypes.Func)
	if !ok {
		panic(fmt.Sprintf("invalid function type; expected *types.Func, got %T", typ))
	}
	params := sig.Params()
	result := sig.Result()
	var args []value.Value
	// TODO: Add support for variadic arguments.
	for i, arg := range callExpr.Args {
		expr := m.expr(f, arg)
		expr = m.convert(f, expr, params[i].Type())
		args = append(args, expr)
	}
	callInst, err := instruction.NewCall(result, callExpr.Name.String(), args)
	if err != nil {
		panic(fmt.Sprintf("unable to create call instruction; %v", err))
	}
	return f.emitInst(callInst)
}
예제 #3
0
파일: fix.go 프로젝트: llir/llvm
// fixValueInst replaces dummy values within the given value instruction with
// their corresponding local variables.
func (m dummyMap) fixValueInst(oldValInst instruction.ValueInst) instruction.ValueInst {
	switch oldValInst := oldValInst.(type) {
	// Binary Operations
	case *instruction.Add:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewAdd(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FAdd:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewFAdd(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.Sub:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewSub(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FSub:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewFSub(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.Mul:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewMul(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FMul:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewFMul(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.UDiv:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewUDiv(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.SDiv:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewSDiv(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FDiv:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewFDiv(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.URem:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewURem(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.SRem:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewSRem(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FRem:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewFRem(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst

	// Bitwise Binary Operations
	case *instruction.ShL:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewShL(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.LShR:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewLShR(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.AShR:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewAShR(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.And:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewAnd(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.Or:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewOr(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.Xor:
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewXor(x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst

	// Vector Operations
	case *instruction.ExtractElement:
		panic("irx.dummyMap.fixValueInst: ExtractElement not yet implemented")
	case *instruction.InsertElement:
		panic("irx.dummyMap.fixValueInst: InsertElement not yet implemented")
	case *instruction.ShuffleVector:
		panic("irx.dummyMap.fixValueInst: ShuffleVector not yet implemented")

	// Aggregate Operations
	case *instruction.ExtractValue:
		panic("irx.dummyMap.fixValueInst: ExtractValue not yet implemented")
	case *instruction.InsertValue:
		panic("irx.dummyMap.fixValueInst: InsertValue not yet implemented")

	// Memory Access and Addressing Operations
	case *instruction.Alloca:
		// Nothing to do; alloca contains no dummy values.
		return oldValInst
	case *instruction.Load:
		srcAddr := m.fixValue(oldValInst.SrcAddr())
		inst, err := instruction.NewLoad(srcAddr)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.CmpXchg:
		panic("irx.dummyMap.fixValueInst: CmpXchg not yet implemented")
	case *instruction.AtomicRMW:
		panic("irx.dummyMap.fixValueInst: AtomicRMW not yet implemented")
	case *instruction.GetElementPtr:
		srcAddr := m.fixValue(oldValInst.SrcAddr())
		var indices []value.Value
		for _, oldIndex := range oldValInst.Indices() {
			index := m.fixValue(oldIndex)
			indices = append(indices, index)
		}
		inst, err := instruction.NewGetElementPtr(srcAddr, indices)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst

	// Conversion Operations
	case *instruction.Trunc:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewTrunc(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.ZExt:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewZExt(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.SExt:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewSExt(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FPTrunc:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewFPTrunc(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FPExt:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewFPExt(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FPToUI:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewFPToUI(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FPToSI:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewFPToSI(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.UIToFP:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewUIToFP(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.SIToFP:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewSIToFP(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.PtrToInt:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewPtrToInt(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.IntToPtr:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewIntToPtr(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.BitCast:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewBitCast(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.AddrSpaceCast:
		from := m.fixValue(oldValInst.From())
		to := oldValInst.RetType()
		inst, err := instruction.NewAddrSpaceCast(from, to)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst

	// Other Operations
	case *instruction.ICmp:
		cond := oldValInst.Cond()
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewICmp(cond, x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.FCmp:
		panic("irx.dummyMap.fixValueInst: FCmp not yet implemented")
	case *instruction.PHI:
		oldIncs := oldValInst.Incs()
		var incs []*instruction.Incoming
		for _, oldInc := range oldIncs {
			val := m.fixValue(oldInc.Value())
			pred := m.fixNamedValue(oldInc.Pred())
			inc, err := instruction.NewIncoming(val, pred)
			if err != nil {
				panic(errutil.Err(err))
			}
			incs = append(incs, inc)
		}
		inst, err := instruction.NewPHI(incs)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.Select:
		cond := m.fixValue(oldValInst.Cond())
		x := m.fixValue(oldValInst.X())
		y := m.fixValue(oldValInst.Y())
		inst, err := instruction.NewSelect(cond, x, y)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.Call:
		result := oldValInst.RetType()
		// TODO: Fix value of callee if the type of Callee changes from string to
		// value.Value.
		callee := oldValInst.Callee()
		var args []value.Value
		for _, oldArg := range oldValInst.Args() {
			arg := m.fixValue(oldArg)
			args = append(args, arg)
		}
		inst, err := instruction.NewCall(result, callee, args)
		if err != nil {
			panic(errutil.Err(err))
		}
		return inst
	case *instruction.VAArg:
		panic("irx.dummyMap.fixValueInst: VAArg not yet implemented")
	case *instruction.LandingPad:
		panic("irx.dummyMap.fixValueInst: LandingPad not yet implemented")
	case *instruction.CatchPad:
		panic("irx.dummyMap.fixValueInst: CatchPad not yet implemented")
	case *instruction.CleanupPad:
		panic("irx.dummyMap.fixValueInst: CleanupPad not yet implemented")
	default:
		panic("irx.dummyMap.fixValueInst: not yet implemented")
	}
}