// OpStoreStack must not allocate registers. func (mach X86) OpStoreStack(code gen.Coder, offset int32, x values.Operand) { var reg regs.R if x.Storage.IsReg() { reg = x.Reg() } else { reg = regScratch mach.OpMove(code, reg, x, true) } mach.OpStoreStackReg(code, x.Type, offset, reg) if x.Storage == values.TempReg { code.FreeReg(x.Type, reg) } }
// OpPush must not allocate registers, and must not update CPU's condition // flags unless the operand is the condition flags. func (mach X86) OpPush(code gen.Coder, x values.Operand) { var reg regs.R switch { case x.Storage.IsReg(): reg = x.Reg() case x.Storage == values.Imm: value := x.ImmValue() switch { case value >= -0x80 && value < 0x80: PushImm8.op(code, imm{int8(value)}) return case value >= -0x80000000 && value < 0x80000000: PushImm32.op(code, imm{int32(value)}) return } fallthrough default: reg = regScratch mach.OpMove(code, reg, x, true) } switch x.Type.Category() { case types.Int: Push.op(code, reg) case types.Float: pushFloatOp(code, x.Type, reg) default: panic(x) } if x.Storage == values.TempReg { code.FreeReg(x.Type, reg) } }
func (mach X86) OpBranchIf(code gen.Coder, x values.Operand, yes bool, addr int32) (sites []int32) { var cond values.Condition if x.Storage == values.ConditionFlags { cond = x.Condition() } else { reg, _, own := mach.opBorrowMaybeScratchReg(code, x, false) if own { defer code.FreeReg(types.I32, reg) } Test.opFromReg(code, types.I32, reg, reg) cond = values.Ne } if !yes { cond = values.InvertedConditions[cond] } var end links.L switch { case cond >= values.MinUnorderedOrCondition: Jp.op(code, addr) sites = append(sites, code.Len()) case cond >= values.MinOrderedAndCondition: Jp.rel8.opStub(code) end.AddSite(code.Len()) } conditionInsns[cond].jcc.op(code, addr) sites = append(sites, code.Len()) end.Addr = code.Len() mach.updateBranches8(code, &end) return }