本文整理汇总了Golang中github.com/tsavola/wag/internal/gen.RegCoder.FreeReg方法的典型用法代码示例。如果您正苦于以下问题:Golang RegCoder.FreeReg方法的具体用法?Golang RegCoder.FreeReg怎么用?Golang RegCoder.FreeReg使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/tsavola/wag/internal/gen.RegCoder
的用法示例。
在下文中一共展示了RegCoder.FreeReg方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: binaryIntCompareOp
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
}
示例2: LoadOp
// LoadOp makes sure that index gets zero-extended if it's a VarReg operand.
func (mach X86) LoadOp(code gen.RegCoder, oper uint16, index values.Operand, resultType types.T, offset uint32) (result values.Operand) {
size := oper >> 8
baseReg, indexReg, ownIndexReg, disp := mach.opMemoryAddress(code, size, index, offset)
if ownIndexReg {
defer code.FreeReg(types.I64, indexReg)
}
load := memoryLoads[uint8(oper)]
targetReg, ok := code.TryAllocReg(resultType)
if !ok {
targetReg = regResult
}
result = values.TempRegOperand(resultType, targetReg, load.zeroExt)
insnType := load.insnType
if insnType == 0 {
insnType = resultType
}
load.insn.opFromIndirect(code, insnType, targetReg, 0, indexReg, baseReg, disp)
return
}
示例3: binaryFloatOp
func (mach X86) binaryFloatOp(code gen.RegCoder, index uint8, a, b values.Operand) values.Operand {
targetReg, _ := mach.opMaybeResultReg(code, a, false)
sourceReg, _, own := mach.opBorrowMaybeScratchReg(code, b, false)
if own {
defer code.FreeReg(b.Type, sourceReg)
}
binaryFloatInsns[index].opFromReg(code, a.Type, targetReg, sourceReg)
return values.TempRegOperand(a.Type, targetReg, false)
}
示例4: binaryFloatCompareOp
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))
}
示例5: unaryIntOp
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
}
示例6: binaryShiftOp
func (mach X86) binaryShiftOp(code gen.RegCoder, index uint8, a, b values.Operand) values.Operand {
insn := binaryShiftInsns[index]
var targetReg regs.R
switch b.Storage {
case values.Imm:
targetReg, _ = mach.opMaybeResultReg(code, a, true)
insn.imm.op(code, b.Type, targetReg, uint8(b.ImmValue()))
default:
if b.Storage.IsReg() && b.Reg() == regShiftCount {
targetReg, _ = mach.opMaybeResultReg(code, a, false)
defer code.Discard(b)
} else {
if code.RegAllocated(types.I32, regShiftCount) {
targetReg, _ = mach.opMaybeResultReg(code, a, true)
if targetReg == regShiftCount {
Mov.opFromReg(code, a.Type, regResult, regShiftCount)
targetReg = regResult
defer code.FreeReg(types.I32, regShiftCount)
} else {
// unknown operand in regShiftCount
Mov.opFromReg(code, types.I64, regScratch, regShiftCount)
defer Mov.opFromReg(code, types.I64, regShiftCount, regScratch)
}
} else {
code.AllocSpecificReg(types.I32, regShiftCount)
defer code.FreeReg(types.I32, regShiftCount)
targetReg, _ = mach.opMaybeResultReg(code, a, true)
}
b.Type = types.I32 // TODO: 8-bit mov
mach.OpMove(code, regShiftCount, b, false)
}
insn.opReg(code, a.Type, targetReg)
}
return values.TempRegOperand(a.Type, targetReg, true)
}
示例7: ConversionOp
func (mach X86) ConversionOp(code gen.RegCoder, oper uint16, resultType types.T, source values.Operand) (result values.Operand) {
if oper == opers.Wrap {
source.Type = types.I32 // short mov; useful zeroExt flag
reg, zeroExt := mach.opMaybeResultReg(code, source, false)
return values.TempRegOperand(resultType, reg, zeroExt)
}
reg, zeroExt := mach.opMaybeResultReg(code, source, false)
// TODO: for int<->float ops: borrow source reg, allocate target reg
switch oper {
case opers.ExtendS:
Movsxd.opFromReg(code, 0, reg, reg)
result = values.TempRegOperand(resultType, reg, false)
case opers.ExtendU:
if !zeroExt {
Mov.opFromReg(code, types.I32, reg, reg)
}
result = values.TempRegOperand(resultType, reg, false)
case opers.Mote:
Cvts2sSSE.opFromReg(code, source.Type, reg, reg)
result = values.TempRegOperand(resultType, reg, false)
case opers.TruncS:
panic(fmt.Errorf("%s.trunc_s/%s not implemented", resultType, source.Type))
case opers.TruncU:
panic(fmt.Errorf("%s.trunc_u/%s not implemented", resultType, source.Type))
case opers.ConvertS:
Cvtsi2sSSE.opReg(code, resultType, source.Type, regResult, reg)
code.FreeReg(source.Type, reg)
result = values.TempRegOperand(resultType, regResult, false)
case opers.ConvertU:
if source.Type == types.I32 {
if !zeroExt {
Mov.opFromReg(code, types.I32, reg, reg)
}
Cvtsi2sSSE.opReg(code, resultType, types.I64, regResult, reg)
} else {
mach.opConvertUnsignedI64ToFloat(code, resultType, reg)
}
code.FreeReg(source.Type, reg)
result = values.TempRegOperand(resultType, regResult, false)
case opers.Reinterpret:
if source.Type.Category() == types.Int {
MovSSE.opFromReg(code, source.Type, regResult, reg)
} else {
MovSSE.opToReg(code, source.Type, regResult, reg)
}
code.FreeReg(source.Type, reg)
result = values.TempRegOperand(resultType, regResult, true)
}
return
}
示例8: OpSelect
func (mach X86) OpSelect(code gen.RegCoder, a, b, condOperand values.Operand) values.Operand {
defer code.Consumed(condOperand)
var cond values.Condition
switch condOperand.Storage {
case values.VarMem:
Cmp.opImmToStack(code, types.I32, condOperand.VarMemOffset(), 0)
cond = values.Ne
case values.VarReg, values.TempReg:
reg := condOperand.Reg()
Test.opFromReg(code, types.I32, reg, reg)
cond = values.Ne
case values.Stack:
mach.OpAddImmToStackPtr(code, 8) // do before cmp to avoid overwriting flags
Cmp.opImmToStack(code, types.I32, -8, 0)
cond = values.Ne
case values.ConditionFlags:
cond = condOperand.Condition()
case values.Imm:
if condOperand.ImmValue() != 0 {
code.Consumed(b)
return a
} else {
code.Consumed(a)
return b
}
default:
panic(condOperand)
}
t := a.Type
targetReg, _ := mach.opMaybeResultReg(code, b, true)
switch t.Category() {
case types.Int:
cmov := conditionInsns[cond].cmov
switch a.Storage {
case values.VarMem:
cmov.opFromStack(code, t, targetReg, a.VarMemOffset())
default:
aReg, _, own := mach.opBorrowMaybeScratchReg(code, a, true)
if own {
defer code.FreeReg(t, aReg)
}
cmov.opFromReg(code, t, targetReg, aReg)
}
case types.Float:
var moveIt links.L
var end links.L
cond = values.InvertedConditions[cond]
notCondJump := conditionInsns[cond].jcc
switch {
case cond >= values.MinUnorderedOrCondition:
Jp.rel8.opStub(code) // move it if unordered
moveIt.AddSite(code.Len())
notCondJump.rel8.opStub(code) // break if not cond
end.AddSite(code.Len())
case cond >= values.MinOrderedAndCondition:
Jp.rel8.opStub(code) // break if unordered
end.AddSite(code.Len())
notCondJump.rel8.opStub(code) // break if not cond
end.AddSite(code.Len())
default:
notCondJump.rel8.opStub(code) // break if not cond
end.AddSite(code.Len())
}
moveIt.Addr = code.Len()
mach.updateBranches8(code, &moveIt)
mach.OpMove(code, targetReg, a, false)
end.Addr = code.Len()
mach.updateBranches8(code, &end)
default:
panic(t)
}
// cmov zero-extends the target unconditionally
return values.TempRegOperand(t, targetReg, true)
}
示例9: StoreOp
// StoreOp makes sure that index gets zero-extended if it's a VarReg operand.
func (mach X86) StoreOp(code gen.RegCoder, oper uint16, index, x values.Operand, offset uint32) {
size := oper >> 8
baseReg, indexReg, ownIndexReg, disp := mach.opMemoryAddress(code, size, index, offset)
if ownIndexReg {
defer code.FreeReg(types.I64, indexReg)
}
store := memoryStores[uint8(oper)]
insnType := store.insnType
if insnType == 0 {
insnType = x.Type
}
if x.Storage == values.Imm {
value := x.ImmValue()
value32 := int32(value)
switch {
case size == 1:
value32 = int32(int8(value32))
case size == 2:
value32 = int32(int16(value32))
case size == 4 || (value >= -0x80000000 && value < 0x80000000):
default:
goto large
}
store.insn.opImmToIndirect(code, insnType, 0, indexReg, baseReg, disp, value32)
return
large:
}
valueReg, _, own := mach.opBorrowMaybeResultReg(code, x, false)
if own {
defer code.FreeReg(x.Type, valueReg)
}
store.insn.opToIndirect(code, insnType, valueReg, 0, indexReg, baseReg, disp)
}
// opMemoryAddress may return the scratch register as the base.
func (mach X86) opMemoryAddress(code gen.RegCoder, size uint16, index values.Operand, offset uint32) (baseReg, indexReg regs.R, ownIndexReg bool, disp int32) {
sizeReach := uint64(size - 1)
reachOffset := uint64(offset) + sizeReach
if reachOffset >= 0x80000000 {
code.OpTrapCall(traps.MemoryOutOfBounds)
return
}
alreadyChecked := reachOffset < uint64(index.Bounds.Upper)
switch index.Storage {
case values.Imm:
value := uint64(index.ImmValue())
if value >= 0x80000000 {
code.OpTrapCall(traps.MemoryOutOfBounds)
return
}
addr := value + uint64(offset)
reachAddr := addr + sizeReach
if reachAddr >= 0x80000000 {
code.OpTrapCall(traps.MemoryOutOfBounds)
return
}
if reachAddr < uint64(code.MinMemorySize()) || alreadyChecked {
baseReg = regMemoryBase
indexReg = NoIndex
disp = int32(addr)
return
}
Lea.opFromIndirect(code, types.I64, regScratch, 0, NoIndex, regMemoryBase, int32(reachAddr))
default:
reg, zeroExt, own := mach.opBorrowMaybeScratchReg(code, index, true)
if !zeroExt {
Mov.opFromReg(code, types.I32, reg, reg) // zero-extend index
}
if alreadyChecked {
baseReg = regMemoryBase
indexReg = reg
ownIndexReg = own
disp = int32(offset)
return
}
//.........这里部分代码省略.........