Пример #1
0
func (v *allocator) addValue(val ir.Value) {
	if _, ok := v.locs[val]; ok {
		panic("allocating value twice")
	}

	v.stackSize += v.target.TypeSize(val.Type())
	v.locs[val] = &location{
		stackPos: -v.stackSize,
	}
}
Пример #2
0
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()))
}
Пример #3
0
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
}
Пример #4
0
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)
		}
	}
}