func truncateSigned(f *gen.Func, targetType wa.Type, target reg.R, sourceType wa.Type, source reg.R) {
	in.CVTTSx2SI.TypeRegReg(&f.Text, sourceType, targetType, target, source)
	in.CMPi.RegImm8(&f.Text, targetType, target, 1)
	jumpUnlessMagicValue := in.JNOcb.Stub8(&f.Text)
	if source != RegResult {
		in.MOVAPx.RegReg(&f.Text, sourceType, RegResult, source)
	}
	in.CALLcd.Addr32(&f.Text, f.TrapLinkTruncOverflow[int(sourceType>>2)&2|int(targetType>>3)].Addr)
	f.MapTrapAddr(f.Text.Addr)
	linker.UpdateNearBranch(f.Text.Bytes(), jumpUnlessMagicValue)
}
Algorithm:

target_i = Convert(source_f)
if target_i == MinInt {
if &source_f != &RegResult_f {
RegResult_f = source_f
}
TrapTruncOverflow()
}
package x86
import (
	"gate.computer/wag/internal/gen"
	"gate.computer/wag/internal/gen/operand"
	"gate.computer/wag/internal/gen/reg"
	"gate.computer/wag/internal/gen/rodata"
	"gate.computer/wag/internal/isa/prop"
	"gate.computer/wag/internal/isa/x86/in"
	"gate.computer/wag/trap"
	"gate.computer/wag/wa"
)
func (MacroAssembler) Convert(f *gen.Func, props uint16, resultType wa.Type, source operand.O) (result operand.O) {
	switch props {
	case prop.ExtendS:
		r, _ := allocResultReg(f, source)
		in.MOVSXD.RegReg(&f.Text, wa.I64, r, r)
		result = operand.Reg(resultType, r)
	case prop.ExtendU:
		r, zeroExtended := allocResultReg(f, source)
		if !zeroExtended {
			in.MOV.RegReg(&f.Text, wa.I32, r, r)
		}
		result = operand.Reg(wa.I64, r)
	case prop.Mote:
		r, _ := allocResultReg(f, source)
		in.CVTS2Sx.RegReg(&f.Text, source.Type, r, r)
		result = operand.Reg(resultType, r)
	case prop.TruncS:
		sourceReg, _ := allocResultReg(f, source)
		resultReg := f.Regs.AllocResult(wa.I64)
		truncateSigned(f, resultType, resultReg, source.Type, sourceReg)
		f.Regs.Free(source.Type, sourceReg)
		result = operand.Reg(resultType, resultReg)
	case prop.TruncU:
		sourceReg, _ := allocResultReg(f, source)
		resultReg := f.Regs.AllocResult(wa.I64)
		if resultType == wa.I32 {
			truncateUnsignedI32(f, resultReg, source.Type, sourceReg)
		} else {
			truncateUnsignedI64(f, resultReg, source.Type, sourceReg)
		}
		f.Regs.Free(source.Type, sourceReg)
		result = operand.Reg(resultType, resultReg)
	case prop.ConvertS:
		sourceReg, _ := getScratchReg(f, source)
		resultReg := f.Regs.AllocResult(resultType)
		in.CVTSI2Sx.TypeRegReg(&f.Text, resultType, source.Type, resultReg, sourceReg)
		f.Regs.Free(source.Type, sourceReg)
		result = operand.Reg(resultType, resultReg)
	case prop.ConvertU:
		sourceReg, zeroExtended := getScratchReg(f, source)
		resultReg := f.Regs.AllocResult(resultType)
		if source.Type == wa.I32 {
			if !zeroExtended {
				in.MOV.RegReg(&f.Text, wa.I32, sourceReg, sourceReg)
			}
			in.CVTSI2Sx.TypeRegReg(&f.Text, resultType, wa.I64, resultReg, sourceReg)
		} else {
			convertUnsignedI64ToFloat(f, resultType, resultReg, sourceReg)
		}
		f.Regs.Free(source.Type, sourceReg)
		result = operand.Reg(resultType, resultReg)
	case prop.Reinterpret:
		sourceReg, _ := getScratchReg(f, source)
		resultReg := f.Regs.AllocResult(resultType)
		if source.Type.Category() == wa.Int {
			in.MOVx.RegReg(&f.Text, source.Type, resultReg, sourceReg)
		} else {
			in.MOVxmr.RegReg(&f.Text, source.Type, sourceReg, resultReg)
		}
		f.Regs.Free(source.Type, sourceReg)
		result = operand.Reg(resultType, resultReg)
	}
	return
}