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 }
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)) }
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 }