// OpStoreStackReg must not allocate registers. func (mach X86) OpStoreStackReg(code gen.OpCoder, t types.T, offset int32, reg regs.R) { switch t.Category() { case types.Int: Mov.opToStack(code, t, reg, offset) case types.Float: MovsSSE.opToStack(code, t, reg, offset) default: panic(t) } }
func (i movImmInsn) op(code gen.OpCoder, t types.T, reg regs.R, value int64) { switch { case value >= -0x80000000 && value < 0x80000000: i.imm32.opImm(code, t, reg, int32(value)) case t.Size() == types.Size64 && value >= 0 && value < 0x100000000: i.imm.op(code, types.I32, reg, imm{uint32(value)}) default: i.imm.op(code, t, reg, imm{value}) } }
func (p *floatSizePrefix) writeTo(code gen.OpCoder, t types.T, ro, index, rmOrBase byte) { switch t.Size() { case types.Size32: code.Write(p.size32) case types.Size64: code.Write(p.size64) default: panic(t) } writeRexTo(code, 0, ro, index, rmOrBase) }
// OpGetGlobal must not update CPU's condition flags. func (mach X86) OpGetGlobal(code gen.RegCoder, t types.T, offset int32) values.Operand { reg, ok := code.TryAllocReg(t) if !ok { reg = regResult } if t.Category() == types.Int { Mov.opFromIndirect(code, t, reg, 0, NoIndex, regMemoryBase, offset) } else { MovSSE.opFromIndirect(code, t, reg, 0, NoIndex, regMemoryBase, offset) } return values.TempRegOperand(t, reg, true) }
func writeRexSizeTo(code gen.OpCoder, t types.T, ro, index, rmOrBase byte) { var rex byte switch t.Size() { case types.Size32: case types.Size64: rex |= rexW default: panic(t) } writeRexTo(code, rex, ro, index, rmOrBase) }
// OpMoveReg must not allocate registers. func (mach X86) OpMoveReg(code gen.Coder, t types.T, targetReg, sourceReg regs.R) { if targetReg == sourceReg { panic("target and source registers are the same") } switch t.Category() { case types.Int: Mov.opFromReg(code, t, targetReg, sourceReg) case types.Float: MovsSSE.opFromReg(code, t, targetReg, sourceReg) default: panic(t) } }
func TypeRegCategory(t types.T) RegCategory { return RegCategory(t.Category() - 1) }