summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct30
-rw-r--r--src/arch/alpha/faults.hh42
-rwxr-xr-xsrc/arch/isa_parser.py46
-rw-r--r--src/arch/mips/faults.hh42
-rw-r--r--src/arch/sparc/faults.hh7
-rw-r--r--src/arch/x86/SConscript3
-rw-r--r--src/arch/x86/emulenv.cc12
-rw-r--r--src/arch/x86/faults.hh4
-rw-r--r--src/arch/x86/insts/microldstop.cc79
-rw-r--r--src/arch/x86/insts/microldstop.hh102
-rw-r--r--src/arch/x86/insts/microop.hh100
-rw-r--r--src/arch/x86/insts/microregop.cc196
-rw-r--r--src/arch/x86/insts/microregop.hh191
-rw-r--r--src/arch/x86/insts/static_inst.cc200
-rw-r--r--src/arch/x86/insts/static_inst.hh140
-rw-r--r--src/arch/x86/intregfile.hh3
-rw-r--r--src/arch/x86/intregs.hh10
-rw-r--r--src/arch/x86/isa/base.isa303
-rw-r--r--src/arch/x86/isa/bitfields.isa3
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa409
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa253
-rw-r--r--src/arch/x86/isa/formats/error.isa2
-rw-r--r--src/arch/x86/isa/formats/formats.isa4
-rw-r--r--src/arch/x86/isa/formats/syscall.isa112
-rw-r--r--src/arch/x86/isa/formats/unimp.isa8
-rw-r--r--src/arch/x86/isa/includes.isa4
-rw-r--r--src/arch/x86/isa/insts/__init__.py3
-rw-r--r--src/arch/x86/isa/insts/arithmetic/add_and_subtract.py210
-rw-r--r--src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py42
-rw-r--r--src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py26
-rw-r--r--src/arch/x86/isa/insts/compare_and_test/compare.py58
-rw-r--r--src/arch/x86/isa/insts/compare_and_test/test.py16
-rw-r--r--src/arch/x86/isa/insts/control_transfer/call.py43
-rw-r--r--src/arch/x86/isa/insts/control_transfer/jump.py194
-rw-r--r--src/arch/x86/isa/insts/control_transfer/xreturn.py28
-rw-r--r--src/arch/x86/isa/insts/data_transfer/__init__.py3
-rw-r--r--src/arch/x86/isa/insts/data_transfer/move.py89
-rw-r--r--src/arch/x86/isa/insts/data_transfer/stack_operations.py19
-rw-r--r--src/arch/x86/isa/insts/data_transfer/xchg.py98
-rw-r--r--src/arch/x86/isa/insts/logical.py106
-rw-r--r--src/arch/x86/isa/insts/no_operation.py11
-rw-r--r--src/arch/x86/isa/insts/rotate_and_shift/rotate.py86
-rw-r--r--src/arch/x86/isa/insts/rotate_and_shift/shift.py62
-rw-r--r--src/arch/x86/isa/insts/system/__init__.py62
-rw-r--r--src/arch/x86/isa/insts/system/undefined_operation.py61
-rw-r--r--src/arch/x86/isa/main.isa4
-rw-r--r--src/arch/x86/isa/microasm.isa19
-rw-r--r--src/arch/x86/isa/microops/base.isa36
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa168
-rw-r--r--src/arch/x86/isa/microops/limmop.isa23
-rw-r--r--src/arch/x86/isa/microops/regop.isa419
-rw-r--r--src/arch/x86/isa/microops/specop.isa21
-rw-r--r--src/arch/x86/isa/operands.isa2
-rw-r--r--src/arch/x86/isa/outputblock.isa91
-rw-r--r--src/arch/x86/isa/specialize.isa5
-rw-r--r--src/arch/x86/linux/syscalls.cc3
-rw-r--r--src/arch/x86/miscregfile.cc47
-rw-r--r--src/arch/x86/miscregfile.hh8
-rw-r--r--src/arch/x86/miscregs.hh329
-rw-r--r--src/arch/x86/predecoder.cc51
-rw-r--r--src/arch/x86/predecoder.hh11
-rw-r--r--src/arch/x86/syscallreturn.hh5
-rw-r--r--src/arch/x86/types.hh11
-rw-r--r--src/arch/x86/x86_traits.hh1
-rw-r--r--src/base/bitfield.hh269
-rw-r--r--src/base/bitunion.hh313
-rw-r--r--src/base/condcodes.hh94
-rw-r--r--src/sim/faults.hh10
-rw-r--r--util/style.py374
69 files changed, 4456 insertions, 1380 deletions
diff --git a/SConstruct b/SConstruct
index ffcd84706..ec60964e4 100644
--- a/SConstruct
+++ b/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
diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh
index 6342122c2..ed0c3a6b1 100644
--- a/src/arch/alpha/faults.hh
+++ b/src/arch/alpha/faults.hh
@@ -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;}
};
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index 754a64fdb..64a120c4c 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -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)
diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh
index 05a86acd7..2e5aa81d6 100644
--- a/src/arch/mips/faults.hh
+++ b/src/arch/mips/faults.hh
@@ -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);
diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh
index 10ef89279..2456ad28a 100644
--- a/src/arch/sparc/faults.hh
+++ b/src/arch/sparc/faults.hh
@@ -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> {};
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript
index 6de243c9c..e8f8059ce 100644
--- a/src/arch/x86/SConscript
+++ b/src/arch/x86/SConscript
@@ -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')
diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc
index e3f703cff..3a54d7365 100644
--- a/src/arch/x86/emulenv.cc
+++ b/src/arch/x86/emulenv.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;
}
}
}
diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh
index 8c9afcdb5..51c34cebd 100644
--- a/src/arch/x86/faults.hh
+++ b/src/arch/x86/faults.hh
@@ -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";
}
diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc
new file mode 100644
index 000000000..8a52ad932
--- /dev/null
+++ b/src/arch/x86/insts/microldstop.cc
@@ -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();
+ }
+}
diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh
new file mode 100644
index 000000000..f90d6670e
--- /dev/null
+++ b/src/arch/x86/insts/microldstop.hh
@@ -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__
diff --git a/src/arch/x86/insts/microop.hh b/src/arch/x86/insts/microop.hh
new file mode 100644
index 000000000..45e1cb5c8
--- /dev/null
+++ b/src/arch/x86/insts/microop.hh
@@ -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__
diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc
new file mode 100644
index 000000000..976b04688
--- /dev/null
+++ b/src/arch/x86/insts/microregop.cc
@@ -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();
+ }
+}
diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh
new file mode 100644
index 000000000..f411c0775
--- /dev/null
+++ b/src/arch/x86/insts/microregop.hh
@@ -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__
diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc
new file mode 100644
index 000000000..9b2f81e49
--- /dev/null
+++ b/src/arch/x86/insts/static_inst.cc
@@ -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();
+ }
+}
diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh
new file mode 100644
index 000000000..c39c2956e
--- /dev/null
+++ b/src/arch/x86/insts/static_inst.hh
@@ -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__
diff --git a/src/arch/x86/intregfile.hh b/src/arch/x86/intregfile.hh
index f7b03f0f0..be6242a41 100644
--- a/src/arch/x86/intregfile.hh
+++ b/src/arch/x86/intregfile.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
{
diff --git a/src/arch/x86/intregs.hh b/src/arch/x86/intregs.hh
index 1b5777f01..bfec7d041 100644
--- a/src/arch/x86/intregs.hh
+++ b/src/arch/x86/intregs.hh
@@ -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,
diff --git a/src/arch/x86/isa/base.isa b/src/arch/x86/isa/base.isa
deleted file mode 100644
index eed969b47..000000000
--- a/src/arch/x86/isa/base.isa
+++ /dev/null
@@ -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();
- }
-}};
diff --git a/src/arch/x86/isa/bitfields.isa b/src/arch/x86/isa/bitfields.isa
index 8707bbb4c..43fee5fef 100644
--- a/src/arch/x86/isa/bitfields.isa
+++ b/src/arch/x86/isa/bitfields.isa
@@ -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
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 484f8160d..b28f2029c 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -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();
}
- 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();
- }
- 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();
- }
- 0x10: decode OPCODE_OP_BOTTOM3 {
- 0x0: group1_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();
- }
- 0x2: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
- default: group1_Eb_Ib();
+ 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);
+ }
+ 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: JNLE(Jb);
}
- //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();
+ }
+ format Inst {
+ 0x10: decode OPCODE_OP_BOTTOM3 {
+ //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,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: 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(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);
- }
- }
- 0x18: decode OPCODE_OP_BOTTOM3 {
- 0x0: group2_Eb_Ib();
- 0x1: group2_Ev_Ib();
- 0x2: ret_near_Iw();
- 0x3: ret_near();
- 0x4: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
- default: les_Gz_Mp();
- }
- 0x5: decode MODE_SUBMODE {
- 0x0: This_should_be_an_illegal_instruction();
- default: lds_Gz_Mp();
- }
- //0x6: group12_Eb_Ib();
- 0x6: decode MODRM_REG {
- 0x0: Inst::MOV(Eb,Ib);
- }
- //0x7: group12_Ev_Iz();
- 0x7: decode MODRM_REG {
- 0x0: Inst::MOV(Ev,Iz);
+ 0x16: MOV(B,Ib);
+ 0x17: MOV(B,Iv);
+ 0x18: decode OPCODE_OP_BOTTOM3 {
+ //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: UD2();
+ default: WarnUnimpl::les_Gz_Mp();
+ }
+ 0x5: decode MODE_SUBMODE {
+ 0x0: UD2();
+ default: WarnUnimpl::lds_Gz_Mp();
+ }
+ //0x6: group12_Eb_Ib();
+ 0x6: decode MODRM_REG {
+ 0x0: MOV(Eb,Ib);
+ default: UD2();
+ }
+ //0x7: group12_Ev_Iz();
+ 0x7: decode MODRM_REG {
+ 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();
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index f05c33bdb..e5631d37b 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -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();
}
- 0x10: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
- }
- 0x11: decode OPCODE_OP_BOTTOM3 {
- 0x0: holder();
- 0x1: holder();
- 0x2: holder();
- 0x3: holder();
- 0x4: holder();
- 0x5: holder();
- 0x6: holder();
- 0x7: holder();
+ format Inst {
+ 0x10: decode OPCODE_OP_BOTTOM3 {
+ 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: 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();
diff --git a/src/arch/x86/isa/formats/error.isa b/src/arch/x86/isa/formats/error.isa
index 8ac2ea44d..e85eff762 100644
--- a/src/arch/x86/isa/formats/error.isa
+++ b/src/arch/x86/isa/formats/error.isa
@@ -64,7 +64,7 @@
def template ErrorDecode {{
{
- panic("X86 decoder internal error: '%%s' %%s",
+ panic("X86 decoder internal error: '%s' %s",
%(message)s, machInst);
}
}};
diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa
index d763c05bc..1e7bb4a74 100644
--- a/src/arch/x86/isa/formats/formats.isa
+++ b/src/arch/x86/isa/formats/formats.isa
@@ -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"
diff --git a/src/arch/x86/isa/formats/syscall.isa b/src/arch/x86/isa/formats/syscall.isa
new file mode 100644
index 000000000..8b860dba4
--- /dev/null
+++ b/src/arch/x86/isa/formats/syscall.isa
@@ -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)
+}};
+
diff --git a/src/arch/x86/isa/formats/unimp.isa b/src/arch/x86/isa/formats/unimp.isa
index 12fa8387b..183beb3b8 100644
--- a/src/arch/x86/isa/formats/unimp.isa
+++ b/src/arch/x86/isa/formats/unimp.isa
@@ -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
diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa
index 4f27c72f5..58aef7b1d 100644
--- a/src/arch/x86/isa/includes.isa
+++ b/src/arch/x86/isa/includes.isa
@@ -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"
diff --git a/src/arch/x86/isa/insts/__init__.py b/src/arch/x86/isa/insts/__init__.py
index 717690926..f5c4e3113 100644
--- a/src/arch/x86/isa/insts/__init__.py
+++ b/src/arch/x86/isa/insts/__init__.py
@@ -69,7 +69,8 @@ categories = ["arithmetic",
"rotate_and_shift",
"semaphores",
"string",
- "system_calls"]
+ "system_calls",
+ "system"]
microcode = '''
# X86 microcode
diff --git a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
index 809b9ac7c..05aa6cd69 100644
--- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
+++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py
@@ -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
+ 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
- subi t1, t1, imm
+ sbb t1, t1, reg
st t1, ds, [scale, index, base], disp
};
'''
diff --git a/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py b/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py
index c504d47ce..eed39c10c 100644
--- a/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py
+++ b/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py
@@ -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}"
diff --git a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
index 662022e6a..8697bef65 100644
--- a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
+++ b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py
@@ -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}"
diff --git a/src/arch/x86/isa/insts/compare_and_test/compare.py b/src/arch/x86/isa/insts/compare_and_test/compare.py
index 12b5b859f..8f5890b23 100644
--- a/src/arch/x86/isa/insts/compare_and_test/compare.py
+++ b/src/arch/x86/isa/insts/compare_and_test/compare.py
@@ -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)
+};
+'''
diff --git a/src/arch/x86/isa/insts/compare_and_test/test.py b/src/arch/x86/isa/insts/compare_and_test/test.py
index 89d406912..8da33899a 100644
--- a/src/arch/x86/isa/insts/compare_and_test/test.py
+++ b/src/arch/x86/isa/insts/compare_and_test/test.py
@@ -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)
};
'''
diff --git a/src/arch/x86/isa/insts/control_transfer/call.py b/src/arch/x86/isa/insts/control_transfer/call.py
index 530162bfd..c5bb66e58 100644
--- a/src/arch/x86/isa/insts/control_transfer/call.py
+++ b/src/arch/x86/isa/insts/control_transfer/call.py
@@ -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 {{
diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py
index e90e5b12b..158861a3d 100644
--- a/src/arch/x86/isa/insts/control_transfer/jump.py
+++ b/src/arch/x86/isa/insts/control_transfer/jump.py
@@ -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
+};
+'''
diff --git a/src/arch/x86/isa/insts/control_transfer/xreturn.py b/src/arch/x86/isa/insts/control_transfer/xreturn.py
index aaffa2b92..0000cd3c1 100644
--- a/src/arch/x86/isa/insts/control_transfer/xreturn.py
+++ b/src/arch/x86/isa/insts/control_transfer/xreturn.py
@@ -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
+};
+'''
diff --git a/src/arch/x86/isa/insts/data_transfer/__init__.py b/src/arch/x86/isa/insts/data_transfer/__init__.py
index eda173b34..365f95eaa 100644
--- a/src/arch/x86/isa/insts/data_transfer/__init__.py
+++ b/src/arch/x86/isa/insts/data_transfer/__init__.py
@@ -55,7 +55,8 @@
categories = ["conditional_move",
"move",
- "stack_operations"]
+ "stack_operations",
+ "xchg"]
microcode = ""
for category in categories:
diff --git a/src/arch/x86/isa/insts/data_transfer/move.py b/src/arch/x86/isa/insts/data_transfer/move.py
index c85dd7cc4..bbc55e47c 100644
--- a/src/arch/x86/isa/insts/data_transfer/move.py
+++ b/src/arch/x86/isa/insts/data_transfer/move.py
@@ -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 {{
diff --git a/src/arch/x86/isa/insts/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/data_transfer/stack_operations.py
index 585437b8c..c381dc4f4 100644
--- a/src/arch/x86/isa/insts/data_transfer/stack_operations.py
+++ b/src/arch/x86/isa/insts/data_transfer/stack_operations.py
@@ -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):
diff --git a/src/arch/x86/isa/insts/data_transfer/xchg.py b/src/arch/x86/isa/insts/data_transfer/xchg.py
new file mode 100644
index 000000000..4f401deb7
--- /dev/null
+++ b/src/arch/x86/isa/insts/data_transfer/xchg.py
@@ -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
+};
+'''
diff --git a/src/arch/x86/isa/insts/logical.py b/src/arch/x86/isa/insts/logical.py
index 2fd369d60..f99638cac 100644
--- a/src/arch/x86/isa/insts/logical.py
+++ b/src/arch/x86/isa/insts/logical.py
@@ -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 = '''
diff --git a/src/arch/x86/isa/insts/no_operation.py b/src/arch/x86/isa/insts/no_operation.py
index 1a287aea7..306ee2797 100644
--- a/src/arch/x86/isa/insts/no_operation.py
+++ b/src/arch/x86/isa/insts/no_operation.py
@@ -53,8 +53,9 @@
#
# Authors: Gabe Black
-microcode = ""
-#let {{
-# class NOP(Inst):
-# "GenFault ${new UnimpInstFault}"
-#}};
+microcode = '''
+def macroop NOP
+{
+ fault "NoFault"
+};
+'''
diff --git a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
index e3aaf0043..0988f8815 100644
--- a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
+++ b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
@@ -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}"
#}};
diff --git a/src/arch/x86/isa/insts/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/rotate_and_shift/shift.py
index f72794657..5a04317d9 100644
--- a/src/arch/x86/isa/insts/rotate_and_shift/shift.py
+++ b/src/arch/x86/isa/insts/rotate_and_shift/shift.py
@@ -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}"
diff --git a/src/arch/x86/isa/insts/system/__init__.py b/src/arch/x86/isa/insts/system/__init__.py
new file mode 100644
index 000000000..72e3bdf0a
--- /dev/null
+++ b/src/arch/x86/isa/insts/system/__init__.py
@@ -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
+
diff --git a/src/arch/x86/isa/insts/system/undefined_operation.py b/src/arch/x86/isa/insts/system/undefined_operation.py
new file mode 100644
index 000000000..e5544b6e7
--- /dev/null
+++ b/src/arch/x86/isa/insts/system/undefined_operation.py
@@ -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"
+};
+'''
diff --git a/src/arch/x86/isa/main.isa b/src/arch/x86/isa/main.isa
index fed8903c0..73cebc12b 100644
--- a/src/arch/x86/isa/main.isa
+++ b/src/arch/x86/isa/main.isa
@@ -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"
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa
index ee2b92f53..213468b0b 100644
--- a/src/arch/x86/isa/microasm.isa
+++ b/src/arch/x86/isa/microasm.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 &&
diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa
index 79ac4493a..71fc3b3a5 100644
--- a/src/arch/x86/isa/microops/base.isa
+++ b/src/arch/x86/isa/microops/base.isa
@@ -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
diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa
index fbff899a0..ccf519963 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -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"
diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa
index 141d7523f..37180d7fa 100644
--- a/src/arch/x86/isa/microops/limmop.isa
+++ b/src/arch/x86/isa/microops/limmop.isa
@@ -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
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index 65b75fab8..dbbe11c90 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -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;
- %(code)s;
- %(flag_code)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;
- %(code)s;
- %(flag_code)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.ext = 0
+ 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.ext = 0
+ 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)
+
+ microopClasses[name] = RegOpChild
- setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, flagCode);
+ 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"
-
- setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, flagCode);
-
- 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)', "")
+ 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)
+
+ microopClasses[name + 'i'] = RegOpChildImm
+
+ 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)
+
+ microopClasses[name] = RegOpChild
- setUpMicroRegOp(name, Name, "RegOp", regCode, 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);')
}};
diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa
index b56223390..5c9e8dda9 100644
--- a/src/arch/x86/isa/microops/specop.isa
+++ b/src/arch/x86/isa/microops/specop.isa
@@ -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):
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index b2ac17d66..406c74a1f 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -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)
}};
diff --git a/src/arch/x86/isa/outputblock.isa b/src/arch/x86/isa/outputblock.isa
new file mode 100644
index 000000000..342d6ac4b
--- /dev/null
+++ b/src/arch/x86/isa/outputblock.isa
@@ -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)
+}};
diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa
index 3183f32ba..5165ea206 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -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.
diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc
index 809784635..30360e602 100644
--- a/src/arch/x86/linux/syscalls.cc
+++ b/src/arch/x86/linux/syscalls.cc
@@ -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),
diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc
index 14ba3c7cc..9d8e94061 100644
--- a/src/arch/x86/miscregfile.cc
+++ b/src/arch/x86/miscregfile.cc
@@ -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);
}
diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh
index 10acb97a4..e095e06e9 100644
--- a/src/arch/x86/miscregfile.hh
+++ b/src/arch/x86/miscregfile.hh
@@ -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();
diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh
new file mode 100644
index 000000000..39425fc9d
--- /dev/null
+++ b/src/arch/x86/miscregs.hh
@@ -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__
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
index 49f76699b..295ca10a4 100644
--- a/src/arch/x86/predecoder.cc
+++ b/src/arch/x86/predecoder.cc
@@ -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!
diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh
index f34b66364..450ebd79b 100644
--- a/src/arch/x86/predecoder.hh
+++ b/src/arch/x86/predecoder.hh
@@ -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 {
diff --git a/src/arch/x86/syscallreturn.hh b/src/arch/x86/syscallreturn.hh
index 9f0d20e2a..6a7fdba58 100644
--- a/src/arch/x86/syscallreturn.hh
+++ b/src/arch/x86/syscallreturn.hh
@@ -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());
}
};
diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh
index 61ab2bac9..a509ff57a 100644
--- a/src/arch/x86/types.hh
+++ b/src/arch/x86/types.hh
@@ -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);
diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh
index e45d62f8f..5794e7079 100644
--- a/src/arch/x86/x86_traits.hh
+++ b/src/arch/x86/x86_traits.hh
@@ -61,6 +61,7 @@
namespace X86ISA
{
const int NumMicroIntRegs = 16;
+ const int NumPseudoIntRegs = 1;
const int NumMMXRegs = 8;
const int NumXMMRegs = 16;
diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh
index 70a46386e..664093fa2 100644
--- a/src/base/bitfield.hh
+++ b/src/base/bitfield.hh
@@ -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__
diff --git a/src/base/bitunion.hh b/src/base/bitunion.hh
new file mode 100644
index 000000000..c02ca6155
--- /dev/null
+++ b/src/base/bitunion.hh
@@ -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__
diff --git a/src/base/condcodes.hh b/src/base/condcodes.hh
new file mode 100644
index 000000000..efff12dc8
--- /dev/null
+++ b/src/base/condcodes.hh
@@ -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__
diff --git a/src/sim/faults.hh b/src/sim/faults.hh
index 2f0b5af62..f2e638945 100644
--- a/src/sim/faults.hh
+++ b/src/sim/faults.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);
};
diff --git a/util/style.py b/util/style.py
new file mode 100644
index 000000000..3824cd7f5
--- /dev/null
+++ b/util/style.py
@@ -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)