Esempio n. 1
0
func (mach X86) binaryIntCompareOp(code gen.RegCoder, cond uint8, a, b values.Operand) (result values.Operand) {
	result = values.ConditionFlagsOperand(values.Condition(cond))

	targetReg, _, own := mach.opBorrowMaybeResultReg(code, a, false)
	if own {
		defer code.FreeReg(a.Type, targetReg)
	}

	if b.Storage == values.VarMem {
		Cmp.opFromStack(code, a.Type, targetReg, b.VarMemOffset())
		return
	}

	var sourceReg regs.R

	if b.Storage.IsReg() {
		sourceReg = b.Reg()
	} else {
		if b.Storage == values.Imm {
			if value := b.ImmValue(); value >= -0x80000000 && value < 0x80000000 {
				Cmp.opImm(code, a.Type, targetReg, int32(value))
				return
			}
		}
		sourceReg = regScratch
		mach.OpMove(code, sourceReg, b, false)
	}

	Cmp.opFromReg(code, a.Type, targetReg, sourceReg)
	code.Consumed(b)
	return
}
Esempio n. 2
0
func (mach X86) binaryFloatCompareOp(code gen.RegCoder, cond uint8, a, b values.Operand) values.Operand {
	aReg, _, own := mach.opBorrowMaybeResultReg(code, a, true)
	if own {
		defer code.FreeReg(a.Type, aReg)
	}

	bReg, _, own := mach.opBorrowMaybeScratchReg(code, b, false)
	if own {
		defer code.FreeReg(b.Type, bReg)
	}

	UcomisSSE.opFromReg(code, a.Type, aReg, bReg)
	return values.ConditionFlagsOperand(values.Condition(cond))
}
Esempio n. 3
0
File: unary.go Progetto: tsavola/wag
func (mach X86) unaryIntOp(code gen.RegCoder, index uint8, x values.Operand) (result values.Operand) {
	if index == opers.IndexIntEqz {
		reg, _, own := mach.opBorrowMaybeScratchReg(code, x, false)
		if own {
			defer code.FreeReg(x.Type, reg)
		}

		Test.opFromReg(code, x.Type, reg, reg)
		return values.ConditionFlagsOperand(values.Eq)
	}

	var targetReg regs.R

	sourceReg, _, own := mach.opBorrowMaybeScratchReg(code, x, false)
	if own {
		targetReg = sourceReg
	} else {
		var ok bool

		targetReg, ok = code.TryAllocReg(x.Type)
		if !ok {
			targetReg = regResult
		}
	}

	result = values.TempRegOperand(x.Type, targetReg, true)

	insn := unaryIntInsns[index]

	switch index {
	case opers.IndexIntClz:
		insn.opFromReg(code, x.Type, regScratch, sourceReg)
		MovImm.opImm(code, x.Type, targetReg, -1)
		Cmove.opFromReg(code, x.Type, regScratch, targetReg)
		MovImm.opImm(code, x.Type, targetReg, (int32(x.Type.Size())<<3)-1)
		Sub.opFromReg(code, x.Type, targetReg, regScratch)

	case opers.IndexIntCtz:
		insn.opFromReg(code, x.Type, targetReg, sourceReg)
		MovImm.opImm(code, x.Type, regScratch, int32(x.Type.Size())<<3)
		Cmove.opFromReg(code, x.Type, targetReg, regScratch)

	case opers.IndexIntPopcnt:
		insn.opFromReg(code, x.Type, targetReg, sourceReg)
	}

	return
}