Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add 64 bit instructions #150

Merged
merged 4 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 122 additions & 85 deletions internal/polkavm/interpreter/mutator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (
x8 = 1
x16 = 2
x32 = 4
x64 = 8
)

const (
Expand Down Expand Up @@ -60,11 +61,11 @@ func (m *Mutator) load(memLen int, signed bool, dst polkavm.Reg, base polkavm.Re
if err != nil {
return err
}
m.setNext32(dst, toSigned(value, memLen, signed))
m.setNext64(dst, toSigned(value, memLen, signed))
return nil
}

func (m *Mutator) store(memLen int, signed bool, src uint32, base polkavm.Reg, offset uint32) error {
func (m *Mutator) store(memLen int, signed bool, src uint64, base polkavm.Reg, offset uint32) error {
var address uint32 = 0
if base != 0 {
address = m.get32(base)
Expand All @@ -81,41 +82,45 @@ func (m *Mutator) store(memLen int, signed bool, src uint32, base polkavm.Reg, o
m.instance.NextOffsets()
return nil
}
func toSigned(v uint32, memLen int, signed bool) uint32 {
func toSigned(v uint64, memLen int, signed bool) uint64 {
if signed {
switch memLen {
case x8:
return uint32(int8(v))
return uint64(int8(v))
case x16:
return uint32(int16(v))
return uint64(int16(v))
case x32:
return uint32(int32(v))
return uint64(int32(v))
case x64:
return uint64(int64(v))
}
}
return v
}
func leEncode(memLen int, src uint32) ([]byte, error) {
func leEncode(memLen int, src uint64) ([]byte, error) {
slice := make([]byte, memLen)
switch memLen {
case x8:
slice[0] = byte(src)
case x16:
binary.LittleEndian.PutUint16(slice, uint16(src))
case x32:
binary.LittleEndian.PutUint32(slice, src)
binary.LittleEndian.PutUint32(slice, uint32(src))
pantrif marked this conversation as resolved.
Show resolved Hide resolved
default:
return nil, polkavm.ErrPanicf("invalid Memory slice length: %d", memLen)
}
return slice, nil
}
func leDecode(memLen int, src []byte) (uint32, error) {
func leDecode(memLen int, src []byte) (uint64, error) {
switch memLen {
case x8:
return uint32(src[0]), nil
return uint64(src[0]), nil
case x16:
return uint32(binary.LittleEndian.Uint16(src)), nil
return uint64(binary.LittleEndian.Uint16(src)), nil
pantrif marked this conversation as resolved.
Show resolved Hide resolved
case x32:
return binary.LittleEndian.Uint32(src), nil
return uint64(binary.LittleEndian.Uint32(src)), nil
case x64:
return binary.LittleEndian.Uint64(src), nil
default:
return 0, polkavm.ErrPanicf("invalid Memory slice length: %d", memLen)
}
Expand Down Expand Up @@ -288,23 +293,27 @@ func (m *Mutator) ShiftLogicalLeftImmAlt32(d polkavm.Reg, s2 polkavm.Reg, s1 uin
func (m *Mutator) ShiftLogicalLeftImmAlt64(d polkavm.Reg, s2 polkavm.Reg, s1 uint32) {
m.setNext32(d, s1<<m.get32(s2))
}

// Add32 32ω′D = X4((ωA + ωB) mod 2^32)
func (m *Mutator) Add32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, m.get32(s1)+m.get32(s2))
}

// Add64 ω′D = (ωA + ωB) mod 2^64
func (m *Mutator) Add64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
m.setNext64(d, m.get64(s1)+m.get64(s2))
}
func (m *Mutator) AddImm32(d polkavm.Reg, s1 polkavm.Reg, s2 uint32) {
m.setNext32(d, m.get32(s1)+s2)
}
func (m *Mutator) AddImm64(d polkavm.Reg, s1 polkavm.Reg, s2 uint32) {
panic("implement me")
m.setNext64(d, m.get64(s1)+uint64(s2))
}
func (m *Mutator) Sub32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, m.get32(s1)-m.get32(s2))
}
func (m *Mutator) Sub64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
m.setNext64(d, m.get64(s1)-m.get64(s2))
}
func (m *Mutator) And(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, m.get32(s1)&m.get32(s2))
Expand All @@ -328,13 +337,13 @@ func (m *Mutator) Mul32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, m.get32(s1)*m.get32(s2))
}
func (m *Mutator) Mul64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
m.setNext64(d, m.get64(s1)*m.get64(s2))
}
func (m *Mutator) MulImm32(d polkavm.Reg, s1 polkavm.Reg, s2 uint32) {
m.setNext32(d, m.get32(s1)*s2)
}
func (m *Mutator) MulImm64(d polkavm.Reg, s1 polkavm.Reg, s2 uint32) {
panic("implement me")
m.setNext64(d, m.get64(s1)*uint64(s2))
}
func (m *Mutator) MulUpperSignedSigned(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, uint32(int32((int64(m.get32(s1))*int64(m.get32(s2)))>>32)))
Expand Down Expand Up @@ -363,51 +372,115 @@ func (m *Mutator) ShiftLogicalLeft32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, shiftedValue)
}
func (m *Mutator) ShiftLogicalLeft64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
shiftAmount := m.get32(s2) % 64
shiftedValue := m.get32(s1) << shiftAmount
m.setNext32(d, shiftedValue)
}
func (m *Mutator) ShiftLogicalRight32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, m.get32(s1)>>(m.get32(s2)%32))
}
func (m *Mutator) ShiftLogicalRight64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
m.setNext64(d, m.get64(s1)>>(m.get64(s2)%64))
}
func (m *Mutator) ShiftLogicalRightImm32(d polkavm.Reg, s1 polkavm.Reg, s2 uint32) {
m.setNext32(d, m.get32(s1)>>s2)
}
func (m *Mutator) ShiftLogicalRightImm64(d polkavm.Reg, s1 polkavm.Reg, s2 uint32) {
panic("implement me")
m.setNext64(d, m.get64(s1)>>s2)
}
func (m *Mutator) ShiftArithmeticRight32(d polkavm.Reg, s1, s2 polkavm.Reg) {
shiftAmount := m.get32(s2) % 32
shiftedValue := int32(m.get32(s1)) >> shiftAmount
m.setNext32(d, uint32(shiftedValue))
}
func (m *Mutator) ShiftArithmeticRight64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
shiftAmount := m.get64(s2) % 64
shiftedValue := int64(m.get64(s1)) >> shiftAmount
m.setNext64(d, uint64(shiftedValue))
}
func (m *Mutator) DivUnsigned32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, divUnsigned(m.get32(s1), m.get32(s2)))
lhs, rhs := m.get32(s1), m.get32(s2)
if rhs == 0 {
m.set64(d, math.MaxUint64)
} else {
m.set32(d, lhs/rhs)
}
m.instance.NextOffsets()
}
func (m *Mutator) DivUnsigned64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
lhs, rhs := m.get64(s1), m.get64(s2)
if rhs == 0 {
m.set64(d, math.MaxUint64)
} else {
m.set64(d, lhs/rhs)
}
m.instance.NextOffsets()
}
func (m *Mutator) DivSigned32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, uint32(div(int32(m.get32(s1)), int32(m.get32(s2)))))
lhs := int32(m.get32(s1))
rhs := int32(m.get32(s2))
if rhs == 0 {
m.set64(d, math.MaxUint64)
} else if lhs == math.MinInt32 && rhs == -1 {
m.set32(d, uint32(lhs))
} else {
m.set32(d, uint32(lhs/rhs))
}
m.instance.NextOffsets()
}
func (m *Mutator) DivSigned64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
rhs := int64(m.get64(s1))
lhs := int64(m.get64(s2))
if rhs == 0 {
m.set64(d, math.MaxUint64)
} else if lhs == math.MinInt64 && rhs == -1 {
m.set64(d, uint64(lhs))
} else {
m.set64(d, uint64(lhs/rhs))
}
m.instance.NextOffsets()
}
func (m *Mutator) RemUnsigned32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, remUnsigned(m.get32(s1), m.get32(s2)))
lhs, rhs := m.get32(s1), m.get32(s2)
if rhs == 0 {
m.set32(d, lhs)
} else {
m.set32(d, lhs%rhs)
}
m.instance.NextOffsets()
}
func (m *Mutator) RemUnsigned64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
lhs, rhs := m.get64(s1), m.get64(s2)
if rhs == 0 {
m.set64(d, lhs)
} else {
m.set64(d, lhs%rhs)
}
m.instance.NextOffsets()
}
func (m *Mutator) RemSigned32(d polkavm.Reg, s1, s2 polkavm.Reg) {
m.setNext32(d, uint32(rem(int32(m.get32(s1)), int32(m.get32(s2)))))
lhs := int32(m.get32(s1))
rhs := int32(m.get32(s2))
if rhs == 0 {
m.set32(d, uint32(lhs))
} else if lhs == math.MinInt32 && rhs == -1 {
m.set32(d, 0)
} else {
m.set32(d, uint32(lhs%rhs))
}
m.instance.NextOffsets()
}

