//===- value.go - govalue and operations ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the govalue type, which combines an LLVM value with its Go
// type, and implements various basic operations on govalues.
//
//===----------------------------------------------------------------------===//

package irgen

import (
	"fmt"
	"go/token"
	"llvm.org/llgo/third_party/gotools/go/exact"
	"llvm.org/llgo/third_party/gotools/go/types"
	"llvm.org/llvm/bindings/go/llvm"
)

// govalue contains an LLVM value and a Go type,
// representing the result of a Go expression.
type govalue struct {
	value llvm.Value
	typ   types.Type
}

func (v *govalue) String() string {
	return fmt.Sprintf("[llgo.govalue typ:%s value:%v]", v.typ, v.value)
}

// Create a new dynamic value from a (LLVM Value, Type) pair.
func newValue(v llvm.Value, t types.Type) *govalue {
	return &govalue{v, t}
}

// TODO(axw) remove this, use .typ directly
func (v *govalue) Type() types.Type {
	return v.typ
}

// newValueFromConst converts a constant value to an LLVM value.
func (fr *frame) newValueFromConst(v exact.Value, typ types.Type) *govalue {
	switch {
	case v == nil:
		llvmtyp := fr.types.ToLLVM(typ)
		return newValue(llvm.ConstNull(llvmtyp), typ)

	case isString(typ):
		if isUntyped(typ) {
			typ = types.Typ[types.String]
		}
		llvmtyp := fr.types.ToLLVM(typ)
		strval := exact.StringVal(v)
		strlen := len(strval)
		i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
		var ptr llvm.Value
		if strlen > 0 {
			init := llvm.ConstString(strval, false)
			ptr = llvm.AddGlobal(fr.module.Module, init.Type(), "")
			ptr.SetInitializer(init)
			ptr.SetLinkage(llvm.InternalLinkage)
			ptr = llvm.ConstBitCast(ptr, i8ptr)
		} else {
			ptr = llvm.ConstNull(i8ptr)
		}
		len_ := llvm.ConstInt(fr.types.inttype, uint64(strlen), false)
		llvmvalue := llvm.Undef(llvmtyp)
		llvmvalue = llvm.ConstInsertValue(llvmvalue, ptr, []uint32{0})
		llvmvalue = llvm.ConstInsertValue(llvmvalue, len_, []uint32{1})
		return newValue(llvmvalue, typ)

	case isInteger(typ):
		if isUntyped(typ) {
			typ = types.Typ[types.Int]
		}
		llvmtyp := fr.types.ToLLVM(typ)
		var llvmvalue llvm.Value
		if isUnsigned(typ) {
			v, _ := exact.Uint64Val(v)
			llvmvalue = llvm.ConstInt(llvmtyp, v, false)
		} else {
			v, _ := exact.Int64Val(v)
			llvmvalue = llvm.ConstInt(llvmtyp, uint64(v), true)
		}
		return newValue(llvmvalue, typ)

	case isBoolean(typ):
		if isUntyped(typ) {
			typ = types.Typ[types.Bool]
		}
		return newValue(boolLLVMValue(exact.BoolVal(v)), typ)

	case isFloat(typ):
		if isUntyped(typ) {
			typ = types.Typ[types.Float64]
		}
		llvmtyp := fr.types.ToLLVM(typ)
		floatval, _ := exact.Float64Val(v)
		llvmvalue := llvm.ConstFloat(llvmtyp, floatval)
		return newValue(llvmvalue, typ)

	case typ == types.Typ[types.UnsafePointer]:
		llvmtyp := fr.types.ToLLVM(typ)
		v, _ := exact.Uint64Val(v)
		llvmvalue := llvm.ConstInt(fr.types.inttype, v, false)
		llvmvalue = llvm.ConstIntToPtr(llvmvalue, llvmtyp)
		return newValue(llvmvalue, typ)

	case isComplex(typ):
		if isUntyped(typ) {
			typ = types.Typ[types.Complex128]
		}
		llvmtyp := fr.types.ToLLVM(typ)
		floattyp := llvmtyp.StructElementTypes()[0]
		llvmvalue := llvm.ConstNull(llvmtyp)
		realv := exact.Real(v)
		imagv := exact.Imag(v)
		realfloatval, _ := exact.Float64Val(realv)
		imagfloatval, _ := exact.Float64Val(imagv)
		llvmre := llvm.ConstFloat(floattyp, realfloatval)
		llvmim := llvm.ConstFloat(floattyp, imagfloatval)
		llvmvalue = llvm.ConstInsertValue(llvmvalue, llvmre, []uint32{0})
		llvmvalue = llvm.ConstInsertValue(llvmvalue, llvmim, []uint32{1})
		return newValue(llvmvalue, typ)
	}

	// Special case for string -> [](byte|rune)
	if u, ok := typ.Underlying().(*types.Slice); ok && isInteger(u.Elem()) {
		if v.Kind() == exact.String {
			strval := fr.newValueFromConst(v, types.Typ[types.String])
			return fr.convert(strval, typ)
		}
	}

	panic(fmt.Sprintf("unhandled: t=%s(%T), v=%v(%T)", typ, typ, v, v))
}

