//===- 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) {
			sliceValue := fr.runtime.stringToByteArray.callOnly(fr, v.value)[0]
			return newValue(sliceValue, origdsttyp)
		}

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

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

	// []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())
}
