当前位置: 首页>>代码示例>>Golang>>正文


Golang Value.BinaryOp方法代码示例

本文整理汇总了Golang中github.com/axw/gollvm/llvm.Value.BinaryOp方法的典型用法代码示例。如果您正苦于以下问题:Golang Value.BinaryOp方法的具体用法?Golang Value.BinaryOp怎么用?Golang Value.BinaryOp使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在github.com/axw/gollvm/llvm.Value的用法示例。


在下文中一共展示了Value.BinaryOp方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。

示例1: BinaryOp

func (lhs *LLVMValue) BinaryOp(op token.Token, rhs_ Value) Value {
	if op == token.NEQ {
		result := lhs.BinaryOp(token.EQL, rhs_)
		return result.UnaryOp(token.NOT)
	}

	var result llvm.Value
	c := lhs.compiler
	b := lhs.compiler.builder

	// Later we can do better by treating constants specially. For now, let's
	// convert to LLVMValue's.
	var rhs *LLVMValue
	rhsisnil := false
	switch rhs_ := rhs_.(type) {
	case *LLVMValue:
		rhs = rhs_
	case NilValue:
		rhsisnil = true
		switch rhs_ := rhs_.Convert(lhs.Type()).(type) {
		case ConstValue:
			rhs = c.NewLLVMValue(rhs_.LLVMValue(), rhs_.Type())
		case *LLVMValue:
			rhs = rhs_
		}
	case ConstValue:
		value := rhs_.Convert(lhs.Type())
		rhs = c.NewLLVMValue(value.LLVMValue(), value.Type())
	}

	switch typ := types.Underlying(lhs.typ).(type) {
	case *types.Struct:
		// TODO check types are the same.
		element_types_count := lhs.LLVMValue().Type().StructElementTypesCount()
		struct_fields := typ.Fields
		if element_types_count > 0 {
			t := c.ObjGetType(struct_fields[0])
			first_lhs := c.NewLLVMValue(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), t)
			first_rhs := c.NewLLVMValue(b.CreateExtractValue(rhs.LLVMValue(), 0, ""), t)
			first := first_lhs.BinaryOp(op, first_rhs)

			logical_op := token.LAND
			if op == token.NEQ {
				logical_op = token.LOR
			}

			result := first
			for i := 1; i < element_types_count; i++ {
				t := c.ObjGetType(struct_fields[i])
				next_lhs := c.NewLLVMValue(b.CreateExtractValue(lhs.LLVMValue(), i, ""), t)
				next_rhs := c.NewLLVMValue(b.CreateExtractValue(rhs.LLVMValue(), i, ""), t)
				next := next_lhs.BinaryOp(op, next_rhs)
				result = result.BinaryOp(logical_op, next)
			}
			return result
		}

	case *types.Interface:
		if rhsisnil {
			valueNull := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), "")
			typeNull := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 1, ""), "")
			result := b.CreateAnd(typeNull, valueNull, "")
			return c.NewLLVMValue(result, types.Bool)
		}
		// TODO check for interface/interface comparison vs. interface/value comparison.
		return lhs.compareI2I(rhs)

	case *types.Slice:
		// []T == nil
		isnil := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), "")
		return c.NewLLVMValue(isnil, types.Bool)
	}

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

	// Determine whether to use integer or floating point instructions.
	// TODO determine the NaN rules.
	isfp := types.Identical(types.Underlying(lhs.typ), types.Float32) ||
		types.Identical(types.Underlying(lhs.typ), types.Float64)

	switch op {
	case token.MUL:
		if isfp {
			result = b.CreateFMul(lhs.LLVMValue(), rhs.LLVMValue(), "")
		} else {
			result = b.CreateMul(lhs.LLVMValue(), rhs.LLVMValue(), "")
		}
//.........这里部分代码省略.........
开发者ID:spate,项目名称:llgo,代码行数:101,代码来源:value.go

示例2: BinaryOp

func (lhs *LLVMValue) BinaryOp(op token.Token, rhs_ Value) Value {
	if op == token.NEQ {
		result := lhs.BinaryOp(token.EQL, rhs_)
		return result.UnaryOp(token.NOT)
	}

	var result llvm.Value
	c := lhs.compiler
	b := lhs.compiler.builder

	// Later we can do better by treating constants specially. For now, let's
	// convert to LLVMValue's.
	var rhs *LLVMValue
	switch rhs_ := rhs_.(type) {
	case *LLVMValue:
		rhs = rhs_
	case NilValue:
		switch rhs_ := rhs_.Convert(lhs.Type()).(type) {
		case ConstValue:
			rhs = c.NewLLVMValue(rhs_.LLVMValue(), rhs_.Type())
		case *LLVMValue:
			rhs = rhs_
		}
	case ConstValue:
		value := rhs_.Convert(lhs.Type())
		rhs = c.NewLLVMValue(value.LLVMValue(), value.Type())
	}

	// Special case for structs.
	// TODO handle strings as an even more special case.
	if struct_type, ok := types.Underlying(lhs.typ).(*types.Struct); ok {
		// TODO check types are the same.

		element_types_count := lhs.LLVMValue().Type().StructElementTypesCount()
		struct_fields := struct_type.Fields

		if element_types_count > 0 {
			t := c.ObjGetType(struct_fields[0])
			first_lhs := c.NewLLVMValue(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), t)
			first_rhs := c.NewLLVMValue(b.CreateExtractValue(rhs.LLVMValue(), 0, ""), t)
			first := first_lhs.BinaryOp(op, first_rhs)

			logical_op := token.LAND
			if op == token.NEQ {
				logical_op = token.LOR
			}

			result := first
			for i := 1; i < element_types_count; i++ {
				t := c.ObjGetType(struct_fields[i])
				next_lhs := c.NewLLVMValue(b.CreateExtractValue(lhs.LLVMValue(), i, ""), t)
				next_rhs := c.NewLLVMValue(b.CreateExtractValue(rhs.LLVMValue(), i, ""), t)
				next := next_lhs.BinaryOp(op, next_rhs)
				result = result.BinaryOp(logical_op, next)
			}
			return result
		}
	}

	// Interfaces.
	if _, ok := types.Underlying(lhs.typ).(*types.Interface); ok {
		// TODO check for interface/interface comparison vs. interface/value comparison.

		// nil comparison
		if /*rhs.LLVMValue().IsConstant() &&*/ rhs.LLVMValue().IsNull() {
			var result llvm.Value
			if op == token.EQL {
				valueNull := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), "")
				typeNull := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 1, ""), "")
				result = b.CreateAnd(typeNull, valueNull, "")
			} else {
				valueNotNull := b.CreateIsNotNull(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), "")
				typeNotNull := b.CreateIsNotNull(b.CreateExtractValue(lhs.LLVMValue(), 1, ""), "")
				result = b.CreateOr(typeNotNull, valueNotNull, "")
			}
			return c.NewLLVMValue(result, types.Bool)
		}

		// First, check that the dynamic types are identical.
		// FIXME provide runtime function for type identity comparison, and
		// value comparisons.
		lhsType := b.CreateExtractValue(lhs.LLVMValue(), 1, "")
		rhsType := b.CreateExtractValue(rhs.LLVMValue(), 1, "")
		diff := b.CreatePtrDiff(lhsType, rhsType, "")
		zero := llvm.ConstNull(diff.Type())

		var result llvm.Value
		if op == token.EQL {
			typesIdentical := b.CreateICmp(llvm.IntEQ, diff, zero, "")
			//valuesEqual := ...
			//result = b.CreateAnd(typesIdentical, valuesEqual, "")
			result = typesIdentical
		} else {
			typesDifferent := b.CreateICmp(llvm.IntNE, diff, zero, "")
			//valuesUnequal := ...
			//result = b.CreateOr(typesDifferent, valuesUnequal, "")
			result = typesDifferent
		}
		return c.NewLLVMValue(result, types.Bool)
	}
//.........这里部分代码省略.........
开发者ID:prattmic,项目名称:llgo,代码行数:101,代码来源:value.go


注:本文中的github.com/axw/gollvm/llvm.Value.BinaryOp方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。