func (fr *frame) binaryOp(lhs *govalue, op token.Token, rhs *govalue) *govalue {
	if op == token.NEQ {
		result := fr.binaryOp(lhs, token.EQL, rhs)
		return fr.unaryOp(result, token.NOT)
	}

	var result llvm.Value
	b := fr.builder

	switch typ := lhs.typ.Underlying().(type) {
	case *types.Struct:
		// TODO(axw) use runtime equality algorithm (will be suitably inlined).
		// For now, we use compare all fields unconditionally and bitwise AND
		// to avoid branching (i.e. so we don't create additional blocks).
		value := newValue(boolLLVMValue(true), types.Typ[types.Bool])
		for i := 0; i < typ.NumFields(); i++ {
			t := typ.Field(i).Type()
			lhs := newValue(b.CreateExtractValue(lhs.value, i, ""), t)
			rhs := newValue(b.CreateExtractValue(rhs.value, i, ""), t)
			value = fr.binaryOp(value, token.AND, fr.binaryOp(lhs, token.EQL, rhs))
		}
		return value

	case *types.Array:
		// TODO(pcc): as above.
		value := newValue(boolLLVMValue(true), types.Typ[types.Bool])
		t := typ.Elem()
		for i := int64(0); i < typ.Len(); i++ {
			lhs := newValue(b.CreateExtractValue(lhs.value, int(i), ""), t)
			rhs := newValue(b.CreateExtractValue(rhs.value, int(i), ""), t)
			value = fr.binaryOp(value, token.AND, fr.binaryOp(lhs, token.EQL, rhs))
		}
		return value

	case *types.Slice:
		// []T == nil or nil == []T
		lhsptr := b.CreateExtractValue(lhs.value, 0, "")
		rhsptr := b.CreateExtractValue(rhs.value, 0, "")
		isnil := b.CreateICmp(llvm.IntEQ, lhsptr, rhsptr, "")
		isnil = b.CreateZExt(isnil, llvm.Int8Type(), "")
		return newValue(isnil, types.Typ[types.Bool])

	case *types.Signature:
		// func == nil or nil == func
		isnil := b.CreateICmp(llvm.IntEQ, lhs.value, rhs.value, "")
		isnil = b.CreateZExt(isnil, llvm.Int8Type(), "")
		return newValue(isnil, types.Typ[types.Bool])

	case *types.Interface:
		return fr.compareInterfaces(lhs, rhs)
	}

	// Strings.
	if isString(lhs.typ) {
		if isString(rhs.typ) {
			switch op {
			case token.ADD:
				return fr.concatenateStrings(lhs, rhs)
			case token.EQL, token.LSS, token.GTR, token.LEQ, token.GEQ:
				return fr.compareStrings(lhs, rhs, op)
			default:
				panic(fmt.Sprint("Unimplemented operator: ", op))
			}
		}
		panic("unimplemented")
	}

	// Complex numbers.
	if isComplex(lhs.typ) {
		// XXX Should we represent complex numbers as vectors?
		lhsval := lhs.value
		rhsval := rhs.value
		a_ := b.CreateExtractValue(lhsval, 0, "")
		b_ := b.CreateExtractValue(lhsval, 1, "")
		c_ := b.CreateExtractValue(rhsval, 0, "")
		d_ := b.CreateExtractValue(rhsval, 1, "")
		switch op {
		case token.QUO:
			// (a+bi)/(c+di) = (ac+bd)/(c**2+d**2) + (bc-ad)/(c**2+d**2)i
			ac := b.CreateFMul(a_, c_, "")
			bd := b.CreateFMul(b_, d_, "")
			bc := b.CreateFMul(b_, c_, "")
			ad := b.CreateFMul(a_, d_, "")
			cpow2 := b.CreateFMul(c_, c_, "")
			dpow2 := b.CreateFMul(d_, d_, "")
			denom := b.CreateFAdd(cpow2, dpow2, "")
			realnumer := b.CreateFAdd(ac, bd, "")
			imagnumer := b.CreateFSub(bc, ad, "")
			real_ := b.CreateFDiv(realnumer, denom, "")
			imag_ := b.CreateFDiv(imagnumer, denom, "")
			lhsval = b.CreateInsertValue(lhsval, real_, 0, "")
			result = b.CreateInsertValue(lhsval, imag_, 1, "")
		case token.MUL:
			// (a+bi)(c+di) = (ac-bd)+(bc+ad)i
			ac := b.CreateFMul(a_, c_, "")
			bd := b.CreateFMul(b_, d_, "")
			bc := b.CreateFMul(b_, c_, "")
			ad := b.CreateFMul(a_, d_, "")
			real_ := b.CreateFSub(ac, bd, "")
			imag_ := b.CreateFAdd(bc, ad, "")
			lhsval = b.CreateInsertValue(lhsval, real_, 0, "")
			result = b.CreateInsertValue(lhsval, imag_, 1, "")
		case token.ADD:
			real_ := b.CreateFAdd(a_, c_, "")
			imag_ := b.CreateFAdd(b_, d_, "")
			lhsval = b.CreateInsertValue(lhsval, real_, 0, "")
			result = b.CreateInsertValue(lhsval, imag_, 1, "")
		case token.SUB:
			real_ := b.CreateFSub(a_, c_, "")
			imag_ := b.CreateFSub(b_, d_, "")
			lhsval = b.CreateInsertValue(lhsval, real_, 0, "")
			result = b.CreateInsertValue(lhsval, imag_, 1, "")
		case token.EQL:
			realeq := b.CreateFCmp(llvm.FloatOEQ, a_, c_, "")
			imageq := b.CreateFCmp(llvm.FloatOEQ, b_, d_, "")
			result = b.CreateAnd(realeq, imageq, "")
			result = b.CreateZExt(result, llvm.Int8Type(), "")
			return newValue(result, types.Typ[types.Bool])
		default:
			panic(fmt.Errorf("unhandled operator: %v", op))
		}
		return newValue(result, lhs.typ)
	}

	// Floats and integers.
	// TODO determine the NaN rules.

	switch op {
	case token.MUL:
		if isFloat(lhs.typ) {
			result = b.CreateFMul(lhs.value, rhs.value, "")
		} else {
			result = b.CreateMul(lhs.value, rhs.value, "")
		}
		return newValue(result, lhs.typ)
	case token.QUO:
		switch {
		case isFloat(lhs.typ):
			result = b.CreateFDiv(lhs.value, rhs.value, "")
		case !isUnsigned(lhs.typ):
			result = b.CreateSDiv(lhs.value, rhs.value, "")
		default:
			result = b.CreateUDiv(lhs.value, rhs.value, "")
		}
		return newValue(result, lhs.typ)
	case token.REM:
		switch {
		case isFloat(lhs.typ):
			result = b.CreateFRem(lhs.value, rhs.value, "")
		case !isUnsigned(lhs.typ):
			result = b.CreateSRem(lhs.value, rhs.value, "")
		default:
			result = b.CreateURem(lhs.value, rhs.value, "")
		}
		return newValue(result, lhs.typ)
	case token.ADD:
		if isFloat(lhs.typ) {
			result = b.CreateFAdd(lhs.value, rhs.value, "")
		} else {
			result = b.CreateAdd(lhs.value, rhs.value, "")
		}
		return newValue(result, lhs.typ)
	case token.SUB:
		if isFloat(lhs.typ) {
			result = b.CreateFSub(lhs.value, rhs.value, "")
		} else {
			result = b.CreateSub(lhs.value, rhs.value, "")
		}
		return newValue(result, lhs.typ)
	case token.SHL, token.SHR:
		return fr.shift(lhs, rhs, op)
	case token.EQL:
		if isFloat(lhs.typ) {
			result = b.CreateFCmp(llvm.FloatOEQ, lhs.value, rhs.value, "")
		} else {
			result = b.CreateICmp(llvm.IntEQ, lhs.value, rhs.value, "")
		}
		result = b.CreateZExt(result, llvm.Int8Type(), "")
		return newValue(result, types.Typ[types.Bool])
	case token.LSS:
		switch {
		case isFloat(lhs.typ):
			result = b.CreateFCmp(llvm.FloatOLT, lhs.value, rhs.value, "")
		case !isUnsigned(lhs.typ):
			result = b.CreateICmp(llvm.IntSLT, lhs.value, rhs.value, "")
		default:
			result = b.CreateICmp(llvm.IntULT, lhs.value, rhs.value, "")
		}
		result = b.CreateZExt(result, llvm.Int8Type(), "")
		return newValue(result, types.Typ[types.Bool])
	case token.LEQ:
		switch {
		case isFloat(lhs.typ):
			result = b.CreateFCmp(llvm.FloatOLE, lhs.value, rhs.value, "")
		case !isUnsigned(lhs.typ):
			result = b.CreateICmp(llvm.IntSLE, lhs.value, rhs.value, "")
		default:
			result = b.CreateICmp(llvm.IntULE, lhs.value, rhs.value, "")
		}
		result = b.CreateZExt(result, llvm.Int8Type(), "")
		return newValue(result, types.Typ[types.Bool])
	case token.GTR:
		switch {
		case isFloat(lhs.typ):
			result = b.CreateFCmp(llvm.FloatOGT, lhs.value, rhs.value, "")
		case !isUnsigned(lhs.typ):
			result = b.CreateICmp(llvm.IntSGT, lhs.value, rhs.value, "")
		default:
			result = b.CreateICmp(llvm.IntUGT, lhs.value, rhs.value, "")
		}
		result = b.CreateZExt(result, llvm.Int8Type(), "")
		return newValue(result, types.Typ[types.Bool])
	case token.GEQ:
		switch {
		case isFloat(lhs.typ):
			result = b.CreateFCmp(llvm.FloatOGE, lhs.value, rhs.value, "")
		case !isUnsigned(lhs.typ):
			result = b.CreateICmp(llvm.IntSGE, lhs.value, rhs.value, "")
		default:
			result = b.CreateICmp(llvm.IntUGE, lhs.value, rhs.value, "")
		}
		result = b.CreateZExt(result, llvm.Int8Type(), "")
		return newValue(result, types.Typ[types.Bool])
	case token.AND: // a & b
		result = b.CreateAnd(lhs.value, rhs.value, "")
		return newValue(result, lhs.typ)
	case token.AND_NOT: // a &^ b
		rhsval := rhs.value
		rhsval = b.CreateXor(rhsval, llvm.ConstAllOnes(rhsval.Type()), "")
		result = b.CreateAnd(lhs.value, rhsval, "")
		return newValue(result, lhs.typ)
	case token.OR: // a | b
		result = b.CreateOr(lhs.value, rhs.value, "")
		return newValue(result, lhs.typ)
	case token.XOR: // a ^ b
		result = b.CreateXor(lhs.value, rhs.value, "")
		return newValue(result, lhs.typ)
	default:
		panic(fmt.Sprint("Unimplemented operator: ", op))
	}
	panic("unreachable")
}

