mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
simple_arm64.Mov(reg, reg) that redirect to Orr(reg, zero, reg)
This commit is contained in:
@@ -75,7 +75,7 @@ class CheckInstr(object):
|
||||
capres = capres_list[0]
|
||||
print("{0} {1}".format(capres.mnemonic, capres.op_str))
|
||||
if self.expected_result is not None:
|
||||
if "{0} {1}".format(capres.mnemonic, capres.op_str) == self.expected_result:
|
||||
if "{0} {1}".format(capres.mnemonic, capres.op_str).strip() == self.expected_result:
|
||||
return True
|
||||
else:
|
||||
raise AssertionError("Expected result <{0}> got <{1}>".format(self.expected_result, "{0} {1}".format(capres.mnemonic, capres.op_str)))
|
||||
@@ -185,12 +185,29 @@ def test_shift_parsing():
|
||||
CheckInstr(Movz, must_fail=True)('W0', 0, "LSL #32"),
|
||||
CheckInstr(Movz, must_fail=True)('X0', 0, "ROR #32"),
|
||||
|
||||
|
||||
CheckInstr(Orr)('X0', 'X18', 'XZR'),
|
||||
# Official encoding for this in ARM64 ref
|
||||
CheckInstr(Orr, expected_result="mov x0, x18")('X0', 'XZR', 'X18'),
|
||||
CheckInstr(Orr, must_fail=True)('X0', 'WZR', 'X18'), # Size mismatch
|
||||
CheckInstr(Orr, must_fail=True)('W0', 'XZR', 'W18'), # Size mismatch
|
||||
|
||||
CheckInstr(Movk)('X0', 0x1234, "LSL #32"),
|
||||
CheckInstr(Movk)('X18', 0x5678, "LSL #48"),
|
||||
|
||||
CheckInstr(Ret)("X0"),
|
||||
CheckInstr(Ret, expected_result="ret ")("X30"),
|
||||
CheckInstr(Ret, expected_result="ret")("X30"),
|
||||
CheckInstr(Ret)(),
|
||||
|
||||
# Virtual instruction that dispatch to something else:
|
||||
# Ex: "mov reg1, re2" -> "orr reg1, xzr, reg2"
|
||||
|
||||
CheckInstr(Mov)('X0', 'X18'),
|
||||
CheckInstr(Mov)('W0', 'W18'),
|
||||
CheckInstr(Mov, must_fail=True)('X0', 'W18'),
|
||||
CheckInstr(Mov, must_fail=True)('X0', 'X18', 'X12'),
|
||||
|
||||
|
||||
], ids=CheckInstr.__repr__)
|
||||
def test_instruction_assembling(checkinstr):
|
||||
assert checkinstr.dotest()
|
||||
@@ -47,9 +47,18 @@ else:
|
||||
XREGISTER = {'X0', 'X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X9', 'X10', 'X11', 'X12', 'X13', 'X14', 'X15', 'X16', 'X17', 'X18', 'X19', 'X20', 'X21', 'X22', 'X23', 'X24', 'X25', 'X26', 'X27', 'X28', 'X29', 'X30'}
|
||||
WREGISTER = {'W0', 'W1', 'W2', 'W3', 'W4', 'W5', 'W6', 'W7', 'W8', 'W9', 'W10', 'W11', 'W12', 'W13', 'W14', 'W15', 'W16', 'W17', 'W18', 'W19', 'W20', 'W21', 'W22', 'W23', 'W24', 'W25', 'W26', 'W27', 'W28', 'W29', 'W30'}
|
||||
ALL_REGISTER = XREGISTER | WREGISTER
|
||||
|
||||
SP = "SP"
|
||||
WSP = "WSP"
|
||||
|
||||
ZR = "XZR"
|
||||
WZR = "WZR"
|
||||
# Special register name for simple_arm64 that do not setup bitness
|
||||
# Bitness will depends on others registers in the instruction
|
||||
ZERO = "ZERO"
|
||||
|
||||
SPECIAL_X31 = set((SP, WSP, ZR, WZR, ZERO))
|
||||
|
||||
# Argument class
|
||||
class Shift(object):
|
||||
"""Represent a shift parameter of an instruction.
|
||||
@@ -108,9 +117,11 @@ class InstructionEncoding(object):
|
||||
self.bitness = self.BITNESS
|
||||
|
||||
@classmethod
|
||||
def is_register(self, arg, accept_sp):
|
||||
def is_register(self, arg, accept_sp=False):
|
||||
arg = arg.upper()
|
||||
return (accept_sp and (arg in [SP, WSP])) or arg in ALL_REGISTER
|
||||
return (arg in ALL_REGISTER or
|
||||
(accept_sp and (arg in [SP, WSP])) or
|
||||
(not accept_sp and (arg in [ZR, WZR, ZERO])))
|
||||
|
||||
@classmethod
|
||||
def is_imm(self, arg):
|
||||
@@ -160,6 +171,15 @@ class InstructionEncoding(object):
|
||||
|
||||
def encode_register(self, register, outsize=5):
|
||||
register = register.upper()
|
||||
if register in SPECIAL_X31:
|
||||
if register == ZERO:
|
||||
pass # Special simple_arm64 value that do not setup bitness
|
||||
elif register.startswith("W"):
|
||||
self.setup_bitness(32)
|
||||
else:
|
||||
self.setup_bitness(64)
|
||||
return self.binencode_imm(31, outsize)
|
||||
|
||||
assert register in ALL_REGISTER
|
||||
if register in XREGISTER:
|
||||
self.setup_bitness(64)
|
||||
@@ -449,6 +469,21 @@ class Movk(Instruction):
|
||||
class Orr(Instruction):
|
||||
encoding = [DataProcessingLogicalShiftedRegister.gen(opc=0b01)]
|
||||
|
||||
|
||||
# Meta Instruction that can dispatch to others Instruction/Encoding based on special case
|
||||
# Ex: "mov reg1, re2" -> "orr reg1, xzr, reg2"
|
||||
|
||||
class Mov(Instruction): # VirtualInstruction ?
|
||||
def __new__(self, *args):
|
||||
argsdict = dict(enumerate(args)) # Like a list but allow arg.get(4)
|
||||
if (set(argsdict) == {0, 1} and # Only 2 args
|
||||
InstructionEncoding.is_register(argsdict[0]) and
|
||||
InstructionEncoding.is_register(argsdict[1])):
|
||||
return Orr(argsdict[0], ZERO, argsdict[1])
|
||||
|
||||
raise ValueError("Cannot encode <{0} {1}>:(".format(type(self).__name__, args))
|
||||
|
||||
|
||||
class MultipleInstr(object):
|
||||
INSTRUCTION_SIZE = 4
|
||||
|
||||
|
||||
Reference in New Issue
Block a user