This is with Capstone (4.0.1) (Python bindings).
MOV (to general), an alias of UMOV, sets the vector element size specifier (vess) to ARM64_VESS_INVALID while the other UMOV variants set it properly.
Maybe it's intentional as the size can be determined based on the destination operand, but it'd be nice to have consistent behavior.
Code:
#!/usr/bin/env python3
from capstone import *
from capstone.arm64_const import *
from keystone import *
import struct
def parse_vess(vess):
if vess == ARM64_VESS_INVALID:
return "invalid"
elif vess == ARM64_VESS_B:
return "b"
elif vess == ARM64_VESS_H:
return "h"
elif vess == ARM64_VESS_S:
return "s"
elif vess == ARM64_VESS_D:
return "d"
else:
print(f"Unsupported vector element size specifier: '{vess}'")
exit(1)
def disasm(code):
c = Cs(CS_ARCH_ARM64, CS_MODE_ARM)
c.detail = True
for insn in c.disasm(code, 0): # addr = 0
assert len(insn.operands) == 2 # XXX: hardcoded
op = insn.operands[1]
print(f'vector_index: {op.vector_index}')
print(f'vess: {parse_vess(op.vess)}')
i = struct.unpack("<I", insn.bytes)[0]
print(f"dis: {i:032b} {i:08x} {insn.mnemonic} {insn.op_str}")
def asm(code):
k = Ks(KS_ARCH_ARM64, 0)
enc, cnt = k.asm(code)
i = struct.unpack("<I", bytes(enc))[0]
print(f"asm: {i:032b} {i:08x} {code}")
def main():
asm('umov w0, v1.s[1]')
asm('mov w0, v1.s[1]')
disasm(b'\x20\x3c\x0c\x0e')
print()
asm('umov x0, v1.d[1]')
asm('mov x0, v1.d[1]')
disasm(b'\x20\x3c\x18\x4e')
print()
asm('umov w0, v1.b[1]')
disasm(b'\x20\x3c\x03\x0e')
print()
asm('umov w0, v1.h[1]')
disasm(b'\x20\x3c\x06\x0e')
print()
if __name__ == "__main__":
main()
Output:
asm: 00001110000011000011110000100000 0e0c3c20 umov w0, v1.s[1]
asm: 00001110000011000011110000100000 0e0c3c20 mov w0, v1.s[1]
vector_index: 1
vess: invalid
dis: 00001110000011000011110000100000 0e0c3c20 mov w0, v1.s[1]
asm: 01001110000110000011110000100000 4e183c20 umov x0, v1.d[1]
asm: 01001110000110000011110000100000 4e183c20 mov x0, v1.d[1]
vector_index: 1
vess: invalid
dis: 01001110000110000011110000100000 4e183c20 mov x0, v1.d[1]
asm: 00001110000000110011110000100000 0e033c20 umov w0, v1.b[1]
vector_index: 1
vess: b
dis: 00001110000000110011110000100000 0e033c20 umov w0, v1.b[1]
asm: 00001110000001100011110000100000 0e063c20 umov w0, v1.h[1]
vector_index: 1
vess: h
dis: 00001110000001100011110000100000 0e063c20 umov w0, v1.h[1]
This is with Capstone (4.0.1) (Python bindings).
MOV (to general), an alias of UMOV, sets the vector element size specifier (
vess) toARM64_VESS_INVALIDwhile the other UMOV variants set it properly.Maybe it's intentional as the size can be determined based on the destination operand, but it'd be nice to have consistent behavior.
Code:
Output: