Example #1
0
func (f *Function) ConvertFromTo(instr *ssa.Convert, fromOpType, toOpType InstrOpType, fromXmm, toXmm XmmData) (string, *Error) {

	asm := ""
	ctx := context{f, instr}
	a, from, err := f.LoadValueSimple(instr, instr.X)
	if err != nil {
		return "", err
	} else {
		asm += a
	}

	a1, to := f.allocIdentReg(instr, f.Ident(instr), f.Ident(instr).size())
	asm += a1

	a, tmp := f.allocReg(instr, DATA_REG, sizeInt())
	asm += a

	fromType :=
		OpDataType{
			op:         fromOpType,
			InstrData:  InstrData{signed: signed(instr.X.Type()), size: f.sizeof(instr.X)},
			xmmvariant: fromXmm}
	toType :=
		OpDataType{
			op:         toOpType,
			InstrData:  InstrData{signed: signed(instr.Type()), size: f.sizeof(instr)},
			xmmvariant: toXmm}

	// round uint64 to nearest int64 before converting to float32/float64
	if isUint(instr.X.Type()) && f.sizeof(instr.X) == 8 && isFloat(instr.Type()) {
		var floatSize uint
		if isFloat32(instr.Type()) {
			floatSize = 32
		} else if isFloat64(instr.Type()) {
			floatSize = 64
		} else {
			ice("converting from uint64 to float")
		}

		asm += f.ConvertUint64ToFloat(instr, tmp, from, to, floatSize)
	} else {
		asm += ConvertOp(ctx, from, fromType, to, toType, tmp)
	}
	toIdent := f.identifiers[instr.Name()]
	if a, err := f.StoreValue(instr, toIdent, to); err != nil {
		return "", err
	} else {
		asm += a
	}
	f.freeReg(from)
	f.freeReg(to)
	f.freeReg(tmp)

	return asm, nil
}