mirror of
https://github.com/RPCSX/xed.git
synced 2024-11-27 05:20:24 +00:00
ffd94e705c
Change-Id: I32a6db1a17988d9df8ff69aa1672dbf08b108e8a
140 lines
4.4 KiB
Python
Executable File
140 lines
4.4 KiB
Python
Executable File
#BEGIN_LEGAL
|
|
#
|
|
#Copyright (c) 2016 Intel Corporation
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
#END_LEGAL
|
|
|
|
import ild_info
|
|
import ild_codegen
|
|
import genutil
|
|
import ildutil
|
|
|
|
_modrm_nt = 'MODRM()'
|
|
_vmodrm = 'VMODRM'
|
|
_modrm_bind = 'MOD['
|
|
_mod3_req = 'MOD=3'
|
|
|
|
_modrm_header_fn = 'xed-ild-modrm.h'
|
|
|
|
_has_modrm_true = 'XED_ILD_HASMODRM_TRUE'
|
|
_has_modrm_false = 'XED_ILD_HASMODRM_FALSE'
|
|
_has_modrm_undef = 'XED_ILD_HASMODRM_UNDEF'
|
|
#for MOV_DR and MOV_CR that ignore MODRM.MOD bits
|
|
_has_modrm_ignore = 'XED_ILD_HASMODRM_IGNORE_MOD'
|
|
_has_modrm_typename = 'xed_uint8_t'
|
|
|
|
_hasmodrm_defines = {
|
|
_has_modrm_false : 0,
|
|
_has_modrm_true : 1,
|
|
_has_modrm_ignore : 2,
|
|
_has_modrm_undef : 3,
|
|
}
|
|
|
|
|
|
#FIXME: do we want to check by NT names or do something similar to
|
|
#EOSZ/EASZ - find all NTs that bind interesting operand and look
|
|
#for them in the pattern.
|
|
#FIXME2: it seems we need to check VMODRM() NT too
|
|
def get_hasmodrm(ptrn):
|
|
"""
|
|
Return XED_ILD_HASMODRM_[TRUE|FALSE|IGNORE_MOD] string
|
|
"""
|
|
if is_ignored_mod(ptrn):
|
|
return _has_modrm_ignore
|
|
has_modrm = (_modrm_nt in ptrn) or (_modrm_bind in ptrn)
|
|
return _bool2has_modrm_str(has_modrm)
|
|
|
|
def is_ignored_mod(ptrn):
|
|
"""
|
|
Return True|False if MODRM.MOD bits are ignored
|
|
e.g. MOV_DR instruction
|
|
"""
|
|
#if MODRM.MOD is ignored then MODRM's fields should
|
|
#be bounded, but it should not be a VMODRM (SIMD
|
|
#instructions, there should not be MODRM() that uses
|
|
#MODRM's fields and there should not be a constraint MOD=3
|
|
#which is usage of MODRM.MOD too.
|
|
return (_modrm_bind in ptrn and
|
|
not _vmodrm in ptrn and
|
|
not _modrm_nt in ptrn and
|
|
not _mod3_req in ptrn)
|
|
|
|
def _resolve_modrm_conflict(info_list):
|
|
"""
|
|
Not trying to dispatch by prefixes, mode or anything else.
|
|
Because modrm doesn't have such conflicts.
|
|
"""
|
|
return None
|
|
|
|
def _is_modrm_conflict(info_list):
|
|
if len(info_list) <= 1:
|
|
return False
|
|
first = info_list[0]
|
|
for info in info_list[1:]:
|
|
if first.has_modrm != info.has_modrm:
|
|
return True
|
|
return False
|
|
|
|
def _bool2has_modrm_str(val):
|
|
"""
|
|
Returns C define string for has_modrm
|
|
"""
|
|
if val == None:
|
|
return _has_modrm_undef
|
|
if val:
|
|
return _has_modrm_true
|
|
return _has_modrm_false
|
|
|
|
|
|
def gen_modrm_lookup(united_lookup, debug):
|
|
modrm_lookup = {}
|
|
for insn_map in ild_info.get_dump_maps():
|
|
modrm_lookup[insn_map] = {}
|
|
for opcode in range(0, 256):
|
|
info_list = united_lookup.get_info_list(insn_map, hex(opcode))
|
|
info_list = ild_info.get_min_prio_list(info_list)
|
|
if len(info_list) == 0:
|
|
#no infos in map-opcode, illegal opcode
|
|
has_modrm = _has_modrm_undef
|
|
elif _is_modrm_conflict(info_list):
|
|
#conflict in has_modrm value in map-opcode's info_list
|
|
#try to resolve
|
|
info = _resolve_modrm_conflict(info_list)
|
|
if not info:
|
|
ildutil.ild_err(
|
|
'UNRESOLVED CONFLICT IN MODRM\n infos:\n%s\n' %
|
|
"\n".join([str(info) for info in info_list]))
|
|
has_modrm = info.has_modrm
|
|
else:
|
|
#several infos that agree on has_modrm property, we can choose
|
|
#any of them to get has_modrm
|
|
info = info_list[0]
|
|
has_modrm = info.has_modrm
|
|
modrm_lookup[insn_map][hex(opcode)] = has_modrm
|
|
return modrm_lookup
|
|
|
|
|
|
|
|
def work(agi, united_lookup, debug):
|
|
"""
|
|
dumps MODRM lookup tables to xed_ild_modrm.h
|
|
"""
|
|
modrm_lookup = gen_modrm_lookup(united_lookup, debug)
|
|
ild_codegen.dump_lookup(agi, modrm_lookup, 'has_modrm', _modrm_header_fn,
|
|
[], _has_modrm_typename,
|
|
define_dict=_hasmodrm_defines)
|
|
|
|
|