func (fr *frame) shift(lhs *govalue, rhs *govalue, op token.Token) *govalue {
	rhs = fr.convert(rhs, lhs.Type())
	lhsval := lhs.value
	bits := rhs.value
	unsigned := isUnsigned(lhs.Type())
	// Shifting >= width of lhs yields undefined behaviour, so we must select.
	max := llvm.ConstInt(bits.Type(), uint64(lhsval.Type().IntTypeWidth()-1), false)
	var result llvm.Value
	lessEqualWidth := fr.builder.CreateICmp(llvm.IntULE, bits, max, "")
	if !unsigned && op == token.SHR {
		bits := fr.builder.CreateSelect(lessEqualWidth, bits, max, "")
		result = fr.builder.CreateAShr(lhsval, bits, "")
	} else {
		if op == token.SHL {
			result = fr.builder.CreateShl(lhsval, bits, "")
		} else {
			result = fr.builder.CreateLShr(lhsval, bits, "")
		}
		zero := llvm.ConstNull(lhsval.Type())
		result = fr.builder.CreateSelect(lessEqualWidth, result, zero, "")
	}
	return newValue(result, lhs.typ)
}

func (fr *frame) unaryOp(v *govalue, op token.Token) *govalue {
	switch op {
	case token.SUB:
		var value llvm.Value
		if isComplex(v.typ) {
			realv := fr.builder.CreateExtractValue(v.value, 0, "")
			imagv := fr.builder.CreateExtractValue(v.value, 1, "")
			negzero := llvm.ConstFloatFromString(realv.Type(), "-0")
			realv = fr.builder.CreateFSub(negzero, realv, "")
			imagv = fr.builder.CreateFSub(negzero, imagv, "")
			value = llvm.Undef(v.value.Type())
			value = fr.builder.CreateInsertValue(value, realv, 0, "")
			value = fr.builder.CreateInsertValue(value, imagv, 1, "")
		} else if isFloat(v.typ) {
			negzero := llvm.ConstFloatFromString(fr.types.ToLLVM(v.Type()), "-0")
			value = fr.builder.CreateFSub(negzero, v.value, "")
		} else {
			value = fr.builder.CreateNeg(v.value, "")
		}
		return newValue(value, v.typ)
	case token.ADD:
		return v // No-op
	case token.NOT:
		value := fr.builder.CreateXor(v.value, boolLLVMValue(true), "")
		return newValue(value, v.typ)
	case token.XOR:
		lhs := v.value
		rhs := llvm.ConstAllOnes(lhs.Type())
		value := fr.builder.CreateXor(lhs, rhs, "")
		return newValue(value, v.typ)
	default:
		panic(fmt.Sprintf("Unhandled operator: %s", op))
	}
}

