Merge more changes in from head.
--HG-- extra : convert_revision : 8f170f2754eccdb424a35b5b077225abcf6eee72
This commit is contained in:
commit
d5c74657c9
69 changed files with 4454 additions and 1378 deletions
30
SConstruct
30
SConstruct
|
@ -67,7 +67,7 @@ import sys
|
|||
import os
|
||||
import subprocess
|
||||
|
||||
from os.path import join as joinpath
|
||||
from os.path import isdir, join as joinpath
|
||||
|
||||
# Check for recent-enough Python and SCons versions. If your system's
|
||||
# default installation of Python is not recent enough, you can use a
|
||||
|
@ -97,6 +97,34 @@ SRCDIR = joinpath(ROOT, 'src')
|
|||
# tell python where to find m5 python code
|
||||
sys.path.append(joinpath(ROOT, 'src/python'))
|
||||
|
||||
def check_style_hook(ui):
|
||||
ui.readconfig(joinpath(ROOT, '.hg', 'hgrc'))
|
||||
style_hook = ui.config('hooks', 'pretxncommit.style', None)
|
||||
|
||||
if not style_hook:
|
||||
print """\
|
||||
You're missing the M5 style hook.
|
||||
Please install the hook so we can ensure that all code fits a common style.
|
||||
|
||||
All you'd need to do is add the following lines to your repository .hg/hgrc
|
||||
or your personal .hgrc
|
||||
----------------
|
||||
|
||||
[extensions]
|
||||
style = %s/util/style.py
|
||||
|
||||
[hooks]
|
||||
pretxncommit.style = python:style.check_whitespace
|
||||
""" % (ROOT)
|
||||
sys.exit(1)
|
||||
|
||||
if isdir(joinpath(ROOT, '.hg')):
|
||||
try:
|
||||
from mercurial import ui
|
||||
check_style_hook(ui.ui())
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
###################################################
|
||||
#
|
||||
# Figure out which configurations to set up based on the path(s) of
|
||||
|
|
|
@ -66,10 +66,10 @@ class MachineCheckFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isMachineCheckFault() {return true;}
|
||||
bool isMachineCheckFault() const {return true;}
|
||||
};
|
||||
|
||||
class AlignmentFault : public AlphaFault
|
||||
|
@ -79,10 +79,10 @@ class AlignmentFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isAlignmentFault() {return true;}
|
||||
bool isAlignmentFault() const {return true;}
|
||||
};
|
||||
|
||||
static inline Fault genMachineCheckFault()
|
||||
|
@ -102,7 +102,7 @@ class ResetFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -116,7 +116,7 @@ class ArithmeticFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
#if FULL_SYSTEM
|
||||
|
@ -133,7 +133,7 @@ class InterruptFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -150,7 +150,7 @@ class DtbFault : public AlphaFault
|
|||
: vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() = 0;
|
||||
FaultName name() const = 0;
|
||||
FaultVect vect() = 0;
|
||||
FaultStat & countStat() = 0;
|
||||
#if FULL_SYSTEM
|
||||
|
@ -170,7 +170,7 @@ class NDtbMissFault : public DtbFault
|
|||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -187,7 +187,7 @@ class PDtbMissFault : public DtbFault
|
|||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -204,7 +204,7 @@ class DtbPageFault : public DtbFault
|
|||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -221,7 +221,7 @@ class DtbAcvFault : public DtbFault
|
|||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -238,7 +238,7 @@ class DtbAlignmentFault : public DtbFault
|
|||
: DtbFault(vaddr, reqFlags, flags)
|
||||
{ }
|
||||
#endif
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -251,7 +251,7 @@ class ItbFault : public AlphaFault
|
|||
ItbFault(Addr _pc)
|
||||
: pc(_pc)
|
||||
{ }
|
||||
FaultName name() = 0;
|
||||
FaultName name() const = 0;
|
||||
FaultVect vect() = 0;
|
||||
FaultStat & countStat() = 0;
|
||||
#if FULL_SYSTEM
|
||||
|
@ -269,7 +269,7 @@ class ItbMissFault : public ItbFault
|
|||
ItbMissFault(Addr pc)
|
||||
: ItbFault(pc)
|
||||
{ }
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -284,7 +284,7 @@ class ItbPageFault : public ItbFault
|
|||
ItbPageFault(Addr pc)
|
||||
: ItbFault(pc)
|
||||
{ }
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -299,7 +299,7 @@ class ItbAcvFault : public ItbFault
|
|||
ItbAcvFault(Addr pc)
|
||||
: ItbFault(pc)
|
||||
{ }
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -311,7 +311,7 @@ class UnimplementedOpcodeFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -323,7 +323,7 @@ class FloatEnableFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -337,7 +337,7 @@ class PalFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -349,7 +349,7 @@ class IntegerOverflowFault : public AlphaFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
|
|
@ -134,7 +134,7 @@ def t_INTLIT(t):
|
|||
try:
|
||||
t.value = int(t.value,0)
|
||||
except ValueError:
|
||||
error(t.lineno, 'Integer value "%s" too large' % t.value)
|
||||
error(t.lexer.lineno, 'Integer value "%s" too large' % t.value)
|
||||
t.value = 0
|
||||
return t
|
||||
|
||||
|
@ -144,7 +144,7 @@ def t_STRLIT(t):
|
|||
r"(?m)'([^'])+'"
|
||||
# strip off quotes
|
||||
t.value = t.value[1:-1]
|
||||
t.lineno += t.value.count('\n')
|
||||
t.lexer.lineno += t.value.count('\n')
|
||||
return t
|
||||
|
||||
|
||||
|
@ -154,22 +154,22 @@ def t_CODELIT(t):
|
|||
r"(?m)\{\{([^\}]|}(?!\}))+\}\}"
|
||||
# strip off {{ & }}
|
||||
t.value = t.value[2:-2]
|
||||
t.lineno += t.value.count('\n')
|
||||
t.lexer.lineno += t.value.count('\n')
|
||||
return t
|
||||
|
||||
def t_CPPDIRECTIVE(t):
|
||||
r'^\#[^\#].*\n'
|
||||
t.lineno += t.value.count('\n')
|
||||
t.lexer.lineno += t.value.count('\n')
|
||||
return t
|
||||
|
||||
def t_NEWFILE(t):
|
||||
r'^\#\#newfile\s+"[\w/.-]*"'
|
||||
fileNameStack.push((t.value[11:-1], t.lineno))
|
||||
t.lineno = 0
|
||||
fileNameStack.push((t.value[11:-1], t.lexer.lineno))
|
||||
t.lexer.lineno = 0
|
||||
|
||||
def t_ENDFILE(t):
|
||||
r'^\#\#endfile'
|
||||
(old_filename, t.lineno) = fileNameStack.pop()
|
||||
(old_filename, t.lexer.lineno) = fileNameStack.pop()
|
||||
|
||||
#
|
||||
# The functions t_NEWLINE, t_ignore, and t_error are
|
||||
|
@ -179,7 +179,7 @@ def t_ENDFILE(t):
|
|||
# Newlines
|
||||
def t_NEWLINE(t):
|
||||
r'\n+'
|
||||
t.lineno += t.value.count('\n')
|
||||
t.lexer.lineno += t.value.count('\n')
|
||||
|
||||
# Comments
|
||||
def t_comment(t):
|
||||
|
@ -190,7 +190,7 @@ t_ignore = ' \t\x0c'
|
|||
|
||||
# Error handler
|
||||
def t_error(t):
|
||||
error(t.lineno, "illegal character '%s'" % t.value[0])
|
||||
error(t.lexer.lineno, "illegal character '%s'" % t.value[0])
|
||||
t.skip(1)
|
||||
|
||||
# Build the lexer
|
||||
|
@ -318,7 +318,7 @@ def p_global_let(t):
|
|||
try:
|
||||
exec fixPythonIndentation(t[2]) in exportContext
|
||||
except Exception, exc:
|
||||
error(t.lineno(1),
|
||||
error(t.lexer.lineno,
|
||||
'error: %s in global let block "%s".' % (exc, t[2]))
|
||||
t[0] = GenCode(header_output = exportContext["header_output"],
|
||||
decoder_output = exportContext["decoder_output"],
|
||||
|
@ -332,9 +332,9 @@ def p_def_operand_types(t):
|
|||
try:
|
||||
userDict = eval('{' + t[3] + '}')
|
||||
except Exception, exc:
|
||||
error(t.lineno(1),
|
||||
error(t.lexer.lineno,
|
||||
'error: %s in def operand_types block "%s".' % (exc, t[3]))
|
||||
buildOperandTypeMap(userDict, t.lineno(1))
|
||||
buildOperandTypeMap(userDict, t.lexer.lineno)
|
||||
t[0] = GenCode() # contributes nothing to the output C++ file
|
||||
|
||||
# Define the mapping from operand names to operand classes and other
|
||||
|
@ -342,14 +342,14 @@ def p_def_operand_types(t):
|
|||
def p_def_operands(t):
|
||||
'def_operands : DEF OPERANDS CODELIT SEMI'
|
||||
if not globals().has_key('operandTypeMap'):
|
||||
error(t.lineno(1),
|
||||
error(t.lexer.lineno,
|
||||
'error: operand types must be defined before operands')
|
||||
try:
|
||||
userDict = eval('{' + t[3] + '}')
|
||||
except Exception, exc:
|
||||
error(t.lineno(1),
|
||||
error(t.lexer.lineno,
|
||||
'error: %s in def operands block "%s".' % (exc, t[3]))
|
||||
buildOperandNameMap(userDict, t.lineno(1))
|
||||
buildOperandNameMap(userDict, t.lexer.lineno)
|
||||
t[0] = GenCode() # contributes nothing to the output C++ file
|
||||
|
||||
# A bitfield definition looks like:
|
||||
|
@ -376,7 +376,7 @@ def p_def_bitfield_1(t):
|
|||
def p_def_bitfield_struct(t):
|
||||
'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI'
|
||||
if (t[2] != ''):
|
||||
error(t.lineno(1), 'error: structure bitfields are always unsigned.')
|
||||
error(t.lexer.lineno, 'error: structure bitfields are always unsigned.')
|
||||
expr = 'machInst.%s' % t[5]
|
||||
hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
|
||||
t[0] = GenCode(header_output = hash_define)
|
||||
|
@ -410,7 +410,7 @@ def p_def_template(t):
|
|||
def p_def_format(t):
|
||||
'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
|
||||
(id, params, code) = (t[3], t[5], t[7])
|
||||
defFormat(id, params, code, t.lineno(1))
|
||||
defFormat(id, params, code, t.lexer.lineno)
|
||||
t[0] = GenCode()
|
||||
|
||||
# The formal parameter list for an instruction format is a possibly
|
||||
|
@ -520,7 +520,7 @@ def p_decode_stmt_list_0(t):
|
|||
def p_decode_stmt_list_1(t):
|
||||
'decode_stmt_list : decode_stmt decode_stmt_list'
|
||||
if (t[1].has_decode_default and t[2].has_decode_default):
|
||||
error(t.lineno(1), 'Two default cases in decode block')
|
||||
error(t.lexer.lineno, 'Two default cases in decode block')
|
||||
t[0] = t[1] + t[2]
|
||||
|
||||
#
|
||||
|
@ -565,7 +565,7 @@ def p_push_format_id(t):
|
|||
formatStack.push(formatMap[t[1]])
|
||||
t[0] = ('', '// format %s' % t[1])
|
||||
except KeyError:
|
||||
error(t.lineno(1), 'instruction format "%s" not defined.' % t[1])
|
||||
error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1])
|
||||
|
||||
# Nested decode block: if the value of the current field matches the
|
||||
# specified constant, do a nested decode on some other field.
|
||||
|
@ -617,7 +617,7 @@ def p_inst_0(t):
|
|||
'inst : ID LPAREN arg_list RPAREN'
|
||||
# Pass the ID and arg list to the current format class to deal with.
|
||||
currentFormat = formatStack.top()
|
||||
codeObj = currentFormat.defineInst(t[1], t[3], t.lineno(1))
|
||||
codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno)
|
||||
args = ','.join(map(str, t[3]))
|
||||
args = re.sub('(?m)^', '//', args)
|
||||
args = re.sub('^//', '', args)
|
||||
|
@ -632,8 +632,8 @@ def p_inst_1(t):
|
|||
try:
|
||||
format = formatMap[t[1]]
|
||||
except KeyError:
|
||||
error(t.lineno(1), 'instruction format "%s" not defined.' % t[1])
|
||||
codeObj = format.defineInst(t[3], t[5], t.lineno(1))
|
||||
error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1])
|
||||
codeObj = format.defineInst(t[3], t[5], t.lexer.lineno)
|
||||
comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5])
|
||||
codeObj.prepend_all(comment)
|
||||
t[0] = codeObj
|
||||
|
@ -722,7 +722,7 @@ def p_empty(t):
|
|||
# *token*, not a grammar symbol (hence the need to use t.value)
|
||||
def p_error(t):
|
||||
if t:
|
||||
error(t.lineno, "syntax error at '%s'" % t.value)
|
||||
error(t.lexer.lineno, "syntax error at '%s'" % t.value)
|
||||
else:
|
||||
error(0, "unknown syntax error", True)
|
||||
|
||||
|
|
|
@ -61,10 +61,10 @@ class MachineCheckFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isMachineCheckFault() {return true;}
|
||||
bool isMachineCheckFault() const {return true;}
|
||||
};
|
||||
|
||||
class AlignmentFault : public MipsFault
|
||||
|
@ -74,10 +74,10 @@ class AlignmentFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
bool isAlignmentFault() {return true;}
|
||||
bool isAlignmentFault() const {return true;}
|
||||
};
|
||||
|
||||
class UnimplementedOpcodeFault : public MipsFault
|
||||
|
@ -87,7 +87,7 @@ class UnimplementedOpcodeFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -133,7 +133,7 @@ class ResetFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
void invoke(ThreadContext * tc);
|
||||
|
@ -146,7 +146,7 @@ class CoprocessorUnusableFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
void invoke(ThreadContext * tc);
|
||||
|
@ -159,7 +159,7 @@ class ReservedInstructionFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
void invoke(ThreadContext * tc);
|
||||
|
@ -172,7 +172,7 @@ class ThreadFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
void invoke(ThreadContext * tc);
|
||||
|
@ -188,7 +188,7 @@ class ArithmeticFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
#if FULL_SYSTEM
|
||||
|
@ -205,7 +205,7 @@ class InterruptFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -217,7 +217,7 @@ class NDtbMissFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -229,7 +229,7 @@ class PDtbMissFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -241,7 +241,7 @@ class DtbPageFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -253,7 +253,7 @@ class DtbAcvFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -265,7 +265,7 @@ class ItbMissFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -277,7 +277,7 @@ class ItbPageFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -289,7 +289,7 @@ class ItbAcvFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -301,7 +301,7 @@ class FloatEnableFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -313,7 +313,7 @@ class IntegerOverflowFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
@ -325,7 +325,7 @@ class DspStateDisabledFault : public MipsFault
|
|||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
FaultName name() {return _name;}
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
void invoke(ThreadContext * tc);
|
||||
|
|
|
@ -65,7 +65,6 @@ class SparcFaultBase : public FaultBase
|
|||
#if FULL_SYSTEM
|
||||
void invoke(ThreadContext * tc);
|
||||
#endif
|
||||
virtual FaultName name() = 0;
|
||||
virtual TrapType trapType() = 0;
|
||||
virtual FaultPriority priority() = 0;
|
||||
virtual FaultStat & countStat() = 0;
|
||||
|
@ -78,7 +77,7 @@ class SparcFault : public SparcFaultBase
|
|||
protected:
|
||||
static FaultVals vals;
|
||||
public:
|
||||
FaultName name() {return vals.name;}
|
||||
FaultName name() const {return vals.name;}
|
||||
TrapType trapType() {return vals.trapType;}
|
||||
FaultPriority priority() {return vals.priority;}
|
||||
FaultStat & countStat() {return vals.count;}
|
||||
|
@ -133,7 +132,7 @@ class InternalProcessorError :
|
|||
public SparcFault<InternalProcessorError>
|
||||
{
|
||||
public:
|
||||
bool isMachineCheckFault() {return true;}
|
||||
bool isMachineCheckFault() const {return true;}
|
||||
};
|
||||
|
||||
class InstructionInvalidTSBEntry : public SparcFault<InstructionInvalidTSBEntry> {};
|
||||
|
@ -152,7 +151,7 @@ class MemAddressNotAligned :
|
|||
public SparcFault<MemAddressNotAligned>
|
||||
{
|
||||
public:
|
||||
bool isAlignmentFault() {return true;}
|
||||
bool isAlignmentFault() const {return true;}
|
||||
};
|
||||
|
||||
class LDDFMemAddressNotAligned : public SparcFault<LDDFMemAddressNotAligned> {};
|
||||
|
|
|
@ -87,6 +87,9 @@ Import('*')
|
|||
if env['TARGET_ISA'] == 'x86':
|
||||
Source('emulenv.cc')
|
||||
Source('floatregfile.cc')
|
||||
Source('insts/microldstop.cc')
|
||||
Source('insts/microregop.cc')
|
||||
Source('insts/static_inst.cc')
|
||||
Source('intregfile.cc')
|
||||
Source('miscregfile.cc')
|
||||
Source('predecoder.cc')
|
||||
|
|
|
@ -66,8 +66,8 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
|
|||
//Use the SIB byte for addressing if the modrm byte calls for it.
|
||||
if (machInst.modRM.rm == 4 && machInst.addrSize != 2) {
|
||||
scale = 1 << machInst.sib.scale;
|
||||
index = machInst.sib.index;
|
||||
base = machInst.sib.base;
|
||||
index = machInst.sib.index | (machInst.rex.x << 3);
|
||||
base = machInst.sib.base | (machInst.rex.b << 3);
|
||||
//In this special case, we don't use a base. The displacement also
|
||||
//changes, but that's managed by the predecoder.
|
||||
if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0)
|
||||
|
@ -80,11 +80,13 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
|
|||
warn("I'm not really using 16 bit MODRM like I'm supposed to!\n");
|
||||
} else {
|
||||
scale = 0;
|
||||
base = machInst.modRM.rm;
|
||||
base = machInst.modRM.rm | (machInst.rex.b << 3);
|
||||
if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) {
|
||||
base = NUM_INTREGS;
|
||||
if (machInst.mode.submode == SixtyFourBitMode)
|
||||
base = NUM_INTREGS+7;
|
||||
//Since we need to use a different encoding of this
|
||||
//instruction anyway, just ignore the base in those cases
|
||||
// if (machInst.mode.submode == SixtyFourBitMode)
|
||||
// base = NUM_INTREGS+7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace X86ISA
|
|||
class X86Fault : public FaultBase
|
||||
{
|
||||
protected:
|
||||
const char * name()
|
||||
const char * name() const
|
||||
{
|
||||
return "generic_x86_fault";
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ namespace X86ISA
|
|||
class UnimpInstFault : public FaultBase
|
||||
{
|
||||
public:
|
||||
const char * name()
|
||||
const char * name() const
|
||||
{
|
||||
return "unimplemented_micro";
|
||||
}
|
||||
|
|
79
src/arch/x86/insts/microldstop.cc
Normal file
79
src/arch/x86/insts/microldstop.cc
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "arch/x86/insts/microldstop.hh"
|
||||
#include <string>
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
std::string LdStOp::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
printReg(response, data, dataSize);
|
||||
response << ", ";
|
||||
printSegment(response, segment);
|
||||
ccprintf(response, ":[%d*", scale);
|
||||
printReg(response, index, addressSize);
|
||||
response << " + ";
|
||||
printReg(response, base, addressSize);
|
||||
ccprintf(response, " + %#x]", disp);
|
||||
return response.str();
|
||||
}
|
||||
}
|
102
src/arch/x86/insts/microldstop.hh
Normal file
102
src/arch/x86/insts/microldstop.hh
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_X86_INSTS_MICROLDSTOP_HH__
|
||||
#define __ARCH_X86_INSTS_MICROLDSTOP_HH__
|
||||
|
||||
#include "arch/x86/insts/microop.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
/**
|
||||
* Base class for load and store ops
|
||||
*/
|
||||
class LdStOp : public X86MicroopBase
|
||||
{
|
||||
protected:
|
||||
const uint8_t scale;
|
||||
const RegIndex index;
|
||||
const RegIndex base;
|
||||
const uint64_t disp;
|
||||
const uint8_t segment;
|
||||
const RegIndex data;
|
||||
const uint8_t dataSize;
|
||||
const uint8_t addressSize;
|
||||
|
||||
//Constructor
|
||||
LdStOp(ExtMachInst _machInst,
|
||||
const char * mnem, const char * _instMnem,
|
||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||
uint8_t _scale, RegIndex _index, RegIndex _base,
|
||||
uint64_t _disp, uint8_t _segment,
|
||||
RegIndex _data,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
OpClass __opClass) :
|
||||
X86MicroopBase(machInst, mnem, _instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast, __opClass),
|
||||
scale(_scale), index(_index), base(_base),
|
||||
disp(_disp), segment(_segment),
|
||||
data(_data),
|
||||
dataSize(_dataSize), addressSize(_addressSize)
|
||||
{}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__ARCH_X86_INSTS_MICROLDSTOP_HH__
|
100
src/arch/x86/insts/microop.hh
Normal file
100
src/arch/x86/insts/microop.hh
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_X86_INSTS_MICROOP_HH__
|
||||
#define __ARCH_X86_INSTS_MICROOP_HH__
|
||||
|
||||
#include "arch/x86/insts/static_inst.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
//A class which is the base of all x86 micro ops. It provides a function to
|
||||
//set necessary flags appropriately.
|
||||
class X86MicroopBase : public X86StaticInst
|
||||
{
|
||||
protected:
|
||||
const char * instMnem;
|
||||
uint8_t opSize;
|
||||
uint8_t addrSize;
|
||||
|
||||
X86MicroopBase(ExtMachInst _machInst,
|
||||
const char *mnem, const char *_instMnem,
|
||||
bool isMicro, bool isDelayed,
|
||||
bool isFirst, bool isLast,
|
||||
OpClass __opClass) :
|
||||
X86ISA::X86StaticInst(mnem, _machInst, __opClass),
|
||||
instMnem(_instMnem)
|
||||
{
|
||||
flags[IsMicroop] = isMicro;
|
||||
flags[IsDelayedCommit] = isDelayed;
|
||||
flags[IsFirstMicroop] = isFirst;
|
||||
flags[IsLastMicroop] = isLast;
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "\t%s.%s", instMnem, mnemonic);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__ARCH_X86_INSTS_MICROOP_HH__
|
196
src/arch/x86/insts/microregop.cc
Normal file
196
src/arch/x86/insts/microregop.cc
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "arch/x86/insts/microregop.hh"
|
||||
#include "arch/x86/miscregs.hh"
|
||||
#include "base/condcodes.hh"
|
||||
#include <string>
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
uint64_t RegOpBase::genFlags(uint64_t oldFlags, uint64_t flagMask,
|
||||
uint64_t _dest, uint64_t _src1, uint64_t _src2,
|
||||
bool subtract) const
|
||||
{
|
||||
DPRINTF(Sparc, "flagMask = %#x\n", flagMask);
|
||||
uint64_t flags = oldFlags & ~flagMask;
|
||||
if(flagMask & CFBit)
|
||||
if(findCarry(dataSize*8, _dest, _src1, _src2))
|
||||
flags |= CFBit;
|
||||
if(subtract)
|
||||
flags ^= CFBit;
|
||||
if(flagMask & PFBit && findParity(dataSize*8, _dest))
|
||||
flags |= PFBit;
|
||||
if(flagMask & ECFBit && findCarry(dataSize*8, _dest, _src1, _src2))
|
||||
flags |= ECFBit;
|
||||
if(flagMask & AFBit)
|
||||
if(findCarry(4, _dest, _src1, _src2))
|
||||
flags |= AFBit;
|
||||
if(subtract)
|
||||
flags ^= AFBit;
|
||||
if(flagMask & EZFBit && findZero(dataSize*8, _dest))
|
||||
flags |= EZFBit;
|
||||
if(flagMask & ZFBit && findZero(dataSize*8, _dest))
|
||||
flags |= ZFBit;
|
||||
if(flagMask & SFBit && findNegative(dataSize*8, _dest))
|
||||
flags |= SFBit;
|
||||
if(flagMask & OFBit && findOverflow(dataSize*8, _dest, _src1, _src2))
|
||||
flags |= OFBit;
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool RegOpBase::checkCondition(uint64_t flags) const
|
||||
{
|
||||
CCFlagBits ccflags = flags;
|
||||
switch(ext)
|
||||
{
|
||||
case ConditionTests::True:
|
||||
return true;
|
||||
case ConditionTests::ECF:
|
||||
return ccflags.ECF;
|
||||
case ConditionTests::EZF:
|
||||
return ccflags.EZF;
|
||||
case ConditionTests::SZnZF:
|
||||
return !(!ccflags.EZF & ccflags.ZF);
|
||||
case ConditionTests::MSTRZ:
|
||||
panic("This condition is not implemented!");
|
||||
case ConditionTests::STRZ:
|
||||
panic("This condition is not implemented!");
|
||||
case ConditionTests::MSTRC:
|
||||
panic("This condition is not implemented!");
|
||||
case ConditionTests::STRZnZF:
|
||||
panic("This condition is not implemented!");
|
||||
case ConditionTests::OF:
|
||||
return ccflags.OF;
|
||||
case ConditionTests::CF:
|
||||
return ccflags.CF;
|
||||
case ConditionTests::ZF:
|
||||
return ccflags.ZF;
|
||||
case ConditionTests::CvZF:
|
||||
return ccflags.CF | ccflags.ZF;
|
||||
case ConditionTests::SF:
|
||||
return ccflags.SF;
|
||||
case ConditionTests::PF:
|
||||
return ccflags.PF;
|
||||
case ConditionTests::SxOF:
|
||||
return ccflags.SF ^ ccflags.OF;
|
||||
case ConditionTests::SxOvZF:
|
||||
return ccflags.SF ^ ccflags.OF | ccflags.ZF;
|
||||
case ConditionTests::False:
|
||||
return false;
|
||||
case ConditionTests::NotECF:
|
||||
return !ccflags.ECF;
|
||||
case ConditionTests::NotEZF:
|
||||
return !ccflags.EZF;
|
||||
case ConditionTests::NotSZnZF:
|
||||
return !ccflags.EZF & ccflags.ZF;
|
||||
case ConditionTests::NotMSTRZ:
|
||||
panic("This condition is not implemented!");
|
||||
case ConditionTests::NotSTRZ:
|
||||
panic("This condition is not implemented!");
|
||||
case ConditionTests::NotMSTRC:
|
||||
panic("This condition is not implemented!");
|
||||
case ConditionTests::NotSTRZnZF:
|
||||
panic("This condition is not implemented!");
|
||||
case ConditionTests::NotOF:
|
||||
return !ccflags.OF;
|
||||
case ConditionTests::NotCF:
|
||||
return !ccflags.CF;
|
||||
case ConditionTests::NotZF:
|
||||
return !ccflags.ZF;
|
||||
case ConditionTests::NotCvZF:
|
||||
return !(ccflags.CF | ccflags.ZF);
|
||||
case ConditionTests::NotSF:
|
||||
return !ccflags.SF;
|
||||
case ConditionTests::NotPF:
|
||||
return !ccflags.PF;
|
||||
case ConditionTests::NotSxOF:
|
||||
return !(ccflags.SF ^ ccflags.OF);
|
||||
case ConditionTests::NotSxOvZF:
|
||||
return !(ccflags.SF ^ ccflags.OF | ccflags.ZF);
|
||||
}
|
||||
panic("Unknown condition: %d\n", ext);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string RegOp::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
printReg(response, dest, dataSize);
|
||||
response << ", ";
|
||||
printReg(response, src1, dataSize);
|
||||
response << ", ";
|
||||
printReg(response, src2, dataSize);
|
||||
return response.str();
|
||||
}
|
||||
|
||||
std::string RegOpImm::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
printReg(response, dest, dataSize);
|
||||
response << ", ";
|
||||
printReg(response, src1, dataSize);
|
||||
ccprintf(response, ", %#x", imm8);
|
||||
return response.str();
|
||||
}
|
||||
}
|
191
src/arch/x86/insts/microregop.hh
Normal file
191
src/arch/x86/insts/microregop.hh
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_X86_INSTS_MICROREGOP_HH__
|
||||
#define __ARCH_X86_INSTS_MICROREGOP_HH__
|
||||
|
||||
#include "arch/x86/insts/microop.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
namespace ConditionTests
|
||||
{
|
||||
enum CondTest {
|
||||
True,
|
||||
NotFalse = True,
|
||||
ECF,
|
||||
EZF,
|
||||
SZnZF,
|
||||
MSTRZ,
|
||||
STRZ,
|
||||
MSTRC,
|
||||
STRZnZF,
|
||||
OF,
|
||||
CF,
|
||||
ZF,
|
||||
CvZF,
|
||||
SF,
|
||||
PF,
|
||||
SxOF,
|
||||
SxOvZF,
|
||||
|
||||
False,
|
||||
NotTrue = False,
|
||||
NotECF,
|
||||
NotEZF,
|
||||
NotSZnZF,
|
||||
NotMSTRZ,
|
||||
NotSTRZ,
|
||||
NotMSTRC,
|
||||
NotSTRZnZF,
|
||||
NotOF,
|
||||
NotCF,
|
||||
NotZF,
|
||||
NotCvZF,
|
||||
NotSF,
|
||||
NotPF,
|
||||
NotSxOF,
|
||||
NotSxOvZF
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Base classes for RegOps which provides a generateDisassembly method.
|
||||
*/
|
||||
class RegOpBase : public X86MicroopBase
|
||||
{
|
||||
protected:
|
||||
const RegIndex src1;
|
||||
const RegIndex dest;
|
||||
const uint8_t dataSize;
|
||||
const uint16_t ext;
|
||||
|
||||
// Constructor
|
||||
RegOpBase(ExtMachInst _machInst,
|
||||
const char *mnem, const char *_instMnem,
|
||||
bool isMicro, bool isDelayed,
|
||||
bool isFirst, bool isLast,
|
||||
RegIndex _src1, RegIndex _dest,
|
||||
uint8_t _dataSize, uint16_t _ext,
|
||||
OpClass __opClass) :
|
||||
X86MicroopBase(_machInst, mnem, _instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast,
|
||||
__opClass),
|
||||
src1(_src1), dest(_dest),
|
||||
dataSize(_dataSize), ext(_ext)
|
||||
{
|
||||
}
|
||||
|
||||
//Figure out what the condition code flags should be.
|
||||
uint64_t genFlags(uint64_t oldFlags, uint64_t flagMask,
|
||||
uint64_t _dest, uint64_t _src1, uint64_t _src2,
|
||||
bool subtract = false) const;
|
||||
bool checkCondition(uint64_t flags) const;
|
||||
};
|
||||
|
||||
class RegOp : public RegOpBase
|
||||
{
|
||||
protected:
|
||||
const RegIndex src2;
|
||||
|
||||
// Constructor
|
||||
RegOp(ExtMachInst _machInst,
|
||||
const char *mnem, const char *_instMnem,
|
||||
bool isMicro, bool isDelayed,
|
||||
bool isFirst, bool isLast,
|
||||
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||
uint8_t _dataSize, uint16_t _ext,
|
||||
OpClass __opClass) :
|
||||
RegOpBase(_machInst, mnem, _instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast,
|
||||
_src1, _dest, _dataSize, _ext,
|
||||
__opClass),
|
||||
src2(_src2)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
class RegOpImm : public RegOpBase
|
||||
{
|
||||
protected:
|
||||
const uint8_t imm8;
|
||||
|
||||
// Constructor
|
||||
RegOpImm(ExtMachInst _machInst,
|
||||
const char * mnem, const char *_instMnem,
|
||||
bool isMicro, bool isDelayed,
|
||||
bool isFirst, bool isLast,
|
||||
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||
uint8_t _dataSize, uint16_t _ext,
|
||||
OpClass __opClass) :
|
||||
RegOpBase(_machInst, mnem, _instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast,
|
||||
_src1, _dest, _dataSize, _ext,
|
||||
__opClass),
|
||||
imm8(_imm8)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__ARCH_X86_INSTS_MICROREGOP_HH__
|
200
src/arch/x86/insts/static_inst.cc
Normal file
200
src/arch/x86/insts/static_inst.cc
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "arch/x86/insts/static_inst.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
void X86StaticInst::printMnemonic(std::ostream &os,
|
||||
const char * mnemonic) const
|
||||
{
|
||||
ccprintf(os, "\t%s ", mnemonic);
|
||||
}
|
||||
|
||||
void X86StaticInst::printMnemonic(std::ostream &os,
|
||||
const char * instMnemonic, const char * mnemonic) const
|
||||
{
|
||||
ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
|
||||
}
|
||||
|
||||
void X86StaticInst::printSegment(std::ostream &os, int segment) const
|
||||
{
|
||||
switch (segment)
|
||||
{
|
||||
case 0:
|
||||
ccprintf(os, "ES");
|
||||
break;
|
||||
case 1:
|
||||
ccprintf(os, "CS");
|
||||
break;
|
||||
case 2:
|
||||
ccprintf(os, "SS");
|
||||
break;
|
||||
case 3:
|
||||
ccprintf(os, "DS");
|
||||
break;
|
||||
case 4:
|
||||
ccprintf(os, "FS");
|
||||
break;
|
||||
case 5:
|
||||
ccprintf(os, "GS");
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized segment %d\n", segment);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const
|
||||
{
|
||||
if(_numSrcRegs > reg)
|
||||
printReg(os, _srcRegIdx[reg], size);
|
||||
}
|
||||
|
||||
void
|
||||
X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const
|
||||
{
|
||||
if(_numDestRegs > reg)
|
||||
printReg(os, _destRegIdx[reg], size);
|
||||
}
|
||||
|
||||
void
|
||||
X86StaticInst::printReg(std::ostream &os, int reg, int size) const
|
||||
{
|
||||
assert(size == 1 || size == 2 || size == 4 || size == 8);
|
||||
static const char * abcdFormats[9] =
|
||||
{"", "%sl", "%sx", "", "e%sx", "", "", "", "r%sx"};
|
||||
static const char * piFormats[9] =
|
||||
{"", "%sl", "%s", "", "e%s", "", "", "", "r%s"};
|
||||
static const char * longFormats[9] =
|
||||
{"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"};
|
||||
static const char * microFormats[9] =
|
||||
{"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
|
||||
|
||||
if (reg < FP_Base_DepTag) {
|
||||
switch (reg) {
|
||||
case INTREG_RAX:
|
||||
ccprintf(os, abcdFormats[size], "a");
|
||||
break;
|
||||
case INTREG_RBX:
|
||||
ccprintf(os, abcdFormats[size], "b");
|
||||
break;
|
||||
case INTREG_RCX:
|
||||
ccprintf(os, abcdFormats[size], "c");
|
||||
break;
|
||||
case INTREG_RDX:
|
||||
ccprintf(os, abcdFormats[size], "d");
|
||||
break;
|
||||
case INTREG_RSP:
|
||||
ccprintf(os, piFormats[size], "sp");
|
||||
break;
|
||||
case INTREG_RBP:
|
||||
ccprintf(os, piFormats[size], "bp");
|
||||
break;
|
||||
case INTREG_RSI:
|
||||
ccprintf(os, piFormats[size], "si");
|
||||
break;
|
||||
case INTREG_RDI:
|
||||
ccprintf(os, piFormats[size], "di");
|
||||
break;
|
||||
case INTREG_R8W:
|
||||
ccprintf(os, longFormats[size], "8");
|
||||
break;
|
||||
case INTREG_R9W:
|
||||
ccprintf(os, longFormats[size], "9");
|
||||
break;
|
||||
case INTREG_R10W:
|
||||
ccprintf(os, longFormats[size], "10");
|
||||
break;
|
||||
case INTREG_R11W:
|
||||
ccprintf(os, longFormats[size], "11");
|
||||
break;
|
||||
case INTREG_R12W:
|
||||
ccprintf(os, longFormats[size], "12");
|
||||
break;
|
||||
case INTREG_R13W:
|
||||
ccprintf(os, longFormats[size], "13");
|
||||
break;
|
||||
case INTREG_R14W:
|
||||
ccprintf(os, longFormats[size], "14");
|
||||
break;
|
||||
case INTREG_R15W:
|
||||
ccprintf(os, longFormats[size], "15");
|
||||
break;
|
||||
default:
|
||||
ccprintf(os, microFormats[size], reg - NUM_INTREGS);
|
||||
}
|
||||
} else if (reg < Ctrl_Base_DepTag) {
|
||||
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
|
||||
} else {
|
||||
switch (reg - Ctrl_Base_DepTag) {
|
||||
default:
|
||||
ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string X86StaticInst::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
printMnemonic(ss, mnemonic);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}
|
140
src/arch/x86/insts/static_inst.hh
Normal file
140
src/arch/x86/insts/static_inst.hh
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_X86_INSTS_STATICINST_HH__
|
||||
#define __ARCH_X86_INSTS_STATICINST_HH__
|
||||
|
||||
#include "cpu/static_inst.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
/**
|
||||
* Base class for all X86 static instructions.
|
||||
*/
|
||||
|
||||
class X86StaticInst : public StaticInst
|
||||
{
|
||||
protected:
|
||||
// Constructor.
|
||||
X86StaticInst(const char *mnem,
|
||||
ExtMachInst _machInst, OpClass __opClass)
|
||||
: StaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
|
||||
void printMnemonic(std::ostream &os, const char * mnemonic) const;
|
||||
void printMnemonic(std::ostream &os, const char * instMnemonic,
|
||||
const char * mnemonic) const;
|
||||
|
||||
void printSegment(std::ostream &os, int segment) const;
|
||||
|
||||
void printReg(std::ostream &os, int reg, int size) const;
|
||||
void printSrcReg(std::ostream &os, int reg, int size) const;
|
||||
void printDestReg(std::ostream &os, int reg, int size) const;
|
||||
|
||||
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
|
||||
{
|
||||
X86IntReg reg;
|
||||
reg = into;
|
||||
//FIXME This needs to be handle high bytes as well
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
reg.L = val;
|
||||
break;
|
||||
case 2:
|
||||
reg.X = val;
|
||||
break;
|
||||
case 4:
|
||||
//XXX Check if this should be zeroed or sign extended
|
||||
reg = 0;
|
||||
reg.E = val;
|
||||
break;
|
||||
case 8:
|
||||
reg.R = val;
|
||||
break;
|
||||
default:
|
||||
panic("Tried to merge with unrecognized size %d.\n", size);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
inline uint64_t pick(uint64_t from, int size)
|
||||
{
|
||||
X86IntReg reg;
|
||||
reg = from;
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
return reg.L;
|
||||
case 2:
|
||||
return reg.E;
|
||||
case 4:
|
||||
return reg.X;
|
||||
case 8:
|
||||
return reg.R;
|
||||
default:
|
||||
panic("Tried to pick with unrecognized size %d.\n", size);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__ARCH_X86_INSTS_STATICINST_HH__
|
|
@ -104,7 +104,8 @@ namespace X86ISA
|
|||
std::string getIntRegName(RegIndex);
|
||||
|
||||
const int NumIntArchRegs = NUM_INTREGS;
|
||||
const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs;
|
||||
const int NumIntRegs =
|
||||
NumIntArchRegs + NumMicroIntRegs + NumPseudoIntRegs;
|
||||
|
||||
class IntRegFile
|
||||
{
|
||||
|
|
|
@ -58,8 +58,18 @@
|
|||
#ifndef __ARCH_X86_INTREGS_HH__
|
||||
#define __ARCH_X86_INTREGS_HH__
|
||||
|
||||
#include "base/bitunion.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
BitUnion64(X86IntReg)
|
||||
Bitfield<63,0> R;
|
||||
Bitfield<31,0> E;
|
||||
Bitfield<15,0> X;
|
||||
Bitfield<15,8> H;
|
||||
Bitfield<7, 0> L;
|
||||
EndBitUnion(X86IntReg)
|
||||
|
||||
enum IntRegIndex
|
||||
{
|
||||
INTREG_RAX,
|
||||
|
|
|
@ -1,303 +0,0 @@
|
|||
// Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use of this software in source and binary forms,
|
||||
// with or without modification, are permitted provided that the
|
||||
// following conditions are met:
|
||||
//
|
||||
// The software must be used only for Non-Commercial Use which means any
|
||||
// use which is NOT directed to receiving any direct monetary
|
||||
// compensation for, or commercial advantage from such use. Illustrative
|
||||
// examples of non-commercial use are academic research, personal study,
|
||||
// teaching, education and corporate research & development.
|
||||
// Illustrative examples of commercial use are distributing products for
|
||||
// commercial advantage and providing services using the software for
|
||||
// commercial advantage.
|
||||
//
|
||||
// If you wish to use this software or functionality therein that may be
|
||||
// covered by patents for commercial use, please contact:
|
||||
// Director of Intellectual Property Licensing
|
||||
// Office of Strategy and Technology
|
||||
// Hewlett-Packard Company
|
||||
// 1501 Page Mill Road
|
||||
// Palo Alto, California 94304
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer. Redistributions
|
||||
// in binary form must reproduce the above copyright notice, this list of
|
||||
// conditions and the following disclaimer in the documentation and/or
|
||||
// other materials provided with the distribution. Neither the name of
|
||||
// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission. No right of
|
||||
// sublicense is granted herewith. Derivatives of the software and
|
||||
// output created using the software may be prepared, but only for
|
||||
// Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
// others provided: (i) the others agree to abide by the list of
|
||||
// conditions herein which includes the Non-Commercial Use restrictions;
|
||||
// and (ii) such Derivatives of the software include the above copyright
|
||||
// notice to acknowledge the contribution from this software where
|
||||
// applicable, this list of conditions and the disclaimer below.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: Gabe Black
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Base class for sparc instructions, and some support functions
|
||||
//
|
||||
|
||||
let {{
|
||||
# This class will help make dealing with output a little less verbose
|
||||
class OutputBlocks(object):
|
||||
def __init__(self, header_output="",
|
||||
decoder_output="",
|
||||
decode_block="",
|
||||
exec_output=""):
|
||||
self.header_output = header_output
|
||||
self.decoder_output = decoder_output
|
||||
self.decode_block = decode_block
|
||||
self.exec_output = exec_output
|
||||
|
||||
def append(self, blocks):
|
||||
if isinstance(blocks, list) or isinstance(blocks, tuple):
|
||||
assert(len(blocks) == 4)
|
||||
self.header_output += blocks[0]
|
||||
self.decoder_output += blocks[1]
|
||||
self.decode_block += blocks[2]
|
||||
self.exec_output += blocks[3]
|
||||
else:
|
||||
self.header_output += blocks.header_output
|
||||
self.decoder_output += blocks.decoder_output
|
||||
self.decode_block += blocks.decode_block
|
||||
self.exec_output += blocks.exec_output
|
||||
|
||||
def makeList(self):
|
||||
return (self.header_output,
|
||||
self.decoder_output,
|
||||
self.decode_block,
|
||||
self.exec_output)
|
||||
}};
|
||||
|
||||
output header {{
|
||||
|
||||
/**
|
||||
* Base class for all X86 static instructions.
|
||||
*/
|
||||
BitUnion64(X86IntReg)
|
||||
Bitfield<63,0> R;
|
||||
Bitfield<31,0> E;
|
||||
Bitfield<15,0> X;
|
||||
Bitfield<15,8> H;
|
||||
Bitfield<7, 0> L;
|
||||
EndBitUnion(X86IntReg)
|
||||
|
||||
class X86StaticInst : public StaticInst
|
||||
{
|
||||
protected:
|
||||
// Constructor.
|
||||
X86StaticInst(const char *mnem,
|
||||
ExtMachInst _machInst, OpClass __opClass)
|
||||
: StaticInst(mnem, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
|
||||
void printReg(std::ostream &os, int reg) const;
|
||||
void printSrcReg(std::ostream &os, int reg) const;
|
||||
void printDestReg(std::ostream &os, int reg) const;
|
||||
|
||||
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
|
||||
{
|
||||
X86IntReg reg;
|
||||
reg = into;
|
||||
//FIXME This needs to be handle high bytes as well
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
reg.L = val;
|
||||
break;
|
||||
case 2:
|
||||
reg.X = val;
|
||||
break;
|
||||
case 4:
|
||||
//XXX Check if this should be zeroed or sign extended
|
||||
reg = 0;
|
||||
reg.E = val;
|
||||
break;
|
||||
case 8:
|
||||
reg.R = val;
|
||||
break;
|
||||
default:
|
||||
panic("Tried to merge with unrecognized size %d.\n", size);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
inline uint64_t pick(uint64_t from, int size)
|
||||
{
|
||||
X86IntReg reg;
|
||||
reg = from;
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
return reg.L;
|
||||
case 2:
|
||||
return reg.E;
|
||||
case 4:
|
||||
return reg.X;
|
||||
case 8:
|
||||
return reg.R;
|
||||
default:
|
||||
panic("Tried to pick with unrecognized size %d.\n", size);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
|
||||
inline void printMnemonic(std::ostream &os, const char * mnemonic)
|
||||
{
|
||||
ccprintf(os, "\t%s ", mnemonic);
|
||||
}
|
||||
|
||||
inline void printMnemonic(std::ostream &os,
|
||||
const char * instMnemonic, const char * mnemonic)
|
||||
{
|
||||
ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
|
||||
}
|
||||
|
||||
void printSegment(std::ostream &os, int segment)
|
||||
{
|
||||
switch (segment)
|
||||
{
|
||||
case 0:
|
||||
ccprintf(os, "ES");
|
||||
break;
|
||||
case 1:
|
||||
ccprintf(os, "CS");
|
||||
break;
|
||||
case 2:
|
||||
ccprintf(os, "SS");
|
||||
break;
|
||||
case 3:
|
||||
ccprintf(os, "DS");
|
||||
break;
|
||||
case 4:
|
||||
ccprintf(os, "FS");
|
||||
break;
|
||||
case 5:
|
||||
ccprintf(os, "GS");
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized segment %d\n", segment);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
X86StaticInst::printSrcReg(std::ostream &os, int reg) const
|
||||
{
|
||||
if(_numSrcRegs > reg)
|
||||
printReg(os, _srcRegIdx[reg]);
|
||||
}
|
||||
|
||||
void
|
||||
X86StaticInst::printDestReg(std::ostream &os, int reg) const
|
||||
{
|
||||
if(_numDestRegs > reg)
|
||||
printReg(os, _destRegIdx[reg]);
|
||||
}
|
||||
|
||||
void
|
||||
X86StaticInst::printReg(std::ostream &os, int reg) const
|
||||
{
|
||||
if (reg < FP_Base_DepTag) {
|
||||
//FIXME These should print differently depending on the
|
||||
//mode etc, but for now this will get the point across
|
||||
switch (reg) {
|
||||
case INTREG_RAX:
|
||||
ccprintf(os, "rax");
|
||||
break;
|
||||
case INTREG_RBX:
|
||||
ccprintf(os, "rbx");
|
||||
break;
|
||||
case INTREG_RCX:
|
||||
ccprintf(os, "rcx");
|
||||
break;
|
||||
case INTREG_RDX:
|
||||
ccprintf(os, "rdx");
|
||||
break;
|
||||
case INTREG_RSP:
|
||||
ccprintf(os, "rsp");
|
||||
break;
|
||||
case INTREG_RBP:
|
||||
ccprintf(os, "rbp");
|
||||
break;
|
||||
case INTREG_RSI:
|
||||
ccprintf(os, "rsi");
|
||||
break;
|
||||
case INTREG_RDI:
|
||||
ccprintf(os, "rdi");
|
||||
break;
|
||||
case INTREG_R8W:
|
||||
ccprintf(os, "r8");
|
||||
break;
|
||||
case INTREG_R9W:
|
||||
ccprintf(os, "r9");
|
||||
break;
|
||||
case INTREG_R10W:
|
||||
ccprintf(os, "r10");
|
||||
break;
|
||||
case INTREG_R11W:
|
||||
ccprintf(os, "r11");
|
||||
break;
|
||||
case INTREG_R12W:
|
||||
ccprintf(os, "r12");
|
||||
break;
|
||||
case INTREG_R13W:
|
||||
ccprintf(os, "r13");
|
||||
break;
|
||||
case INTREG_R14W:
|
||||
ccprintf(os, "r14");
|
||||
break;
|
||||
case INTREG_R15W:
|
||||
ccprintf(os, "r15");
|
||||
break;
|
||||
default:
|
||||
ccprintf(os, "t%d", reg - NUM_INTREGS);
|
||||
}
|
||||
} else if (reg < Ctrl_Base_DepTag) {
|
||||
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
|
||||
} else {
|
||||
switch (reg - Ctrl_Base_DepTag) {
|
||||
default:
|
||||
ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string X86StaticInst::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
printMnemonic(ss, mnemonic);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}};
|
|
@ -67,11 +67,12 @@ def bitfield REX_B rex.b;
|
|||
|
||||
//Legacy prefixes
|
||||
def bitfield LEGACY legacy;
|
||||
def bitfield LEGACY_DECODEVAL legacy.decodeVal;
|
||||
def bitfield LEGACY_REPNE legacy.repne;
|
||||
def bitfield LEGACY_REP legacy.rep;
|
||||
def bitfield LEGACY_LOCK legacy.lock;
|
||||
def bitfield LEGACY_ADDR legacy.addr;
|
||||
def bitfield LEGACY_OP legacy.op;
|
||||
def bitfield LEGACY_ADDR legacy.addr;
|
||||
def bitfield LEGACY_SEG legacy.seg;
|
||||
|
||||
// Pieces of the opcode
|
||||
|
|
|
@ -61,178 +61,130 @@
|
|||
0x1: decode OPCODE_OP_TOP5 {
|
||||
format WarnUnimpl {
|
||||
0x00: decode OPCODE_OP_BOTTOM3 {
|
||||
0x4: ADD();
|
||||
0x5: ADD();
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: push_ES();
|
||||
}
|
||||
0x7: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: pop_ES();
|
||||
}
|
||||
default: ADD();
|
||||
default: MultiInst::ADD(OPCODE_OP_BOTTOM3,
|
||||
[Eb,Gb], [Ev,Gv],
|
||||
[Gb,Eb], [Gv,Ev],
|
||||
[rAl,Ib], [rAx,Iz]);
|
||||
}
|
||||
0x01: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: or_Eb_Gb();
|
||||
0x1: or_Ev_Gv();
|
||||
0x2: or_Gb_Eb();
|
||||
0x3: or_Gv_Ev();
|
||||
0x4: or_Al_Ib();
|
||||
0x5: or_rAX_Iz();
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: push_CS();
|
||||
}
|
||||
//Any time this is seen, it should generate a two byte opcode
|
||||
0x7: M5InternalError::error(
|
||||
{{"Saw a one byte opcode whose value was 0x0F!"}});
|
||||
default: MultiInst::OR(OPCODE_OP_BOTTOM3,
|
||||
[Eb,Gb], [Ev,Gv],
|
||||
[Gb,Eb], [Gv,Ev],
|
||||
[rAl,Ib], [rAx,Iz]);
|
||||
}
|
||||
0x02: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: adc_Eb_Gb();
|
||||
0x1: adc_Ev_Gv();
|
||||
0x2: adc_Gb_Eb();
|
||||
0x3: adc_Gv_Ev();
|
||||
0x4: adc_Al_Ib();
|
||||
0x5: adc_rAX_Iz();
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: push_SS();
|
||||
}
|
||||
0x7: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: pop_SS();
|
||||
}
|
||||
default: MultiInst::ADC(OPCODE_OP_BOTTOM3,
|
||||
[Eb,Gb], [Ev,Gv],
|
||||
[Gb,Eb], [Gv,Ev],
|
||||
[rAl,Ib], [rAx,Iz]);
|
||||
}
|
||||
0x03: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: sbb_Eb_Gb();
|
||||
0x1: sbb_Ev_Gv();
|
||||
0x2: sbb_Gb_Eb();
|
||||
0x3: sbb_Gv_Ev();
|
||||
0x4: sbb_Al_Ib();
|
||||
0x5: sbb_rAX_Iz();
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: push_DS();
|
||||
}
|
||||
0x7: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: pop_DS();
|
||||
}
|
||||
default: MultiInst::SBB(OPCODE_OP_BOTTOM3,
|
||||
[Eb,Gb], [Ev,Gv],
|
||||
[Gb,Eb], [Gv,Ev],
|
||||
[rAl,Ib], [rAx,Iz]);
|
||||
}
|
||||
0x04: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: and_Eb_Gb();
|
||||
0x1: and_Ev_Gv();
|
||||
0x2: and_Gb_Eb();
|
||||
0x3: and_Gv_Ev();
|
||||
0x4: and_Al_Ib();
|
||||
0x5: and_rAX_Iz();
|
||||
0x6: M5InternalError::error(
|
||||
{{"Tried to execute the ES segment override prefix!"}});
|
||||
0x7: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: daa();
|
||||
}
|
||||
default: MultiInst::AND(OPCODE_OP_BOTTOM3,
|
||||
[Eb,Gb], [Ev,Gv],
|
||||
[Gb,Eb], [Gv,Ev],
|
||||
[rAl,Ib], [rAx,Iz]);
|
||||
}
|
||||
0x05: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: sub_Eb_Gb();
|
||||
0x1: sub_Ev_Gv();
|
||||
0x2: sub_Gb_Eb();
|
||||
0x3: sub_Gv_Ev();
|
||||
0x4: sub_Al_Ib();
|
||||
0x5: sub_rAX_Iz();
|
||||
0x6: M5InternalError::error(
|
||||
{{"Tried to execute the CS segment override prefix!"}});
|
||||
0x7: das();
|
||||
default: MultiInst::SUB(OPCODE_OP_BOTTOM3,
|
||||
[Eb,Gb], [Ev,Gv],
|
||||
[Gb,Eb], [Gv,Ev],
|
||||
[rAl,Ib], [rAx,Iz]);
|
||||
}
|
||||
0x06: decode OPCODE_OP_BOTTOM3 {
|
||||
0x4: Inst::XOR(rAl,Ib);
|
||||
0x5: Inst::XOR(rAx,Iz);
|
||||
0x6: M5InternalError::error(
|
||||
{{"Tried to execute the SS segment override prefix!"}});
|
||||
0x7: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: aaa();
|
||||
}
|
||||
default: MultiInst::XOR(OPCODE_OP_BOTTOM3,
|
||||
[Eb,Gb], [Ev,Gv],
|
||||
[Gb,Eb], [Gv,Ev]);
|
||||
[Gb,Eb], [Gv,Ev],
|
||||
[rAl,Ib], [rAx,Iz]);
|
||||
}
|
||||
0x07: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: cmp_Eb_Gb();
|
||||
0x1: cmp_Ev_Gv();
|
||||
0x2: cmp_Gb_Eb();
|
||||
0x3: cmp_Gv_Ev();
|
||||
0x4: cmp_Al_Ib();
|
||||
0x5: cmp_rAX_Iz();
|
||||
0x6: M5InternalError::error(
|
||||
{{"Tried to execute the DS segment override prefix!"}});
|
||||
0x7: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: aas();
|
||||
}
|
||||
default: MultiInst::CMP(OPCODE_OP_BOTTOM3,
|
||||
[Eb,Gb], [Ev,Gv],
|
||||
[Gb,Eb], [Gv,Ev],
|
||||
[rAl,Ib], [rAx,Iz]);
|
||||
}
|
||||
0x08: decode MODE_SUBMODE {
|
||||
0x0: M5InternalError::error (
|
||||
{{"Tried to execute an REX prefix!"}});
|
||||
default: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: inc_eAX();
|
||||
0x1: inc_eCX();
|
||||
0x2: inc_eDX();
|
||||
0x3: inc_eBX();
|
||||
0x4: inc_eSP();
|
||||
0x5: inc_eBP();
|
||||
0x6: inc_eSI();
|
||||
0x7: inc_eDI();
|
||||
}
|
||||
default: Inst::INC(B);
|
||||
}
|
||||
0x09: decode MODE_SUBMODE {
|
||||
0x0: M5InternalError::error (
|
||||
{{"Tried to execute an REX prefix!"}});
|
||||
default: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: dec_eAX();
|
||||
0x1: dec_eCX();
|
||||
0x2: dec_eDX();
|
||||
0x3: dec_eBX();
|
||||
0x4: dec_eSP();
|
||||
0x5: dec_eBP();
|
||||
0x6: dec_eSI();
|
||||
0x7: dec_eDI();
|
||||
}
|
||||
default: Inst::DEC(B);
|
||||
}
|
||||
format Inst {
|
||||
0x0A: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: PUSH(rAx);
|
||||
0x1: PUSH(rCx);
|
||||
0x2: PUSH(rDx);
|
||||
0x3: PUSH(rBx);
|
||||
0x4: PUSH(rSP);
|
||||
0x5: PUSH(rBP);
|
||||
0x6: PUSH(rSI);
|
||||
0x7: PUSH(rDI);
|
||||
}
|
||||
0x0B: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: POP(rAx);
|
||||
0x1: POP(rCx);
|
||||
0x2: POP(rDx);
|
||||
0x3: POP(rBx);
|
||||
0x4: POP(rSP);
|
||||
0x5: POP(rBP);
|
||||
0x6: POP(rSI);
|
||||
0x7: POP(rDI);
|
||||
}
|
||||
0x0A: PUSH(B);
|
||||
0x0B: POP(B);
|
||||
}
|
||||
0x0C: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: pusha();
|
||||
}
|
||||
0x1: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: popa();
|
||||
}
|
||||
0x2: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: bound_Gv_Ma();
|
||||
}
|
||||
0x3: decode MODE_SUBMODE {
|
||||
|
@ -258,58 +210,82 @@
|
|||
0x6: outs_Dx_Xb();
|
||||
0x7: outs_Dx_Xz();
|
||||
}
|
||||
format Inst {
|
||||
0x0E: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: jo_Jb();
|
||||
0x1: jno_Jb();
|
||||
0x2: jb_Jb();
|
||||
0x3: jnb_Jb();
|
||||
0x4: jz_Jb();
|
||||
0x5: jnz_Jb();
|
||||
0x6: jbe_Jb();
|
||||
0x7: jnbe_Jb();
|
||||
0x0: JO(Jb);
|
||||
0x1: JNO(Jb);
|
||||
0x2: JB(Jb);
|
||||
0x3: JNB(Jb);
|
||||
0x4: JZ(Jb);
|
||||
0x5: JNZ(Jb);
|
||||
0x6: JBE(Jb);
|
||||
0x7: JNBE(Jb);
|
||||
}
|
||||
0x0F: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: js_Jb();
|
||||
0x1: jns_Jb();
|
||||
0x2: jp_Jb();
|
||||
0x3: jnp_Jb();
|
||||
0x4: jl_Jb();
|
||||
0x5: jnl_Jb();
|
||||
0x6: jle_Jb();
|
||||
0x7: jnke_Jb();
|
||||
0x0: JS(Jb);
|
||||
0x1: JNS(Jb);
|
||||
0x2: JP(Jb);
|
||||
0x3: JNP(Jb);
|
||||
0x4: JL(Jb);
|
||||
0x5: JNL(Jb);
|
||||
0x6: JLE(Jb);
|
||||
0x7: JNLE(Jb);
|
||||
}
|
||||
}
|
||||
format Inst {
|
||||
0x10: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: group1_Eb_Ib();
|
||||
//0x0: group1_Eb_Ib();
|
||||
0x0: decode MODRM_REG {
|
||||
0x0: ADD(Eb,Ib);
|
||||
0x1: OR(Eb,Ib);
|
||||
0x2: ADC(Eb,Ib);
|
||||
0x3: SBB(Eb,Ib);
|
||||
0x4: AND(Eb,Ib);
|
||||
0x5: SUB(Eb,Ib);
|
||||
0x6: XOR(Eb,Ib);
|
||||
0x7: CMP(Eb,Ib);
|
||||
}
|
||||
//0x1: group1_Ev_Iz();
|
||||
0x1: decode MODRM_REG {
|
||||
0x0: add_Ev_Iz();
|
||||
0x1: or_Ev_Ibz();
|
||||
0x2: adc_Ev_Iz();
|
||||
0x3: sbb_Ev_Iz();
|
||||
0x4: Inst::AND(Ev,Iz);
|
||||
0x5: Inst::SUB(Ev,Iz);
|
||||
0x6: xor_Ev_Iz();
|
||||
0x7: cmp_Ev_Iz();
|
||||
0x0: ADD(Ev,Iz);
|
||||
0x1: OR(Ev,Iz);
|
||||
0x2: ADC(Ev,Iz);
|
||||
0x3: SBB(Ev,Iz);
|
||||
0x4: AND(Ev,Iz);
|
||||
0x5: SUB(Ev,Iz);
|
||||
0x6: XOR(Ev,Iz);
|
||||
0x7: CMP(Ev,Iz);
|
||||
}
|
||||
0x2: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
default: group1_Eb_Ib();
|
||||
0x0: UD2();
|
||||
//default: group1_Eb_Ib();
|
||||
default: decode MODRM_REG {
|
||||
0x0: ADD(Eb,Ib);
|
||||
0x1: OR(Eb,Ib);
|
||||
0x2: ADC(Eb,Ib);
|
||||
0x3: SBB(Eb,Ib);
|
||||
0x4: AND(Eb,Ib);
|
||||
0x5: SUB(Eb,Ib);
|
||||
0x6: XOR(Eb,Ib);
|
||||
0x7: CMP(Eb,Ib);
|
||||
}
|
||||
}
|
||||
//0x3: group1_Ev_Ib();
|
||||
0x3: decode MODRM_REG {
|
||||
0x0: add_Eb_Ib();
|
||||
0x1: or_Eb_Ib();
|
||||
0x2: adc_Eb_Ib();
|
||||
0x3: sbb_Eb_Ib();
|
||||
0x4: Inst::AND(Eb,Ib);
|
||||
0x5: sub_Eb_Ib();
|
||||
0x6: xor_Eb_Ib();
|
||||
0x7: cmp_Eb_Ib();
|
||||
0x0: ADD(Ev,Ib);
|
||||
0x1: OR(Ev,Ib);
|
||||
0x2: ADC(Ev,Ib);
|
||||
0x3: SBB(Ev,Ib);
|
||||
0x4: AND(Ev,Ib);
|
||||
0x5: SUB(Ev,Ib);
|
||||
0x6: XOR(Ev,Ib);
|
||||
0x7: CMP(Ev,Ib);
|
||||
}
|
||||
0x4: TEST(Eb,Gb);
|
||||
0x5: TEST(Ev,Gv);
|
||||
0x6: XCHG(Eb,Gb);
|
||||
0x7: XCHG(Ev,Gv);
|
||||
}
|
||||
0x4: Inst::TEST(Eb,Gb);
|
||||
0x5: Inst::TEST(Ev,Gv);
|
||||
0x6: xchg_Eb_Gb();
|
||||
0x7: xchg_Ev_Gv();
|
||||
}
|
||||
0x11: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: Inst::MOV(Eb,Gb);
|
||||
|
@ -322,21 +298,15 @@
|
|||
0x7: group10_Ev(); //Make sure this is Ev
|
||||
}
|
||||
0x12: decode OPCODE_OP_BOTTOM3 {
|
||||
default: nop_or_pause(); //Check for repe prefix
|
||||
0x1: xchg_rCX_rAX();
|
||||
0x2: xchg_rDX_rAX();
|
||||
0x3: xchg_rVX_rAX();
|
||||
0x4: xchg_rSP_rAX();
|
||||
0x5: xchg_rBP_rAX();
|
||||
0x6: xchg_rSI_rAX();
|
||||
0x7: xchg_rDI_rAX();
|
||||
0x0: Inst::NOP(); //XXX repe makes this a "pause"
|
||||
default: xchg_B_rAX();
|
||||
}
|
||||
0x13: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: cbw_or_cwde_or_cdqe_rAX();
|
||||
0x1: cwd_or_cdq_or_cqo_rAX_rDX();
|
||||
0x2: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
default: call_Ap();
|
||||
0x0: Inst::UD2();
|
||||
default: call_far_Ap();
|
||||
}
|
||||
0x3: fwait(); //aka wait
|
||||
0x4: pushf_Fv();
|
||||
|
@ -344,11 +314,11 @@
|
|||
//Both of these should be illegal only if CPUID.AHF64=0,
|
||||
//according to sandpile.org
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: sahf();
|
||||
}
|
||||
0x7: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: lahf();
|
||||
}
|
||||
}
|
||||
|
@ -372,48 +342,52 @@
|
|||
0x6: scas_Yb_Al();
|
||||
0x7: scas_Yv_rAX();
|
||||
}
|
||||
0x16: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: mov_Al_Ib();
|
||||
0x1: mov_Cl_Ib();
|
||||
0x2: mov_Dl_Ib();
|
||||
0x3: mov_Bl_Ib();
|
||||
0x4: mov_Ah_Ib();
|
||||
0x5: mov_Ch_Ib();
|
||||
0x6: mov_Dh_Ib();
|
||||
0x7: mov_Bh_Ib();
|
||||
}
|
||||
format Inst {
|
||||
0x17: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: MOV(rAX,Iv);
|
||||
0x1: MOV(rCX,Iv);
|
||||
0x2: MOV(rDX,Iv);
|
||||
0x3: MOV(rBX,Iv);
|
||||
0x4: MOV(rSP,Iv);
|
||||
0x5: MOV(rBP,Iv);
|
||||
0x6: MOV(rSI,Iv);
|
||||
0x7: MOV(rDI,Iv);
|
||||
}
|
||||
}
|
||||
0x16: MOV(B,Ib);
|
||||
0x17: MOV(B,Iv);
|
||||
0x18: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: group2_Eb_Ib();
|
||||
0x1: group2_Ev_Ib();
|
||||
0x2: ret_near_Iw();
|
||||
0x3: ret_near();
|
||||
//0x0: group2_Eb_Ib();
|
||||
0x0: decode MODRM_REG {
|
||||
0x0: ROL(Eb,Ib);
|
||||
0x1: ROR(Eb,Ib);
|
||||
0x2: RCL(Eb,Ib);
|
||||
0x3: RCR(Eb,Ib);
|
||||
0x4: SAL(Eb,Ib);
|
||||
0x5: SHR(Eb,Ib);
|
||||
0x6: SAL(Eb,Ib);
|
||||
0x7: SAR(Eb,Ib);
|
||||
}
|
||||
//0x1: group2_Ev_Ib();
|
||||
0x1: decode MODRM_REG {
|
||||
0x0: ROL(Ev,Ib);
|
||||
0x1: ROR(Ev,Ib);
|
||||
0x2: RCL(Ev,Ib);
|
||||
0x3: RCR(Ev,Ib);
|
||||
0x4: SAL(Ev,Ib);
|
||||
0x5: SHR(Ev,Ib);
|
||||
0x6: SAL(Ev,Ib);
|
||||
0x7: SAR(Ev,Ib);
|
||||
}
|
||||
0x2: RET_NEAR(Iw);
|
||||
0x3: RET_NEAR();
|
||||
0x4: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
default: les_Gz_Mp();
|
||||
0x0: UD2();
|
||||
default: WarnUnimpl::les_Gz_Mp();
|
||||
}
|
||||
0x5: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
default: lds_Gz_Mp();
|
||||
0x0: UD2();
|
||||
default: WarnUnimpl::lds_Gz_Mp();
|
||||
}
|
||||
//0x6: group12_Eb_Ib();
|
||||
0x6: decode MODRM_REG {
|
||||
0x0: Inst::MOV(Eb,Ib);
|
||||
0x0: MOV(Eb,Ib);
|
||||
default: UD2();
|
||||
}
|
||||
//0x7: group12_Ev_Iz();
|
||||
0x7: decode MODRM_REG {
|
||||
0x0: Inst::MOV(Ev,Iz);
|
||||
0x0: MOV(Ev,Iz);
|
||||
default: UD2();
|
||||
}
|
||||
}
|
||||
}
|
||||
0x19: decode OPCODE_OP_BOTTOM3 {
|
||||
|
@ -424,7 +398,7 @@
|
|||
0x4: int3();
|
||||
0x5: int_Ib();
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: into();
|
||||
}
|
||||
0x7: iret();
|
||||
|
@ -435,15 +409,15 @@
|
|||
0x2: group2_Eb_Cl();
|
||||
0x3: group2_Ev_Cl();
|
||||
0x4: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: aam_Ib();
|
||||
}
|
||||
0x5: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: aad_Ib();
|
||||
}
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
0x0: Inst::UD2();
|
||||
default: salc();
|
||||
}
|
||||
0x7: xlat();
|
||||
|
@ -469,13 +443,13 @@
|
|||
0x7: out_Ib_eAX();
|
||||
}
|
||||
0x1D: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: Inst::CALL(Jz);
|
||||
0x1: jmp_Jz();
|
||||
0x0: Inst::CALL_NEAR(Jz);
|
||||
0x1: Inst::JMP(Jz);
|
||||
0x2: decode MODE_SUBMODE {
|
||||
0x0: This_should_be_an_illegal_instruction();
|
||||
default: jmp_Ap();
|
||||
0x0: Inst::UD2();
|
||||
default: jmp_far_Ap();
|
||||
}
|
||||
0x3: jmp_Jb();
|
||||
0x3: Inst::JMP(Jb);
|
||||
0x4: in_Al_Dx();
|
||||
0x5: in_eAX_Dx();
|
||||
0x6: out_Dx_Al();
|
||||
|
@ -501,8 +475,25 @@
|
|||
0x3: sti();
|
||||
0x4: cld();
|
||||
0x5: std();
|
||||
0x6: group4();
|
||||
0x7: group5();
|
||||
format Inst {
|
||||
//0x6: group4();
|
||||
0x6: decode MODRM_REG {
|
||||
0x0: INC(Eb);
|
||||
0x1: DEC(Eb);
|
||||
default: UD2();
|
||||
}
|
||||
//0x7: group5();
|
||||
0x7: decode MODRM_REG {
|
||||
0x0: INC(Ev);
|
||||
0x1: DEC(Ev);
|
||||
0x2: CALL_NEAR(Ev);
|
||||
0x3: WarnUnimpl::call_far_Mp();
|
||||
0x4: JMP(Ev);
|
||||
0x5: WarnUnimpl::jmp_far_Mp();
|
||||
0x6: PUSH(Ev);
|
||||
0x7: UD2();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default: FailUnimpl::oneByteOps();
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
// Decode the two byte opcodes
|
||||
//
|
||||
0x2: decode OPCODE_PREFIXA {
|
||||
0xF0: decode OPCODE_OP_TOP5 {
|
||||
0x0F: decode OPCODE_OP_TOP5 {
|
||||
format WarnUnimpl {
|
||||
0x00: decode OPCODE_OP_BOTTOM3 {
|
||||
0x00: group6();
|
||||
|
@ -67,23 +67,25 @@
|
|||
0x03: lsl_Gv_Ew();
|
||||
//sandpile.org doesn't seem to know what this is... ?
|
||||
0x04: loadall_or_reset_or_hang();
|
||||
//sandpile.org says (AMD) after syscall, so I might want to check
|
||||
//if that means amd64 or AMD machines
|
||||
0x05: loadall_or_syscall();
|
||||
#if FULL_SYSTEM
|
||||
0x05: syscall();
|
||||
#else
|
||||
0x05: SyscallInst::syscall('xc->syscall(rax)');
|
||||
#endif
|
||||
0x06: clts();
|
||||
//sandpile.org says (AMD) after sysret, so I might want to check
|
||||
//if that means amd64 or AMD machines
|
||||
0x07: loadall_or_sysret();
|
||||
}
|
||||
0x01: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holderholder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: invd();
|
||||
0x1: wbinvd();
|
||||
0x2: Inst::UD2();
|
||||
0x3: UD2();
|
||||
0x4: Inst::UD2();
|
||||
0x5: threednow();
|
||||
0x6: threednow();
|
||||
0x7: threednow();
|
||||
}
|
||||
0x02: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
|
@ -96,14 +98,14 @@
|
|||
0x7: holder();
|
||||
}
|
||||
0x03: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: group17();
|
||||
0x1: group17();
|
||||
0x2: group17();
|
||||
0x3: group17();
|
||||
0x4: group17();
|
||||
0x5: group17();
|
||||
0x6: group17();
|
||||
0x7: group17();
|
||||
}
|
||||
0x04: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
|
@ -126,44 +128,44 @@
|
|||
0x7: holder();
|
||||
}
|
||||
0x06: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: wrmsr();
|
||||
0x1: rdtsc();
|
||||
0x2: rdmsr();
|
||||
0x3: rdpmc();
|
||||
0x4: sysenter();
|
||||
0x5: sysexit();
|
||||
0x6: Inst::UD2();
|
||||
0x7: getsec();
|
||||
}
|
||||
0x07: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: three_byte_opcode();
|
||||
0x1: three_byte_opcode();
|
||||
0x2: three_byte_opcode();
|
||||
0x3: three_byte_opcode();
|
||||
0x4: three_byte_opcode();
|
||||
0x5: three_byte_opcode();
|
||||
0x6: three_byte_opcode();
|
||||
0x7: three_byte_opcode();
|
||||
}
|
||||
0x08: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: cmovo_Gv_Ev();
|
||||
0x1: cmovno_Gv_Ev();
|
||||
0x2: cmovb_Gv_Ev();
|
||||
0x3: cmovnb_Gv_Ev();
|
||||
0x4: cmovz_Gv_Ev();
|
||||
0x5: cmovnz_Gv_Ev();
|
||||
0x6: cmovbe_Gv_Ev();
|
||||
0x7: cmovnbe_Gv_Ev();
|
||||
}
|
||||
0x09: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: cmovs_Gv_Ev();
|
||||
0x1: cmovns_Gv_Ev();
|
||||
0x2: cmovp_Gv_Ev();
|
||||
0x3: cmovnp_Gv_Ev();
|
||||
0x4: cmovl_Gv_Ev();
|
||||
0x5: cmovnl_Gv_Ev();
|
||||
0x6: cmovle_Gv_Ev();
|
||||
0x7: cmovnle_Gv_Ev();
|
||||
}
|
||||
0x0A: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
|
@ -225,85 +227,87 @@
|
|||
0x6: holder();
|
||||
0x7: holder();
|
||||
}
|
||||
format Inst {
|
||||
0x10: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: JO(Jz);
|
||||
0x1: JNO(Jz);
|
||||
0x2: JB(Jz);
|
||||
0x3: JNB(Jz);
|
||||
0x4: JZ(Jz);
|
||||
0x5: JNZ(Jz);
|
||||
0x6: JBE(Jz);
|
||||
0x7: JNBE(Jz);
|
||||
}
|
||||
0x11: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: JS(Jz);
|
||||
0x1: JNS(Jz);
|
||||
0x2: JP(Jz);
|
||||
0x3: JNP(Jz);
|
||||
0x4: JL(Jz);
|
||||
0x5: JNL(Jz);
|
||||
0x6: JLE(Jz);
|
||||
0x7: JNLE(Jz);
|
||||
}
|
||||
}
|
||||
0x12: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: seto_Eb();
|
||||
0x1: setno_Eb();
|
||||
0x2: setb_Eb();
|
||||
0x3: setnb_Eb();
|
||||
0x4: setz_Eb();
|
||||
0x5: setnz_Eb();
|
||||
0x6: setbe_Eb();
|
||||
0x7: setnbe_Eb();
|
||||
}
|
||||
0x13: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: sets_Eb();
|
||||
0x1: setns_Eb();
|
||||
0x2: setp_Eb();
|
||||
0x3: setnp_Eb();
|
||||
0x4: setl_Eb();
|
||||
0x5: setnl_Eb();
|
||||
0x6: setle_Eb();
|
||||
0x7: setnle_Eb();
|
||||
}
|
||||
0x14: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: push_fs();
|
||||
0x1: pop_fs();
|
||||
0x2: cpuid();
|
||||
0x3: bt_Ev_Gv();
|
||||
0x4: shld_Ev_Gv_Ib();
|
||||
0x5: shld_Ev_Gv_rCl();
|
||||
0x6: xbts_and_cmpxchg();
|
||||
0x7: ibts_and_cmpxchg();
|
||||
}
|
||||
0x15: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: push_gs();
|
||||
0x1: pop_gs();
|
||||
0x2: rsm_smm();
|
||||
0x3: bts_Ev_Gv();
|
||||
0x4: shrd_Ev_Gv_Ib();
|
||||
0x5: shrd_Ev_Gv_rCl();
|
||||
0x6: group16();
|
||||
0x7: Inst::IMUL(Gv,Ev);
|
||||
}
|
||||
0x16: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: cmpxchg_Eb_Gb();
|
||||
0x1: cmpxchg_Ev_Gv();
|
||||
0x2: lss_Gz_Mp();
|
||||
0x3: btr_Ev_Gv();
|
||||
0x4: lfs_Gz_Mp();
|
||||
0x5: lgs_Gz_Mp();
|
||||
0x6: Inst::MOVZX_B(Gv,Eb);
|
||||
0x7: Inst::MOVZX_W(Gv,Ew);
|
||||
}
|
||||
0x17: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
0x0: jmpe_Jz(); // IA-64?
|
||||
0x1: group11_UD2();
|
||||
0x2: group8_Ev_Ib();
|
||||
0x3: btc_Ev_Gv();
|
||||
0x4: bsf_Gv_Ev();
|
||||
0x5: bsr_Gv_Ev();
|
||||
0x6: Inst::MOVSX_B(Gv,Eb);
|
||||
0x7: Inst::MOVSX_W(Gv,Ew);
|
||||
}
|
||||
0x18: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
|
@ -315,16 +319,7 @@
|
|||
0x6: holder();
|
||||
0x7: holder();
|
||||
}
|
||||
0x19: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
0x2: holder();
|
||||
0x3: holder();
|
||||
0x4: holder();
|
||||
0x5: holder();
|
||||
0x6: holder();
|
||||
0x7: holder();
|
||||
}
|
||||
0x19: bswap_B();
|
||||
0x1A: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: holder();
|
||||
0x1: holder();
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
|
||||
def template ErrorDecode {{
|
||||
{
|
||||
panic("X86 decoder internal error: '%%s' %%s",
|
||||
panic("X86 decoder internal error: '%s' %s",
|
||||
%(message)s, machInst);
|
||||
}
|
||||
}};
|
||||
|
|
|
@ -98,3 +98,7 @@
|
|||
//Include a format which implements a batch of instructions which do the same
|
||||
//thing on a variety of inputs
|
||||
##include "multi.isa"
|
||||
|
||||
//Include a format which makes instructions who's sole purpose is to generate
|
||||
//a syscall.
|
||||
##include "syscall.isa"
|
||||
|
|
112
src/arch/x86/isa/formats/syscall.isa
Normal file
112
src/arch/x86/isa/formats/syscall.isa
Normal file
|
@ -0,0 +1,112 @@
|
|||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use of this software in source and binary forms,
|
||||
// with or without modification, are permitted provided that the
|
||||
// following conditions are met:
|
||||
//
|
||||
// The software must be used only for Non-Commercial Use which means any
|
||||
// use which is NOT directed to receiving any direct monetary
|
||||
// compensation for, or commercial advantage from such use. Illustrative
|
||||
// examples of non-commercial use are academic research, personal study,
|
||||
// teaching, education and corporate research & development.
|
||||
// Illustrative examples of commercial use are distributing products for
|
||||
// commercial advantage and providing services using the software for
|
||||
// commercial advantage.
|
||||
//
|
||||
// If you wish to use this software or functionality therein that may be
|
||||
// covered by patents for commercial use, please contact:
|
||||
// Director of Intellectual Property Licensing
|
||||
// Office of Strategy and Technology
|
||||
// Hewlett-Packard Company
|
||||
// 1501 Page Mill Road
|
||||
// Palo Alto, California 94304
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer. Redistributions
|
||||
// in binary form must reproduce the above copyright notice, this list of
|
||||
// conditions and the following disclaimer in the documentation and/or
|
||||
// other materials provided with the distribution. Neither the name of
|
||||
// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission. No right of
|
||||
// sublicense is granted herewith. Derivatives of the software and
|
||||
// output created using the software may be prepared, but only for
|
||||
// Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
// others provided: (i) the others agree to abide by the list of
|
||||
// conditions herein which includes the Non-Commercial Use restrictions;
|
||||
// and (ii) such Derivatives of the software include the above copyright
|
||||
// notice to acknowledge the contribution from this software where
|
||||
// applicable, this list of conditions and the disclaimer below.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: Gabe Black
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// "Format" which describes an instruction whose only purpose is to
|
||||
// call a syscall in SE mode.
|
||||
//
|
||||
|
||||
output header {{
|
||||
class SyscallInst : public X86ISA::X86StaticInst
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
SyscallInst(const char *_mnemonic, ExtMachInst _machInst,
|
||||
OpClass __opClass) :
|
||||
X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string SyscallInst::generateDisassembly(Addr PC,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, mnemonic);
|
||||
ccprintf(response, " ");
|
||||
printReg(response, _srcRegIdx[0], machInst.opSize);
|
||||
return response.str();
|
||||
}
|
||||
}};
|
||||
|
||||
def template SyscallExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(code)s;
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
def format SyscallInst(code, *opt_flags) {{
|
||||
iop = InstObjParams(name, Name, 'SyscallInst', code, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = SyscallExecute.subst(iop)
|
||||
}};
|
||||
|
|
@ -68,12 +68,12 @@ output header {{
|
|||
* 'Unknown' class is used for unrecognized/illegal instructions.
|
||||
* This is a leaf class.
|
||||
*/
|
||||
class FailUnimplemented : public X86StaticInst
|
||||
class FailUnimplemented : public X86ISA::X86StaticInst
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
|
||||
: X86StaticInst(_mnemonic, _machInst, No_OpClass)
|
||||
: X86ISA::X86StaticInst(_mnemonic, _machInst, No_OpClass)
|
||||
{
|
||||
// don't call execute() (which panics) if we're on a
|
||||
// speculative path
|
||||
|
@ -95,7 +95,7 @@ output header {{
|
|||
* probably make the 'warned' flag a static member of the derived
|
||||
* class.
|
||||
*/
|
||||
class WarnUnimplemented : public X86StaticInst
|
||||
class WarnUnimplemented : public X86ISA::X86StaticInst
|
||||
{
|
||||
private:
|
||||
/// Have we warned on this instruction yet?
|
||||
|
@ -104,7 +104,7 @@ output header {{
|
|||
public:
|
||||
/// Constructor
|
||||
WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
|
||||
: X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
|
||||
: X86ISA::X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
|
||||
{
|
||||
// don't call execute() (which panics) if we're on a
|
||||
// speculative path
|
||||
|
|
|
@ -97,6 +97,9 @@ output header {{
|
|||
#include <iostream>
|
||||
|
||||
#include "arch/x86/emulenv.hh"
|
||||
#include "arch/x86/insts/microldstop.hh"
|
||||
#include "arch/x86/insts/microregop.hh"
|
||||
#include "arch/x86/insts/static_inst.hh"
|
||||
#include "arch/x86/isa_traits.hh"
|
||||
#include "arch/x86/regfile.hh"
|
||||
#include "arch/x86/types.hh"
|
||||
|
@ -108,6 +111,7 @@ output header {{
|
|||
|
||||
output decoder {{
|
||||
#include "arch/x86/faults.hh"
|
||||
#include "arch/x86/miscregs.hh"
|
||||
#include "arch/x86/segmentregs.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
|
|
|
@ -69,7 +69,8 @@ categories = ["arithmetic",
|
|||
"rotate_and_shift",
|
||||
"semaphores",
|
||||
"string",
|
||||
"system_calls"]
|
||||
"system_calls",
|
||||
"system"]
|
||||
|
||||
microcode = '''
|
||||
# X86 microcode
|
||||
|
|
|
@ -54,23 +54,227 @@
|
|||
# Authors: Gabe Black
|
||||
|
||||
microcode = '''
|
||||
def macroop ADD_R_R
|
||||
{
|
||||
add reg, reg, regm
|
||||
};
|
||||
|
||||
def macroop ADD_R_I
|
||||
{
|
||||
limm t1, imm
|
||||
add reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop ADD_M_I
|
||||
{
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
add t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADD_P_I
|
||||
{
|
||||
rdip t7
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
add t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADD_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
add t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADD_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
add t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADD_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
add reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop ADD_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
add reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop SUB_R_R
|
||||
{
|
||||
sub reg, reg, regm
|
||||
};
|
||||
|
||||
def macroop SUB_R_I
|
||||
{
|
||||
subi reg, reg, imm
|
||||
limm t1, imm
|
||||
sub reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop SUB_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sub reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop SUB_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sub reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop SUB_M_I
|
||||
{
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
subi t1, t1, imm
|
||||
sub t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SUB_P_I
|
||||
{
|
||||
rdip t7
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
subi t1, t1, imm
|
||||
sub t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SUB_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sub t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SUB_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sub t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADC_R_R
|
||||
{
|
||||
adc reg, reg, regm
|
||||
};
|
||||
|
||||
def macroop ADC_R_I
|
||||
{
|
||||
limm t1, imm
|
||||
adc reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop ADC_M_I
|
||||
{
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
adc t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADC_P_I
|
||||
{
|
||||
rdip t7
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
adc t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADC_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
adc t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADC_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
adc t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ADC_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
adc reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop ADC_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
adc reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop SBB_R_R
|
||||
{
|
||||
sbb reg, reg, regm
|
||||
};
|
||||
|
||||
def macroop SBB_R_I
|
||||
{
|
||||
limm t1, imm
|
||||
sbb reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop SBB_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sbb reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop SBB_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sbb reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop SBB_M_I
|
||||
{
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sbb t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SBB_P_I
|
||||
{
|
||||
rdip t7
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sbb t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SBB_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sbb t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SBB_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sbb t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
'''
|
||||
|
|
|
@ -53,7 +53,47 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
microcode = '''
|
||||
def macroop INC_R
|
||||
{
|
||||
addi reg, reg, 1, flags=(OF, SF, ZF, AF, PF)
|
||||
};
|
||||
|
||||
def macroop INC_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
addi t1, t1, 1, flags=(OF, SF, ZF, AF, PF)
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop INC_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
addi reg, reg, 1, flags=(OF, SF, ZF, AF, PF)
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop DEC_R
|
||||
{
|
||||
subi reg, reg, 1, flags=(OF, SF, ZF, AF, PF)
|
||||
};
|
||||
|
||||
def macroop DEC_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
subi t1, t1, 1, flags=(OF, SF, ZF, AF, PF)
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop DEC_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
subi reg, reg, 1, flags=(OF, SF, ZF, AF, PF)
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class DEC(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
|
|
|
@ -53,7 +53,31 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
microcode = '''
|
||||
|
||||
#
|
||||
# Two operand signed multiply. These should set the CF and OF flags if the
|
||||
# result is too large for the destination register
|
||||
#
|
||||
|
||||
def macroop IMUL_R_R
|
||||
{
|
||||
mul1s reg, reg, regm
|
||||
};
|
||||
|
||||
def macroop IMUL_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
mul1s reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop IMUL_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
mul1s reg, reg, t1
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class MUL(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
|
|
|
@ -53,8 +53,56 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
#let {{
|
||||
# class CMP(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
#}};
|
||||
microcode = '''
|
||||
def macroop CMP_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF)
|
||||
};
|
||||
|
||||
def macroop CMP_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF)
|
||||
};
|
||||
|
||||
def macroop CMP_M_I
|
||||
{
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF)
|
||||
};
|
||||
|
||||
def macroop CMP_P_I
|
||||
{
|
||||
limm t2, imm
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF)
|
||||
};
|
||||
|
||||
def macroop CMP_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sub t0, t1, reg, flags=(OF, SF, ZF, AF, PF, CF)
|
||||
};
|
||||
|
||||
def macroop CMP_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
sub t0, t1, reg, flags=(OF, SF, ZF, AF, PF, CF)
|
||||
};
|
||||
|
||||
def macroop CMP_R_R
|
||||
{
|
||||
sub t0, reg, regm, flags=(OF, SF, ZF, AF, PF, CF)
|
||||
};
|
||||
|
||||
def macroop CMP_R_I
|
||||
{
|
||||
limm t1, imm
|
||||
sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF)
|
||||
};
|
||||
'''
|
||||
|
|
|
@ -57,39 +57,39 @@ microcode = '''
|
|||
def macroop TEST_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
and t0, t1, reg
|
||||
and t0, t1, reg, flags=(SF, ZF, PF)
|
||||
};
|
||||
|
||||
def macroop TEST_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
and t0, t1, reg
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
and t0, t1, reg, flags=(SF, ZF, PF)
|
||||
};
|
||||
|
||||
def macroop TEST_R_R
|
||||
{
|
||||
and t0, reg, regm
|
||||
and t0, reg, regm, flags=(SF, ZF, PF)
|
||||
};
|
||||
|
||||
def macroop TEST_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
limm t2, imm
|
||||
and t0, t1, t2
|
||||
and t0, t1, t2, flags=(SF, ZF, PF)
|
||||
};
|
||||
|
||||
def macroop TEST_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
limm t2, imm
|
||||
and t0, t1, t2
|
||||
and t0, t1, t2, flags=(SF, ZF, PF)
|
||||
};
|
||||
|
||||
def macroop TEST_R_I
|
||||
{
|
||||
limm t1, imm
|
||||
and t0, reg, t1
|
||||
and t0, reg, t1, flags=(SF, ZF, PF)
|
||||
};
|
||||
'''
|
||||
|
|
|
@ -54,16 +54,51 @@
|
|||
# Authors: Gabe Black
|
||||
|
||||
microcode = '''
|
||||
def macroop CALL_I
|
||||
def macroop CALL_NEAR_I
|
||||
{
|
||||
# Make the default data size of pops 64 bits in 64 bit mode
|
||||
# Make the default data size of calls 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
limm t1, imm
|
||||
rdip t7
|
||||
subi rsp, rsp, dsz
|
||||
st t7, ss, [0, t0, rsp]
|
||||
wrip t7, t1
|
||||
};
|
||||
|
||||
def macroop CALL_NEAR_R
|
||||
{
|
||||
# Make the default data size of calls 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
limm t2, imm
|
||||
rdip t1
|
||||
subi rsp, rsp, dsz
|
||||
st t1, ss, [0, t0, rsp]
|
||||
wrip t1, t2
|
||||
wripi reg, 0
|
||||
};
|
||||
|
||||
def macroop CALL_NEAR_M
|
||||
{
|
||||
# Make the default data size of calls 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
subi rsp, rsp, dsz
|
||||
st t7, ss, [0, t0, rsp]
|
||||
wripi t1, 0
|
||||
};
|
||||
|
||||
def macroop CALL_NEAR_P
|
||||
{
|
||||
# Make the default data size of calls 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
subi rsp, rsp, dsz
|
||||
st t7, ss, [0, t0, rsp]
|
||||
wripi t1, 0
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
|
|
|
@ -53,8 +53,192 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
#let {{
|
||||
# class JMP(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
#}};
|
||||
microcode = '''
|
||||
def macroop JZ_I
|
||||
{
|
||||
# Make the defualt data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(CZF,)
|
||||
};
|
||||
|
||||
def macroop JNZ_I
|
||||
{
|
||||
# Make the defualt data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(nCZF,)
|
||||
};
|
||||
|
||||
def macroop JB_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(CCF,)
|
||||
};
|
||||
|
||||
def macroop JNB_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(nCCF,)
|
||||
};
|
||||
|
||||
def macroop JBE_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(CCvZF,)
|
||||
};
|
||||
|
||||
def macroop JNBE_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(nCCvZF,)
|
||||
};
|
||||
|
||||
def macroop JS_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(CSF,)
|
||||
};
|
||||
|
||||
def macroop JNS_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(nCSF,)
|
||||
};
|
||||
|
||||
def macroop JP_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(CPF,)
|
||||
};
|
||||
|
||||
def macroop JNP_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(nCPF,)
|
||||
};
|
||||
|
||||
def macroop JL_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(CSxOF,)
|
||||
};
|
||||
|
||||
def macroop JNL_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(nCSxOF,)
|
||||
};
|
||||
|
||||
def macroop JLE_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(CSxOvZF,)
|
||||
};
|
||||
|
||||
def macroop JNLE_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(nCSxOvZF,)
|
||||
};
|
||||
|
||||
def macroop JO_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(COF,)
|
||||
};
|
||||
|
||||
def macroop JNO_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2, flags=(nCOF,)
|
||||
};
|
||||
|
||||
def macroop JMP_I
|
||||
{
|
||||
# Make the default data size of jumps 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
limm t2, imm
|
||||
wrip t1, t2
|
||||
};
|
||||
|
||||
def macroop JMP_R
|
||||
{
|
||||
wripi reg, 0
|
||||
};
|
||||
|
||||
def macroop JMP_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
wripi t1, 0
|
||||
};
|
||||
|
||||
def macroop JMP_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
wripi t1, 0
|
||||
};
|
||||
'''
|
||||
|
|
|
@ -53,8 +53,26 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
#let {{
|
||||
# class RET(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
#}};
|
||||
microcode = '''
|
||||
def macroop RET_NEAR
|
||||
{
|
||||
# Make the default data size of rets 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
ld t1, ss, [0, t0, rsp]
|
||||
addi rsp, rsp, dsz
|
||||
wripi t1, 0
|
||||
};
|
||||
|
||||
def macroop RET_NEAR_I
|
||||
{
|
||||
# Make the default data size of rets 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
limm t2, imm
|
||||
ld t1, ss, [0, t0, rsp]
|
||||
addi rsp, rsp, dsz
|
||||
add rsp, rsp, t2
|
||||
wripi t1, 0
|
||||
};
|
||||
'''
|
||||
|
|
|
@ -55,7 +55,8 @@
|
|||
|
||||
categories = ["conditional_move",
|
||||
"move",
|
||||
"stack_operations"]
|
||||
"stack_operations",
|
||||
"xchg"]
|
||||
|
||||
microcode = ""
|
||||
for category in categories:
|
||||
|
|
|
@ -54,6 +54,11 @@
|
|||
# Authors: Gabe Black
|
||||
|
||||
microcode = '''
|
||||
|
||||
#
|
||||
# Regular moves
|
||||
#
|
||||
|
||||
def macroop MOV_R_R {
|
||||
mov reg, reg, regm
|
||||
};
|
||||
|
@ -64,7 +69,7 @@ def macroop MOV_M_R {
|
|||
|
||||
def macroop MOV_P_R {
|
||||
rdip t7
|
||||
st reg, ds, [scale, index, base], disp
|
||||
st reg, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop MOV_R_M {
|
||||
|
@ -73,7 +78,7 @@ def macroop MOV_R_M {
|
|||
|
||||
def macroop MOV_R_P {
|
||||
rdip t7
|
||||
ld reg, ds, [scale, index, base], disp
|
||||
ld reg, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop MOV_R_I {
|
||||
|
@ -88,22 +93,90 @@ def macroop MOV_M_I {
|
|||
def macroop MOV_P_I {
|
||||
rdip t7
|
||||
limm t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
#
|
||||
# Sign extending moves
|
||||
#
|
||||
|
||||
def macroop MOVSXD_R_R {
|
||||
sext reg, regm, dsz
|
||||
sext reg, regm, 32
|
||||
};
|
||||
|
||||
def macroop MOVSXD_R_M {
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sext reg, t1, dsz
|
||||
ld t1, ds, [scale, index, base], disp, dataSize=4
|
||||
sext reg, t1, 32
|
||||
};
|
||||
|
||||
def macroop MOVSXD_R_P {
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sext reg, t1, dsz
|
||||
ld t1, ds, [0, t0, t7], disp, dataSize=4
|
||||
sext reg, t1, 32
|
||||
};
|
||||
|
||||
def macroop MOVSX_B_R_R {
|
||||
sext reg, regm, 8
|
||||
};
|
||||
|
||||
def macroop MOVSX_B_R_M {
|
||||
ld reg, ds, [scale, index, base], disp, dataSize=1
|
||||
sext reg, reg, 8
|
||||
};
|
||||
|
||||
def macroop MOVSX_B_R_P {
|
||||
rdip t7
|
||||
ld reg, ds, [0, t0, t7], disp, dataSize=1
|
||||
sext reg, reg, 8
|
||||
};
|
||||
|
||||
def macroop MOVSX_W_R_R {
|
||||
sext reg, regm, 16
|
||||
};
|
||||
|
||||
def macroop MOVSX_W_R_M {
|
||||
ld reg, ds, [scale, index, base], disp, dataSize=2
|
||||
sext reg, reg, 16
|
||||
};
|
||||
|
||||
def macroop MOVSX_W_R_P {
|
||||
rdip t7
|
||||
ld reg, ds, [0, t0, t7], disp, dataSize=2
|
||||
sext reg, reg, 16
|
||||
};
|
||||
|
||||
#
|
||||
# Zero extending moves
|
||||
#
|
||||
|
||||
def macroop MOVZX_B_R_R {
|
||||
zext reg, regm, 8
|
||||
};
|
||||
|
||||
def macroop MOVZX_B_R_M {
|
||||
ld t1, ds, [scale, index, base], disp, dataSize=1
|
||||
zext reg, t1, 8
|
||||
};
|
||||
|
||||
def macroop MOVZX_B_R_P {
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp, dataSize=1
|
||||
zext reg, t1, 8
|
||||
};
|
||||
|
||||
def macroop MOVZX_W_R_R {
|
||||
zext reg, regm, 16
|
||||
};
|
||||
|
||||
def macroop MOVZX_W_R_M {
|
||||
ld t1, ds, [scale, index, base], disp, dataSize=2
|
||||
zext reg, t1, 16
|
||||
};
|
||||
|
||||
def macroop MOVZX_W_R_P {
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp, dataSize=2
|
||||
zext reg, t1, 16
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
|
|
|
@ -69,6 +69,25 @@ def macroop PUSH_R {
|
|||
subi rsp, rsp, dsz
|
||||
st reg, ss, [0, t0, rsp]
|
||||
};
|
||||
|
||||
def macroop PUSH_M {
|
||||
# Make the default data size of pops 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
subi rsp, rsp, dsz
|
||||
st t1, ss, [0, t0, rsp]
|
||||
};
|
||||
|
||||
def macroop PUSH_P {
|
||||
# Make the default data size of pops 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
subi rsp, rsp, dsz
|
||||
st t1, ss, [0, t0, rsp]
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class POPA(Inst):
|
||||
|
|
98
src/arch/x86/isa/insts/data_transfer/xchg.py
Normal file
98
src/arch/x86/isa/insts/data_transfer/xchg.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
# Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use of this software in source and binary forms,
|
||||
# with or without modification, are permitted provided that the
|
||||
# following conditions are met:
|
||||
#
|
||||
# The software must be used only for Non-Commercial Use which means any
|
||||
# use which is NOT directed to receiving any direct monetary
|
||||
# compensation for, or commercial advantage from such use. Illustrative
|
||||
# examples of non-commercial use are academic research, personal study,
|
||||
# teaching, education and corporate research & development.
|
||||
# Illustrative examples of commercial use are distributing products for
|
||||
# commercial advantage and providing services using the software for
|
||||
# commercial advantage.
|
||||
#
|
||||
# If you wish to use this software or functionality therein that may be
|
||||
# covered by patents for commercial use, please contact:
|
||||
# Director of Intellectual Property Licensing
|
||||
# Office of Strategy and Technology
|
||||
# Hewlett-Packard Company
|
||||
# 1501 Page Mill Road
|
||||
# Palo Alto, California 94304
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer. Redistributions
|
||||
# in binary form must reproduce the above copyright notice, this list of
|
||||
# conditions and the following disclaimer in the documentation and/or
|
||||
# other materials provided with the distribution. Neither the name of
|
||||
# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission. No right of
|
||||
# sublicense is granted herewith. Derivatives of the software and
|
||||
# output created using the software may be prepared, but only for
|
||||
# Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
# others provided: (i) the others agree to abide by the list of
|
||||
# conditions herein which includes the Non-Commercial Use restrictions;
|
||||
# and (ii) such Derivatives of the software include the above copyright
|
||||
# notice to acknowledge the contribution from this software where
|
||||
# applicable, this list of conditions and the disclaimer below.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = '''
|
||||
|
||||
# All the memory versions need to use LOCK, regardless of if it was set
|
||||
|
||||
def macroop XCHG_R_R
|
||||
{
|
||||
# Use the xor trick instead of moves to reduce register pressure.
|
||||
# This probably doesn't make much of a difference, but it's easy.
|
||||
xor reg, reg, regm
|
||||
xor regm, regm, reg
|
||||
xor reg, reg, regm
|
||||
};
|
||||
|
||||
def macroop XCHG_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
st reg, ds, [scale, index, base], disp
|
||||
mov reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop XCHG_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
st reg, ds, [0, t0, t7], disp
|
||||
mov reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop XCHG_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
st reg, ds, [scale, index, base], disp
|
||||
mov reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop XCHG_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
st reg, ds, [0, t0, t7], disp
|
||||
mov reg, reg, t1
|
||||
};
|
||||
'''
|
|
@ -54,6 +54,62 @@
|
|||
# Authors: Gabe Black
|
||||
|
||||
microcode = '''
|
||||
def macroop OR_R_R
|
||||
{
|
||||
or reg, reg, regm
|
||||
};
|
||||
|
||||
def macroop OR_M_I
|
||||
{
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
or t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop OR_P_I
|
||||
{
|
||||
limm t2, imm
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
or t1, t1, t2
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop OR_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
or t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop OR_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
or t1, t1, reg
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop OR_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
or reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop OR_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
or reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop OR_R_I
|
||||
{
|
||||
limm t1, imm
|
||||
or reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop XOR_R_R
|
||||
{
|
||||
xor reg, reg, regm
|
||||
|
@ -65,6 +121,23 @@ def macroop XOR_R_I
|
|||
xor reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop XOR_M_I
|
||||
{
|
||||
limm t2, imm
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
xor t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop XOR_P_I
|
||||
{
|
||||
limm t2, imm
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
xor t1, t1, t2
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop XOR_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
|
@ -93,6 +166,24 @@ def macroop XOR_R_P
|
|||
xor reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop AND_R_R
|
||||
{
|
||||
and reg, reg, regm
|
||||
};
|
||||
|
||||
def macroop AND_R_M
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
and reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop AND_R_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
and reg, reg, t1
|
||||
};
|
||||
|
||||
def macroop AND_R_I
|
||||
{
|
||||
limm t1, imm
|
||||
|
@ -115,6 +206,21 @@ def macroop AND_P_I
|
|||
and t2, t2, t1
|
||||
st t2, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop AND_M_R
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
and t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop AND_P_R
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
and t1, t1, reg
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
#microcodeString = '''
|
||||
|
|
|
@ -53,8 +53,9 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
#let {{
|
||||
# class NOP(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
#}};
|
||||
microcode = '''
|
||||
def macroop NOP
|
||||
{
|
||||
fault "NoFault"
|
||||
};
|
||||
'''
|
||||
|
|
|
@ -53,14 +53,90 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
microcode = '''
|
||||
def macroop ROL_R_I
|
||||
{
|
||||
rol reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop ROL_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
rol t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ROL_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
rol t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop ROR_R_I
|
||||
{
|
||||
ror reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop ROR_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
ror t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ROR_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
ror t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop RCL_R_I
|
||||
{
|
||||
rcl reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop RCL_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
rcl t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop RCL_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
rcl t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop RCR_R_I
|
||||
{
|
||||
rcr reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop RCR_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
rcr t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop RCR_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
rcr t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class RCL(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class RCR(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class ROL(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class ROR(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
#}};
|
||||
|
|
|
@ -53,7 +53,67 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
microcode = '''
|
||||
def macroop SAL_R_I
|
||||
{
|
||||
sll reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop SAL_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sll t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SAL_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
sll t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop SHR_R_I
|
||||
{
|
||||
srl reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop SHR_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
srl t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SHR_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
srl t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop SAR_R_I
|
||||
{
|
||||
sra reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop SAR_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sra t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SAR_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
sra t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class SAL(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
|
|
62
src/arch/x86/isa/insts/system/__init__.py
Normal file
62
src/arch/x86/isa/insts/system/__init__.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use of this software in source and binary forms,
|
||||
# with or without modification, are permitted provided that the
|
||||
# following conditions are met:
|
||||
#
|
||||
# The software must be used only for Non-Commercial Use which means any
|
||||
# use which is NOT directed to receiving any direct monetary
|
||||
# compensation for, or commercial advantage from such use. Illustrative
|
||||
# examples of non-commercial use are academic research, personal study,
|
||||
# teaching, education and corporate research & development.
|
||||
# Illustrative examples of commercial use are distributing products for
|
||||
# commercial advantage and providing services using the software for
|
||||
# commercial advantage.
|
||||
#
|
||||
# If you wish to use this software or functionality therein that may be
|
||||
# covered by patents for commercial use, please contact:
|
||||
# Director of Intellectual Property Licensing
|
||||
# Office of Strategy and Technology
|
||||
# Hewlett-Packard Company
|
||||
# 1501 Page Mill Road
|
||||
# Palo Alto, California 94304
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer. Redistributions
|
||||
# in binary form must reproduce the above copyright notice, this list of
|
||||
# conditions and the following disclaimer in the documentation and/or
|
||||
# other materials provided with the distribution. Neither the name of
|
||||
# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission. No right of
|
||||
# sublicense is granted herewith. Derivatives of the software and
|
||||
# output created using the software may be prepared, but only for
|
||||
# Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
# others provided: (i) the others agree to abide by the list of
|
||||
# conditions herein which includes the Non-Commercial Use restrictions;
|
||||
# and (ii) such Derivatives of the software include the above copyright
|
||||
# notice to acknowledge the contribution from this software where
|
||||
# applicable, this list of conditions and the disclaimer below.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
categories = ["undefined_operation"]
|
||||
|
||||
microcode = ""
|
||||
for category in categories:
|
||||
exec "import %s as cat" % category
|
||||
microcode += cat.microcode
|
||||
|
61
src/arch/x86/isa/insts/system/undefined_operation.py
Normal file
61
src/arch/x86/isa/insts/system/undefined_operation.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use of this software in source and binary forms,
|
||||
# with or without modification, are permitted provided that the
|
||||
# following conditions are met:
|
||||
#
|
||||
# The software must be used only for Non-Commercial Use which means any
|
||||
# use which is NOT directed to receiving any direct monetary
|
||||
# compensation for, or commercial advantage from such use. Illustrative
|
||||
# examples of non-commercial use are academic research, personal study,
|
||||
# teaching, education and corporate research & development.
|
||||
# Illustrative examples of commercial use are distributing products for
|
||||
# commercial advantage and providing services using the software for
|
||||
# commercial advantage.
|
||||
#
|
||||
# If you wish to use this software or functionality therein that may be
|
||||
# covered by patents for commercial use, please contact:
|
||||
# Director of Intellectual Property Licensing
|
||||
# Office of Strategy and Technology
|
||||
# Hewlett-Packard Company
|
||||
# 1501 Page Mill Road
|
||||
# Palo Alto, California 94304
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer. Redistributions
|
||||
# in binary form must reproduce the above copyright notice, this list of
|
||||
# conditions and the following disclaimer in the documentation and/or
|
||||
# other materials provided with the distribution. Neither the name of
|
||||
# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission. No right of
|
||||
# sublicense is granted herewith. Derivatives of the software and
|
||||
# output created using the software may be prepared, but only for
|
||||
# Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
# others provided: (i) the others agree to abide by the list of
|
||||
# conditions herein which includes the Non-Commercial Use restrictions;
|
||||
# and (ii) such Derivatives of the software include the above copyright
|
||||
# notice to acknowledge the contribution from this software where
|
||||
# applicable, this list of conditions and the disclaimer below.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = '''
|
||||
def macroop UD2
|
||||
{
|
||||
fault "new X86Fault"
|
||||
};
|
||||
'''
|
|
@ -79,8 +79,8 @@ namespace X86ISA;
|
|||
//Include the bitfield definitions
|
||||
##include "bitfields.isa"
|
||||
|
||||
//Include the base class for x86 instructions, and some support code.
|
||||
##include "base.isa"
|
||||
//Include the OutputBlocks class which is used to bundle output.
|
||||
##include "outputblock.isa"
|
||||
|
||||
//Include the definitions for the instruction formats
|
||||
##include "formats/formats.isa"
|
||||
|
|
|
@ -56,9 +56,9 @@
|
|||
// Authors: Gabe Black
|
||||
|
||||
//Include the definitions of the micro ops.
|
||||
//These are StaticInst classes which stand on their own and make up an
|
||||
//internal instruction set, and also python representations which are passed
|
||||
//into the microcode assembler.
|
||||
//These are python representations of static insts which stand on their own
|
||||
//and make up an internal instruction set. They are used by the micro
|
||||
//assembler.
|
||||
##include "microops/microops.isa"
|
||||
|
||||
//Include code to build macroops in both C++ and python.
|
||||
|
@ -96,6 +96,19 @@ let {{
|
|||
assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper()
|
||||
assembler.symbols.update(symbols)
|
||||
|
||||
for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF'):
|
||||
assembler.symbols[flag] = flag + "Bit"
|
||||
|
||||
for cond in ('True', 'False', 'ECF', 'EZF', 'SZnZF',
|
||||
'MSTRZ', 'STRZ', 'MSTRC', 'STRZnZF',
|
||||
'OF', 'CF', 'ZF', 'CvZF',
|
||||
'SF', 'PF', 'SxOF', 'SxOvZF'):
|
||||
assembler.symbols["C%s" % cond] = "ConditionTests::%s" % cond
|
||||
assembler.symbols["nC%s" % cond] = "ConditionTests::Not%s" % cond
|
||||
|
||||
assembler.symbols["CTrue"] = "ConditionTests::True"
|
||||
assembler.symbols["CFalse"] = "ConditionTests::False"
|
||||
|
||||
# Code literal which forces a default 64 bit operand size in 64 bit mode.
|
||||
assembler.symbols["oszIn64Override"] = '''
|
||||
if (machInst.mode.submode == SixtyFourBitMode &&
|
||||
|
|
|
@ -61,42 +61,6 @@ let {{
|
|||
microopClasses = {}
|
||||
}};
|
||||
|
||||
//A class which is the base of all x86 micro ops. It provides a function to
|
||||
//set necessary flags appropriately.
|
||||
output header {{
|
||||
class X86MicroopBase : public X86StaticInst
|
||||
{
|
||||
protected:
|
||||
const char * instMnem;
|
||||
uint8_t opSize;
|
||||
uint8_t addrSize;
|
||||
|
||||
X86MicroopBase(ExtMachInst _machInst,
|
||||
const char *mnem, const char *_instMnem,
|
||||
bool isMicro, bool isDelayed,
|
||||
bool isFirst, bool isLast,
|
||||
OpClass __opClass) :
|
||||
X86StaticInst(mnem, _machInst, __opClass),
|
||||
instMnem(_instMnem)
|
||||
{
|
||||
flags[IsMicroop] = isMicro;
|
||||
flags[IsDelayedCommit] = isDelayed;
|
||||
flags[IsFirstMicroop] = isFirst;
|
||||
flags[IsLastMicroop] = isLast;
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "\t%s.%s", instMnem, mnemonic);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Base class for the python representation of x86 microops
|
||||
|
|
|
@ -59,63 +59,6 @@
|
|||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base class for load and store ops
|
||||
*/
|
||||
class LdStOp : public X86MicroopBase
|
||||
{
|
||||
protected:
|
||||
const uint8_t scale;
|
||||
const RegIndex index;
|
||||
const RegIndex base;
|
||||
const uint64_t disp;
|
||||
const uint8_t segment;
|
||||
const RegIndex data;
|
||||
const uint8_t dataSize;
|
||||
const uint8_t addressSize;
|
||||
|
||||
//Constructor
|
||||
LdStOp(ExtMachInst _machInst,
|
||||
const char * mnem, const char * _instMnem,
|
||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||
uint8_t _scale, RegIndex _index, RegIndex _base,
|
||||
uint64_t _disp, uint8_t _segment,
|
||||
RegIndex _data,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
OpClass __opClass) :
|
||||
X86MicroopBase(machInst, mnem, _instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast, __opClass),
|
||||
scale(_scale), index(_index), base(_base),
|
||||
disp(_disp), segment(_segment),
|
||||
data(_data),
|
||||
dataSize(_dataSize), addressSize(_addressSize)
|
||||
{}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string LdStOp::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
printReg(response, data);
|
||||
response << ", ";
|
||||
printSegment(response, segment);
|
||||
ccprintf(response, ":[%d*", scale);
|
||||
printReg(response, index);
|
||||
response << " + ";
|
||||
printReg(response, base);
|
||||
ccprintf(response, " + %#x]", disp);
|
||||
return response.str();
|
||||
}
|
||||
}};
|
||||
|
||||
// LEA template
|
||||
|
||||
def template MicroLeaExecute {{
|
||||
|
@ -180,7 +123,25 @@ def template MicroLoadExecute {{
|
|||
%(ea_code)s;
|
||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||
|
||||
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
|
||||
unsigned flags = 0;
|
||||
switch(dataSize)
|
||||
{
|
||||
case 1:
|
||||
fault = xc->read(EA, (uint8_t&)Mem, flags);
|
||||
break;
|
||||
case 2:
|
||||
fault = xc->read(EA, (uint16_t&)Mem, flags);
|
||||
break;
|
||||
case 4:
|
||||
fault = xc->read(EA, (uint32_t&)Mem, flags);
|
||||
break;
|
||||
case 8:
|
||||
fault = xc->read(EA, (uint64_t&)Mem, flags);
|
||||
break;
|
||||
default:
|
||||
panic("Bad operand size!\n");
|
||||
}
|
||||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
%(code)s;
|
||||
|
@ -206,7 +167,24 @@ def template MicroLoadInitiateAcc {{
|
|||
%(ea_code)s;
|
||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||
|
||||
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
|
||||
unsigned flags = 0;
|
||||
switch(dataSize)
|
||||
{
|
||||
case 1:
|
||||
fault = xc->read(EA, (uint8_t&)Mem, flags);
|
||||
break;
|
||||
case 2:
|
||||
fault = xc->read(EA, (uint16_t&)Mem, flags);
|
||||
break;
|
||||
case 4:
|
||||
fault = xc->read(EA, (uint32_t&)Mem, flags);
|
||||
break;
|
||||
case 8:
|
||||
fault = xc->read(EA, (uint64_t&)Mem, flags);
|
||||
break;
|
||||
default:
|
||||
panic("Bad operand size!\n");
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
|
@ -252,8 +230,25 @@ def template MicroStoreExecute {{
|
|||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
||||
EA, 0, 0);
|
||||
unsigned flags = 0;
|
||||
uint64_t *res = 0;
|
||||
switch(dataSize)
|
||||
{
|
||||
case 1:
|
||||
fault = xc->write((uint8_t&)Mem, EA, flags, res);
|
||||
break;
|
||||
case 2:
|
||||
fault = xc->write((uint16_t&)Mem, EA, flags, res);
|
||||
break;
|
||||
case 4:
|
||||
fault = xc->write((uint32_t&)Mem, EA, flags, res);
|
||||
break;
|
||||
case 8:
|
||||
fault = xc->write((uint64_t&)Mem, EA, flags, res);
|
||||
break;
|
||||
default:
|
||||
panic("Bad operand size!\n");
|
||||
}
|
||||
}
|
||||
if(fault == NoFault)
|
||||
{
|
||||
|
@ -280,8 +275,25 @@ def template MicroStoreInitiateAcc {{
|
|||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
||||
EA, 0, 0);
|
||||
unsigned flags = 0;
|
||||
uint64_t *res = 0;
|
||||
switch(dataSize)
|
||||
{
|
||||
case 1:
|
||||
fault = xc->write((uint8_t&)Mem, EA, flags, res);
|
||||
break;
|
||||
case 2:
|
||||
fault = xc->write((uint16_t&)Mem, EA, flags, res);
|
||||
break;
|
||||
case 4:
|
||||
fault = xc->write((uint32_t&)Mem, EA, flags, res);
|
||||
break;
|
||||
case 8:
|
||||
fault = xc->write((uint64_t&)Mem, EA, flags, res);
|
||||
break;
|
||||
default:
|
||||
panic("Bad operand size!\n");
|
||||
}
|
||||
}
|
||||
if(fault == NoFault)
|
||||
{
|
||||
|
@ -382,12 +394,12 @@ def template MicroLdStOpConstructor {{
|
|||
|
||||
let {{
|
||||
class LdStOp(X86Microop):
|
||||
def __init__(self, data, segment, addr, disp):
|
||||
def __init__(self, data, segment, addr, disp, dataSize):
|
||||
self.data = data
|
||||
[self.scale, self.index, self.base] = addr
|
||||
self.disp = disp
|
||||
self.segment = segment
|
||||
self.dataSize = "env.dataSize"
|
||||
self.dataSize = dataSize
|
||||
self.addressSize = "env.addressSize"
|
||||
|
||||
def getAllocator(self, *microFlags):
|
||||
|
@ -424,7 +436,7 @@ let {{
|
|||
name = mnemonic.lower()
|
||||
|
||||
# Build up the all register version of this micro op
|
||||
iop = InstObjParams(name, Name, 'LdStOp',
|
||||
iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
|
||||
{"code": code, "ea_code": calculateEA})
|
||||
header_output += MicroLdStOpDeclare.subst(iop)
|
||||
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||
|
@ -433,8 +445,10 @@ let {{
|
|||
exec_output += MicroLoadCompleteAcc.subst(iop)
|
||||
|
||||
class LoadOp(LdStOp):
|
||||
def __init__(self, data, segment, addr, disp = 0):
|
||||
super(LoadOp, self).__init__(data, segment, addr, disp)
|
||||
def __init__(self, data, segment, addr,
|
||||
disp = 0, dataSize="env.dataSize"):
|
||||
super(LoadOp, self).__init__(data, segment,
|
||||
addr, disp, dataSize)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
|
||||
|
@ -451,7 +465,7 @@ let {{
|
|||
name = mnemonic.lower()
|
||||
|
||||
# Build up the all register version of this micro op
|
||||
iop = InstObjParams(name, Name, 'LdStOp',
|
||||
iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
|
||||
{"code": code, "ea_code": calculateEA})
|
||||
header_output += MicroLdStOpDeclare.subst(iop)
|
||||
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||
|
@ -460,24 +474,28 @@ let {{
|
|||
exec_output += MicroStoreCompleteAcc.subst(iop)
|
||||
|
||||
class StoreOp(LdStOp):
|
||||
def __init__(self, data, segment, addr, disp = 0):
|
||||
super(LoadOp, self).__init__(data, segment, addr, disp)
|
||||
def __init__(self, data, segment, addr,
|
||||
disp = 0, dataSize="env.dataSize"):
|
||||
super(StoreOp, self).__init__(data, segment,
|
||||
addr, disp, dataSize)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
|
||||
microopClasses[name] = StoreOp
|
||||
|
||||
defineMicroLoadOp('St', 'Mem = Data;')
|
||||
defineMicroStoreOp('St', 'Mem = Data;')
|
||||
|
||||
iop = InstObjParams("lea", "Lea", 'LdStOp',
|
||||
iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
|
||||
{"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA})
|
||||
header_output += MicroLeaDeclare.subst(iop)
|
||||
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||
exec_output += MicroLeaExecute.subst(iop)
|
||||
|
||||
class LeaOp(LdStOp):
|
||||
def __init__(self, data, segment, addr, disp = 0):
|
||||
super(LeaOp, self).__init__(data, segment, addr, disp)
|
||||
def __init__(self, data, segment, addr,
|
||||
disp = 0, dataSize="env.dataSize"):
|
||||
super(LeaOp, self).__init__(data, segment,
|
||||
addr, disp, dataSize)
|
||||
self.className = "Lea"
|
||||
self.mnemonic = "lea"
|
||||
|
||||
|
|
|
@ -72,11 +72,12 @@ def template MicroLimmOpExecute {{
|
|||
}};
|
||||
|
||||
def template MicroLimmOpDeclare {{
|
||||
class %(class_name)s : public X86MicroopBase
|
||||
class %(class_name)s : public X86ISA::X86MicroopBase
|
||||
{
|
||||
protected:
|
||||
const RegIndex dest;
|
||||
const uint64_t imm;
|
||||
const uint8_t dataSize;
|
||||
void buildMe();
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
|
@ -86,11 +87,11 @@ def template MicroLimmOpDeclare {{
|
|||
%(class_name)s(ExtMachInst _machInst,
|
||||
const char * instMnem,
|
||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||
RegIndex _dest, uint64_t _imm);
|
||||
RegIndex _dest, uint64_t _imm, uint8_t _dataSize);
|
||||
|
||||
%(class_name)s(ExtMachInst _machInst,
|
||||
const char * instMnem,
|
||||
RegIndex _dest, uint64_t _imm);
|
||||
RegIndex _dest, uint64_t _imm, uint8_t _dataSize);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
|
@ -103,7 +104,7 @@ def template MicroLimmOpDisassembly {{
|
|||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
printReg(response, dest);
|
||||
printReg(response, dest, dataSize);
|
||||
response << ", ";
|
||||
ccprintf(response, "%#x", imm);
|
||||
return response.str();
|
||||
|
@ -119,10 +120,10 @@ def template MicroLimmOpConstructor {{
|
|||
|
||||
inline %(class_name)s::%(class_name)s(
|
||||
ExtMachInst machInst, const char * instMnem,
|
||||
RegIndex _dest, uint64_t _imm) :
|
||||
RegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
|
||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
||||
false, false, false, false, %(op_class)s),
|
||||
dest(_dest), imm(_imm)
|
||||
dest(_dest), imm(_imm), dataSize(_dataSize)
|
||||
{
|
||||
buildMe();
|
||||
}
|
||||
|
@ -130,10 +131,10 @@ def template MicroLimmOpConstructor {{
|
|||
inline %(class_name)s::%(class_name)s(
|
||||
ExtMachInst machInst, const char * instMnem,
|
||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||
RegIndex _dest, uint64_t _imm) :
|
||||
RegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
|
||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast, %(op_class)s),
|
||||
dest(_dest), imm(_imm)
|
||||
dest(_dest), imm(_imm), dataSize(_dataSize)
|
||||
{
|
||||
buildMe();
|
||||
}
|
||||
|
@ -146,14 +147,16 @@ let {{
|
|||
self.mnemonic = "limm"
|
||||
self.dest = dest
|
||||
self.imm = imm
|
||||
self.dataSize = "env.dataSize"
|
||||
|
||||
def getAllocator(self, *microFlags):
|
||||
allocator = '''new %(class_name)s(machInst, mnemonic
|
||||
%(flags)s, %(dest)s, %(imm)s)''' % {
|
||||
%(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % {
|
||||
"class_name" : self.className,
|
||||
"mnemonic" : self.mnemonic,
|
||||
"flags" : self.microFlagsText(microFlags),
|
||||
"dest" : self.dest, "imm" : self.imm }
|
||||
"dest" : self.dest, "imm" : self.imm,
|
||||
"dataSize" : self.dataSize}
|
||||
return allocator
|
||||
|
||||
microopClasses["limm"] = LimmOp
|
||||
|
|
|
@ -59,100 +59,6 @@
|
|||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
output header {{
|
||||
/**
|
||||
* Base classes for RegOps which provides a generateDisassembly method.
|
||||
*/
|
||||
class RegOp : public X86MicroopBase
|
||||
{
|
||||
protected:
|
||||
const RegIndex src1;
|
||||
const RegIndex src2;
|
||||
const RegIndex dest;
|
||||
const bool setStatus;
|
||||
const uint8_t dataSize;
|
||||
const uint8_t ext;
|
||||
|
||||
// Constructor
|
||||
RegOp(ExtMachInst _machInst,
|
||||
const char *mnem, const char *_instMnem,
|
||||
bool isMicro, bool isDelayed,
|
||||
bool isFirst, bool isLast,
|
||||
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext,
|
||||
OpClass __opClass) :
|
||||
X86MicroopBase(_machInst, mnem, _instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast,
|
||||
__opClass),
|
||||
src1(_src1), src2(_src2), dest(_dest),
|
||||
setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
class RegOpImm : public X86MicroopBase
|
||||
{
|
||||
protected:
|
||||
const RegIndex src1;
|
||||
const uint8_t imm8;
|
||||
const RegIndex dest;
|
||||
const bool setStatus;
|
||||
const uint8_t dataSize;
|
||||
const uint8_t ext;
|
||||
|
||||
// Constructor
|
||||
RegOpImm(ExtMachInst _machInst,
|
||||
const char * mnem, const char *_instMnem,
|
||||
bool isMicro, bool isDelayed,
|
||||
bool isFirst, bool isLast,
|
||||
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext,
|
||||
OpClass __opClass) :
|
||||
X86MicroopBase(_machInst, mnem, _instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast,
|
||||
__opClass),
|
||||
src1(_src1), imm8(_imm8), dest(_dest),
|
||||
setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string RegOp::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
printReg(response, dest);
|
||||
response << ", ";
|
||||
printReg(response, src1);
|
||||
response << ", ";
|
||||
printReg(response, src2);
|
||||
return response.str();
|
||||
}
|
||||
|
||||
std::string RegOpImm::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
printReg(response, dest);
|
||||
response << ", ";
|
||||
printReg(response, src1);
|
||||
ccprintf(response, ", %#x", imm8);
|
||||
return response.str();
|
||||
}
|
||||
}};
|
||||
|
||||
def template MicroRegOpExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
|
@ -161,8 +67,16 @@ def template MicroRegOpExecute {{
|
|||
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
if(%(cond_check)s)
|
||||
{
|
||||
%(code)s;
|
||||
%(flag_code)s;
|
||||
}
|
||||
else
|
||||
{
|
||||
%(else_code)s;
|
||||
}
|
||||
|
||||
//Write the resulting state to the execution context
|
||||
if(fault == NoFault)
|
||||
|
@ -181,8 +95,16 @@ def template MicroRegOpImmExecute {{
|
|||
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
if(%(cond_check)s)
|
||||
{
|
||||
%(code)s;
|
||||
%(flag_code)s;
|
||||
}
|
||||
else
|
||||
{
|
||||
%(else_code)s;
|
||||
}
|
||||
|
||||
//Write the resulting state to the execution context
|
||||
if(fault == NoFault)
|
||||
|
@ -204,12 +126,12 @@ def template MicroRegOpDeclare {{
|
|||
const char * instMnem,
|
||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext);
|
||||
uint8_t _dataSize, uint16_t _ext);
|
||||
|
||||
%(class_name)s(ExtMachInst _machInst,
|
||||
const char * instMnem,
|
||||
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext);
|
||||
uint8_t _dataSize, uint16_t _ext);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
|
@ -227,12 +149,12 @@ def template MicroRegOpImmDeclare {{
|
|||
const char * instMnem,
|
||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext);
|
||||
uint8_t _dataSize, uint16_t _ext);
|
||||
|
||||
%(class_name)sImm(ExtMachInst _machInst,
|
||||
const char * instMnem,
|
||||
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext);
|
||||
uint8_t _dataSize, uint16_t _ext);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
};
|
||||
|
@ -248,10 +170,10 @@ def template MicroRegOpConstructor {{
|
|||
inline %(class_name)s::%(class_name)s(
|
||||
ExtMachInst machInst, const char * instMnem,
|
||||
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
||||
uint8_t _dataSize, uint16_t _ext) :
|
||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
||||
false, false, false, false,
|
||||
_src1, _src2, _dest, _setStatus, _dataSize, _ext,
|
||||
_src1, _src2, _dest, _dataSize, _ext,
|
||||
%(op_class)s)
|
||||
{
|
||||
buildMe();
|
||||
|
@ -261,10 +183,10 @@ def template MicroRegOpConstructor {{
|
|||
ExtMachInst machInst, const char * instMnem,
|
||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||
RegIndex _src1, RegIndex _src2, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
||||
uint8_t _dataSize, uint16_t _ext) :
|
||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast,
|
||||
_src1, _src2, _dest, _setStatus, _dataSize, _ext,
|
||||
_src1, _src2, _dest, _dataSize, _ext,
|
||||
%(op_class)s)
|
||||
{
|
||||
buildMe();
|
||||
|
@ -281,10 +203,10 @@ def template MicroRegOpImmConstructor {{
|
|||
inline %(class_name)sImm::%(class_name)sImm(
|
||||
ExtMachInst machInst, const char * instMnem,
|
||||
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
||||
uint8_t _dataSize, uint16_t _ext) :
|
||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
||||
false, false, false, false,
|
||||
_src1, _imm8, _dest, _setStatus, _dataSize, _ext,
|
||||
_src1, _imm8, _dest, _dataSize, _ext,
|
||||
%(op_class)s)
|
||||
{
|
||||
buildMe();
|
||||
|
@ -294,10 +216,10 @@ def template MicroRegOpImmConstructor {{
|
|||
ExtMachInst machInst, const char * instMnem,
|
||||
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
||||
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
|
||||
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
|
||||
uint8_t _dataSize, uint16_t _ext) :
|
||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
||||
isMicro, isDelayed, isFirst, isLast,
|
||||
_src1, _imm8, _dest, _setStatus, _dataSize, _ext,
|
||||
_src1, _imm8, _dest, _dataSize, _ext,
|
||||
%(op_class)s)
|
||||
{
|
||||
buildMe();
|
||||
|
@ -305,46 +227,74 @@ def template MicroRegOpImmConstructor {{
|
|||
}};
|
||||
|
||||
let {{
|
||||
class X86MicroMeta(type):
|
||||
def __new__(mcls, name, bases, dict):
|
||||
abstract = False
|
||||
if "abstract" in dict:
|
||||
abstract = dict['abstract']
|
||||
del dict['abstract']
|
||||
|
||||
cls = type.__new__(mcls, name, bases, dict)
|
||||
if not abstract:
|
||||
allClasses[name] = cls
|
||||
return cls
|
||||
|
||||
class XXX86Microop(object):
|
||||
__metaclass__ = X86MicroMeta
|
||||
abstract = True
|
||||
|
||||
class RegOp(X86Microop):
|
||||
def __init__(self, dest, src1, src2, setStatus):
|
||||
abstract = True
|
||||
def __init__(self, dest, src1, src2, flags, dataSize):
|
||||
self.dest = dest
|
||||
self.src1 = src1
|
||||
self.src2 = src2
|
||||
self.setStatus = setStatus
|
||||
self.dataSize = "env.dataSize"
|
||||
self.flags = flags
|
||||
self.dataSize = dataSize
|
||||
if flags is None:
|
||||
self.ext = 0
|
||||
else:
|
||||
if not isinstance(flags, (list, tuple)):
|
||||
raise Exception, "flags must be a list or tuple of flags"
|
||||
self.ext = " | ".join(flags)
|
||||
self.className += "Flags"
|
||||
|
||||
def getAllocator(self, *microFlags):
|
||||
allocator = '''new %(class_name)s(machInst, mnemonic
|
||||
%(flags)s, %(src1)s, %(src2)s, %(dest)s,
|
||||
%(setStatus)s, %(dataSize)s, %(ext)s)''' % {
|
||||
%(dataSize)s, %(ext)s)''' % {
|
||||
"class_name" : self.className,
|
||||
"flags" : self.microFlagsText(microFlags),
|
||||
"src1" : self.src1, "src2" : self.src2,
|
||||
"dest" : self.dest,
|
||||
"setStatus" : self.cppBool(self.setStatus),
|
||||
"dataSize" : self.dataSize,
|
||||
"ext" : self.ext}
|
||||
return allocator
|
||||
|
||||
class RegOpImm(X86Microop):
|
||||
def __init__(self, dest, src1, imm8, setStatus):
|
||||
abstract = True
|
||||
def __init__(self, dest, src1, imm8, flags, dataSize):
|
||||
self.dest = dest
|
||||
self.src1 = src1
|
||||
self.imm8 = imm8
|
||||
self.setStatus = setStatus
|
||||
self.dataSize = "env.dataSize"
|
||||
self.flags = flags
|
||||
self.dataSize = dataSize
|
||||
if flags is None:
|
||||
self.ext = 0
|
||||
else:
|
||||
if not isinstance(flags, (list, tuple)):
|
||||
raise Exception, "flags must be a list or tuple of flags"
|
||||
self.ext = " | ".join(flags)
|
||||
self.className += "Flags"
|
||||
|
||||
def getAllocator(self, *microFlags):
|
||||
allocator = '''new %(class_name)s(machInst, mnemonic
|
||||
%(flags)s, %(src1)s, %(imm8)s, %(dest)s,
|
||||
%(setStatus)s, %(dataSize)s, %(ext)s)''' % {
|
||||
%(dataSize)s, %(ext)s)''' % {
|
||||
"class_name" : self.className,
|
||||
"flags" : self.microFlagsText(microFlags),
|
||||
"src1" : self.src1, "imm8" : self.imm8,
|
||||
"dest" : self.dest,
|
||||
"setStatus" : self.cppBool(self.setStatus),
|
||||
"dataSize" : self.dataSize,
|
||||
"ext" : self.ext}
|
||||
return allocator
|
||||
|
@ -358,7 +308,8 @@ let {{
|
|||
decoder_output = ""
|
||||
exec_output = ""
|
||||
|
||||
def setUpMicroRegOp(name, Name, base, code, child, flagCode):
|
||||
# A function which builds the C++ classes that implement the microops
|
||||
def setUpMicroRegOp(name, Name, base, code, flagCode = "", condCheck = "true", elseCode = ";"):
|
||||
global header_output
|
||||
global decoder_output
|
||||
global exec_output
|
||||
|
@ -366,14 +317,21 @@ let {{
|
|||
|
||||
iop = InstObjParams(name, Name, base,
|
||||
{"code" : code,
|
||||
"flag_code" : flagCode})
|
||||
"flag_code" : flagCode,
|
||||
"cond_check" : condCheck,
|
||||
"else_code" : elseCode})
|
||||
header_output += MicroRegOpDeclare.subst(iop)
|
||||
decoder_output += MicroRegOpConstructor.subst(iop)
|
||||
exec_output += MicroRegOpExecute.subst(iop)
|
||||
|
||||
microopClasses[name] = child
|
||||
|
||||
def defineMicroRegOp(mnemonic, code, flagCode):
|
||||
checkCCFlagBits = "checkCondition(ccFlagBits)"
|
||||
genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);"
|
||||
|
||||
|
||||
# This creates a python representations of a microop which are a cross
|
||||
# product of reg/immediate and flag/no flag versions.
|
||||
def defineMicroRegOp(mnemonic, code, subtract = False, cc=False, elseCode=";"):
|
||||
Name = mnemonic
|
||||
name = mnemonic.lower()
|
||||
|
||||
|
@ -384,36 +342,47 @@ let {{
|
|||
regCode = matcher.sub("SrcReg2", code)
|
||||
immCode = matcher.sub("imm8", code)
|
||||
|
||||
# Build the all register version of this micro op
|
||||
if subtract:
|
||||
secondSrc = "-op2, true"
|
||||
else:
|
||||
secondSrc = "op2"
|
||||
|
||||
if not cc:
|
||||
flagCode = genCCFlagBits % secondSrc
|
||||
condCode = "true"
|
||||
else:
|
||||
flagCode = ""
|
||||
condCode = checkCCFlagBits
|
||||
|
||||
regFlagCode = matcher.sub("SrcReg2", flagCode)
|
||||
immFlagCode = matcher.sub("imm8", flagCode)
|
||||
|
||||
class RegOpChild(RegOp):
|
||||
def __init__(self, dest, src1, src2, setStatus=False):
|
||||
super(RegOpChild, self).__init__(dest, src1, src2, setStatus)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
mnemonic = name
|
||||
className = Name
|
||||
def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
|
||||
super(RegOpChild, self).__init__(dest, src1, src2, flags, dataSize)
|
||||
|
||||
setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, flagCode);
|
||||
microopClasses[name] = RegOpChild
|
||||
|
||||
setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
|
||||
setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
|
||||
flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode);
|
||||
|
||||
# Build the immediate version of this micro op
|
||||
class RegOpChildImm(RegOpImm):
|
||||
def __init__(self, dest, src1, src2, setStatus=False):
|
||||
super(RegOpChildImm, self).__init__(dest, src1, src2, setStatus)
|
||||
self.className = Name + "Imm"
|
||||
self.mnemonic = name + "i"
|
||||
mnemonic = name + 'i'
|
||||
className = Name + 'Imm'
|
||||
def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
|
||||
super(RegOpChildImm, self).__init__(dest, src1, src2, flags, dataSize)
|
||||
|
||||
setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, flagCode);
|
||||
microopClasses[name + 'i'] = RegOpChildImm
|
||||
|
||||
defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to set OF,CF,SF
|
||||
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', "")
|
||||
defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to add in CF, set OF,CF,SF
|
||||
defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to subtract CF, set OF,CF,SF
|
||||
defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', "")
|
||||
defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to set OF,CF,SF
|
||||
defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', "")
|
||||
defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', "") #Needs to set OF,CF,SF and not DestReg
|
||||
defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', "")
|
||||
setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode);
|
||||
setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
|
||||
flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
|
||||
|
||||
# This has it's own function because Wr ops have implicit destinations
|
||||
def defineMicroRegOpWr(mnemonic, code):
|
||||
def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
|
||||
Name = mnemonic
|
||||
name = mnemonic.lower()
|
||||
|
||||
|
@ -424,25 +393,29 @@ let {{
|
|||
regCode = matcher.sub("SrcReg2", code)
|
||||
immCode = matcher.sub("imm8", code)
|
||||
|
||||
# Build the all register version of this micro op
|
||||
class RegOpChild(RegOp):
|
||||
def __init__(self, src1, src2):
|
||||
super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, False)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
mnemonic = name
|
||||
className = Name
|
||||
def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
|
||||
super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
|
||||
|
||||
setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, "");
|
||||
microopClasses[name] = RegOpChild
|
||||
|
||||
setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
|
||||
setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
|
||||
condCheck = checkCCFlagBits, elseCode = elseCode);
|
||||
|
||||
# Build the immediate version of this micro op
|
||||
class RegOpChildImm(RegOpImm):
|
||||
def __init__(self, src1, src2):
|
||||
super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, False)
|
||||
self.className = Name + "Imm"
|
||||
self.mnemonic = name + "i"
|
||||
mnemonic = name + 'i'
|
||||
className = Name + 'Imm'
|
||||
def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
|
||||
super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
|
||||
|
||||
setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, "");
|
||||
microopClasses[name + 'i'] = RegOpChildImm
|
||||
|
||||
defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2')
|
||||
setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode);
|
||||
setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
|
||||
condCheck = checkCCFlagBits, elseCode = elseCode);
|
||||
|
||||
# This has it's own function because Rd ops don't always have two parameters
|
||||
def defineMicroRegOpRd(mnemonic, code):
|
||||
|
@ -450,30 +423,136 @@ let {{
|
|||
name = mnemonic.lower()
|
||||
|
||||
class RegOpChild(RegOp):
|
||||
def __init__(self, dest, src1 = "NUM_INTREGS"):
|
||||
super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", False)
|
||||
def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"):
|
||||
super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
|
||||
setUpMicroRegOp(name, Name, "RegOp", code, RegOpChild, "");
|
||||
microopClasses[name] = RegOpChild
|
||||
|
||||
defineMicroRegOpRd('Rdip', 'DestReg = RIP')
|
||||
setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
|
||||
|
||||
def defineMicroRegOpImm(mnemonic, code):
|
||||
Name = mnemonic
|
||||
name = mnemonic.lower()
|
||||
|
||||
class RegOpChild(RegOpImm):
|
||||
def __init__(self, dest, src1, src2):
|
||||
super(RegOpChild, self).__init__(dest, src1, src2, False)
|
||||
def __init__(self, dest, src1, src2, dataSize="env.dataSize"):
|
||||
super(RegOpChild, self).__init__(dest, src1, src2, None, dataSize)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
|
||||
setUpMicroRegOp(name, Name, "RegOpImm", code, RegOpChild, "");
|
||||
microopClasses[name] = RegOpChild
|
||||
|
||||
setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
|
||||
|
||||
defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
|
||||
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
|
||||
defineMicroRegOp('Adc', '''
|
||||
CCFlagBits flags = ccFlagBits;
|
||||
DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Sbb', '''
|
||||
CCFlagBits flags = ccFlagBits;
|
||||
DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
|
||||
''', True)
|
||||
defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
|
||||
defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
|
||||
defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
|
||||
# defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
|
||||
defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
|
||||
defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
|
||||
elseCode='DestReg=DestReg;', cc=True)
|
||||
|
||||
# Shift instructions
|
||||
defineMicroRegOp('Sll', '''
|
||||
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Srl', '''
|
||||
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
// Because what happens to the bits shift -in- on a right shift
|
||||
// is not defined in the C/C++ standard, we have to mask them out
|
||||
// to be sure they're zero.
|
||||
uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
|
||||
DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) & logicalMask, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Sra', '''
|
||||
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
// Because what happens to the bits shift -in- on a right shift
|
||||
// is not defined in the C/C++ standard, we have to sign extend
|
||||
// them manually to be sure.
|
||||
uint64_t arithMask =
|
||||
-bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
|
||||
DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Ror', '''
|
||||
uint8_t shiftAmt =
|
||||
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
if(shiftAmt)
|
||||
{
|
||||
uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
|
||||
uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
|
||||
DestReg = merge(DestReg, top | bottom, dataSize);
|
||||
}
|
||||
else
|
||||
DestReg = DestReg;
|
||||
''')
|
||||
defineMicroRegOp('Rcr', '''
|
||||
uint8_t shiftAmt =
|
||||
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
if(shiftAmt)
|
||||
{
|
||||
CCFlagBits flags = ccFlagBits;
|
||||
uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
|
||||
if(shiftAmt > 1)
|
||||
top |= SrcReg1 << (dataSize * 8 - shiftAmt - 1);
|
||||
uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
|
||||
DestReg = merge(DestReg, top | bottom, dataSize);
|
||||
}
|
||||
else
|
||||
DestReg = DestReg;
|
||||
''')
|
||||
defineMicroRegOp('Rol', '''
|
||||
uint8_t shiftAmt =
|
||||
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
if(shiftAmt)
|
||||
{
|
||||
uint64_t top = SrcReg1 << shiftAmt;
|
||||
uint64_t bottom =
|
||||
bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
|
||||
DestReg = merge(DestReg, top | bottom, dataSize);
|
||||
}
|
||||
else
|
||||
DestReg = DestReg;
|
||||
''')
|
||||
defineMicroRegOp('Rcl', '''
|
||||
uint8_t shiftAmt =
|
||||
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
if(shiftAmt)
|
||||
{
|
||||
CCFlagBits flags = ccFlagBits;
|
||||
uint64_t top = SrcReg1 << shiftAmt;
|
||||
uint64_t bottom = flags.CF << (shiftAmt - 1);
|
||||
if(shiftAmt > 1)
|
||||
bottom |=
|
||||
bits(SrcReg1, dataSize * 8 - 1,
|
||||
dataSize * 8 - shiftAmt + 1);
|
||||
DestReg = merge(DestReg, top | bottom, dataSize);
|
||||
}
|
||||
else
|
||||
DestReg = DestReg;
|
||||
''')
|
||||
|
||||
defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
|
||||
|
||||
defineMicroRegOpRd('Rdip', 'DestReg = RIP')
|
||||
|
||||
defineMicroRegOpImm('Sext', '''
|
||||
IntReg val = SrcReg1;
|
||||
int sign_bit = bits(val, imm8-1, imm8-1);
|
||||
val = sign_bit ? (val | ~mask(imm8)) : val;
|
||||
DestReg = merge(DestReg, val, dataSize);''')
|
||||
|
||||
defineMicroRegOpImm('Zext', 'DestReg = bits(SrcReg1, imm8-1, 0);')
|
||||
}};
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
output header {{
|
||||
class MicroFault : public X86MicroopBase
|
||||
class MicroFault : public X86ISA::X86MicroopBase
|
||||
{
|
||||
protected:
|
||||
Fault fault;
|
||||
|
@ -75,6 +75,9 @@ output header {{
|
|||
Fault _fault);
|
||||
|
||||
%(BasicExecDeclare)s
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
|
@ -106,6 +109,22 @@ output decoder {{
|
|||
}
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string MicroFault::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
if(fault)
|
||||
response << fault->name();
|
||||
else
|
||||
response << "No Fault";
|
||||
|
||||
return response.str();
|
||||
}
|
||||
}};
|
||||
|
||||
let {{
|
||||
class Fault(X86Microop):
|
||||
def __init__(self, fault):
|
||||
|
|
|
@ -102,6 +102,8 @@ def operands {{
|
|||
'Base': ('IntReg', 'uqw', 'base', 'IsInteger', 4),
|
||||
'Index': ('IntReg', 'uqw', 'index', 'IsInteger', 5),
|
||||
'Data': ('IntReg', 'uqw', 'data', 'IsInteger', 6),
|
||||
'rax': ('IntReg', 'uqw', 'INTREG_RAX', 'IsInteger', 7),
|
||||
'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 10),
|
||||
'ccFlagBits': ('IntReg', 'uqw', 'NUM_INTREGS + NumMicroIntRegs', None, 20),
|
||||
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
|
||||
}};
|
||||
|
|
91
src/arch/x86/isa/outputblock.isa
Normal file
91
src/arch/x86/isa/outputblock.isa
Normal file
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use of this software in source and binary forms,
|
||||
// with or without modification, are permitted provided that the
|
||||
// following conditions are met:
|
||||
//
|
||||
// The software must be used only for Non-Commercial Use which means any
|
||||
// use which is NOT directed to receiving any direct monetary
|
||||
// compensation for, or commercial advantage from such use. Illustrative
|
||||
// examples of non-commercial use are academic research, personal study,
|
||||
// teaching, education and corporate research & development.
|
||||
// Illustrative examples of commercial use are distributing products for
|
||||
// commercial advantage and providing services using the software for
|
||||
// commercial advantage.
|
||||
//
|
||||
// If you wish to use this software or functionality therein that may be
|
||||
// covered by patents for commercial use, please contact:
|
||||
// Director of Intellectual Property Licensing
|
||||
// Office of Strategy and Technology
|
||||
// Hewlett-Packard Company
|
||||
// 1501 Page Mill Road
|
||||
// Palo Alto, California 94304
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer. Redistributions
|
||||
// in binary form must reproduce the above copyright notice, this list of
|
||||
// conditions and the following disclaimer in the documentation and/or
|
||||
// other materials provided with the distribution. Neither the name of
|
||||
// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission. No right of
|
||||
// sublicense is granted herewith. Derivatives of the software and
|
||||
// output created using the software may be prepared, but only for
|
||||
// Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
// others provided: (i) the others agree to abide by the list of
|
||||
// conditions herein which includes the Non-Commercial Use restrictions;
|
||||
// and (ii) such Derivatives of the software include the above copyright
|
||||
// notice to acknowledge the contribution from this software where
|
||||
// applicable, this list of conditions and the disclaimer below.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: Gabe Black
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Output blocks which group together code generated by the parser.
|
||||
//
|
||||
|
||||
let {{
|
||||
# This class will help make dealing with output a little less verbose
|
||||
class OutputBlocks(object):
|
||||
def __init__(self, header_output="",
|
||||
decoder_output="",
|
||||
decode_block="",
|
||||
exec_output=""):
|
||||
self.header_output = header_output
|
||||
self.decoder_output = decoder_output
|
||||
self.decode_block = decode_block
|
||||
self.exec_output = exec_output
|
||||
|
||||
def append(self, blocks):
|
||||
if isinstance(blocks, list) or isinstance(blocks, tuple):
|
||||
assert(len(blocks) == 4)
|
||||
self.header_output += blocks[0]
|
||||
self.decoder_output += blocks[1]
|
||||
self.decode_block += blocks[2]
|
||||
self.exec_output += blocks[3]
|
||||
else:
|
||||
self.header_output += blocks.header_output
|
||||
self.decoder_output += blocks.decoder_output
|
||||
self.decode_block += blocks.decode_block
|
||||
self.exec_output += blocks.exec_output
|
||||
|
||||
def makeList(self):
|
||||
return (self.header_output,
|
||||
self.decoder_output,
|
||||
self.decode_block,
|
||||
self.exec_output)
|
||||
}};
|
|
@ -118,6 +118,7 @@ let {{
|
|||
|
||||
ModRMRegIndex = "(MODRM_REG | (REX_R << 3))"
|
||||
ModRMRMIndex = "(MODRM_RM | (REX_B << 3))"
|
||||
InstRegIndex = "(OPCODE_OP_BOTTOM3 | (REX_B << 3))"
|
||||
|
||||
# This function specializes the given piece of code to use a particular
|
||||
# set of argument types described by "opTypes".
|
||||
|
@ -143,6 +144,10 @@ let {{
|
|||
else:
|
||||
print "Didn't recognize fixed register size %s!" % opType.rsize
|
||||
Name += "_R"
|
||||
elif opType.tag == "B":
|
||||
# This refers to registers whose index is encoded as part of the opcode
|
||||
Name += "_R"
|
||||
env.addReg(InstRegIndex)
|
||||
elif opType.tag == "M":
|
||||
# This refers to memory. The macroop constructor sets up modrm
|
||||
# addressing. Non memory modrm settings should cause an error.
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
*/
|
||||
|
||||
#include "arch/x86/linux/process.hh"
|
||||
#include "arch/x86/linux/linux.hh"
|
||||
#include "kern/linux/linux.hh"
|
||||
#include "sim/syscall_emul.hh"
|
||||
|
||||
|
@ -82,7 +83,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
SyscallDesc X86LinuxProcess::syscallDescs[] = {
|
||||
/* 0 */ SyscallDesc("read", unimplementedFunc),
|
||||
/* 1 */ SyscallDesc("write", unimplementedFunc),
|
||||
/* 2 */ SyscallDesc("open", unimplementedFunc),
|
||||
/* 2 */ SyscallDesc("open", openFunc<X86Linux>),
|
||||
/* 3 */ SyscallDesc("close", unimplementedFunc),
|
||||
/* 4 */ SyscallDesc("stat", unimplementedFunc),
|
||||
/* 5 */ SyscallDesc("fstat", unimplementedFunc),
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
*/
|
||||
|
||||
#include "arch/x86/miscregfile.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
using namespace X86ISA;
|
||||
using namespace std;
|
||||
|
@ -105,31 +106,65 @@ void MiscRegFile::clear()
|
|||
|
||||
MiscReg MiscRegFile::readRegNoEffect(int miscReg)
|
||||
{
|
||||
panic("No misc registers in x86 yet!\n");
|
||||
switch(miscReg)
|
||||
{
|
||||
case MISCREG_CR1:
|
||||
case MISCREG_CR5:
|
||||
case MISCREG_CR6:
|
||||
case MISCREG_CR7:
|
||||
case MISCREG_CR9:
|
||||
case MISCREG_CR10:
|
||||
case MISCREG_CR11:
|
||||
case MISCREG_CR12:
|
||||
case MISCREG_CR13:
|
||||
case MISCREG_CR14:
|
||||
case MISCREG_CR15:
|
||||
panic("Tried to read invalid control register %d\n", miscReg);
|
||||
break;
|
||||
}
|
||||
return regVal[miscReg];
|
||||
}
|
||||
|
||||
MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
|
||||
{
|
||||
panic("No misc registers in x86 yet!\n");
|
||||
warn("No miscreg effects implemented yet!\n");
|
||||
return readRegNoEffect(miscReg);
|
||||
}
|
||||
|
||||
void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
|
||||
{
|
||||
panic("No misc registers in x86 yet!\n");
|
||||
switch(miscReg)
|
||||
{
|
||||
case MISCREG_CR1:
|
||||
case MISCREG_CR5:
|
||||
case MISCREG_CR6:
|
||||
case MISCREG_CR7:
|
||||
case MISCREG_CR9:
|
||||
case MISCREG_CR10:
|
||||
case MISCREG_CR11:
|
||||
case MISCREG_CR12:
|
||||
case MISCREG_CR13:
|
||||
case MISCREG_CR14:
|
||||
case MISCREG_CR15:
|
||||
panic("Tried to write invalid control register %d\n", miscReg);
|
||||
break;
|
||||
}
|
||||
regVal[miscReg] = val;
|
||||
}
|
||||
|
||||
void MiscRegFile::setReg(int miscReg,
|
||||
const MiscReg &val, ThreadContext * tc)
|
||||
{
|
||||
panic("No misc registers in x86 yet!\n");
|
||||
warn("No miscreg effects implemented yet!\n");
|
||||
setRegNoEffect(miscReg, val);
|
||||
}
|
||||
|
||||
void MiscRegFile::serialize(std::ostream & os)
|
||||
{
|
||||
panic("No misc registers in x86 yet!\n");
|
||||
SERIALIZE_ARRAY(regVal, NumMiscRegs);
|
||||
}
|
||||
|
||||
void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
|
||||
{
|
||||
panic("No misc registers in x86 yet!\n");
|
||||
UNSERIALIZE_ARRAY(regVal, NumMiscRegs);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
#define __ARCH_X86_MISCREGFILE_HH__
|
||||
|
||||
#include "arch/x86/faults.hh"
|
||||
#include "arch/x86/miscregs.hh"
|
||||
#include "arch/x86/types.hh"
|
||||
|
||||
#include <string>
|
||||
|
@ -100,11 +101,14 @@ namespace X86ISA
|
|||
std::string getMiscRegName(RegIndex);
|
||||
|
||||
//These will have to be updated in the future.
|
||||
const int NumMiscArchRegs = 0;
|
||||
const int NumMiscRegs = 0;
|
||||
const int NumMiscArchRegs = NUM_MISCREGS;
|
||||
const int NumMiscRegs = NUM_MISCREGS;
|
||||
|
||||
class MiscRegFile
|
||||
{
|
||||
protected:
|
||||
MiscReg regVal[NumMiscRegs];
|
||||
|
||||
public:
|
||||
void clear();
|
||||
|
||||
|
|
329
src/arch/x86/miscregs.hh
Normal file
329
src/arch/x86/miscregs.hh
Normal file
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_X86_MISCREGS_HH__
|
||||
#define __ARCH_X86_MISCREGS_HH__
|
||||
|
||||
#include "base/bitunion.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
enum CondFlagBit {
|
||||
CFBit = 1 << 0,
|
||||
PFBit = 1 << 2,
|
||||
ECFBit = 1 << 3,
|
||||
AFBit = 1 << 4,
|
||||
EZFBit = 1 << 5,
|
||||
ZFBit = 1 << 6,
|
||||
SFBit = 1 << 7,
|
||||
OFBit = 1 << 11
|
||||
};
|
||||
|
||||
enum MiscRegIndex
|
||||
{
|
||||
// Control registers
|
||||
// Most of these are invalid.
|
||||
MISCREG_CR0,
|
||||
MISCREG_CR1,
|
||||
MISCREG_CR2,
|
||||
MISCREG_CR3,
|
||||
MISCREG_CR4,
|
||||
MISCREG_CR5,
|
||||
MISCREG_CR6,
|
||||
MISCREG_CR7,
|
||||
MISCREG_CR8,
|
||||
MISCREG_CR9,
|
||||
MISCREG_CR10,
|
||||
MISCREG_CR11,
|
||||
MISCREG_CR12,
|
||||
MISCREG_CR13,
|
||||
MISCREG_CR14,
|
||||
MISCREG_CR15,
|
||||
|
||||
// Debug registers
|
||||
MISCREG_DR0,
|
||||
MISCREG_DR1,
|
||||
MISCREG_DR2,
|
||||
MISCREG_DR3,
|
||||
MISCREG_DR4,
|
||||
MISCREG_DR5,
|
||||
MISCREG_DR6,
|
||||
MISCREG_DR7,
|
||||
|
||||
// Flags register
|
||||
MISCREG_RFLAGS,
|
||||
|
||||
// Segment selectors
|
||||
MISCREG_ES,
|
||||
MISCREG_CS,
|
||||
MISCREG_SS,
|
||||
MISCREG_DS,
|
||||
MISCREG_FS,
|
||||
MISCREG_GS,
|
||||
|
||||
// Hidden segment base field
|
||||
MISCREG_ES_BASE,
|
||||
MISCREG_CS_BASE,
|
||||
MISCREG_SS_BASE,
|
||||
MISCREG_DS_BASE,
|
||||
MISCREG_FS_BASE,
|
||||
MISCREG_GS_BASE,
|
||||
|
||||
// Hidden segment limit field
|
||||
MISCREG_ES_LIMIT,
|
||||
MISCREG_CS_LIMIT,
|
||||
MISCREG_SS_LIMIT,
|
||||
MISCREG_DS_LIMIT,
|
||||
MISCREG_FS_LIMIT,
|
||||
MISCREG_GS_LIMIT,
|
||||
|
||||
// Hidden segment limit attributes
|
||||
MISCREG_ES_ATTR,
|
||||
MISCREG_CS_ATTR,
|
||||
MISCREG_SS_ATTR,
|
||||
MISCREG_DS_ATTR,
|
||||
MISCREG_FS_ATTR,
|
||||
MISCREG_GS_ATTR,
|
||||
|
||||
// System segment selectors
|
||||
MISCREG_LDTR,
|
||||
MISCREG_TR,
|
||||
|
||||
// Hidden system segment base field
|
||||
MISCREG_LDTR_BASE,
|
||||
MISCREG_TR_BASE,
|
||||
MISCREG_GDTR_BASE,
|
||||
MISCREG_IDTR_BASE,
|
||||
|
||||
// Hidden system segment limit field
|
||||
MISCREG_LDTR_LIMIT,
|
||||
MISCREG_TR_LIMIT,
|
||||
MISCREG_GDTR_LIMIT,
|
||||
MISCREG_IDTR_LIMIT,
|
||||
|
||||
// Hidden system segment attribute field
|
||||
MISCREG_LDTR_ATTR,
|
||||
MISCREG_TR_ATTR,
|
||||
|
||||
//XXX Add "Model-Specific Registers"
|
||||
|
||||
NUM_MISCREGS
|
||||
};
|
||||
|
||||
/**
|
||||
* A type to describe the condition code bits of the RFLAGS register,
|
||||
* plus two flags, EZF and ECF, which are only visible to microcode.
|
||||
*/
|
||||
BitUnion64(CCFlagBits)
|
||||
Bitfield<11> OF;
|
||||
Bitfield<7> SF;
|
||||
Bitfield<6> ZF;
|
||||
Bitfield<5> EZF;
|
||||
Bitfield<4> AF;
|
||||
Bitfield<3> ECF;
|
||||
Bitfield<2> PF;
|
||||
Bitfield<0> CF;
|
||||
EndBitUnion(CCFlagBits)
|
||||
|
||||
/**
|
||||
* RFLAGS
|
||||
*/
|
||||
BitUnion64(RFLAGS)
|
||||
Bitfield<21> ID; // ID Flag
|
||||
Bitfield<20> VIP; // Virtual Interrupt Pending
|
||||
Bitfield<19> VIF; // Virtual Interrupt Flag
|
||||
Bitfield<18> AC; // Alignment Check
|
||||
Bitfield<17> VM; // Virtual-8086 Mode
|
||||
Bitfield<16> RF; // Resume Flag
|
||||
Bitfield<14> NT; // Nested Task
|
||||
Bitfield<13, 12> IOPL; // I/O Privilege Level
|
||||
Bitfield<11> OF; // Overflow Flag
|
||||
Bitfield<10> DF; // Direction Flag
|
||||
Bitfield<9> IF; // Interrupt Flag
|
||||
Bitfield<8> TF; // Trap Flag
|
||||
Bitfield<7> SF; // Sign Flag
|
||||
Bitfield<6> ZF; // Zero Flag
|
||||
Bitfield<4> AF; // Auxiliary Flag
|
||||
Bitfield<2> PF; // Parity Flag
|
||||
Bitfield<0> CF; // Carry Flag
|
||||
EndBitUnion(RFLAGS)
|
||||
|
||||
/**
|
||||
* Control registers
|
||||
*/
|
||||
BitUnion64(CR0)
|
||||
Bitfield<31> PG; // Paging
|
||||
Bitfield<30> CD; // Cache Disable
|
||||
Bitfield<29> NW; // Not Writethrough
|
||||
Bitfield<18> AM; // Alignment Mask
|
||||
Bitfield<16> WP; // Write Protect
|
||||
Bitfield<5> NE; // Numeric Error
|
||||
Bitfield<4> ET; // Extension Type
|
||||
Bitfield<3> TS; // Task Switched
|
||||
Bitfield<2> EM; // Emulation
|
||||
Bitfield<1> MP; // Monitor Coprocessor
|
||||
Bitfield<0> PE; // Protection Enabled
|
||||
EndBitUnion(CR0)
|
||||
|
||||
// Page Fault Virtual Address
|
||||
BitUnion64(CR2)
|
||||
Bitfield<31, 0> legacy;
|
||||
EndBitUnion(CR2)
|
||||
|
||||
BitUnion64(CR3)
|
||||
Bitfield<51, 12> longPDTB; // Long Mode Page-Directory-Table
|
||||
// Base Address
|
||||
Bitfield<31, 12> PDTB; // Non-PAE Addressing Page-Directory-Table
|
||||
// Base Address
|
||||
Bitfield<31, 5> PAEPDTB; // PAE Addressing Page-Directory-Table
|
||||
// Base Address
|
||||
Bitfield<4> PCD; // Page-Level Cache Disable
|
||||
Bitfield<3> PWT; // Page-Level Writethrough
|
||||
EndBitUnion(CR3)
|
||||
|
||||
BitUnion64(CR4)
|
||||
Bitfield<10> OSXMMEXCPT; // Operating System Unmasked
|
||||
// Exception Support
|
||||
Bitfield<9> OSFXSR; // Operating System FXSave/FSRSTOR Support
|
||||
Bitfield<8> PCE; // Performance-Monitoring Counter Enable
|
||||
Bitfield<7> PGE; // Page-Global Enable
|
||||
Bitfield<6> MCE; // Machine Check Enable
|
||||
Bitfield<5> PAE; // Physical-Address Extension
|
||||
Bitfield<4> PSE; // Page Size Extensions
|
||||
Bitfield<3> DE; // Debugging Extensions
|
||||
Bitfield<2> TSD; // Time Stamp Disable
|
||||
Bitfield<1> PVI; // Protected-Mode Virtual Interrupts
|
||||
Bitfield<0> VME; // Virtual-8086 Mode Extensions
|
||||
EndBitUnion(CR4)
|
||||
|
||||
BitUnion64(CR8)
|
||||
Bitfield<3, 0> TPR; // Task Priority Register
|
||||
EndBitUnion(CR4)
|
||||
|
||||
/**
|
||||
* Segment Selector
|
||||
*/
|
||||
BitUnion64(SegSelector)
|
||||
Bitfield<15, 3> SI; // Selector Index
|
||||
Bitfield<2> TI; // Table Indicator
|
||||
Bitfield<1, 0> RPL; // Requestor Privilege Level
|
||||
EndBitUnion(SegSelector)
|
||||
|
||||
/**
|
||||
* Segment Descriptors
|
||||
*/
|
||||
|
||||
BitUnion64(SegDescriptor)
|
||||
Bitfield<63, 56> baseHigh;
|
||||
Bitfield<39, 16> baseLow;
|
||||
Bitfield<55> G; // Granularity
|
||||
Bitfield<54> D; // Default Operand Size
|
||||
Bitfield<54> B; // Default Operand Size
|
||||
Bitfield<53> L; // Long Attribute Bit
|
||||
Bitfield<52> AVL; // Available To Software
|
||||
Bitfield<51, 48> limitHigh;
|
||||
Bitfield<15, 0> limitLow;
|
||||
Bitfield<47> P; // Present
|
||||
Bitfield<46, 45> DPL; // Descriptor Privilege-Level
|
||||
Bitfield<44> S; // System
|
||||
SubBitUnion(type, 43, 40)
|
||||
// Specifies whether this descriptor is for code or data.
|
||||
Bitfield<43> codeOrData;
|
||||
|
||||
// These bit fields are for code segments
|
||||
Bitfield<42> C; // Conforming
|
||||
Bitfield<41> R; // Readable
|
||||
|
||||
// These bit fields are for data segments
|
||||
Bitfield<42> E; // Expand-Down
|
||||
Bitfield<41> W; // Writable
|
||||
|
||||
// This is used for both code and data segments.
|
||||
Bitfield<40> A; // Accessed
|
||||
EndSubBitUnion(type)
|
||||
EndBitUnion(SegDescriptor)
|
||||
|
||||
BitUnion64(GateDescriptor)
|
||||
Bitfield<63, 48> offsetHigh; // Target Code-Segment Offset
|
||||
Bitfield<15, 0> offsetLow; // Target Code-Segment Offset
|
||||
Bitfield<31, 16> selector; // Target Code-Segment Selector
|
||||
Bitfield<47> P; // Present
|
||||
Bitfield<46, 45> DPL; // Descriptor Privilege-Level
|
||||
Bitfield<43, 40> type;
|
||||
Bitfield<36, 32> count; // Parameter Count
|
||||
EndBitUnion(GateDescriptor)
|
||||
|
||||
/**
|
||||
* Descriptor-Table Registers
|
||||
*/
|
||||
BitUnion64(GDTR)
|
||||
EndBitUnion(GDTR)
|
||||
|
||||
BitUnion64(IDTR)
|
||||
EndBitUnion(IDTR)
|
||||
|
||||
BitUnion64(LDTR)
|
||||
EndBitUnion(LDTR)
|
||||
|
||||
/**
|
||||
* Task Register
|
||||
*/
|
||||
BitUnion64(TR)
|
||||
EndBitUnion(TR)
|
||||
};
|
||||
|
||||
#endif // __ARCH_X86_INTREGS_HH__
|
|
@ -72,7 +72,6 @@ namespace X86ISA
|
|||
|
||||
immediateCollected = 0;
|
||||
emi.immediate = 0;
|
||||
displacementCollected = 0;
|
||||
emi.displacement = 0;
|
||||
|
||||
emi.modRM = 0;
|
||||
|
@ -235,14 +234,42 @@ namespace X86ISA
|
|||
logOpSize = 1; // 16 bit operand size
|
||||
}
|
||||
|
||||
//Set the actual op size
|
||||
emi.opSize = 1 << logOpSize;
|
||||
|
||||
//Figure out the effective address size. This can be overriden to
|
||||
//a fixed value at the decoder level.
|
||||
int logAddrSize;
|
||||
if(/*FIXME 64-bit mode*/1)
|
||||
{
|
||||
if(emi.legacy.addr)
|
||||
logAddrSize = 2; // 32 bit address size
|
||||
else
|
||||
logAddrSize = 3; // 64 bit address size
|
||||
}
|
||||
else if(/*FIXME default 32*/1)
|
||||
{
|
||||
if(emi.legacy.addr)
|
||||
logAddrSize = 1; // 16 bit address size
|
||||
else
|
||||
logAddrSize = 2; // 32 bit address size
|
||||
}
|
||||
else // 16 bit default operand size
|
||||
{
|
||||
if(emi.legacy.addr)
|
||||
logAddrSize = 2; // 32 bit address size
|
||||
else
|
||||
logAddrSize = 1; // 16 bit address size
|
||||
}
|
||||
|
||||
//Set the actual address size
|
||||
emi.addrSize = 1 << logAddrSize;
|
||||
|
||||
//Figure out how big of an immediate we'll retreive based
|
||||
//on the opcode.
|
||||
int immType = ImmediateType[emi.opcode.num - 1][nextByte];
|
||||
immediateSize = SizeTypeToSize[logOpSize - 1][immType];
|
||||
|
||||
//Set the actual op size
|
||||
emi.opSize = 1 << logOpSize;
|
||||
|
||||
//Determine what to expect next
|
||||
if (UsesModRM[emi.opcode.num - 1][nextByte]) {
|
||||
nextState = ModRMState;
|
||||
|
@ -277,8 +304,7 @@ namespace X86ISA
|
|||
displacementSize = 0;
|
||||
} else {
|
||||
//figure out 32/64 bit displacement size
|
||||
if(modRM.mod == 0 && (modRM.rm == 4 || modRM.rm == 5)
|
||||
|| modRM.mod == 2)
|
||||
if(modRM.mod == 0 && modRM.rm == 5 || modRM.mod == 2)
|
||||
displacementSize = 4;
|
||||
else if(modRM.mod == 1)
|
||||
displacementSize = 1;
|
||||
|
@ -313,6 +339,8 @@ namespace X86ISA
|
|||
emi.sib = nextByte;
|
||||
DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte);
|
||||
consumeByte();
|
||||
if(emi.modRM.mod == 0 && emi.sib.base == 5)
|
||||
displacementSize = 4;
|
||||
if(displacementSize) {
|
||||
nextState = DisplacementState;
|
||||
} else if(immediateSize) {
|
||||
|
@ -330,14 +358,16 @@ namespace X86ISA
|
|||
{
|
||||
State nextState = ErrorState;
|
||||
|
||||
getImmediate(displacementCollected,
|
||||
getImmediate(immediateCollected,
|
||||
emi.displacement,
|
||||
displacementSize);
|
||||
|
||||
DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n",
|
||||
displacementSize, displacementCollected);
|
||||
displacementSize, immediateCollected);
|
||||
|
||||
if(displacementSize == displacementCollected) {
|
||||
if(displacementSize == immediateCollected) {
|
||||
//Reset this for other immediates.
|
||||
immediateCollected = 0;
|
||||
//Sign extend the displacement
|
||||
switch(displacementSize)
|
||||
{
|
||||
|
@ -382,6 +412,9 @@ namespace X86ISA
|
|||
|
||||
if(immediateSize == immediateCollected)
|
||||
{
|
||||
//Reset this for other immediates.
|
||||
immediateCollected = 0;
|
||||
|
||||
//XXX Warning! The following is an observed pattern and might
|
||||
//not always be true!
|
||||
|
||||
|
|
|
@ -106,13 +106,13 @@ namespace X86ISA
|
|||
toGet = toGet > remaining ? remaining : toGet;
|
||||
|
||||
//Shift the bytes we want to be all the way to the right
|
||||
uint64_t partialDisp = fetchChunk >> (offset * 8);
|
||||
uint64_t partialImm = fetchChunk >> (offset * 8);
|
||||
//Mask off what we don't want
|
||||
partialDisp &= mask(toGet * 8);
|
||||
partialImm &= mask(toGet * 8);
|
||||
//Shift it over to overlay with our displacement.
|
||||
partialDisp <<= (displacementCollected * 8);
|
||||
partialImm <<= (immediateCollected * 8);
|
||||
//Put it into our displacement
|
||||
current |= partialDisp;
|
||||
current |= partialImm;
|
||||
//Update how many bytes we've collected.
|
||||
collected += toGet;
|
||||
consumeBytes(toGet);
|
||||
|
@ -144,9 +144,10 @@ namespace X86ISA
|
|||
bool emiIsReady;
|
||||
//The size of the displacement value
|
||||
int displacementSize;
|
||||
int displacementCollected;
|
||||
//The size of the immediate value
|
||||
int immediateSize;
|
||||
//This is how much of any immediate value we've gotten. This is used
|
||||
//for both the actual immediate and the displacement.
|
||||
int immediateCollected;
|
||||
|
||||
enum State {
|
||||
|
|
|
@ -59,16 +59,15 @@
|
|||
#define __ARCH_X86_SYSCALLRETURN_HH__
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "sim/syscallreturn.hh"
|
||||
|
||||
class ThreadContext;
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
static inline void setSyscallReturn(SyscallReturn return_value,
|
||||
ThreadContext * tc)
|
||||
{
|
||||
panic("setSyscallReturn not implemented!\n");
|
||||
tc->setIntReg(INTREG_RAX, return_value.value());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
#include <inttypes.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/bitunion.hh"
|
||||
#include "base/cprintf.hh"
|
||||
|
||||
namespace X86ISA
|
||||
|
@ -86,11 +86,12 @@ namespace X86ISA
|
|||
};
|
||||
|
||||
BitUnion8(LegacyPrefixVector)
|
||||
Bitfield<7, 4> decodeVal;
|
||||
Bitfield<7> repne;
|
||||
Bitfield<6> rep;
|
||||
Bitfield<5> lock;
|
||||
Bitfield<4> addr;
|
||||
Bitfield<3> op;
|
||||
Bitfield<4> op;
|
||||
Bitfield<3> addr;
|
||||
//There can be only one segment override, so they share the
|
||||
//first 3 bits in the legacyPrefixes bitfield.
|
||||
Bitfield<2,0> seg;
|
||||
|
@ -184,8 +185,8 @@ namespace X86ISA
|
|||
"prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t"
|
||||
"modRM = %#x,\n\tsib = %#x,\n\t"
|
||||
"immediate = %#x,\n\tdisplacement = %#x\n}\n",
|
||||
emi.legacy, (uint8_t)emi.rex,
|
||||
emi.opcode.num, emi.opcode.op,
|
||||
(uint8_t)emi.legacy, (uint8_t)emi.rex,
|
||||
emi.opcode.num, (uint8_t)emi.opcode.op,
|
||||
emi.opcode.prefixA, emi.opcode.prefixB,
|
||||
(uint8_t)emi.modRM, (uint8_t)emi.sib,
|
||||
emi.immediate, emi.displacement);
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
namespace X86ISA
|
||||
{
|
||||
const int NumMicroIntRegs = 16;
|
||||
const int NumPseudoIntRegs = 1;
|
||||
|
||||
const int NumMMXRegs = 8;
|
||||
const int NumXMMRegs = 16;
|
||||
|
|
|
@ -161,273 +161,4 @@ findMsbSet(uint64_t val) {
|
|||
return msb;
|
||||
}
|
||||
|
||||
// The following implements the BitUnion system of defining bitfields
|
||||
//on top of an underlying class. This is done through the pervasive use of
|
||||
//both named and unnamed unions which all contain the same actual storage.
|
||||
//Since they're unioned with each other, all of these storage locations
|
||||
//overlap. This allows all of the bitfields to manipulate the same data
|
||||
//without having to have access to each other. More details are provided with the
|
||||
//individual components.
|
||||
|
||||
//This namespace is for classes which implement the backend of the BitUnion
|
||||
//stuff. Don't use any of these directly, except for the Bitfield classes in
|
||||
//the *BitfieldTypes class(es).
|
||||
namespace BitfieldBackend
|
||||
{
|
||||
//A base class for all bitfields. It instantiates the actual storage,
|
||||
//and provides getBits and setBits functions for manipulating it. The
|
||||
//Data template parameter is type of the underlying storage.
|
||||
template<class Data>
|
||||
class BitfieldBase
|
||||
{
|
||||
protected:
|
||||
Data __data;
|
||||
|
||||
//This function returns a range of bits from the underlying storage.
|
||||
//It relies on the "bits" function above. It's the user's
|
||||
//responsibility to make sure that there is a properly overloaded
|
||||
//version of this function for whatever type they want to overlay.
|
||||
inline uint64_t
|
||||
getBits(int first, int last) const
|
||||
{
|
||||
return bits(__data, first, last);
|
||||
}
|
||||
|
||||
//Similar to the above, but for settings bits with replaceBits.
|
||||
inline void
|
||||
setBits(int first, int last, uint64_t val)
|
||||
{
|
||||
replaceBits(__data, first, last, val);
|
||||
}
|
||||
};
|
||||
|
||||
//This class contains all the "regular" bitfield classes. It is inherited
|
||||
//by all BitUnions which give them access to those types.
|
||||
template<class Type>
|
||||
class RegularBitfieldTypes
|
||||
{
|
||||
protected:
|
||||
//This class implements ordinary bitfields, that is a span of bits
|
||||
//who's msb is "first", and who's lsb is "last".
|
||||
template<int first, int last=first>
|
||||
class Bitfield : public BitfieldBase<Type>
|
||||
{
|
||||
public:
|
||||
operator uint64_t () const
|
||||
{
|
||||
return this->getBits(first, last);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
operator=(const uint64_t _data)
|
||||
{
|
||||
this->setBits(first, last, _data);
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
|
||||
//A class which specializes the above so that it can only be read
|
||||
//from. This is accomplished explicitly making sure the assignment
|
||||
//operator is blocked. The conversion operator is carried through
|
||||
//inheritance. This will unfortunately need to be copied into each
|
||||
//bitfield type due to limitations with how templates work
|
||||
template<int first, int last=first>
|
||||
class BitfieldRO : public Bitfield<first, last>
|
||||
{
|
||||
private:
|
||||
uint64_t
|
||||
operator=(const uint64_t _data);
|
||||
};
|
||||
|
||||
//Similar to the above, but only allows writing.
|
||||
template<int first, int last=first>
|
||||
class BitfieldWO : public Bitfield<first, last>
|
||||
{
|
||||
private:
|
||||
operator uint64_t () const;
|
||||
|
||||
public:
|
||||
using Bitfield<first, last>::operator=;
|
||||
};
|
||||
};
|
||||
|
||||
//This class contains all the "regular" bitfield classes. It is inherited
|
||||
//by all BitUnions which give them access to those types.
|
||||
template<class Type>
|
||||
class SignedBitfieldTypes
|
||||
{
|
||||
protected:
|
||||
//This class implements ordinary bitfields, that is a span of bits
|
||||
//who's msb is "first", and who's lsb is "last".
|
||||
template<int first, int last=first>
|
||||
class SignedBitfield : public BitfieldBase<Type>
|
||||
{
|
||||
public:
|
||||
operator int64_t () const
|
||||
{
|
||||
return sext<first - last + 1>(this->getBits(first, last));
|
||||
}
|
||||
|
||||
int64_t
|
||||
operator=(const int64_t _data)
|
||||
{
|
||||
this->setBits(first, last, _data);
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
|
||||
//A class which specializes the above so that it can only be read
|
||||
//from. This is accomplished explicitly making sure the assignment
|
||||
//operator is blocked. The conversion operator is carried through
|
||||
//inheritance. This will unfortunately need to be copied into each
|
||||
//bitfield type due to limitations with how templates work
|
||||
template<int first, int last=first>
|
||||
class SignedBitfieldRO : public SignedBitfield<first, last>
|
||||
{
|
||||
private:
|
||||
int64_t
|
||||
operator=(const int64_t _data);
|
||||
};
|
||||
|
||||
//Similar to the above, but only allows writing.
|
||||
template<int first, int last=first>
|
||||
class SignedBitfieldWO : public SignedBitfield<first, last>
|
||||
{
|
||||
private:
|
||||
operator int64_t () const;
|
||||
|
||||
public:
|
||||
int64_t operator=(const int64_t _data)
|
||||
{
|
||||
*((SignedBitfield<first, last> *)this) = _data;
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
class BitfieldTypes : public RegularBitfieldTypes<Type>,
|
||||
public SignedBitfieldTypes<Type>
|
||||
{};
|
||||
|
||||
//When a BitUnion is set up, an underlying class is created which holds
|
||||
//the actual union. This class then inherits from it, and provids the
|
||||
//implementations for various operators. Setting things up this way
|
||||
//prevents having to redefine these functions in every different BitUnion
|
||||
//type. More operators could be implemented in the future, as the need
|
||||
//arises.
|
||||
template <class Type, class Base>
|
||||
class BitUnionOperators : public Base
|
||||
{
|
||||
public:
|
||||
operator Type () const
|
||||
{
|
||||
return Base::__data;
|
||||
}
|
||||
|
||||
Type
|
||||
operator=(const Type & _data)
|
||||
{
|
||||
Base::__data = _data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const Base & base) const
|
||||
{
|
||||
return Base::__data < base.__data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const Base & base) const
|
||||
{
|
||||
return Base::__data == base.__data;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//This macro is a backend for other macros that specialize it slightly.
|
||||
//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and
|
||||
//sticks the class which has the actual union in it, which
|
||||
//BitfieldOperators above inherits from. Putting these classes in a special
|
||||
//namespace ensures that there will be no collisions with other names as long
|
||||
//as the BitUnion names themselves are all distinct and nothing else uses
|
||||
//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself
|
||||
//creates a typedef of the "type" parameter called __DataType. This allows
|
||||
//the type to propagate outside of the macro itself in a controlled way.
|
||||
//Finally, the base storage is defined which BitfieldOperators will refer to
|
||||
//in the operators it defines. This macro is intended to be followed by
|
||||
//bitfield definitions which will end up inside it's union. As explained
|
||||
//above, these is overlayed the __data member in its entirety by each of the
|
||||
//bitfields which are defined in the union, creating shared storage with no
|
||||
//overhead.
|
||||
#define __BitUnion(type, name) \
|
||||
namespace BitfieldUnderlyingClasses \
|
||||
{ \
|
||||
class name; \
|
||||
} \
|
||||
class BitfieldUnderlyingClasses::name : \
|
||||
public BitfieldBackend::BitfieldTypes<type> \
|
||||
{ \
|
||||
public: \
|
||||
typedef type __DataType; \
|
||||
union { \
|
||||
type __data;\
|
||||
|
||||
//This closes off the class and union started by the above macro. It is
|
||||
//followed by a typedef which makes "name" refer to a BitfieldOperator
|
||||
//class inheriting from the class and union just defined, which completes
|
||||
//building up the type for the user.
|
||||
#define EndBitUnion(name) \
|
||||
}; \
|
||||
}; \
|
||||
typedef BitfieldBackend::BitUnionOperators< \
|
||||
BitfieldUnderlyingClasses::name::__DataType, \
|
||||
BitfieldUnderlyingClasses::name> name;
|
||||
|
||||
//This sets up a bitfield which has other bitfields nested inside of it. The
|
||||
//__data member functions like the "underlying storage" of the top level
|
||||
//BitUnion. Like everything else, it overlays with the top level storage, so
|
||||
//making it a regular bitfield type makes the entire thing function as a
|
||||
//regular bitfield when referred to by itself.
|
||||
#define __SubBitUnion(fieldType, first, last, name) \
|
||||
class : public BitfieldBackend::BitfieldTypes<__DataType> \
|
||||
{ \
|
||||
public: \
|
||||
union { \
|
||||
fieldType<first, last> __data;
|
||||
|
||||
//This closes off the union created above and gives it a name. Unlike the top
|
||||
//level BitUnion, we're interested in creating an object instead of a type.
|
||||
//The operators are defined in the macro itself instead of a class for
|
||||
//technical reasons. If someone determines a way to move them to one, please
|
||||
//do so.
|
||||
#define EndSubBitUnion(name) \
|
||||
}; \
|
||||
inline operator const __DataType () \
|
||||
{ return __data; } \
|
||||
\
|
||||
inline const __DataType operator = (const __DataType & _data) \
|
||||
{ __data = _data; } \
|
||||
} name;
|
||||
|
||||
//Regular bitfields
|
||||
//These define macros for read/write regular bitfield based subbitfields.
|
||||
#define SubBitUnion(name, first, last) \
|
||||
__SubBitUnion(Bitfield, first, last, name)
|
||||
|
||||
//Regular bitfields
|
||||
//These define macros for read/write regular bitfield based subbitfields.
|
||||
#define SignedSubBitUnion(name, first, last) \
|
||||
__SubBitUnion(SignedBitfield, first, last, name)
|
||||
|
||||
//Use this to define an arbitrary type overlayed with bitfields.
|
||||
#define BitUnion(type, name) __BitUnion(type, name)
|
||||
|
||||
//Use this to define conveniently sized values overlayed with bitfields.
|
||||
#define BitUnion64(name) __BitUnion(uint64_t, name)
|
||||
#define BitUnion32(name) __BitUnion(uint32_t, name)
|
||||
#define BitUnion16(name) __BitUnion(uint16_t, name)
|
||||
#define BitUnion8(name) __BitUnion(uint8_t, name)
|
||||
|
||||
#endif // __BASE_BITFIELD_HH__
|
||||
|
|
313
src/base/bitunion.hh
Normal file
313
src/base/bitunion.hh
Normal file
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __BASE_BITUNION_HH__
|
||||
#define __BASE_BITUNION_HH__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "base/bitfield.hh"
|
||||
|
||||
// The following implements the BitUnion system of defining bitfields
|
||||
//on top of an underlying class. This is done through the pervasive use of
|
||||
//both named and unnamed unions which all contain the same actual storage.
|
||||
//Since they're unioned with each other, all of these storage locations
|
||||
//overlap. This allows all of the bitfields to manipulate the same data
|
||||
//without having to have access to each other. More details are provided with
|
||||
//the individual components.
|
||||
|
||||
//This namespace is for classes which implement the backend of the BitUnion
|
||||
//stuff. Don't use any of these directly, except for the Bitfield classes in
|
||||
//the *BitfieldTypes class(es).
|
||||
namespace BitfieldBackend
|
||||
{
|
||||
//A base class for all bitfields. It instantiates the actual storage,
|
||||
//and provides getBits and setBits functions for manipulating it. The
|
||||
//Data template parameter is type of the underlying storage.
|
||||
template<class Data>
|
||||
class BitfieldBase
|
||||
{
|
||||
protected:
|
||||
Data __data;
|
||||
|
||||
//This function returns a range of bits from the underlying storage.
|
||||
//It relies on the "bits" function above. It's the user's
|
||||
//responsibility to make sure that there is a properly overloaded
|
||||
//version of this function for whatever type they want to overlay.
|
||||
inline uint64_t
|
||||
getBits(int first, int last) const
|
||||
{
|
||||
return bits(__data, first, last);
|
||||
}
|
||||
|
||||
//Similar to the above, but for settings bits with replaceBits.
|
||||
inline void
|
||||
setBits(int first, int last, uint64_t val)
|
||||
{
|
||||
replaceBits(__data, first, last, val);
|
||||
}
|
||||
};
|
||||
|
||||
//This class contains all the "regular" bitfield classes. It is inherited
|
||||
//by all BitUnions which give them access to those types.
|
||||
template<class Type>
|
||||
class RegularBitfieldTypes
|
||||
{
|
||||
protected:
|
||||
//This class implements ordinary bitfields, that is a span of bits
|
||||
//who's msb is "first", and who's lsb is "last".
|
||||
template<int first, int last=first>
|
||||
class Bitfield : public BitfieldBase<Type>
|
||||
{
|
||||
public:
|
||||
operator uint64_t () const
|
||||
{
|
||||
return this->getBits(first, last);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
operator=(const uint64_t _data)
|
||||
{
|
||||
this->setBits(first, last, _data);
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
|
||||
//A class which specializes the above so that it can only be read
|
||||
//from. This is accomplished explicitly making sure the assignment
|
||||
//operator is blocked. The conversion operator is carried through
|
||||
//inheritance. This will unfortunately need to be copied into each
|
||||
//bitfield type due to limitations with how templates work
|
||||
template<int first, int last=first>
|
||||
class BitfieldRO : public Bitfield<first, last>
|
||||
{
|
||||
private:
|
||||
uint64_t
|
||||
operator=(const uint64_t _data);
|
||||
};
|
||||
|
||||
//Similar to the above, but only allows writing.
|
||||
template<int first, int last=first>
|
||||
class BitfieldWO : public Bitfield<first, last>
|
||||
{
|
||||
private:
|
||||
operator uint64_t () const;
|
||||
|
||||
public:
|
||||
using Bitfield<first, last>::operator=;
|
||||
};
|
||||
};
|
||||
|
||||
//This class contains all the "regular" bitfield classes. It is inherited
|
||||
//by all BitUnions which give them access to those types.
|
||||
template<class Type>
|
||||
class SignedBitfieldTypes
|
||||
{
|
||||
protected:
|
||||
//This class implements ordinary bitfields, that is a span of bits
|
||||
//who's msb is "first", and who's lsb is "last".
|
||||
template<int first, int last=first>
|
||||
class SignedBitfield : public BitfieldBase<Type>
|
||||
{
|
||||
public:
|
||||
operator int64_t () const
|
||||
{
|
||||
return sext<first - last + 1>(this->getBits(first, last));
|
||||
}
|
||||
|
||||
int64_t
|
||||
operator=(const int64_t _data)
|
||||
{
|
||||
this->setBits(first, last, _data);
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
|
||||
//A class which specializes the above so that it can only be read
|
||||
//from. This is accomplished explicitly making sure the assignment
|
||||
//operator is blocked. The conversion operator is carried through
|
||||
//inheritance. This will unfortunately need to be copied into each
|
||||
//bitfield type due to limitations with how templates work
|
||||
template<int first, int last=first>
|
||||
class SignedBitfieldRO : public SignedBitfield<first, last>
|
||||
{
|
||||
private:
|
||||
int64_t
|
||||
operator=(const int64_t _data);
|
||||
};
|
||||
|
||||
//Similar to the above, but only allows writing.
|
||||
template<int first, int last=first>
|
||||
class SignedBitfieldWO : public SignedBitfield<first, last>
|
||||
{
|
||||
private:
|
||||
operator int64_t () const;
|
||||
|
||||
public:
|
||||
int64_t operator=(const int64_t _data)
|
||||
{
|
||||
*((SignedBitfield<first, last> *)this) = _data;
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
class BitfieldTypes : public RegularBitfieldTypes<Type>,
|
||||
public SignedBitfieldTypes<Type>
|
||||
{};
|
||||
|
||||
//When a BitUnion is set up, an underlying class is created which holds
|
||||
//the actual union. This class then inherits from it, and provids the
|
||||
//implementations for various operators. Setting things up this way
|
||||
//prevents having to redefine these functions in every different BitUnion
|
||||
//type. More operators could be implemented in the future, as the need
|
||||
//arises.
|
||||
template <class Type, class Base>
|
||||
class BitUnionOperators : public Base
|
||||
{
|
||||
public:
|
||||
BitUnionOperators(Type & _data)
|
||||
{
|
||||
Base::__data = _data;
|
||||
}
|
||||
|
||||
BitUnionOperators() {}
|
||||
|
||||
operator Type () const
|
||||
{
|
||||
return Base::__data;
|
||||
}
|
||||
|
||||
Type
|
||||
operator=(const Type & _data)
|
||||
{
|
||||
Base::__data = _data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const Base & base) const
|
||||
{
|
||||
return Base::__data < base.__data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const Base & base) const
|
||||
{
|
||||
return Base::__data == base.__data;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//This macro is a backend for other macros that specialize it slightly.
|
||||
//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and
|
||||
//sticks the class which has the actual union in it, which
|
||||
//BitfieldOperators above inherits from. Putting these classes in a special
|
||||
//namespace ensures that there will be no collisions with other names as long
|
||||
//as the BitUnion names themselves are all distinct and nothing else uses
|
||||
//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself
|
||||
//creates a typedef of the "type" parameter called __DataType. This allows
|
||||
//the type to propagate outside of the macro itself in a controlled way.
|
||||
//Finally, the base storage is defined which BitfieldOperators will refer to
|
||||
//in the operators it defines. This macro is intended to be followed by
|
||||
//bitfield definitions which will end up inside it's union. As explained
|
||||
//above, these is overlayed the __data member in its entirety by each of the
|
||||
//bitfields which are defined in the union, creating shared storage with no
|
||||
//overhead.
|
||||
#define __BitUnion(type, name) \
|
||||
namespace BitfieldUnderlyingClasses \
|
||||
{ \
|
||||
class name; \
|
||||
} \
|
||||
class BitfieldUnderlyingClasses::name : \
|
||||
public BitfieldBackend::BitfieldTypes<type> \
|
||||
{ \
|
||||
public: \
|
||||
typedef type __DataType; \
|
||||
union { \
|
||||
type __data;\
|
||||
|
||||
//This closes off the class and union started by the above macro. It is
|
||||
//followed by a typedef which makes "name" refer to a BitfieldOperator
|
||||
//class inheriting from the class and union just defined, which completes
|
||||
//building up the type for the user.
|
||||
#define EndBitUnion(name) \
|
||||
}; \
|
||||
}; \
|
||||
typedef BitfieldBackend::BitUnionOperators< \
|
||||
BitfieldUnderlyingClasses::name::__DataType, \
|
||||
BitfieldUnderlyingClasses::name> name;
|
||||
|
||||
//This sets up a bitfield which has other bitfields nested inside of it. The
|
||||
//__data member functions like the "underlying storage" of the top level
|
||||
//BitUnion. Like everything else, it overlays with the top level storage, so
|
||||
//making it a regular bitfield type makes the entire thing function as a
|
||||
//regular bitfield when referred to by itself.
|
||||
#define __SubBitUnion(fieldType, first, last, name) \
|
||||
class : public BitfieldBackend::BitfieldTypes<__DataType> \
|
||||
{ \
|
||||
public: \
|
||||
union { \
|
||||
fieldType<first, last> __data;
|
||||
|
||||
//This closes off the union created above and gives it a name. Unlike the top
|
||||
//level BitUnion, we're interested in creating an object instead of a type.
|
||||
//The operators are defined in the macro itself instead of a class for
|
||||
//technical reasons. If someone determines a way to move them to one, please
|
||||
//do so.
|
||||
#define EndSubBitUnion(name) \
|
||||
}; \
|
||||
inline operator const __DataType () \
|
||||
{ return __data; } \
|
||||
\
|
||||
inline const __DataType operator = (const __DataType & _data) \
|
||||
{ return __data = _data;} \
|
||||
} name;
|
||||
|
||||
//Regular bitfields
|
||||
//These define macros for read/write regular bitfield based subbitfields.
|
||||
#define SubBitUnion(name, first, last) \
|
||||
__SubBitUnion(Bitfield, first, last, name)
|
||||
|
||||
//Regular bitfields
|
||||
//These define macros for read/write regular bitfield based subbitfields.
|
||||
#define SignedSubBitUnion(name, first, last) \
|
||||
__SubBitUnion(SignedBitfield, first, last, name)
|
||||
|
||||
//Use this to define an arbitrary type overlayed with bitfields.
|
||||
#define BitUnion(type, name) __BitUnion(type, name)
|
||||
|
||||
//Use this to define conveniently sized values overlayed with bitfields.
|
||||
#define BitUnion64(name) __BitUnion(uint64_t, name)
|
||||
#define BitUnion32(name) __BitUnion(uint32_t, name)
|
||||
#define BitUnion16(name) __BitUnion(uint16_t, name)
|
||||
#define BitUnion8(name) __BitUnion(uint8_t, name)
|
||||
|
||||
#endif // __BASE_BITUNION_HH__
|
94
src/base/condcodes.hh
Normal file
94
src/base/condcodes.hh
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __BASE_CONDCODE_HH__
|
||||
#define __BASE_CONDCODE_HH__
|
||||
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/trace.hh"
|
||||
|
||||
/**
|
||||
* Calculate the carry flag from an addition. This should work even when
|
||||
* a carry value is also added in.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findCarry(int width, uint64_t dest, uint64_t src1, uint64_t src2) {
|
||||
int shift = width - 1;
|
||||
return ((~(dest >> shift) & 1) +
|
||||
((src1 >> shift) & 1) +
|
||||
((src2 >> shift) & 1)) & 0x2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the overflow flag from an addition.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findOverflow(int width, uint64_t dest, uint64_t src1, uint64_t src2) {
|
||||
int shift = width - 1;
|
||||
return ((src1 ^ ~src2) & (src1 ^ dest)) & (1 << shift);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the parity of a value. 1 is for odd parity and 0 is for even.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findParity(int width, uint64_t dest) {
|
||||
dest &= width;
|
||||
dest ^= (dest >> 32);
|
||||
dest ^= (dest >> 16);
|
||||
dest ^= (dest >> 8);
|
||||
dest ^= (dest >> 4);
|
||||
dest ^= (dest >> 2);
|
||||
dest ^= (dest >> 1);
|
||||
return dest & 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the negative flag.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findNegative(int width, uint64_t dest) {
|
||||
return bits(dest, width - 1, width - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the zero flag.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findZero(int width, uint64_t dest) {
|
||||
return !(dest & mask(width));
|
||||
}
|
||||
|
||||
#endif // __BASE_CONDCODE_HH__
|
|
@ -53,12 +53,12 @@ typedef Stats::Scalar<> FaultStat;
|
|||
class FaultBase : public RefCounted
|
||||
{
|
||||
public:
|
||||
virtual FaultName name() = 0;
|
||||
virtual FaultName name() const = 0;
|
||||
virtual void invoke(ThreadContext * tc);
|
||||
// template<typename T>
|
||||
// bool isA() {return dynamic_cast<T *>(this);}
|
||||
virtual bool isMachineCheckFault() {return false;}
|
||||
virtual bool isAlignmentFault() {return false;}
|
||||
virtual bool isMachineCheckFault() const {return false;}
|
||||
virtual bool isAlignmentFault() const {return false;}
|
||||
};
|
||||
|
||||
FaultBase * const NoFault = 0;
|
||||
|
@ -72,7 +72,7 @@ class UnimpFault : public FaultBase
|
|||
: panicStr(_str)
|
||||
{ }
|
||||
|
||||
FaultName name() {return "Unimplemented simulator feature";}
|
||||
FaultName name() const {return "Unimplemented simulator feature";}
|
||||
void invoke(ThreadContext * tc);
|
||||
};
|
||||
|
||||
|
@ -82,7 +82,7 @@ class PageTableFault : public FaultBase
|
|||
private:
|
||||
Addr vaddr;
|
||||
public:
|
||||
FaultName name() {return "M5 page table fault";}
|
||||
FaultName name() const {return "M5 page table fault";}
|
||||
PageTableFault(Addr va) : vaddr(va) {}
|
||||
void invoke(ThreadContext * tc);
|
||||
};
|
||||
|
|
374
util/style.py
Normal file
374
util/style.py
Normal file
|
@ -0,0 +1,374 @@
|
|||
#! /usr/bin/env python
|
||||
# Copyright (c) 2007 The Regents of The University of Michigan
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Nathan Binkert
|
||||
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
|
||||
lead = re.compile(r'^([ \t]+)')
|
||||
trail = re.compile(r'([ \t]+)$')
|
||||
any_control = re.compile(r'\b(if|while|for)[ \t]*[(]')
|
||||
good_control = re.compile(r'\b(if|while|for) [(]')
|
||||
|
||||
lang_types = { 'c' : "C",
|
||||
'h' : "C",
|
||||
'cc' : "C++",
|
||||
'hh' : "C++",
|
||||
'cxx' : "C++",
|
||||
'hxx' : "C++",
|
||||
'cpp' : "C++",
|
||||
'hpp' : "C++",
|
||||
'C' : "C++",
|
||||
'H' : "C++",
|
||||
'i' : "swig",
|
||||
'py' : "python",
|
||||
's' : "asm",
|
||||
'S' : "asm",
|
||||
'isa' : "isa" }
|
||||
whitespace_types = ('C', 'C++', 'swig', 'python', 'asm', 'isa')
|
||||
format_types = ( 'C', 'C++' )
|
||||
|
||||
def file_type(filename):
|
||||
extension = filename.split('.')
|
||||
extension = len(extension) > 1 and extension[-1]
|
||||
return lang_types.get(extension, None)
|
||||
|
||||
def checkwhite_line(line):
|
||||
match = lead.search(line)
|
||||
if match and match.group(1).find('\t') != -1:
|
||||
return False
|
||||
|
||||
match = trail.search(line)
|
||||
if match:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def checkwhite(filename):
|
||||
if file_type(filename) not in whitespace_types:
|
||||
return
|
||||
|
||||
try:
|
||||
f = file(filename, 'r+')
|
||||
except OSError, msg:
|
||||
print 'could not open file %s: %s' % (filename, msg)
|
||||
return
|
||||
|
||||
for num,line in enumerate(f):
|
||||
if not checkwhite_line(line):
|
||||
yield line,num + 1
|
||||
|
||||
def fixwhite_line(line):
|
||||
if lead.search(line):
|
||||
newline = ''
|
||||
for i,c in enumerate(line):
|
||||
if c == ' ':
|
||||
newline += ' '
|
||||
elif c == '\t':
|
||||
newline += ' ' * (tabsize - len(newline) % tabsize)
|
||||
else:
|
||||
newline += line[i:]
|
||||
break
|
||||
|
||||
line = newline
|
||||
|
||||
return line.rstrip() + '\n'
|
||||
|
||||
def fixwhite(filename, tabsize, fixonly=None):
|
||||
if file_type(filename) not in whitespace_types:
|
||||
return
|
||||
|
||||
try:
|
||||
f = file(filename, 'r+')
|
||||
except OSError, msg:
|
||||
print 'could not open file %s: %s' % (filename, msg)
|
||||
return
|
||||
|
||||
lines = list(f)
|
||||
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
|
||||
for i,line in enumerate(lines):
|
||||
if fixonly is None or i in fixonly:
|
||||
line = fixwhite_line(line)
|
||||
|
||||
print >>f, line,
|
||||
|
||||
def linelen(line):
|
||||
tabs = line.count('\t')
|
||||
if not tabs:
|
||||
return len(line)
|
||||
|
||||
count = 0
|
||||
for c in line:
|
||||
if c == '\t':
|
||||
count += tabsize - count % tabsize
|
||||
else:
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
class ValidationStats(object):
|
||||
def __init__(self):
|
||||
self.toolong = 0
|
||||
self.toolong80 = 0
|
||||
self.leadtabs = 0
|
||||
self.trailwhite = 0
|
||||
self.badcontrol = 0
|
||||
self.cret = 0
|
||||
|
||||
def dump(self):
|
||||
print '''\
|
||||
%d violations of lines over 79 chars. %d of which are 80 chars exactly.
|
||||
%d cases of whitespace at the end of a line.
|
||||
%d cases of tabs to indent.
|
||||
%d bad parens after if/while/for.
|
||||
%d carriage returns found.
|
||||
''' % (self.toolong, self.toolong80, self.trailwhite, self.leadtabs,
|
||||
self.badcontrol, self.cret)
|
||||
|
||||
def __nonzero__(self):
|
||||
return self.toolong or self.toolong80 or self.leadtabs or \
|
||||
self.trailwhite or self.badcontrol or self.cret
|
||||
|
||||
def validate(filename, stats, verbose, exit_code):
|
||||
if file_type(filename) not in format_types:
|
||||
return
|
||||
|
||||
def msg(lineno, line, message):
|
||||
print '%s:%d>' % (filename, lineno + 1), message
|
||||
if verbose > 2:
|
||||
print line
|
||||
|
||||
def bad():
|
||||
if exit_code is not None:
|
||||
sys.exit(exit_code)
|
||||
|
||||
cpp = filename.endswith('.cc') or filename.endswith('.hh')
|
||||
py = filename.endswith('.py')
|
||||
|
||||
if py + cpp != 1:
|
||||
raise AttributeError, \
|
||||
"I don't know how to deal with the file %s" % filename
|
||||
|
||||
try:
|
||||
f = file(filename, 'r')
|
||||
except OSError:
|
||||
if verbose > 0:
|
||||
print 'could not open file %s' % filename
|
||||
bad()
|
||||
return
|
||||
|
||||
for i,line in enumerate(f):
|
||||
line = line.rstrip('\n')
|
||||
|
||||
# no carriage returns
|
||||
if line.find('\r') != -1:
|
||||
self.cret += 1
|
||||
if verbose > 1:
|
||||
msg(i, line, 'carriage return found')
|
||||
bad()
|
||||
|
||||
# lines max out at 79 chars
|
||||
llen = linelen(line)
|
||||
if llen > 79:
|
||||
stats.toolong += 1
|
||||
if llen == 80:
|
||||
stats.toolong80 += 1
|
||||
if verbose > 1:
|
||||
msg(i, line, 'line too long (%d chars)' % llen)
|
||||
bad()
|
||||
|
||||
# no tabs used to indent
|
||||
match = lead.search(line)
|
||||
if match and match.group(1).find('\t') != -1:
|
||||
stats.leadtabs += 1
|
||||
if verbose > 1:
|
||||
msg(i, line, 'using tabs to indent')
|
||||
bad()
|
||||
|
||||
# no trailing whitespace
|
||||
if trail.search(line):
|
||||
stats.trailwhite +=1
|
||||
if verbose > 1:
|
||||
msg(i, line, 'trailing whitespace')
|
||||
bad()
|
||||
|
||||
# for c++, exactly one space betwen if/while/for and (
|
||||
if cpp:
|
||||
match = any_control.search(line)
|
||||
if match and not good_control.search(line):
|
||||
stats.badcontrol += 1
|
||||
if verbose > 1:
|
||||
msg(i, line, 'improper spacing after %s' % match.group(1))
|
||||
bad()
|
||||
|
||||
def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
|
||||
from mercurial import bdiff, mdiff, util
|
||||
if hooktype != 'pretxncommit':
|
||||
raise AttributeError, \
|
||||
"This hook is only meant for pretxncommit, not %s" % hooktype
|
||||
|
||||
tabsize = 8
|
||||
verbose = ui.configbool('style', 'verbose', False)
|
||||
def prompt(name, fixonly=None):
|
||||
result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", "^[aif]$", "a")
|
||||
if result == 'a':
|
||||
return True
|
||||
elif result == 'i':
|
||||
pass
|
||||
elif result == 'f':
|
||||
fixwhite(name, tabsize, fixonly)
|
||||
else:
|
||||
raise RepoError, "Invalid response: '%s'" % result
|
||||
|
||||
return False
|
||||
|
||||
modified, added, removed, deleted, unknown, ignore, clean = repo.status()
|
||||
|
||||
for fname in added:
|
||||
ok = True
|
||||
for line,num in checkwhite(fname):
|
||||
ui.write("invalid whitespace in %s:%d\n" % (fname, num))
|
||||
if verbose:
|
||||
ui.write(">>%s<<\n" % line[-1])
|
||||
ok = False
|
||||
|
||||
if not ok:
|
||||
if prompt(fname):
|
||||
return True
|
||||
|
||||
wctx = repo.workingctx()
|
||||
for fname in modified:
|
||||
fctx = wctx.filectx(fname)
|
||||
pctx = fctx.parents()
|
||||
assert len(pctx) == 1
|
||||
|
||||
pdata = pctx[0].data()
|
||||
fdata = fctx.data()
|
||||
|
||||
fixonly = set()
|
||||
lines = enumerate(mdiff.splitnewlines(fdata))
|
||||
for pbeg, pend, fbeg, fend in bdiff.blocks(pdata, fdata):
|
||||
for i, line in lines:
|
||||
if i < fbeg:
|
||||
if checkwhite_line(line):
|
||||
continue
|
||||
|
||||
ui.write("invalid whitespace: %s:%d\n" % (fname, i+1))
|
||||
if verbose:
|
||||
ui.write(">>%s<<\n" % line[:-1])
|
||||
fixonly.add(i)
|
||||
elif i + 1 >= fend:
|
||||
break
|
||||
|
||||
if fixonly:
|
||||
if prompt(fname, fixonly):
|
||||
return True
|
||||
|
||||
def check_format(ui, repo, hooktype, node, parent1, parent2):
|
||||
if hooktype != 'pretxncommit':
|
||||
raise AttributeError, \
|
||||
"This hook is only meant for pretxncommit, not %s" % hooktype
|
||||
|
||||
modified, added, removed, deleted, unknown, ignore, clean = repo.status()
|
||||
|
||||
verbose = 0
|
||||
stats = ValidationStats()
|
||||
for f in modified + added:
|
||||
validate(f, stats, verbose, None)
|
||||
|
||||
if stats:
|
||||
stats.dump()
|
||||
result = ui.prompt("invalid formatting\n(i)gnore or (a)bort?",
|
||||
"^[ia]$", "a")
|
||||
if result.startswith('i'):
|
||||
pass
|
||||
elif result.startswith('a'):
|
||||
return True
|
||||
else:
|
||||
raise RepoError, "Invalid response: '%s'" % result
|
||||
|
||||
return False
|
||||
|
||||
if __name__ == '__main__':
|
||||
import getopt
|
||||
|
||||
progname = sys.argv[0]
|
||||
if len(sys.argv) < 2:
|
||||
sys.exit('usage: %s <command> [<command args>]' % progname)
|
||||
|
||||
fixwhite_usage = '%s fixwhite [-t <tabsize> ] <path> [...] \n' % progname
|
||||
chkformat_usage = '%s chkformat <path> [...] \n' % progname
|
||||
chkwhite_usage = '%s chkwhite <path> [...] \n' % progname
|
||||
|
||||
command = sys.argv[1]
|
||||
if command == 'fixwhite':
|
||||
flags = 't:'
|
||||
usage = fixwhite_usage
|
||||
elif command == 'chkwhite':
|
||||
flags = 'nv'
|
||||
usage = chkwhite_usage
|
||||
elif command == 'chkformat':
|
||||
flags = 'nv'
|
||||
usage = chkformat_usage
|
||||
else:
|
||||
sys.exit(fixwhite_usage + chkwhite_usage + chkformat_usage)
|
||||
|
||||
opts, args = getopt.getopt(sys.argv[2:], flags)
|
||||
|
||||
code = 1
|
||||
verbose = 1
|
||||
tabsize = 8
|
||||
for opt,arg in opts:
|
||||
if opt == '-n':
|
||||
code = None
|
||||
if opt == '-t':
|
||||
tabsize = int(arg)
|
||||
if opt == '-v':
|
||||
verbose += 1
|
||||
|
||||
if command == 'fixwhite':
|
||||
for filename in args:
|
||||
fixwhite(filename, tabsize)
|
||||
elif command == 'chkwhite':
|
||||
for filename in args:
|
||||
line = checkwhite(filename)
|
||||
if line:
|
||||
print 'invalid whitespace at %s:%d' % (filename, line)
|
||||
elif command == 'chkformat':
|
||||
stats = ValidationStats()
|
||||
for filename in files:
|
||||
validate(filename, stats=stats, verbose=verbose, exit_code=code)
|
||||
|
||||
if verbose > 0:
|
||||
stats.dump()
|
||||
else:
|
||||
sys.exit("command '%s' not found" % command)
|
Loading…
Reference in a new issue