34 lines
1.1 KiB
Go
34 lines
1.1 KiB
Go
package examples
|
|
|
|
import (
|
|
"git.gammaspectra.live/WeebDataHoarder/compute-go/amd64"
|
|
"git.gammaspectra.live/WeebDataHoarder/compute-go/assembler"
|
|
"git.gammaspectra.live/WeebDataHoarder/compute-go/assembler/obj"
|
|
)
|
|
|
|
func Mul64() (mul func(a, b uint64) (hi, lo uint64), clean func() error, err error) {
|
|
b, err := assembler.NewBuilder(amd64.ABIDefinition)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
mul, clean, err = assembler.CreateFunction[func(a, b uint64) (hi, lo uint64)](b, obj.ABIInternal, "mul64",
|
|
func(b *assembler.Builder, params []assembler.AddressableList, returns []assembler.AddressableList, regs *assembler.RegisterAllocator, data *assembler.DataAllocator) (frameSize, textFlag int, err error) {
|
|
aReg := regs.AllocArgOutput(params[0])
|
|
defer regs.Free(aReg)
|
|
// this gets optimized out on ABI1
|
|
amd64.Mov64(b, params[0].One(), aReg)
|
|
amd64.Mov64(b, aReg, amd64.AX)
|
|
amd64.MulUint64(b, params[1].One())
|
|
|
|
amd64.Mov64(b, amd64.AX, returns[1].One())
|
|
amd64.Mov64(b, amd64.DX, returns[0].One())
|
|
amd64.Return(b)
|
|
return 0, obj.NOFRAME | obj.NOSPLIT, nil
|
|
},
|
|
nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return mul, clean, nil
|
|
}
|