func (v *allocator) valToReg(gen *gen, reg string, val ir.Value) string { bits := v.target.TypeSizeInBits(val.Type()) bytes := v.target.TypeSize(val.Type()) bitmask := uint64((1 << uint(bits)) - 1) if val.IsLit() { switch val.(type) { case *ir.IntLit: il := val.(*ir.IntLit) gen.emitOp("movl $%d, %s", il.Value()&bitmask, reg) } } else { if bits != 32 { gen.emitOp("xorl %s, %s", reg, reg) } gen.emitOp("mov%s %s, %s", sizeSuffix(bytes), v.get(val).String(), regToSize(reg, bytes)) if bits%8 != 0 { gen.emitOp("andl $0x%x, %s", bitmask, reg) } } return regToSize(reg, v.target.TypeSize(val.Type())) }
func (v *allocator) regToVal(gen *gen, val ir.Value, reg string) ir.Value { if val.IsLit() { panic("can't move reg to literal value") } bits := v.target.TypeSizeInBits(val.Type()) bytes := v.target.TypeSize(val.Type()) bitmask := uint64((1 << uint(bits)) - 1) if bits == 32 { gen.emitOp("movl %s, %s", reg, v.get(val).String()) } else { if bits%8 != 0 { gen.emitOp("and%s $0x%x, %s", sizeSuffix(bytes), bitmask, regToSize(reg, bytes)) } gen.emitOp("mov%s %s, %s", sizeSuffix(bytes), regToSize(reg, bytes), v.get(val).String()) } return val }
func (v *allocator) pushVal(gen *gen, val ir.Value) { bits := v.target.TypeSizeInBits(val.Type()) bytes := v.target.TypeSize(val.Type()) if bytes%2 == 1 { bytes++ } bitmask := uint64((1 << uint(bits)) - 1) if val.IsLit() { switch val.(type) { case *ir.IntLit: il := val.(*ir.IntLit) gen.emitOp("push%s $%d", sizeSuffix(bytes), il.Value()&bitmask) } } else { gen.emitOp("push%s %s", sizeSuffix(bytes), v.get(val).String()) if bits%8 != 0 { gen.emitOp("and%s $0x%x, (@esp)", sizeSuffix(bytes), bitmask) } } }