func (fr *frame) convert(v *govalue, dsttyp types.Type) *govalue {
	b := fr.builder

	// If it's a stack allocated value, we'll want to compare the
	// value type, not the pointer type.
	srctyp := v.typ

	// Get the underlying type, if any.
	origdsttyp := dsttyp
	dsttyp = dsttyp.Underlying()
	srctyp = srctyp.Underlying()

	// Identical (underlying) types? Just swap in the destination type.
	if types.Identical(srctyp, dsttyp) {
		return newValue(v.value, origdsttyp)
	}

	// Both pointer types with identical underlying types? Same as above.
	if srctyp, ok := srctyp.(*types.Pointer); ok {
		if dsttyp, ok := dsttyp.(*types.Pointer); ok {
			srctyp := srctyp.Elem().Underlying()
			dsttyp := dsttyp.Elem().Underlying()
			if types.Identical(srctyp, dsttyp) {
				return newValue(v.value, origdsttyp)
			}
		}
	}

	// string ->
	if isString(srctyp) {
		// (untyped) string -> string
		// XXX should untyped strings be able to escape go/types?
		if isString(dsttyp) {
			return newValue(v.value, origdsttyp)
		}

		// string -> []byte
		if isSlice(dsttyp, types.Byte) {
			value := v.value
			strdata := fr.builder.CreateExtractValue(value, 0, "")
			strlen := fr.builder.CreateExtractValue(value, 1, "")

			// Data must be copied, to prevent changes in
			// the byte slice from mutating the string.
			newdata := fr.createMalloc(strlen)
			fr.memcpy(newdata, strdata, strlen)

			struct_ := llvm.Undef(fr.types.ToLLVM(dsttyp))
			struct_ = fr.builder.CreateInsertValue(struct_, newdata, 0, "")
			struct_ = fr.builder.CreateInsertValue(struct_, strlen, 1, "")
			struct_ = fr.builder.CreateInsertValue(struct_, strlen, 2, "")
			return newValue(struct_, origdsttyp)
		}

		// string -> []rune
		if isSlice(dsttyp, types.Rune) {
			return fr.stringToRuneSlice(v)
		}
	}

	// []byte -> string
	if isSlice(srctyp, types.Byte) && isString(dsttyp) {
		value := v.value
		data := fr.builder.CreateExtractValue(value, 0, "")
		len := fr.builder.CreateExtractValue(value, 1, "")

		// Data must be copied, to prevent changes in
		// the byte slice from mutating the string.
		newdata := fr.createMalloc(len)
		fr.memcpy(newdata, data, len)

		struct_ := llvm.Undef(fr.types.ToLLVM(types.Typ[types.String]))
		struct_ = fr.builder.CreateInsertValue(struct_, newdata, 0, "")
		struct_ = fr.builder.CreateInsertValue(struct_, len, 1, "")
		return newValue(struct_, types.Typ[types.String])
	}

	// []rune -> string
	if isSlice(srctyp, types.Rune) && isString(dsttyp) {
		return fr.runeSliceToString(v)
	}

	// rune -> string
	if isString(dsttyp) && isInteger(srctyp) {
		return fr.runeToString(v)
	}

	// Unsafe pointer conversions.
	llvm_type := fr.types.ToLLVM(dsttyp)
	if dsttyp == types.Typ[types.UnsafePointer] { // X -> unsafe.Pointer
		if _, isptr := srctyp.(*types.Pointer); isptr {
			return newValue(v.value, origdsttyp)
		} else if srctyp == types.Typ[types.Uintptr] {
			value := b.CreateIntToPtr(v.value, llvm_type, "")
			return newValue(value, origdsttyp)
		}
	} else if srctyp == types.Typ[types.UnsafePointer] { // unsafe.Pointer -> X
		if _, isptr := dsttyp.(*types.Pointer); isptr {
			return newValue(v.value, origdsttyp)
		} else if dsttyp == types.Typ[types.Uintptr] {
			value := b.CreatePtrToInt(v.value, llvm_type, "")
			return newValue(value, origdsttyp)
		}
	}

	lv := v.value
	srcType := lv.Type()
	switch srcType.TypeKind() {
	case llvm.IntegerTypeKind:
		switch llvm_type.TypeKind() {
		case llvm.IntegerTypeKind:
			srcBits := srcType.IntTypeWidth()
			dstBits := llvm_type.IntTypeWidth()
			delta := srcBits - dstBits
			switch {
			case delta < 0:
				if !isUnsigned(srctyp) {
					lv = b.CreateSExt(lv, llvm_type, "")
				} else {
					lv = b.CreateZExt(lv, llvm_type, "")
				}
			case delta > 0:
				lv = b.CreateTrunc(lv, llvm_type, "")
			}
			return newValue(lv, origdsttyp)
		case llvm.FloatTypeKind, llvm.DoubleTypeKind:
			if !isUnsigned(v.Type()) {
				lv = b.CreateSIToFP(lv, llvm_type, "")
			} else {
				lv = b.CreateUIToFP(lv, llvm_type, "")
			}
			return newValue(lv, origdsttyp)
		}
	case llvm.DoubleTypeKind:
		switch llvm_type.TypeKind() {
		case llvm.FloatTypeKind:
			lv = b.CreateFPTrunc(lv, llvm_type, "")
			return newValue(lv, origdsttyp)
		case llvm.IntegerTypeKind:
			if !isUnsigned(dsttyp) {
				lv = b.CreateFPToSI(lv, llvm_type, "")
			} else {
				lv = b.CreateFPToUI(lv, llvm_type, "")
			}
			return newValue(lv, origdsttyp)
		}
	case llvm.FloatTypeKind:
		switch llvm_type.TypeKind() {
		case llvm.DoubleTypeKind:
			lv = b.CreateFPExt(lv, llvm_type, "")
			return newValue(lv, origdsttyp)
		case llvm.IntegerTypeKind:
			if !isUnsigned(dsttyp) {
				lv = b.CreateFPToSI(lv, llvm_type, "")
			} else {
				lv = b.CreateFPToUI(lv, llvm_type, "")
			}
			return newValue(lv, origdsttyp)
		}
	}

	// Complex -> complex. Complexes are only convertible to other
	// complexes, contant conversions aside. So we can just check the
	// source type here; given that the types are not identical
	// (checked above), we can assume the destination type is the alternate
	// complex type.
	if isComplex(srctyp) {
		var fpcast func(llvm.Builder, llvm.Value, llvm.Type, string) llvm.Value
		var fptype llvm.Type
		if srctyp == types.Typ[types.Complex64] {
			fpcast = (llvm.Builder).CreateFPExt
			fptype = llvm.DoubleType()
		} else {
			fpcast = (llvm.Builder).CreateFPTrunc
			fptype = llvm.FloatType()
		}
		if fpcast != nil {
			realv := b.CreateExtractValue(lv, 0, "")
			imagv := b.CreateExtractValue(lv, 1, "")
			realv = fpcast(b, realv, fptype, "")
			imagv = fpcast(b, imagv, fptype, "")
			lv = llvm.Undef(fr.types.ToLLVM(dsttyp))
			lv = b.CreateInsertValue(lv, realv, 0, "")
			lv = b.CreateInsertValue(lv, imagv, 1, "")
			return newValue(lv, origdsttyp)
		}
	}
	panic(fmt.Sprintf("unimplemented conversion: %s (%s) -> %s", v.typ, lv.Type(), origdsttyp))
}

// extractRealValue extracts the real component of a complex number.
func (fr *frame) extractRealValue(v *govalue) *govalue {
	component := fr.builder.CreateExtractValue(v.value, 0, "")
	if component.Type().TypeKind() == llvm.FloatTypeKind {
		return newValue(component, types.Typ[types.Float32])
	}
	return newValue(component, types.Typ[types.Float64])
}

// extractRealValue extracts the imaginary component of a complex number.
func (fr *frame) extractImagValue(v *govalue) *govalue {
	component := fr.builder.CreateExtractValue(v.value, 1, "")
	if component.Type().TypeKind() == llvm.FloatTypeKind {
		return newValue(component, types.Typ[types.Float32])
	}
	return newValue(component, types.Typ[types.Float64])
}

func boolLLVMValue(v bool) (lv llvm.Value) {
	if v {
		return llvm.ConstInt(llvm.Int8Type(), 1, false)
	}
	return llvm.ConstNull(llvm.Int8Type())
}