func (m *Mutator) RemSigned64(d polkavm.Reg, s1, s2 polkavm.Reg) {
panic("implement me")
rhs, lhs := int64(m.get64(s1)), int64(m.get64(s2))
if rhs == 0 {
m.set64(d, uint64(lhs))
} else if lhs == math.MinInt32 && rhs == -1 {
m.set64(d, 0)
} else {
m.set64(d, uint64(lhs%rhs))
}
m.instance.NextOffsets()
}
func (m *Mutator) CmovIfZero(d polkavm.Reg, s, c polkavm.Reg) {
if m.get32(c) == 0 {
Expand Down Expand Up @@ -436,52 +509,52 @@ func (m *Mutator) CmovIfNotZeroImm(d polkavm.Reg, c polkavm.Reg, s uint32) {
}

func (m *Mutator) StoreU8(src polkavm.Reg, offset uint32) error {
return m.store(x8, unsigned, m.get32(src), 0, offset)
return m.store(x8, unsigned, uint64(m.get32(src)), 0, offset)
}
func (m *Mutator) StoreU16(src polkavm.Reg, offset uint32) error {
return m.store(x16, unsigned, m.get32(src), 0, offset)
return m.store(x16, unsigned, uint64(m.get32(src)), 0, offset)
}
func (m *Mutator) StoreU32(src polkavm.Reg, offset uint32) error {
return m.store(x32, unsigned, m.get32(src), 0, offset)
return m.store(x32, unsigned, uint64(m.get32(src)), 0, offset)
}
func (m *Mutator) StoreU64(src polkavm.Reg, offset uint32) error {
panic("implement me")
return m.store(x32, unsigned, uint64(m.get32(src)), 0, offset)
}
func (m *Mutator) StoreImmU8(offset uint32, value uint32) error {
return m.store(x8, unsigned, value, 0, offset)
return m.store(x8, unsigned, uint64(value), 0, offset)
}
func (m *Mutator) StoreImmU16(offset uint32, value uint32) error {
return m.store(x16, unsigned, value, 0, offset)
return m.store(x16, unsigned, uint64(value), 0, offset)
}
func (m *Mutator) StoreImmU32(offset uint32, value uint32) error {
return m.store(x32, unsigned, value, 0, offset)
return m.store(x32, unsigned, uint64(value), 0, offset)
}
func (m *Mutator) StoreImmU64(offset uint32, value uint32) error {
panic("implement me")
return m.store(x64, unsigned, uint64(value), 0, offset)
}
func (m *Mutator) StoreImmIndirectU8(base polkavm.Reg, offset uint32, value uint32) error {
return m.store(x8, unsigned, value, base, offset)
return m.store(x8, unsigned, uint64(value), base, offset)
}
func (m *Mutator) StoreImmIndirectU16(base polkavm.Reg, offset uint32, value uint32) error {
return m.store(x16, unsigned, value, base, offset)
return m.store(x16, unsigned, uint64(value), base, offset)
}
func (m *Mutator) StoreImmIndirectU32(base polkavm.Reg, offset uint32, value uint32) error {
return m.store(x32, unsigned, value, base, offset)
return m.store(x32, unsigned, uint64(value), base, offset)
}
func (m *Mutator) StoreImmIndirectU64(base polkavm.Reg, offset uint32, value uint32) error {
panic("implement me")
return m.store(x64, unsigned, uint64(value), base, offset)
}
func (m *Mutator) StoreIndirectU8(src polkavm.Reg, base polkavm.Reg, offset uint32) error {
return m.store(x8, unsigned, m.get32(src), base, offset)
return m.store(x8, unsigned, m.get64(src), base, offset)
}
func (m *Mutator) StoreIndirectU16(src polkavm.Reg, base polkavm.Reg, offset uint32) error {
return m.store(x16, unsigned, m.get32(src), base, offset)
return m.store(x16, unsigned, m.get64(src), base, offset)
}
func (m *Mutator) StoreIndirectU32(src polkavm.Reg, base polkavm.Reg, offset uint32) error {
return m.store(x32, unsigned, m.get32(src), base, offset)
return m.store(x32, unsigned, m.get64(src), base, offset)
}
func (m *Mutator) StoreIndirectU64(src polkavm.Reg, base polkavm.Reg, offset uint32) error {
panic("implement me")
return m.store(x64, unsigned, m.get64(src), base, offset)
}
func (m *Mutator) LoadU8(dst polkavm.Reg, offset uint32) error {
return m.load(x8, unsigned, dst, 0, offset)
Expand All @@ -496,13 +569,13 @@ func (m *Mutator) LoadI16(dst polkavm.Reg, offset uint32) error {
return m.load(x16, signed, dst, 0, offset)
}
func (m *Mutator) LoadI32(dst polkavm.Reg, offset uint32) error {
panic("implement me")
return m.load(x32, signed, dst, 0, offset)
}
func (m *Mutator) LoadU32(dst polkavm.Reg, offset uint32) error {
return m.load(x32, unsigned, dst, 0, offset)
}
func (m *Mutator) LoadU64(dst polkavm.Reg, offset uint32) error {
panic("implement me")
return m.load(x64, unsigned, dst, 0, offset)
}
func (m *Mutator) LoadIndirectU8(dst polkavm.Reg, base polkavm.Reg, offset uint32) error {
return m.load(x8, unsigned, dst, base, offset)
Expand All @@ -517,13 +590,13 @@ func (m *Mutator) LoadIndirectI16(dst polkavm.Reg, base polkavm.Reg, offset uint
return m.load(x16, signed, dst, base, offset)
}
func (m *Mutator) LoadIndirectI32(dst polkavm.Reg, base polkavm.Reg, offset uint32) error {
panic("implement me")
return m.load(x32, signed, dst, base, offset)
}
func (m *Mutator) LoadIndirectU32(dst polkavm.Reg, base polkavm.Reg, offset uint32) error {
return m.load(x32, unsigned, dst, base, offset)
}
func (m *Mutator) LoadIndirectU64(dst polkavm.Reg, base polkavm.Reg, offset uint32) error {
panic("implement me")
return m.load(x64, unsigned, dst, base, offset)
}
func (m *Mutator) LoadImm(dst polkavm.Reg, imm uint32) {
m.setNext32(dst, imm)
Expand All @@ -549,42 +622,6 @@ func (m *Mutator) JumpIndirect(base polkavm.Reg, offset uint32) error {
return m.djump(m.get32(base) + offset)
}

func divUnsigned(lhs uint32, rhs uint32) uint32 {
if rhs == 0 {
return math.MaxUint32
} else {
return lhs / rhs
}
}

func remUnsigned(lhs uint32, rhs uint32) uint32 {
if rhs == 0 {
return lhs
} else {
return lhs % rhs
}
}

func div(lhs int32, rhs int32) int32 {
if rhs == 0 {
return -1
} else if lhs == math.MinInt32 && rhs == -1 {
return lhs
} else {
return lhs / rhs
}
}

func rem(lhs int32, rhs int32) int32 {
if rhs == 0 {
return lhs
} else if lhs == math.MinInt32 && rhs == -1 {
return 0
} else {
return lhs % rhs
}
}

func bool2uint32(v bool) uint32 {
if v {
return 1
Expand Down
Loading
Loading