pre/post-indexed to pre/post_indexed. Now have use ImmediateOperand type for mem offset. Changed some parser tests also

This commit is contained in:
stefandesouza
2023-12-02 16:56:43 +01:00
parent e77dfb4eb3
commit 37ca6670c7
25 changed files with 859 additions and 803 deletions

View File

@@ -4,6 +4,7 @@ from itertools import chain
from osaca import utils
from osaca.parser import AttrDict, ParserAArch64, ParserX86ATT
from osaca.parser.memory import MemoryOperand
from osaca.parser.operand import Operand
from osaca.parser.register import RegisterOperand
from osaca.parser.immediate import ImmediateOperand
@@ -56,6 +57,7 @@ class ISASemantics(object):
isa_data = self._isa_model.get_instruction(
instruction_form.instruction, instruction_form.operands
)
if (
isa_data is None
and self._isa == "x86"
@@ -119,24 +121,22 @@ class ISASemantics(object):
for operand in [op for op in op_dict["source"] if isinstance(op, MemoryOperand)]:
post_indexed = operand.post_indexed
pre_indexed = operand.pre_indexed
if post_indexed or pre_indexed:
if post_indexed or pre_indexed or (isinstance(post_indexed, dict) and "value" in post_indexed):
new_op = operand.base
new_op.pre_indexed = pre_indexed
new_op.post_indexed = post_indexed
op_dict["src_dst"].append(
{
"register": operand.base,
"pre_indexed": pre_indexed,
"post_indexed": post_indexed,
}
new_op
)
for operand in [op for op in op_dict["destination"] if isinstance(op, MemoryOperand)]:
post_indexed = operand.post_indexed
pre_indexed = operand.pre_indexed
if post_indexed or pre_indexed:
if post_indexed or pre_indexed or (isinstance(post_indexed, dict) and "value" in post_indexed):
new_op = operand.base
new_op.pre_indexed = pre_indexed
new_op.post_indexed = post_indexed
op_dict["src_dst"].append(
{
"register": operand.base,
"pre_indexed": pre_indexed,
"post_indexed": post_indexed,
}
new_op
)
# store operand list in dict and reassign operand key/value pair
instruction_form.semantic_operands = op_dict
@@ -204,19 +204,20 @@ class ISASemantics(object):
for o in instruction_form.operands:
if isinstance(o, MemoryOperand) and o.pre_indexed:
# Assuming no isa_data.operation
if isa_data is not None and isa_data.get("operation", None) is not None:
if isa_data is not None and isa_data.operation is not None:
raise ValueError(
"ISA information for pre-indexed instruction {!r} has operation set."
"ISA information for pre_indexed instruction {!r} has operation set."
"This is currently not supprted.".format(instruction_form.line)
)
base_name = o.base.prefix if o.base.prefix != None else "" + o.base.name
reg_operand_names = {base_name: "op1"}
operand_state = {"op1": {"name": base_name, "value": o.offset["value"]}}
operand_state = {"op1": {"name": base_name, "value": o.offset.value}}
if isa_data is not None:
if isa_data is not None and isa_data.operation is not None:
for i, o in enumerate(instruction_form.operands):
operand_name = "op{}".format(i + 1)
if isinstance(o, RegisterOperand):
o_reg_name = o.prefix if o.prefix != None else "" + o.name
reg_operand_names[o_reg_name] = operand_name
@@ -226,8 +227,7 @@ class ISASemantics(object):
elif isinstance(o, MemoryOperand):
# TODO lea needs some thinking about
pass
# exec(isa_data["operation"], {}, operand_state)
exec(isa_data.operation, {}, operand_state)
change_dict = {
reg_name: operand_state.get(reg_operand_names.get(reg_name))
@@ -251,18 +251,16 @@ class ISASemantics(object):
op_dict["source"] = []
op_dict["destination"] = []
op_dict["src_dst"] = []
# handle dependency breaking instructions
"""
if isa_data.breaks_dep and operands[1:] == operands[:-1]:
op_dict["destination"] += operands
if isa_data.hidden_operands!=[]:
op_dict["destination"] += [
{hop["class"]: {k: hop[k] for k in ["name", "class", "source", "destination"]}}
hop
for hop in isa_data.hidden_operands
]
return op_dict
"""
for i, op in enumerate(isa_data.operands):
if op.source and op.destination:
@@ -274,25 +272,29 @@ class ISASemantics(object):
if op.destination:
op_dict["destination"].append(operands[i])
continue
# check for hidden operands like flags or registers
"""
if isa_data.hidden_operands!=[]:
# add operand(s) to semantic_operands of instruction form
for op in isa_data.hidden_operands:
dict_key = (
"src_dst"
if op.source and op.destination
else "source"
if op.source
else "destination"
)
hidden_op = {op["class"]: {}}
key_filter = ["class", "source", "destination"]
for key in [k for k in op.keys() if k not in key_filter]:
hidden_op[op["class"]][key] = op[key]
op_dict[dict_key].append(hidden_op)
"""
if isinstance(op, Operand):
dict_key = (
"src_dst"
if op.source and op.destination
else "source"
if op.source
else "destination"
)
else:
dict_key = (
"src_dst"
if op["source"] and op["destination"]
else "source"
if op["source"]
else "destination"
)
op_dict[dict_key].append(op)
return op_dict
def _has_load(self, instruction_form):