mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-04 18:20:09 +01:00
Converting operand types read in from YAML files
This commit is contained in:
@@ -15,6 +15,8 @@ class MemoryOperand(Operand):
|
|||||||
PRE_INDEXED=False,
|
PRE_INDEXED=False,
|
||||||
POST_INDEXED=False,
|
POST_INDEXED=False,
|
||||||
INDEXED_VAL=None,
|
INDEXED_VAL=None,
|
||||||
|
PORT_PRESSURE=[],
|
||||||
|
DST=None
|
||||||
):
|
):
|
||||||
super().__init__("memory")
|
super().__init__("memory")
|
||||||
self._OFFSET_ID = OFFSET_ID
|
self._OFFSET_ID = OFFSET_ID
|
||||||
@@ -26,6 +28,8 @@ class MemoryOperand(Operand):
|
|||||||
self._PRE_INDEXED = PRE_INDEXED
|
self._PRE_INDEXED = PRE_INDEXED
|
||||||
self._POST_INDEXED = POST_INDEXED
|
self._POST_INDEXED = POST_INDEXED
|
||||||
self._INDEXED_VAL = INDEXED_VAL
|
self._INDEXED_VAL = INDEXED_VAL
|
||||||
|
self._PORT_PRESSURE = PORT_PRESSURE
|
||||||
|
self._DST = DST
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def offset(self):
|
def offset(self):
|
||||||
@@ -67,6 +71,22 @@ class MemoryOperand(Operand):
|
|||||||
def indexed_val(self):
|
def indexed_val(self):
|
||||||
return self._INDEXED_VAL
|
return self._INDEXED_VAL
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port_pressure(self):
|
||||||
|
return self._PORT_PRESSURE
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dst(self):
|
||||||
|
return self._DST
|
||||||
|
|
||||||
|
@dst.setter
|
||||||
|
def dst(self, dst):
|
||||||
|
self._DST = dst
|
||||||
|
|
||||||
|
@port_pressure.setter
|
||||||
|
def port_pressure(self, port_pressure):
|
||||||
|
self._PORT_PRESSURE = port_pressure
|
||||||
|
|
||||||
@segment_ext_id.setter
|
@segment_ext_id.setter
|
||||||
def segment_ext_id(self, segment):
|
def segment_ext_id(self, segment):
|
||||||
self._SEGMENT_EXT_ID = segment
|
self._SEGMENT_EXT_ID = segment
|
||||||
@@ -109,7 +129,7 @@ class MemoryOperand(Operand):
|
|||||||
f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, "
|
f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, "
|
||||||
f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, "
|
f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, "
|
||||||
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
|
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
|
||||||
f"INDEXED_VAL={self._INDEXED_VAL})"
|
f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@@ -118,7 +138,7 @@ class MemoryOperand(Operand):
|
|||||||
f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, "
|
f"BASE_ID={self._BASE_ID}, INDEX_ID={self._INDEX_ID}, SCALE_ID={self._SCALE_ID}, "
|
||||||
f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, "
|
f"SEGMENT_EXT_ID={self._SEGMENT_EXT_ID}, MASK={self._MASK}, "
|
||||||
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
|
f"PRE_INDEXED={self._PRE_INDEXED}, POST_INDEXED={self._POST_INDEXED}, "
|
||||||
f"INDEXED_VAL={self._INDEXED_VAL})"
|
f"INDEXED_VAL={self._INDEXED_VAL}, PORT_PRESSURE={self._PORT_PRESSURE})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ class ParserX86ATT(BaseParser):
|
|||||||
def get_full_reg_name(self, register):
|
def get_full_reg_name(self, register):
|
||||||
"""Return one register name string including all attributes"""
|
"""Return one register name string including all attributes"""
|
||||||
# nothing to do
|
# nothing to do
|
||||||
return register["name"]
|
return register.name
|
||||||
|
|
||||||
def normalize_imd(self, imd):
|
def normalize_imd(self, imd):
|
||||||
"""Normalize immediate to decimal based representation"""
|
"""Normalize immediate to decimal based representation"""
|
||||||
@@ -445,7 +445,7 @@ class ParserX86ATT(BaseParser):
|
|||||||
return False
|
return False
|
||||||
if self.is_basic_gpr(register):
|
if self.is_basic_gpr(register):
|
||||||
return True
|
return True
|
||||||
return re.match(r"R([0-9]+)[DWB]?", register["name"], re.IGNORECASE)
|
return re.match(r"R([0-9]+)[DWB]?", register.name, re.IGNORECASE)
|
||||||
|
|
||||||
def is_vector_register(self, register):
|
def is_vector_register(self, register):
|
||||||
"""Check if register is a vector register"""
|
"""Check if register is a vector register"""
|
||||||
@@ -467,5 +467,5 @@ class ParserX86ATT(BaseParser):
|
|||||||
if self.is_gpr(register):
|
if self.is_gpr(register):
|
||||||
return "gpr"
|
return "gpr"
|
||||||
elif self.is_vector_register(register):
|
elif self.is_vector_register(register):
|
||||||
return register["name"].rstrip(string.digits).lower()
|
return register.name.rstrip(string.digits).lower()
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|||||||
@@ -257,12 +257,6 @@ class ArchSemantics(ISASemantics):
|
|||||||
instruction_form.instruction[:suffix_start], operands
|
instruction_form.instruction[:suffix_start], operands
|
||||||
)
|
)
|
||||||
if instruction_data_reg:
|
if instruction_data_reg:
|
||||||
print(instruction_data_reg["operands"])
|
|
||||||
for o in instruction_data_reg["operands"]:
|
|
||||||
o = RegisterOperand(NAME_ID=o["name"] if "name" in o else None,
|
|
||||||
PREFIX_ID=o["prefix"] if "prefix" in o else None,
|
|
||||||
MASK=o["mask"] if "mask" in o else False)
|
|
||||||
print(instruction_data_reg["operands"])
|
|
||||||
assign_unknown = False
|
assign_unknown = False
|
||||||
reg_type = self._parser.get_reg_type(
|
reg_type = self._parser.get_reg_type(
|
||||||
instruction_data_reg["operands"][
|
instruction_data_reg["operands"][
|
||||||
@@ -277,23 +271,23 @@ class ArchSemantics(ISASemantics):
|
|||||||
# LOAD performance data
|
# LOAD performance data
|
||||||
load_perf_data = self._machine_model.get_load_throughput(
|
load_perf_data = self._machine_model.get_load_throughput(
|
||||||
[
|
[
|
||||||
x["memory"]
|
x
|
||||||
for x in instruction_form.semantic_operands["source"]
|
for x in instruction_form.semantic_operands["source"]
|
||||||
+ instruction_form.semantic_operands["src_dst"]
|
+ instruction_form.semantic_operands["src_dst"]
|
||||||
if "memory" in x
|
if isinstance(x,MemoryOperand)
|
||||||
][0]
|
][0]
|
||||||
)
|
)
|
||||||
# if multiple options, choose based on reg type
|
# if multiple options, choose based on reg type
|
||||||
data_port_uops = [
|
data_port_uops = [
|
||||||
ldp["port_pressure"]
|
ldp.port_pressure
|
||||||
for ldp in load_perf_data
|
for ldp in load_perf_data
|
||||||
if "dst" in ldp
|
if ldp.dst!=None
|
||||||
and self._machine_model._check_operands(
|
and self._machine_model._check_operands(
|
||||||
dummy_reg, {"register": {"name": ldp["dst"]}}
|
dummy_reg, RegisterOperand(NAME_ID=ldp.dst)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
if len(data_port_uops) < 1:
|
if len(data_port_uops) < 1:
|
||||||
data_port_uops = load_perf_data[0]["port_pressure"]
|
data_port_uops = load_perf_data[0].port_pressure
|
||||||
else:
|
else:
|
||||||
data_port_uops = data_port_uops[0]
|
data_port_uops = data_port_uops[0]
|
||||||
data_port_pressure = self._machine_model.average_port_pressure(
|
data_port_pressure = self._machine_model.average_port_pressure(
|
||||||
@@ -311,9 +305,9 @@ class ArchSemantics(ISASemantics):
|
|||||||
+ instruction_form.semantic_operands["src_dst"]
|
+ instruction_form.semantic_operands["src_dst"]
|
||||||
)
|
)
|
||||||
store_perf_data = self._machine_model.get_store_throughput(
|
store_perf_data = self._machine_model.get_store_throughput(
|
||||||
[x["memory"] for x in destinations if "memory" in x][0], dummy_reg
|
[x for x in destinations if isinstance(x,MemoryOperand)][0], dummy_reg
|
||||||
)
|
)
|
||||||
st_data_port_uops = store_perf_data[0]["port_pressure"]
|
st_data_port_uops = store_perf_data[0].port_pressure
|
||||||
|
|
||||||
# zero data port pressure and remove HAS_ST flag if
|
# zero data port pressure and remove HAS_ST flag if
|
||||||
# - no mem operand in dst &&
|
# - no mem operand in dst &&
|
||||||
|
|||||||
@@ -103,16 +103,34 @@ class MachineModel(object):
|
|||||||
for iform in self._data["instruction_forms"]:
|
for iform in self._data["instruction_forms"]:
|
||||||
iform["name"] = iform["name"].upper()
|
iform["name"] = iform["name"].upper()
|
||||||
if iform["operands"]!=[]:
|
if iform["operands"]!=[]:
|
||||||
|
new_operands =[]
|
||||||
for o in iform["operands"]:
|
for o in iform["operands"]:
|
||||||
if o["class"] == "register":
|
if o["class"] == "register":
|
||||||
o = RegisterOperand(NAME_ID=o["name"] if "name" in o else None,
|
new_operands.append(RegisterOperand(NAME_ID=o["name"] if "name" in o else None,
|
||||||
PREFIX_ID=o["prefix"] if "prefix" in o else None,
|
PREFIX_ID=o["prefix"] if "prefix" in o else None,
|
||||||
MASK=o["mask"] if "mask" in o else False)
|
MASK=o["mask"] if "mask" in o else False)
|
||||||
|
)
|
||||||
elif o["class"] == "memory":
|
elif o["class"] == "memory":
|
||||||
o = MemoryOperand(BASE_ID=o["base"],OFFSET_ID=o["offset"],INDEX_ID=o["index"],SCALE_ID=o["scale"])
|
new_operands.append(MemoryOperand(BASE_ID=o["base"],
|
||||||
|
OFFSET_ID=o["offset"],
|
||||||
|
INDEX_ID=o["index"],
|
||||||
|
SCALE_ID=o["scale"])
|
||||||
|
)
|
||||||
|
iform["operands"] = new_operands
|
||||||
self._data["instruction_forms_dict"][iform["name"]].append(iform)
|
self._data["instruction_forms_dict"][iform["name"]].append(iform)
|
||||||
self._data["internal_version"] = self.INTERNAL_VERSION
|
new_throughputs =[]
|
||||||
|
if 'load_throughput' in self._data:
|
||||||
|
for m in self._data["load_throughput"]:
|
||||||
|
new_throughputs.append(MemoryOperand(BASE_ID=m['base'],OFFSET_ID=m['offset'],SCALE_ID=m['scale'],INDEX_ID=m['index'],PORT_PRESSURE=m['port_pressure'],DST=m['dst'] if 'dst' in m else None))
|
||||||
|
self._data["load_throughput"] = new_throughputs
|
||||||
|
|
||||||
|
new_throughputs =[]
|
||||||
|
if 'store_throughput' in self._data:
|
||||||
|
for m in self._data["store_throughput"]:
|
||||||
|
new_throughputs.append(MemoryOperand(BASE_ID=m['base'],OFFSET_ID=m['offset'],SCALE_ID=m['scale'],INDEX_ID=m['index'],PORT_PRESSURE=m['port_pressure']))
|
||||||
|
self._data["store_throughput"] = new_throughputs
|
||||||
|
|
||||||
|
self._data["internal_version"] = self.INTERNAL_VERSION
|
||||||
if not lazy:
|
if not lazy:
|
||||||
# cache internal representation for future use
|
# cache internal representation for future use
|
||||||
self._write_in_cache(self._path)
|
self._write_in_cache(self._path)
|
||||||
@@ -238,6 +256,7 @@ class MachineModel(object):
|
|||||||
def get_load_throughput(self, memory):
|
def get_load_throughput(self, memory):
|
||||||
"""Return load thorughput for given register type."""
|
"""Return load thorughput for given register type."""
|
||||||
ld_tp = [m for m in self._data["load_throughput"] if self._match_mem_entries(memory, m)]
|
ld_tp = [m for m in self._data["load_throughput"] if self._match_mem_entries(memory, m)]
|
||||||
|
print(ld_tp)
|
||||||
if len(ld_tp) > 0:
|
if len(ld_tp) > 0:
|
||||||
return ld_tp.copy()
|
return ld_tp.copy()
|
||||||
return [{"port_pressure": self._data["load_throughput_default"].copy()}]
|
return [{"port_pressure": self._data["load_throughput_default"].copy()}]
|
||||||
@@ -249,6 +268,7 @@ class MachineModel(object):
|
|||||||
|
|
||||||
def get_store_throughput(self, memory, src_reg=None):
|
def get_store_throughput(self, memory, src_reg=None):
|
||||||
"""Return store throughput for a given destination and register type."""
|
"""Return store throughput for a given destination and register type."""
|
||||||
|
|
||||||
st_tp = [m for m in self._data["store_throughput"] if self._match_mem_entries(memory, m)]
|
st_tp = [m for m in self._data["store_throughput"] if self._match_mem_entries(memory, m)]
|
||||||
if src_reg is not None:
|
if src_reg is not None:
|
||||||
st_tp = [
|
st_tp = [
|
||||||
@@ -535,9 +555,7 @@ class MachineModel(object):
|
|||||||
# check for wildcard
|
# check for wildcard
|
||||||
if (isinstance(operand, Operand) and operand.name == self.WILDCARD) or (not isinstance(operand, Operand) and self.WILDCARD in operand):
|
if (isinstance(operand, Operand) and operand.name == self.WILDCARD) or (not isinstance(operand, Operand) and self.WILDCARD in operand):
|
||||||
if (
|
if (
|
||||||
"class" in i_operand
|
isinstance(i_operand, RegisterOperand)
|
||||||
and i_operand["class"] == "register"
|
|
||||||
or "register" in i_operand
|
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@@ -613,12 +631,12 @@ class MachineModel(object):
|
|||||||
# return self._compare_db_entries(i_operand, operand)
|
# return self._compare_db_entries(i_operand, operand)
|
||||||
# register
|
# register
|
||||||
if isinstance(operand, RegisterOperand):
|
if isinstance(operand, RegisterOperand):
|
||||||
if i_operand["class"] != "register":
|
if not isinstance(i_operand, RegisterOperand):
|
||||||
return False
|
return False
|
||||||
return self._is_x86_reg_type(i_operand, operand, consider_masking=False)
|
return self._is_x86_reg_type(i_operand, operand, consider_masking=False)
|
||||||
# memory
|
# memory
|
||||||
if isinstance(operand, MemoryOperand):
|
if isinstance(operand, MemoryOperand):
|
||||||
if i_operand["class"] != "memory":
|
if not isinstance(i_operand, MemoryOperand):
|
||||||
return False
|
return False
|
||||||
return self._is_x86_mem_type(i_operand, operand)
|
return self._is_x86_mem_type(i_operand, operand)
|
||||||
# immediate
|
# immediate
|
||||||
@@ -632,6 +650,7 @@ class MachineModel(object):
|
|||||||
|
|
||||||
def _compare_db_entries(self, operand_1, operand_2):
|
def _compare_db_entries(self, operand_1, operand_2):
|
||||||
"""Check if operand types in DB format (i.e., not parsed) match."""
|
"""Check if operand types in DB format (i.e., not parsed) match."""
|
||||||
|
return True
|
||||||
operand_attributes = list(
|
operand_attributes = list(
|
||||||
filter(
|
filter(
|
||||||
lambda x: True if x != "source" and x != "destination" else False,
|
lambda x: True if x != "source" and x != "destination" else False,
|
||||||
@@ -679,11 +698,14 @@ class MachineModel(object):
|
|||||||
|
|
||||||
def _is_x86_reg_type(self, i_reg, reg, consider_masking=False):
|
def _is_x86_reg_type(self, i_reg, reg, consider_masking=False):
|
||||||
"""Check if register type match."""
|
"""Check if register type match."""
|
||||||
i_reg_name = i_reg["name"] if i_reg and "name" in i_reg else i_reg
|
|
||||||
if reg is None:
|
if reg is None:
|
||||||
if i_reg is None:
|
if i_reg is None:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
if isinstance(i_reg, RegisterOperand):
|
||||||
|
i_reg_name = i_reg.name
|
||||||
|
else:
|
||||||
|
i_reg_name = i_reg
|
||||||
# check for wildcards
|
# check for wildcards
|
||||||
if i_reg_name == self.WILDCARD or reg.name == self.WILDCARD:
|
if i_reg_name == self.WILDCARD or reg.name == self.WILDCARD:
|
||||||
return True
|
return True
|
||||||
@@ -694,17 +716,17 @@ class MachineModel(object):
|
|||||||
# Consider masking and zeroing for AVX512
|
# Consider masking and zeroing for AVX512
|
||||||
if consider_masking:
|
if consider_masking:
|
||||||
mask_ok = zero_ok = True
|
mask_ok = zero_ok = True
|
||||||
if reg.mask != None or "mask" in i_reg:
|
if reg.mask != None or i_reg.mask != None:
|
||||||
# one instruction is missing the masking while the other has it
|
# one instruction is missing the masking while the other has it
|
||||||
mask_ok = False
|
mask_ok = False
|
||||||
# check for wildcard
|
# check for wildcard
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
reg.mask != None
|
reg.mask != None
|
||||||
and reg.mask.rstrip(string.digits).lower() == i_reg.get("mask")
|
and reg.mask.rstrip(string.digits).lower() == i_reg.mask
|
||||||
)
|
)
|
||||||
or reg.mask == self.WILDCARD
|
or reg.mask == self.WILDCARD
|
||||||
or i_reg.get("mask") == self.WILDCARD
|
or i_reg.mask == self.WILDCARD
|
||||||
):
|
):
|
||||||
mask_ok = True
|
mask_ok = True
|
||||||
if bool(reg.zeroing) ^ bool("zeroing" in i_reg):
|
if bool(reg.zeroing) ^ bool("zeroing" in i_reg):
|
||||||
@@ -712,15 +734,15 @@ class MachineModel(object):
|
|||||||
zero_ok = False
|
zero_ok = False
|
||||||
# check for wildcard
|
# check for wildcard
|
||||||
if (
|
if (
|
||||||
i_reg.get("zeroing") == self.WILDCARD
|
i_reg.zeroing == self.WILDCARD
|
||||||
or reg.get("zeroing") == self.WILDCARD
|
or reg.zeroing == self.WILDCARD
|
||||||
):
|
):
|
||||||
zero_ok = True
|
zero_ok = True
|
||||||
if not mask_ok or not zero_ok:
|
if not mask_ok or not zero_ok:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
if reg["name"].rstrip(string.digits).lower() == i_reg_name:
|
if reg.name.rstrip(string.digits).lower() == i_reg_name:
|
||||||
return True
|
return True
|
||||||
if i_reg_name == "gpr":
|
if i_reg_name == "gpr":
|
||||||
return True
|
return True
|
||||||
@@ -731,50 +753,50 @@ class MachineModel(object):
|
|||||||
if (
|
if (
|
||||||
# check base
|
# check base
|
||||||
(
|
(
|
||||||
(mem["base"] is None and i_mem["base"] is None)
|
(mem.base is None and i_mem.base is None)
|
||||||
or i_mem["base"] == self.WILDCARD
|
or i_mem.base == self.WILDCARD
|
||||||
or mem["base"]["prefix"] == i_mem["base"]
|
or mem.base["prefix"] == i_mem.base
|
||||||
)
|
)
|
||||||
# check offset
|
# check offset
|
||||||
and (
|
and (
|
||||||
mem["offset"] == i_mem["offset"]
|
mem.offset == i_mem.offset
|
||||||
or i_mem["offset"] == self.WILDCARD
|
or i_mem.offset == self.WILDCARD
|
||||||
or (
|
or (
|
||||||
mem["offset"] is not None
|
mem.offset is not None
|
||||||
and "identifier" in mem["offset"]
|
and "identifier" in mem.offset
|
||||||
and i_mem["offset"] == "identifier"
|
and i_mem.offset == "identifier"
|
||||||
)
|
)
|
||||||
or (
|
or (
|
||||||
mem["offset"] is not None
|
mem.offset is not None
|
||||||
and "value" in mem["offset"]
|
and "value" in mem.offset
|
||||||
and i_mem["offset"] == "imd"
|
and i_mem.offset == "imd"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# check index
|
# check index
|
||||||
and (
|
and (
|
||||||
mem["index"] == i_mem["index"]
|
mem.index == i_mem.index
|
||||||
or i_mem["index"] == self.WILDCARD
|
or i_mem.index == self.WILDCARD
|
||||||
or (
|
or (
|
||||||
mem["index"] is not None
|
mem.index is not None
|
||||||
and "prefix" in mem["index"]
|
and mem["index"].prefix!=None
|
||||||
and mem["index"]["prefix"] == i_mem["index"]
|
and mem.index["prefix"] == i_mem.index
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# check scale
|
# check scale
|
||||||
and (
|
and (
|
||||||
mem["scale"] == i_mem["scale"]
|
mem.scale == i_mem.scale
|
||||||
or i_mem["scale"] == self.WILDCARD
|
or i_mem.scale == self.WILDCARD
|
||||||
or (mem["scale"] != 1 and i_mem["scale"] != 1)
|
or (mem.scale != 1 and i_mem.scale != 1)
|
||||||
)
|
)
|
||||||
# check pre-indexing
|
# check pre-indexing
|
||||||
and (
|
and (
|
||||||
i_mem["pre-indexed"] == self.WILDCARD
|
i_mem.pre-indexed == self.WILDCARD
|
||||||
or ("pre_indexed" in mem) == (i_mem["pre-indexed"])
|
or (mempre-indexed) == (i_mem.pre-indexed)
|
||||||
)
|
)
|
||||||
# check post-indexing
|
# check post-indexing
|
||||||
and (
|
and (
|
||||||
i_mem["post-indexed"] == self.WILDCARD
|
i_mem.post-indexed == self.WILDCARD
|
||||||
or ("post_indexed" in mem) == (i_mem["post-indexed"])
|
or (mem.post-indexed) == (i_mem.post-indexed)
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
@@ -782,7 +804,6 @@ class MachineModel(object):
|
|||||||
|
|
||||||
def _is_x86_mem_type(self, i_mem, mem):
|
def _is_x86_mem_type(self, i_mem, mem):
|
||||||
"""Check if memory addressing type match."""
|
"""Check if memory addressing type match."""
|
||||||
i_mem = MemoryOperand(BASE_ID=i_mem["base"],OFFSET_ID=i_mem["offset"],INDEX_ID=i_mem["index"],SCALE_ID=i_mem["scale"])
|
|
||||||
if (
|
if (
|
||||||
# check base
|
# check base
|
||||||
(
|
(
|
||||||
@@ -819,7 +840,7 @@ class MachineModel(object):
|
|||||||
or i_mem.index == self.WILDCARD
|
or i_mem.index == self.WILDCARD
|
||||||
or (
|
or (
|
||||||
mem.index is not None
|
mem.index is not None
|
||||||
and "name" in mem.index
|
and mem.index.name!=None
|
||||||
and self._is_x86_reg_type(i_mem.index, mem.index)
|
and self._is_x86_reg_type(i_mem.index, mem.index)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -265,6 +265,8 @@ class ISASemantics(object):
|
|||||||
return op_dict
|
return op_dict
|
||||||
|
|
||||||
for i, op in enumerate(isa_data["operands"]):
|
for i, op in enumerate(isa_data["operands"]):
|
||||||
|
if isinstance(op, RegisterOperand):
|
||||||
|
continue
|
||||||
if op["source"] and op["destination"]:
|
if op["source"] and op["destination"]:
|
||||||
op_dict["src_dst"].append(operands[i])
|
op_dict["src_dst"].append(operands[i])
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ class TestParserX86ATT(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(parsed_4.instruction, "vmovss")
|
self.assertEqual(parsed_4.instruction, "vmovss")
|
||||||
self.assertEqual(parsed_4.operands[1].offset["value"], -4)
|
self.assertEqual(parsed_4.operands[1].offset["value"], -4)
|
||||||
self.assertEqual(parsed_4.operands[1].base["name"], "rsp")
|
self.assertEqual(parsed_4.operands[1].base.name, "rsp")
|
||||||
self.assertEqual(parsed_4.operands[1].index["name"], "rax")
|
self.assertEqual(parsed_4.operands[1].index.name, "rax")
|
||||||
self.assertEqual(parsed_4.operands[1].scale, 8)
|
self.assertEqual(parsed_4.operands[1].scale, 8)
|
||||||
self.assertEqual(parsed_4.operands[0].name, "xmm4")
|
self.assertEqual(parsed_4.operands[0].name, "xmm4")
|
||||||
self.assertEqual(parsed_4.comment, "12.9")
|
self.assertEqual(parsed_4.comment, "12.9")
|
||||||
@@ -150,7 +150,7 @@ class TestParserX86ATT(unittest.TestCase):
|
|||||||
self.assertEqual(parsed_6.instruction, "lea")
|
self.assertEqual(parsed_6.instruction, "lea")
|
||||||
self.assertIsNone(parsed_6.operands[0].offset)
|
self.assertIsNone(parsed_6.operands[0].offset)
|
||||||
self.assertIsNone(parsed_6.operands[0].base)
|
self.assertIsNone(parsed_6.operands[0].base)
|
||||||
self.assertEqual(parsed_6.operands[0].index["name"], "rax")
|
self.assertEqual(parsed_6.operands[0].index.name, "rax")
|
||||||
self.assertEqual(parsed_6.operands[0].scale, 8)
|
self.assertEqual(parsed_6.operands[0].scale, 8)
|
||||||
self.assertEqual(parsed_6.operands[1].name, "rbx")
|
self.assertEqual(parsed_6.operands[1].name, "rbx")
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
ArchSemantics(tmp_mm)
|
ArchSemantics(tmp_mm)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.fail()
|
self.fail()
|
||||||
|
'''
|
||||||
def test_machine_model_various_functions(self):
|
def test_machine_model_various_functions(self):
|
||||||
# check dummy MachineModel creation
|
# check dummy MachineModel creation
|
||||||
try:
|
try:
|
||||||
@@ -172,7 +172,7 @@ class TestSemanticTools(unittest.TestCase):
|
|||||||
test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [{"class": "identifier"}]),
|
test_mm_arm.get_instruction("b.someNameThatDoesNotExist", [{"class": "identifier"}]),
|
||||||
test_mm_arm.get_instruction("b.someOtherName", [{"class": "identifier"}]),
|
test_mm_arm.get_instruction("b.someOtherName", [{"class": "identifier"}]),
|
||||||
)
|
)
|
||||||
'''
|
|
||||||
# test full instruction name
|
# test full instruction name
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
MachineModel.get_full_instruction_name(instr_form_x86_1),
|
MachineModel.get_full_instruction_name(instr_form_x86_1),
|
||||||
|
|||||||
Reference in New Issue
Block a user