Merge Gabe's changes with mine.

--HG--
extra : convert_revision : f50ed42e7acb3f11e610fd6976eaa8df0c6ba2ab
This commit is contained in:
Steve Reinhardt 2007-07-22 10:40:45 -04:00
commit 03730edc45
69 changed files with 4454 additions and 1378 deletions

View file

@ -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

View file

@ -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;}
};

View file

@ -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)

View file

@ -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);

View file

@ -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> {};

View file

@ -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')

View file

@ -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;
}
}
}

View file

@ -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";
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#include "arch/x86/insts/microldstop.hh"
#include <string>
namespace X86ISA
{
std::string LdStOp::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
printReg(response, data, dataSize);
response << ", ";
printSegment(response, segment);
ccprintf(response, ":[%d*", scale);
printReg(response, index, addressSize);
response << " + ";
printReg(response, base, addressSize);
ccprintf(response, " + %#x]", disp);
return response.str();
}
}

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_X86_INSTS_MICROLDSTOP_HH__
#define __ARCH_X86_INSTS_MICROLDSTOP_HH__
#include "arch/x86/insts/microop.hh"
namespace X86ISA
{
/**
* Base class for load and store ops
*/
class LdStOp : public X86MicroopBase
{
protected:
const uint8_t scale;
const RegIndex index;
const RegIndex base;
const uint64_t disp;
const uint8_t segment;
const RegIndex data;
const uint8_t dataSize;
const uint8_t addressSize;
//Constructor
LdStOp(ExtMachInst _machInst,
const char * mnem, const char * _instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize,
OpClass __opClass) :
X86MicroopBase(machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast, __opClass),
scale(_scale), index(_index), base(_base),
disp(_disp), segment(_segment),
data(_data),
dataSize(_dataSize), addressSize(_addressSize)
{}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
}
#endif //__ARCH_X86_INSTS_MICROLDSTOP_HH__

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_X86_INSTS_MICROOP_HH__
#define __ARCH_X86_INSTS_MICROOP_HH__
#include "arch/x86/insts/static_inst.hh"
namespace X86ISA
{
//A class which is the base of all x86 micro ops. It provides a function to
//set necessary flags appropriately.
class X86MicroopBase : public X86StaticInst
{
protected:
const char * instMnem;
uint8_t opSize;
uint8_t addrSize;
X86MicroopBase(ExtMachInst _machInst,
const char *mnem, const char *_instMnem,
bool isMicro, bool isDelayed,
bool isFirst, bool isLast,
OpClass __opClass) :
X86ISA::X86StaticInst(mnem, _machInst, __opClass),
instMnem(_instMnem)
{
flags[IsMicroop] = isMicro;
flags[IsDelayedCommit] = isDelayed;
flags[IsFirstMicroop] = isFirst;
flags[IsLastMicroop] = isLast;
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "\t%s.%s", instMnem, mnemonic);
return ss.str();
}
};
}
#endif //__ARCH_X86_INSTS_MICROOP_HH__

View file

@ -0,0 +1,196 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#include "arch/x86/insts/microregop.hh"
#include "arch/x86/miscregs.hh"
#include "base/condcodes.hh"
#include <string>
namespace X86ISA
{
uint64_t RegOpBase::genFlags(uint64_t oldFlags, uint64_t flagMask,
uint64_t _dest, uint64_t _src1, uint64_t _src2,
bool subtract) const
{
DPRINTF(Sparc, "flagMask = %#x\n", flagMask);
uint64_t flags = oldFlags & ~flagMask;
if(flagMask & CFBit)
if(findCarry(dataSize*8, _dest, _src1, _src2))
flags |= CFBit;
if(subtract)
flags ^= CFBit;
if(flagMask & PFBit && findParity(dataSize*8, _dest))
flags |= PFBit;
if(flagMask & ECFBit && findCarry(dataSize*8, _dest, _src1, _src2))
flags |= ECFBit;
if(flagMask & AFBit)
if(findCarry(4, _dest, _src1, _src2))
flags |= AFBit;
if(subtract)
flags ^= AFBit;
if(flagMask & EZFBit && findZero(dataSize*8, _dest))
flags |= EZFBit;
if(flagMask & ZFBit && findZero(dataSize*8, _dest))
flags |= ZFBit;
if(flagMask & SFBit && findNegative(dataSize*8, _dest))
flags |= SFBit;
if(flagMask & OFBit && findOverflow(dataSize*8, _dest, _src1, _src2))
flags |= OFBit;
return flags;
}
bool RegOpBase::checkCondition(uint64_t flags) const
{
CCFlagBits ccflags = flags;
switch(ext)
{
case ConditionTests::True:
return true;
case ConditionTests::ECF:
return ccflags.ECF;
case ConditionTests::EZF:
return ccflags.EZF;
case ConditionTests::SZnZF:
return !(!ccflags.EZF & ccflags.ZF);
case ConditionTests::MSTRZ:
panic("This condition is not implemented!");
case ConditionTests::STRZ:
panic("This condition is not implemented!");
case ConditionTests::MSTRC:
panic("This condition is not implemented!");
case ConditionTests::STRZnZF:
panic("This condition is not implemented!");
case ConditionTests::OF:
return ccflags.OF;
case ConditionTests::CF:
return ccflags.CF;
case ConditionTests::ZF:
return ccflags.ZF;
case ConditionTests::CvZF:
return ccflags.CF | ccflags.ZF;
case ConditionTests::SF:
return ccflags.SF;
case ConditionTests::PF:
return ccflags.PF;
case ConditionTests::SxOF:
return ccflags.SF ^ ccflags.OF;
case ConditionTests::SxOvZF:
return ccflags.SF ^ ccflags.OF | ccflags.ZF;
case ConditionTests::False:
return false;
case ConditionTests::NotECF:
return !ccflags.ECF;
case ConditionTests::NotEZF:
return !ccflags.EZF;
case ConditionTests::NotSZnZF:
return !ccflags.EZF & ccflags.ZF;
case ConditionTests::NotMSTRZ:
panic("This condition is not implemented!");
case ConditionTests::NotSTRZ:
panic("This condition is not implemented!");
case ConditionTests::NotMSTRC:
panic("This condition is not implemented!");
case ConditionTests::NotSTRZnZF:
panic("This condition is not implemented!");
case ConditionTests::NotOF:
return !ccflags.OF;
case ConditionTests::NotCF:
return !ccflags.CF;
case ConditionTests::NotZF:
return !ccflags.ZF;
case ConditionTests::NotCvZF:
return !(ccflags.CF | ccflags.ZF);
case ConditionTests::NotSF:
return !ccflags.SF;
case ConditionTests::NotPF:
return !ccflags.PF;
case ConditionTests::NotSxOF:
return !(ccflags.SF ^ ccflags.OF);
case ConditionTests::NotSxOvZF:
return !(ccflags.SF ^ ccflags.OF | ccflags.ZF);
}
panic("Unknown condition: %d\n", ext);
return true;
}
std::string RegOp::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
printReg(response, dest, dataSize);
response << ", ";
printReg(response, src1, dataSize);
response << ", ";
printReg(response, src2, dataSize);
return response.str();
}
std::string RegOpImm::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
printReg(response, dest, dataSize);
response << ", ";
printReg(response, src1, dataSize);
ccprintf(response, ", %#x", imm8);
return response.str();
}
}

View file

@ -0,0 +1,191 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_X86_INSTS_MICROREGOP_HH__
#define __ARCH_X86_INSTS_MICROREGOP_HH__
#include "arch/x86/insts/microop.hh"
namespace X86ISA
{
namespace ConditionTests
{
enum CondTest {
True,
NotFalse = True,
ECF,
EZF,
SZnZF,
MSTRZ,
STRZ,
MSTRC,
STRZnZF,
OF,
CF,
ZF,
CvZF,
SF,
PF,
SxOF,
SxOvZF,
False,
NotTrue = False,
NotECF,
NotEZF,
NotSZnZF,
NotMSTRZ,
NotSTRZ,
NotMSTRC,
NotSTRZnZF,
NotOF,
NotCF,
NotZF,
NotCvZF,
NotSF,
NotPF,
NotSxOF,
NotSxOvZF
};
}
/**
* Base classes for RegOps which provides a generateDisassembly method.
*/
class RegOpBase : public X86MicroopBase
{
protected:
const RegIndex src1;
const RegIndex dest;
const uint8_t dataSize;
const uint16_t ext;
// Constructor
RegOpBase(ExtMachInst _machInst,
const char *mnem, const char *_instMnem,
bool isMicro, bool isDelayed,
bool isFirst, bool isLast,
RegIndex _src1, RegIndex _dest,
uint8_t _dataSize, uint16_t _ext,
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast,
__opClass),
src1(_src1), dest(_dest),
dataSize(_dataSize), ext(_ext)
{
}
//Figure out what the condition code flags should be.
uint64_t genFlags(uint64_t oldFlags, uint64_t flagMask,
uint64_t _dest, uint64_t _src1, uint64_t _src2,
bool subtract = false) const;
bool checkCondition(uint64_t flags) const;
};
class RegOp : public RegOpBase
{
protected:
const RegIndex src2;
// Constructor
RegOp(ExtMachInst _machInst,
const char *mnem, const char *_instMnem,
bool isMicro, bool isDelayed,
bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
uint8_t _dataSize, uint16_t _ext,
OpClass __opClass) :
RegOpBase(_machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast,
_src1, _dest, _dataSize, _ext,
__opClass),
src2(_src2)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
class RegOpImm : public RegOpBase
{
protected:
const uint8_t imm8;
// Constructor
RegOpImm(ExtMachInst _machInst,
const char * mnem, const char *_instMnem,
bool isMicro, bool isDelayed,
bool isFirst, bool isLast,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
uint8_t _dataSize, uint16_t _ext,
OpClass __opClass) :
RegOpBase(_machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast,
_src1, _dest, _dataSize, _ext,
__opClass),
imm8(_imm8)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
}
#endif //__ARCH_X86_INSTS_MICROREGOP_HH__

View file

@ -0,0 +1,200 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#include "arch/x86/insts/static_inst.hh"
namespace X86ISA
{
void X86StaticInst::printMnemonic(std::ostream &os,
const char * mnemonic) const
{
ccprintf(os, "\t%s ", mnemonic);
}
void X86StaticInst::printMnemonic(std::ostream &os,
const char * instMnemonic, const char * mnemonic) const
{
ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
}
void X86StaticInst::printSegment(std::ostream &os, int segment) const
{
switch (segment)
{
case 0:
ccprintf(os, "ES");
break;
case 1:
ccprintf(os, "CS");
break;
case 2:
ccprintf(os, "SS");
break;
case 3:
ccprintf(os, "DS");
break;
case 4:
ccprintf(os, "FS");
break;
case 5:
ccprintf(os, "GS");
break;
default:
panic("Unrecognized segment %d\n", segment);
}
}
void
X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const
{
if(_numSrcRegs > reg)
printReg(os, _srcRegIdx[reg], size);
}
void
X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const
{
if(_numDestRegs > reg)
printReg(os, _destRegIdx[reg], size);
}
void
X86StaticInst::printReg(std::ostream &os, int reg, int size) const
{
assert(size == 1 || size == 2 || size == 4 || size == 8);
static const char * abcdFormats[9] =
{"", "%sl", "%sx", "", "e%sx", "", "", "", "r%sx"};
static const char * piFormats[9] =
{"", "%sl", "%s", "", "e%s", "", "", "", "r%s"};
static const char * longFormats[9] =
{"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"};
static const char * microFormats[9] =
{"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
if (reg < FP_Base_DepTag) {
switch (reg) {
case INTREG_RAX:
ccprintf(os, abcdFormats[size], "a");
break;
case INTREG_RBX:
ccprintf(os, abcdFormats[size], "b");
break;
case INTREG_RCX:
ccprintf(os, abcdFormats[size], "c");
break;
case INTREG_RDX:
ccprintf(os, abcdFormats[size], "d");
break;
case INTREG_RSP:
ccprintf(os, piFormats[size], "sp");
break;
case INTREG_RBP:
ccprintf(os, piFormats[size], "bp");
break;
case INTREG_RSI:
ccprintf(os, piFormats[size], "si");
break;
case INTREG_RDI:
ccprintf(os, piFormats[size], "di");
break;
case INTREG_R8W:
ccprintf(os, longFormats[size], "8");
break;
case INTREG_R9W:
ccprintf(os, longFormats[size], "9");
break;
case INTREG_R10W:
ccprintf(os, longFormats[size], "10");
break;
case INTREG_R11W:
ccprintf(os, longFormats[size], "11");
break;
case INTREG_R12W:
ccprintf(os, longFormats[size], "12");
break;
case INTREG_R13W:
ccprintf(os, longFormats[size], "13");
break;
case INTREG_R14W:
ccprintf(os, longFormats[size], "14");
break;
case INTREG_R15W:
ccprintf(os, longFormats[size], "15");
break;
default:
ccprintf(os, microFormats[size], reg - NUM_INTREGS);
}
} else if (reg < Ctrl_Base_DepTag) {
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
} else {
switch (reg - Ctrl_Base_DepTag) {
default:
ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
}
}
}
std::string X86StaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss, mnemonic);
return ss.str();
}
}

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_X86_INSTS_STATICINST_HH__
#define __ARCH_X86_INSTS_STATICINST_HH__
#include "cpu/static_inst.hh"
namespace X86ISA
{
/**
* Base class for all X86 static instructions.
*/
class X86StaticInst : public StaticInst
{
protected:
// Constructor.
X86StaticInst(const char *mnem,
ExtMachInst _machInst, OpClass __opClass)
: StaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
void printMnemonic(std::ostream &os, const char * mnemonic) const;
void printMnemonic(std::ostream &os, const char * instMnemonic,
const char * mnemonic) const;
void printSegment(std::ostream &os, int segment) const;
void printReg(std::ostream &os, int reg, int size) const;
void printSrcReg(std::ostream &os, int reg, int size) const;
void printDestReg(std::ostream &os, int reg, int size) const;
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
{
X86IntReg reg;
reg = into;
//FIXME This needs to be handle high bytes as well
switch(size)
{
case 1:
reg.L = val;
break;
case 2:
reg.X = val;
break;
case 4:
//XXX Check if this should be zeroed or sign extended
reg = 0;
reg.E = val;
break;
case 8:
reg.R = val;
break;
default:
panic("Tried to merge with unrecognized size %d.\n", size);
}
return val;
}
inline uint64_t pick(uint64_t from, int size)
{
X86IntReg reg;
reg = from;
switch(size)
{
case 1:
return reg.L;
case 2:
return reg.E;
case 4:
return reg.X;
case 8:
return reg.R;
default:
panic("Tried to pick with unrecognized size %d.\n", size);
}
}
};
}
#endif //__ARCH_X86_INSTS_STATICINST_HH__

View file

@ -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
{

View file

@ -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,

View file

@ -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();
}
}};

View file

@ -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

View file

@ -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();
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);
}
}
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();
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);
}
0x2: decode MODE_SUBMODE {
0x0: This_should_be_an_illegal_instruction();
default: group1_Eb_Ib();
}
//0x3: group1_Ev_Ib();
0x3: decode MODRM_REG {
0x0: add_Eb_Ib();
0x1: or_Eb_Ib();
0x2: adc_Eb_Ib();
0x3: sbb_Eb_Ib();
0x4: Inst::AND(Eb,Ib);
0x5: sub_Eb_Ib();
0x6: xor_Eb_Ib();
0x7: cmp_Eb_Ib();
}
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();

View file

@ -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();

View file

@ -64,7 +64,7 @@
def template ErrorDecode {{
{
panic("X86 decoder internal error: '%%s' %%s",
panic("X86 decoder internal error: '%s' %s",
%(message)s, machInst);
}
}};

View file

@ -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"

View file

@ -0,0 +1,112 @@
// -*- mode:c++ -*-
// Copyright (c) 2007 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
// with or without modification, are permitted provided that the
// following conditions are met:
//
// The software must be used only for Non-Commercial Use which means any
// use which is NOT directed to receiving any direct monetary
// compensation for, or commercial advantage from such use. Illustrative
// examples of non-commercial use are academic research, personal study,
// teaching, education and corporate research & development.
// Illustrative examples of commercial use are distributing products for
// commercial advantage and providing services using the software for
// commercial advantage.
//
// If you wish to use this software or functionality therein that may be
// covered by patents for commercial use, please contact:
// Director of Intellectual Property Licensing
// Office of Strategy and Technology
// Hewlett-Packard Company
// 1501 Page Mill Road
// Palo Alto, California 94304
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. Redistributions
// in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution. Neither the name of
// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission. No right of
// sublicense is granted herewith. Derivatives of the software and
// output created using the software may be prepared, but only for
// Non-Commercial Uses. Derivatives of the software may be shared with
// others provided: (i) the others agree to abide by the list of
// conditions herein which includes the Non-Commercial Use restrictions;
// and (ii) such Derivatives of the software include the above copyright
// notice to acknowledge the contribution from this software where
// applicable, this list of conditions and the disclaimer below.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Gabe Black
////////////////////////////////////////////////////////////////////
//
// "Format" which describes an instruction whose only purpose is to
// call a syscall in SE mode.
//
output header {{
class SyscallInst : public X86ISA::X86StaticInst
{
public:
/// Constructor
SyscallInst(const char *_mnemonic, ExtMachInst _machInst,
OpClass __opClass) :
X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string SyscallInst::generateDisassembly(Addr PC,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
ccprintf(response, " ");
printReg(response, _srcRegIdx[0], machInst.opSize);
return response.str();
}
}};
def template SyscallExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(code)s;
return fault;
}
}};
def format SyscallInst(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SyscallInst', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = SyscallExecute.subst(iop)
}};

View file

@ -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

View file

@ -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"

View file

@ -69,7 +69,8 @@ categories = ["arithmetic",
"rotate_and_shift",
"semaphores",
"string",
"system_calls"]
"system_calls",
"system"]
microcode = '''
# X86 microcode

View file

@ -54,23 +54,227 @@
# Authors: Gabe Black
microcode = '''
def macroop ADD_R_R
{
add reg, reg, regm
};
def macroop ADD_R_I
{
limm t1, imm
add reg, reg, t1
};
def macroop ADD_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
add t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop ADD_P_I
{
rdip t7
limm t2, imm
ld t1, ds, [scale, index, base], disp
add t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop ADD_M_R
{
ld t1, ds, [scale, index, base], disp
add t1, t1, reg
st t1, ds, [scale, index, base], disp
};
def macroop ADD_P_R
{
rdip t7
ld t1, ds, [scale, index, base], disp
add t1, t1, reg
st t1, ds, [scale, index, base], disp
};
def macroop ADD_R_M
{
ld t1, ds, [scale, index, base], disp
add reg, reg, t1
};
def macroop ADD_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
add reg, reg, t1
};
def macroop SUB_R_R
{
sub reg, reg, regm
};
def macroop SUB_R_I
{
subi reg, reg, imm
limm t1, imm
sub reg, reg, t1
};
def macroop SUB_R_M
{
ld t1, ds, [scale, index, base], disp
sub reg, reg, t1
};
def macroop SUB_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
sub reg, reg, t1
};
def macroop SUB_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
subi t1, t1, imm
sub t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop SUB_P_I
{
rdip t7
limm t2, imm
ld t1, ds, [scale, index, base], disp
subi t1, t1, imm
sub t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop SUB_M_R
{
ld t1, ds, [scale, index, base], disp
sub t1, t1, reg
st t1, ds, [scale, index, base], disp
};
def macroop SUB_P_R
{
rdip t7
ld t1, ds, [scale, index, base], disp
sub t1, t1, reg
st t1, ds, [scale, index, base], disp
};
def macroop ADC_R_R
{
adc reg, reg, regm
};
def macroop ADC_R_I
{
limm t1, imm
adc reg, reg, t1
};
def macroop ADC_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
adc t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop ADC_P_I
{
rdip t7
limm t2, imm
ld t1, ds, [scale, index, base], disp
adc t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop ADC_M_R
{
ld t1, ds, [scale, index, base], disp
adc t1, t1, reg
st t1, ds, [scale, index, base], disp
};
def macroop ADC_P_R
{
rdip t7
ld t1, ds, [scale, index, base], disp
adc t1, t1, reg
st t1, ds, [scale, index, base], disp
};
def macroop ADC_R_M
{
ld t1, ds, [scale, index, base], disp
adc reg, reg, t1
};
def macroop ADC_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
adc reg, reg, t1
};
def macroop SBB_R_R
{
sbb reg, reg, regm
};
def macroop SBB_R_I
{
limm t1, imm
sbb reg, reg, t1
};
def macroop SBB_R_M
{
ld t1, ds, [scale, index, base], disp
sbb reg, reg, t1
};
def macroop SBB_R_P
{
rdip t7
ld t1, ds, [scale, index, base], disp
sbb reg, reg, t1
};
def macroop SBB_M_I
{
limm t2, imm
ld t1, ds, [scale, index, base], disp
sbb t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop SBB_P_I
{
rdip t7
limm t2, imm
ld t1, ds, [scale, index, base], disp
sbb t1, t1, t2
st t1, ds, [scale, index, base], disp
};
def macroop SBB_M_R
{
ld t1, ds, [scale, index, base], disp
sbb t1, t1, reg
st t1, ds, [scale, index, base], disp
};
def macroop SBB_P_R
{
rdip t7
ld t1, ds, [scale, index, base], disp
sbb t1, t1, reg
st t1, ds, [scale, index, base], disp
};
'''

View file

@ -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}"

View file

@ -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}"

View file

@ -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)
};
'''

View file

@ -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)
};
'''

View file

@ -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 {{

View file

@ -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
};
'''

View file

@ -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
};
'''

View file

@ -55,7 +55,8 @@
categories = ["conditional_move",
"move",
"stack_operations"]
"stack_operations",
"xchg"]
microcode = ""
for category in categories:

View file

@ -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 {{

View file

@ -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):

View file

@ -0,0 +1,98 @@
# Copyright (c) 2007 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
# with or without modification, are permitted provided that the
# following conditions are met:
#
# The software must be used only for Non-Commercial Use which means any
# use which is NOT directed to receiving any direct monetary
# compensation for, or commercial advantage from such use. Illustrative
# examples of non-commercial use are academic research, personal study,
# teaching, education and corporate research & development.
# Illustrative examples of commercial use are distributing products for
# commercial advantage and providing services using the software for
# commercial advantage.
#
# If you wish to use this software or functionality therein that may be
# covered by patents for commercial use, please contact:
# Director of Intellectual Property Licensing
# Office of Strategy and Technology
# Hewlett-Packard Company
# 1501 Page Mill Road
# Palo Alto, California 94304
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer. Redistributions
# in binary form must reproduce the above copyright notice, this list of
# conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution. Neither the name of
# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission. No right of
# sublicense is granted herewith. Derivatives of the software and
# output created using the software may be prepared, but only for
# Non-Commercial Uses. Derivatives of the software may be shared with
# others provided: (i) the others agree to abide by the list of
# conditions herein which includes the Non-Commercial Use restrictions;
# and (ii) such Derivatives of the software include the above copyright
# notice to acknowledge the contribution from this software where
# applicable, this list of conditions and the disclaimer below.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Gabe Black
microcode = '''
# All the memory versions need to use LOCK, regardless of if it was set
def macroop XCHG_R_R
{
# Use the xor trick instead of moves to reduce register pressure.
# This probably doesn't make much of a difference, but it's easy.
xor reg, reg, regm
xor regm, regm, reg
xor reg, reg, regm
};
def macroop XCHG_R_M
{
ld t1, ds, [scale, index, base], disp
st reg, ds, [scale, index, base], disp
mov reg, reg, t1
};
def macroop XCHG_R_P
{
rdip t7
ld t1, ds, [0, t0, t7], disp
st reg, ds, [0, t0, t7], disp
mov reg, reg, t1
};
def macroop XCHG_M_R
{
ld t1, ds, [scale, index, base], disp
st reg, ds, [scale, index, base], disp
mov reg, reg, t1
};
def macroop XCHG_P_R
{
rdip t7
ld t1, ds, [0, t0, t7], disp
st reg, ds, [0, t0, t7], disp
mov reg, reg, t1
};
'''

View file

@ -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 = '''

View file

@ -53,8 +53,9 @@
#
# Authors: Gabe Black
microcode = ""
#let {{
# class NOP(Inst):
# "GenFault ${new UnimpInstFault}"
#}};
microcode = '''
def macroop NOP
{
fault "NoFault"
};
'''

View file

@ -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}"
#}};

View file

@ -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}"

View file

@ -0,0 +1,62 @@
# Copyright (c) 2007 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
# with or without modification, are permitted provided that the
# following conditions are met:
#
# The software must be used only for Non-Commercial Use which means any
# use which is NOT directed to receiving any direct monetary
# compensation for, or commercial advantage from such use. Illustrative
# examples of non-commercial use are academic research, personal study,
# teaching, education and corporate research & development.
# Illustrative examples of commercial use are distributing products for
# commercial advantage and providing services using the software for
# commercial advantage.
#
# If you wish to use this software or functionality therein that may be
# covered by patents for commercial use, please contact:
# Director of Intellectual Property Licensing
# Office of Strategy and Technology
# Hewlett-Packard Company
# 1501 Page Mill Road
# Palo Alto, California 94304
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer. Redistributions
# in binary form must reproduce the above copyright notice, this list of
# conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution. Neither the name of
# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission. No right of
# sublicense is granted herewith. Derivatives of the software and
# output created using the software may be prepared, but only for
# Non-Commercial Uses. Derivatives of the software may be shared with
# others provided: (i) the others agree to abide by the list of
# conditions herein which includes the Non-Commercial Use restrictions;
# and (ii) such Derivatives of the software include the above copyright
# notice to acknowledge the contribution from this software where
# applicable, this list of conditions and the disclaimer below.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Gabe Black
categories = ["undefined_operation"]
microcode = ""
for category in categories:
exec "import %s as cat" % category
microcode += cat.microcode

View file

@ -0,0 +1,61 @@
# Copyright (c) 2007 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
# with or without modification, are permitted provided that the
# following conditions are met:
#
# The software must be used only for Non-Commercial Use which means any
# use which is NOT directed to receiving any direct monetary
# compensation for, or commercial advantage from such use. Illustrative
# examples of non-commercial use are academic research, personal study,
# teaching, education and corporate research & development.
# Illustrative examples of commercial use are distributing products for
# commercial advantage and providing services using the software for
# commercial advantage.
#
# If you wish to use this software or functionality therein that may be
# covered by patents for commercial use, please contact:
# Director of Intellectual Property Licensing
# Office of Strategy and Technology
# Hewlett-Packard Company
# 1501 Page Mill Road
# Palo Alto, California 94304
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer. Redistributions
# in binary form must reproduce the above copyright notice, this list of
# conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution. Neither the name of
# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission. No right of
# sublicense is granted herewith. Derivatives of the software and
# output created using the software may be prepared, but only for
# Non-Commercial Uses. Derivatives of the software may be shared with
# others provided: (i) the others agree to abide by the list of
# conditions herein which includes the Non-Commercial Use restrictions;
# and (ii) such Derivatives of the software include the above copyright
# notice to acknowledge the contribution from this software where
# applicable, this list of conditions and the disclaimer below.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Gabe Black
microcode = '''
def macroop UD2
{
fault "new X86Fault"
};
'''

View file

@ -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"

View file

@ -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 &&

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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)
setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, flagCode);
microopClasses[name] = RegOpChild
setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode);
# Build the immediate version of this micro op
class RegOpChildImm(RegOpImm):
def __init__(self, dest, src1, src2, setStatus=False):
super(RegOpChildImm, self).__init__(dest, src1, src2, setStatus)
self.className = Name + "Imm"
self.mnemonic = name + "i"
mnemonic = name + 'i'
className = Name + 'Imm'
def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"):
super(RegOpChildImm, self).__init__(dest, src1, src2, flags, dataSize)
setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, flagCode);
microopClasses[name + 'i'] = RegOpChildImm
defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to set OF,CF,SF
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', "")
defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to add in CF, set OF,CF,SF
defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to subtract CF, set OF,CF,SF
defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', "")
defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to set OF,CF,SF
defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', "")
defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', "") #Needs to set OF,CF,SF and not DestReg
defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', "")
setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode);
setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
# This has it's own function because Wr ops have implicit destinations
def defineMicroRegOpWr(mnemonic, code):
def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
Name = mnemonic
name = mnemonic.lower()
@ -424,25 +393,29 @@ let {{
regCode = matcher.sub("SrcReg2", code)
immCode = matcher.sub("imm8", code)
# Build the all register version of this micro op
class RegOpChild(RegOp):
def __init__(self, src1, src2):
super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, False)
self.className = Name
self.mnemonic = name
mnemonic = name
className = Name
def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, "");
microopClasses[name] = RegOpChild
setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
condCheck = checkCCFlagBits, elseCode = elseCode);
# Build the immediate version of this micro op
class RegOpChildImm(RegOpImm):
def __init__(self, src1, src2):
super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, False)
self.className = Name + "Imm"
self.mnemonic = name + "i"
mnemonic = name + 'i'
className = Name + 'Imm'
def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, "");
microopClasses[name + 'i'] = RegOpChildImm
defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2')
setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode);
setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
condCheck = checkCCFlagBits, elseCode = elseCode);
# This has it's own function because Rd ops don't always have two parameters
def defineMicroRegOpRd(mnemonic, code):
@ -450,30 +423,136 @@ let {{
name = mnemonic.lower()
class RegOpChild(RegOp):
def __init__(self, dest, src1 = "NUM_INTREGS"):
super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", False)
def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"):
super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize)
self.className = Name
self.mnemonic = name
setUpMicroRegOp(name, Name, "RegOp", code, RegOpChild, "");
microopClasses[name] = RegOpChild
defineMicroRegOpRd('Rdip', 'DestReg = RIP')
setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
def defineMicroRegOpImm(mnemonic, code):
Name = mnemonic
name = mnemonic.lower()
class RegOpChild(RegOpImm):
def __init__(self, dest, src1, src2):
super(RegOpChild, self).__init__(dest, src1, src2, False)
def __init__(self, dest, src1, src2, dataSize="env.dataSize"):
super(RegOpChild, self).__init__(dest, src1, src2, None, dataSize)
self.className = Name
self.mnemonic = name
setUpMicroRegOp(name, Name, "RegOpImm", code, RegOpChild, "");
microopClasses[name] = RegOpChild
setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
defineMicroRegOp('Adc', '''
CCFlagBits flags = ccFlagBits;
DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
''')
defineMicroRegOp('Sbb', '''
CCFlagBits flags = ccFlagBits;
DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
''', True)
defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
# defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
elseCode='DestReg=DestReg;', cc=True)
# Shift instructions
defineMicroRegOp('Sll', '''
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
''')
defineMicroRegOp('Srl', '''
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
// Because what happens to the bits shift -in- on a right shift
// is not defined in the C/C++ standard, we have to mask them out
// to be sure they're zero.
uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) & logicalMask, dataSize);
''')
defineMicroRegOp('Sra', '''
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
// Because what happens to the bits shift -in- on a right shift
// is not defined in the C/C++ standard, we have to sign extend
// them manually to be sure.
uint64_t arithMask =
-bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
''')
defineMicroRegOp('Ror', '''
uint8_t shiftAmt =
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
if(shiftAmt)
{
uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
DestReg = merge(DestReg, top | bottom, dataSize);
}
else
DestReg = DestReg;
''')
defineMicroRegOp('Rcr', '''
uint8_t shiftAmt =
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
if(shiftAmt)
{
CCFlagBits flags = ccFlagBits;
uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
if(shiftAmt > 1)
top |= SrcReg1 << (dataSize * 8 - shiftAmt - 1);
uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
DestReg = merge(DestReg, top | bottom, dataSize);
}
else
DestReg = DestReg;
''')
defineMicroRegOp('Rol', '''
uint8_t shiftAmt =
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
if(shiftAmt)
{
uint64_t top = SrcReg1 << shiftAmt;
uint64_t bottom =
bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
DestReg = merge(DestReg, top | bottom, dataSize);
}
else
DestReg = DestReg;
''')
defineMicroRegOp('Rcl', '''
uint8_t shiftAmt =
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
if(shiftAmt)
{
CCFlagBits flags = ccFlagBits;
uint64_t top = SrcReg1 << shiftAmt;
uint64_t bottom = flags.CF << (shiftAmt - 1);
if(shiftAmt > 1)
bottom |=
bits(SrcReg1, dataSize * 8 - 1,
dataSize * 8 - shiftAmt + 1);
DestReg = merge(DestReg, top | bottom, dataSize);
}
else
DestReg = DestReg;
''')
defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
defineMicroRegOpRd('Rdip', 'DestReg = RIP')
defineMicroRegOpImm('Sext', '''
IntReg val = SrcReg1;
int sign_bit = bits(val, imm8-1, imm8-1);
val = sign_bit ? (val | ~mask(imm8)) : val;
DestReg = merge(DestReg, val, dataSize);''')
defineMicroRegOpImm('Zext', 'DestReg = bits(SrcReg1, imm8-1, 0);')
}};

View file

@ -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):

View file

@ -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)
}};

View file

@ -0,0 +1,91 @@
// Copyright (c) 2007 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
// with or without modification, are permitted provided that the
// following conditions are met:
//
// The software must be used only for Non-Commercial Use which means any
// use which is NOT directed to receiving any direct monetary
// compensation for, or commercial advantage from such use. Illustrative
// examples of non-commercial use are academic research, personal study,
// teaching, education and corporate research & development.
// Illustrative examples of commercial use are distributing products for
// commercial advantage and providing services using the software for
// commercial advantage.
//
// If you wish to use this software or functionality therein that may be
// covered by patents for commercial use, please contact:
// Director of Intellectual Property Licensing
// Office of Strategy and Technology
// Hewlett-Packard Company
// 1501 Page Mill Road
// Palo Alto, California 94304
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. Redistributions
// in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution. Neither the name of
// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission. No right of
// sublicense is granted herewith. Derivatives of the software and
// output created using the software may be prepared, but only for
// Non-Commercial Uses. Derivatives of the software may be shared with
// others provided: (i) the others agree to abide by the list of
// conditions herein which includes the Non-Commercial Use restrictions;
// and (ii) such Derivatives of the software include the above copyright
// notice to acknowledge the contribution from this software where
// applicable, this list of conditions and the disclaimer below.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Gabe Black
////////////////////////////////////////////////////////////////////
//
// Output blocks which group together code generated by the parser.
//
let {{
# This class will help make dealing with output a little less verbose
class OutputBlocks(object):
def __init__(self, header_output="",
decoder_output="",
decode_block="",
exec_output=""):
self.header_output = header_output
self.decoder_output = decoder_output
self.decode_block = decode_block
self.exec_output = exec_output
def append(self, blocks):
if isinstance(blocks, list) or isinstance(blocks, tuple):
assert(len(blocks) == 4)
self.header_output += blocks[0]
self.decoder_output += blocks[1]
self.decode_block += blocks[2]
self.exec_output += blocks[3]
else:
self.header_output += blocks.header_output
self.decoder_output += blocks.decoder_output
self.decode_block += blocks.decode_block
self.exec_output += blocks.exec_output
def makeList(self):
return (self.header_output,
self.decoder_output,
self.decode_block,
self.exec_output)
}};

View file

@ -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.

View file

@ -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),

View file

@ -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);
}

View file

@ -89,6 +89,7 @@
#define __ARCH_X86_MISCREGFILE_HH__
#include "arch/x86/faults.hh"
#include "arch/x86/miscregs.hh"
#include "arch/x86/types.hh"
#include <string>
@ -100,11 +101,14 @@ namespace X86ISA
std::string getMiscRegName(RegIndex);
//These will have to be updated in the future.
const int NumMiscArchRegs = 0;
const int NumMiscRegs = 0;
const int NumMiscArchRegs = NUM_MISCREGS;
const int NumMiscRegs = NUM_MISCREGS;
class MiscRegFile
{
protected:
MiscReg regVal[NumMiscRegs];
public:
void clear();

329
src/arch/x86/miscregs.hh Normal file
View file

@ -0,0 +1,329 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_X86_MISCREGS_HH__
#define __ARCH_X86_MISCREGS_HH__
#include "base/bitunion.hh"
namespace X86ISA
{
enum CondFlagBit {
CFBit = 1 << 0,
PFBit = 1 << 2,
ECFBit = 1 << 3,
AFBit = 1 << 4,
EZFBit = 1 << 5,
ZFBit = 1 << 6,
SFBit = 1 << 7,
OFBit = 1 << 11
};
enum MiscRegIndex
{
// Control registers
// Most of these are invalid.
MISCREG_CR0,
MISCREG_CR1,
MISCREG_CR2,
MISCREG_CR3,
MISCREG_CR4,
MISCREG_CR5,
MISCREG_CR6,
MISCREG_CR7,
MISCREG_CR8,
MISCREG_CR9,
MISCREG_CR10,
MISCREG_CR11,
MISCREG_CR12,
MISCREG_CR13,
MISCREG_CR14,
MISCREG_CR15,
// Debug registers
MISCREG_DR0,
MISCREG_DR1,
MISCREG_DR2,
MISCREG_DR3,
MISCREG_DR4,
MISCREG_DR5,
MISCREG_DR6,
MISCREG_DR7,
// Flags register
MISCREG_RFLAGS,
// Segment selectors
MISCREG_ES,
MISCREG_CS,
MISCREG_SS,
MISCREG_DS,
MISCREG_FS,
MISCREG_GS,
// Hidden segment base field
MISCREG_ES_BASE,
MISCREG_CS_BASE,
MISCREG_SS_BASE,
MISCREG_DS_BASE,
MISCREG_FS_BASE,
MISCREG_GS_BASE,
// Hidden segment limit field
MISCREG_ES_LIMIT,
MISCREG_CS_LIMIT,
MISCREG_SS_LIMIT,
MISCREG_DS_LIMIT,
MISCREG_FS_LIMIT,
MISCREG_GS_LIMIT,
// Hidden segment limit attributes
MISCREG_ES_ATTR,
MISCREG_CS_ATTR,
MISCREG_SS_ATTR,
MISCREG_DS_ATTR,
MISCREG_FS_ATTR,
MISCREG_GS_ATTR,
// System segment selectors
MISCREG_LDTR,
MISCREG_TR,
// Hidden system segment base field
MISCREG_LDTR_BASE,
MISCREG_TR_BASE,
MISCREG_GDTR_BASE,
MISCREG_IDTR_BASE,
// Hidden system segment limit field
MISCREG_LDTR_LIMIT,
MISCREG_TR_LIMIT,
MISCREG_GDTR_LIMIT,
MISCREG_IDTR_LIMIT,
// Hidden system segment attribute field
MISCREG_LDTR_ATTR,
MISCREG_TR_ATTR,
//XXX Add "Model-Specific Registers"
NUM_MISCREGS
};
/**
* A type to describe the condition code bits of the RFLAGS register,
* plus two flags, EZF and ECF, which are only visible to microcode.
*/
BitUnion64(CCFlagBits)
Bitfield<11> OF;
Bitfield<7> SF;
Bitfield<6> ZF;
Bitfield<5> EZF;
Bitfield<4> AF;
Bitfield<3> ECF;
Bitfield<2> PF;
Bitfield<0> CF;
EndBitUnion(CCFlagBits)
/**
* RFLAGS
*/
BitUnion64(RFLAGS)
Bitfield<21> ID; // ID Flag
Bitfield<20> VIP; // Virtual Interrupt Pending
Bitfield<19> VIF; // Virtual Interrupt Flag
Bitfield<18> AC; // Alignment Check
Bitfield<17> VM; // Virtual-8086 Mode
Bitfield<16> RF; // Resume Flag
Bitfield<14> NT; // Nested Task
Bitfield<13, 12> IOPL; // I/O Privilege Level
Bitfield<11> OF; // Overflow Flag
Bitfield<10> DF; // Direction Flag
Bitfield<9> IF; // Interrupt Flag
Bitfield<8> TF; // Trap Flag
Bitfield<7> SF; // Sign Flag
Bitfield<6> ZF; // Zero Flag
Bitfield<4> AF; // Auxiliary Flag
Bitfield<2> PF; // Parity Flag
Bitfield<0> CF; // Carry Flag
EndBitUnion(RFLAGS)
/**
* Control registers
*/
BitUnion64(CR0)
Bitfield<31> PG; // Paging
Bitfield<30> CD; // Cache Disable
Bitfield<29> NW; // Not Writethrough
Bitfield<18> AM; // Alignment Mask
Bitfield<16> WP; // Write Protect
Bitfield<5> NE; // Numeric Error
Bitfield<4> ET; // Extension Type
Bitfield<3> TS; // Task Switched
Bitfield<2> EM; // Emulation
Bitfield<1> MP; // Monitor Coprocessor
Bitfield<0> PE; // Protection Enabled
EndBitUnion(CR0)
// Page Fault Virtual Address
BitUnion64(CR2)
Bitfield<31, 0> legacy;
EndBitUnion(CR2)
BitUnion64(CR3)
Bitfield<51, 12> longPDTB; // Long Mode Page-Directory-Table
// Base Address
Bitfield<31, 12> PDTB; // Non-PAE Addressing Page-Directory-Table
// Base Address
Bitfield<31, 5> PAEPDTB; // PAE Addressing Page-Directory-Table
// Base Address
Bitfield<4> PCD; // Page-Level Cache Disable
Bitfield<3> PWT; // Page-Level Writethrough
EndBitUnion(CR3)
BitUnion64(CR4)
Bitfield<10> OSXMMEXCPT; // Operating System Unmasked
// Exception Support
Bitfield<9> OSFXSR; // Operating System FXSave/FSRSTOR Support
Bitfield<8> PCE; // Performance-Monitoring Counter Enable
Bitfield<7> PGE; // Page-Global Enable
Bitfield<6> MCE; // Machine Check Enable
Bitfield<5> PAE; // Physical-Address Extension
Bitfield<4> PSE; // Page Size Extensions
Bitfield<3> DE; // Debugging Extensions
Bitfield<2> TSD; // Time Stamp Disable
Bitfield<1> PVI; // Protected-Mode Virtual Interrupts
Bitfield<0> VME; // Virtual-8086 Mode Extensions
EndBitUnion(CR4)
BitUnion64(CR8)
Bitfield<3, 0> TPR; // Task Priority Register
EndBitUnion(CR4)
/**
* Segment Selector
*/
BitUnion64(SegSelector)
Bitfield<15, 3> SI; // Selector Index
Bitfield<2> TI; // Table Indicator
Bitfield<1, 0> RPL; // Requestor Privilege Level
EndBitUnion(SegSelector)
/**
* Segment Descriptors
*/
BitUnion64(SegDescriptor)
Bitfield<63, 56> baseHigh;
Bitfield<39, 16> baseLow;
Bitfield<55> G; // Granularity
Bitfield<54> D; // Default Operand Size
Bitfield<54> B; // Default Operand Size
Bitfield<53> L; // Long Attribute Bit
Bitfield<52> AVL; // Available To Software
Bitfield<51, 48> limitHigh;
Bitfield<15, 0> limitLow;
Bitfield<47> P; // Present
Bitfield<46, 45> DPL; // Descriptor Privilege-Level
Bitfield<44> S; // System
SubBitUnion(type, 43, 40)
// Specifies whether this descriptor is for code or data.
Bitfield<43> codeOrData;
// These bit fields are for code segments
Bitfield<42> C; // Conforming
Bitfield<41> R; // Readable
// These bit fields are for data segments
Bitfield<42> E; // Expand-Down
Bitfield<41> W; // Writable
// This is used for both code and data segments.
Bitfield<40> A; // Accessed
EndSubBitUnion(type)
EndBitUnion(SegDescriptor)
BitUnion64(GateDescriptor)
Bitfield<63, 48> offsetHigh; // Target Code-Segment Offset
Bitfield<15, 0> offsetLow; // Target Code-Segment Offset
Bitfield<31, 16> selector; // Target Code-Segment Selector
Bitfield<47> P; // Present
Bitfield<46, 45> DPL; // Descriptor Privilege-Level
Bitfield<43, 40> type;
Bitfield<36, 32> count; // Parameter Count
EndBitUnion(GateDescriptor)
/**
* Descriptor-Table Registers
*/
BitUnion64(GDTR)
EndBitUnion(GDTR)
BitUnion64(IDTR)
EndBitUnion(IDTR)
BitUnion64(LDTR)
EndBitUnion(LDTR)
/**
* Task Register
*/
BitUnion64(TR)
EndBitUnion(TR)
};
#endif // __ARCH_X86_INTREGS_HH__

View file

@ -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!

View file

@ -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 {

View file

@ -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());
}
};

View file

@ -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);

View file

@ -61,6 +61,7 @@
namespace X86ISA
{
const int NumMicroIntRegs = 16;
const int NumPseudoIntRegs = 1;
const int NumMMXRegs = 8;
const int NumXMMRegs = 16;

View file

@ -161,273 +161,4 @@ findMsbSet(uint64_t val) {
return msb;
}
// The following implements the BitUnion system of defining bitfields
//on top of an underlying class. This is done through the pervasive use of
//both named and unnamed unions which all contain the same actual storage.
//Since they're unioned with each other, all of these storage locations
//overlap. This allows all of the bitfields to manipulate the same data
//without having to have access to each other. More details are provided with the
//individual components.
//This namespace is for classes which implement the backend of the BitUnion
//stuff. Don't use any of these directly, except for the Bitfield classes in
//the *BitfieldTypes class(es).
namespace BitfieldBackend
{
//A base class for all bitfields. It instantiates the actual storage,
//and provides getBits and setBits functions for manipulating it. The
//Data template parameter is type of the underlying storage.
template<class Data>
class BitfieldBase
{
protected:
Data __data;
//This function returns a range of bits from the underlying storage.
//It relies on the "bits" function above. It's the user's
//responsibility to make sure that there is a properly overloaded
//version of this function for whatever type they want to overlay.
inline uint64_t
getBits(int first, int last) const
{
return bits(__data, first, last);
}
//Similar to the above, but for settings bits with replaceBits.
inline void
setBits(int first, int last, uint64_t val)
{
replaceBits(__data, first, last, val);
}
};
//This class contains all the "regular" bitfield classes. It is inherited
//by all BitUnions which give them access to those types.
template<class Type>
class RegularBitfieldTypes
{
protected:
//This class implements ordinary bitfields, that is a span of bits
//who's msb is "first", and who's lsb is "last".
template<int first, int last=first>
class Bitfield : public BitfieldBase<Type>
{
public:
operator uint64_t () const
{
return this->getBits(first, last);
}
uint64_t
operator=(const uint64_t _data)
{
this->setBits(first, last, _data);
return _data;
}
};
//A class which specializes the above so that it can only be read
//from. This is accomplished explicitly making sure the assignment
//operator is blocked. The conversion operator is carried through
//inheritance. This will unfortunately need to be copied into each
//bitfield type due to limitations with how templates work
template<int first, int last=first>
class BitfieldRO : public Bitfield<first, last>
{
private:
uint64_t
operator=(const uint64_t _data);
};
//Similar to the above, but only allows writing.
template<int first, int last=first>
class BitfieldWO : public Bitfield<first, last>
{
private:
operator uint64_t () const;
public:
using Bitfield<first, last>::operator=;
};
};
//This class contains all the "regular" bitfield classes. It is inherited
//by all BitUnions which give them access to those types.
template<class Type>
class SignedBitfieldTypes
{
protected:
//This class implements ordinary bitfields, that is a span of bits
//who's msb is "first", and who's lsb is "last".
template<int first, int last=first>
class SignedBitfield : public BitfieldBase<Type>
{
public:
operator int64_t () const
{
return sext<first - last + 1>(this->getBits(first, last));
}
int64_t
operator=(const int64_t _data)
{
this->setBits(first, last, _data);
return _data;
}
};
//A class which specializes the above so that it can only be read
//from. This is accomplished explicitly making sure the assignment
//operator is blocked. The conversion operator is carried through
//inheritance. This will unfortunately need to be copied into each
//bitfield type due to limitations with how templates work
template<int first, int last=first>
class SignedBitfieldRO : public SignedBitfield<first, last>
{
private:
int64_t
operator=(const int64_t _data);
};
//Similar to the above, but only allows writing.
template<int first, int last=first>
class SignedBitfieldWO : public SignedBitfield<first, last>
{
private:
operator int64_t () const;
public:
int64_t operator=(const int64_t _data)
{
*((SignedBitfield<first, last> *)this) = _data;
return _data;
}
};
};
template<class Type>
class BitfieldTypes : public RegularBitfieldTypes<Type>,
public SignedBitfieldTypes<Type>
{};
//When a BitUnion is set up, an underlying class is created which holds
//the actual union. This class then inherits from it, and provids the
//implementations for various operators. Setting things up this way
//prevents having to redefine these functions in every different BitUnion
//type. More operators could be implemented in the future, as the need
//arises.
template <class Type, class Base>
class BitUnionOperators : public Base
{
public:
operator Type () const
{
return Base::__data;
}
Type
operator=(const Type & _data)
{
Base::__data = _data;
return _data;
}
bool
operator<(const Base & base) const
{
return Base::__data < base.__data;
}
bool
operator==(const Base & base) const
{
return Base::__data == base.__data;
}
};
}
//This macro is a backend for other macros that specialize it slightly.
//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and
//sticks the class which has the actual union in it, which
//BitfieldOperators above inherits from. Putting these classes in a special
//namespace ensures that there will be no collisions with other names as long
//as the BitUnion names themselves are all distinct and nothing else uses
//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself
//creates a typedef of the "type" parameter called __DataType. This allows
//the type to propagate outside of the macro itself in a controlled way.
//Finally, the base storage is defined which BitfieldOperators will refer to
//in the operators it defines. This macro is intended to be followed by
//bitfield definitions which will end up inside it's union. As explained
//above, these is overlayed the __data member in its entirety by each of the
//bitfields which are defined in the union, creating shared storage with no
//overhead.
#define __BitUnion(type, name) \
namespace BitfieldUnderlyingClasses \
{ \
class name; \
} \
class BitfieldUnderlyingClasses::name : \
public BitfieldBackend::BitfieldTypes<type> \
{ \
public: \
typedef type __DataType; \
union { \
type __data;\
//This closes off the class and union started by the above macro. It is
//followed by a typedef which makes "name" refer to a BitfieldOperator
//class inheriting from the class and union just defined, which completes
//building up the type for the user.
#define EndBitUnion(name) \
}; \
}; \
typedef BitfieldBackend::BitUnionOperators< \
BitfieldUnderlyingClasses::name::__DataType, \
BitfieldUnderlyingClasses::name> name;
//This sets up a bitfield which has other bitfields nested inside of it. The
//__data member functions like the "underlying storage" of the top level
//BitUnion. Like everything else, it overlays with the top level storage, so
//making it a regular bitfield type makes the entire thing function as a
//regular bitfield when referred to by itself.
#define __SubBitUnion(fieldType, first, last, name) \
class : public BitfieldBackend::BitfieldTypes<__DataType> \
{ \
public: \
union { \
fieldType<first, last> __data;
//This closes off the union created above and gives it a name. Unlike the top
//level BitUnion, we're interested in creating an object instead of a type.
//The operators are defined in the macro itself instead of a class for
//technical reasons. If someone determines a way to move them to one, please
//do so.
#define EndSubBitUnion(name) \
}; \
inline operator const __DataType () \
{ return __data; } \
\
inline const __DataType operator = (const __DataType & _data) \
{ __data = _data; } \
} name;
//Regular bitfields
//These define macros for read/write regular bitfield based subbitfields.
#define SubBitUnion(name, first, last) \
__SubBitUnion(Bitfield, first, last, name)
//Regular bitfields
//These define macros for read/write regular bitfield based subbitfields.
#define SignedSubBitUnion(name, first, last) \
__SubBitUnion(SignedBitfield, first, last, name)
//Use this to define an arbitrary type overlayed with bitfields.
#define BitUnion(type, name) __BitUnion(type, name)
//Use this to define conveniently sized values overlayed with bitfields.
#define BitUnion64(name) __BitUnion(uint64_t, name)
#define BitUnion32(name) __BitUnion(uint32_t, name)
#define BitUnion16(name) __BitUnion(uint16_t, name)
#define BitUnion8(name) __BitUnion(uint8_t, name)
#endif // __BASE_BITFIELD_HH__

313
src/base/bitunion.hh Normal file
View file

@ -0,0 +1,313 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __BASE_BITUNION_HH__
#define __BASE_BITUNION_HH__
#include <inttypes.h>
#include "base/bitfield.hh"
// The following implements the BitUnion system of defining bitfields
//on top of an underlying class. This is done through the pervasive use of
//both named and unnamed unions which all contain the same actual storage.
//Since they're unioned with each other, all of these storage locations
//overlap. This allows all of the bitfields to manipulate the same data
//without having to have access to each other. More details are provided with
//the individual components.
//This namespace is for classes which implement the backend of the BitUnion
//stuff. Don't use any of these directly, except for the Bitfield classes in
//the *BitfieldTypes class(es).
namespace BitfieldBackend
{
//A base class for all bitfields. It instantiates the actual storage,
//and provides getBits and setBits functions for manipulating it. The
//Data template parameter is type of the underlying storage.
template<class Data>
class BitfieldBase
{
protected:
Data __data;
//This function returns a range of bits from the underlying storage.
//It relies on the "bits" function above. It's the user's
//responsibility to make sure that there is a properly overloaded
//version of this function for whatever type they want to overlay.
inline uint64_t
getBits(int first, int last) const
{
return bits(__data, first, last);
}
//Similar to the above, but for settings bits with replaceBits.
inline void
setBits(int first, int last, uint64_t val)
{
replaceBits(__data, first, last, val);
}
};
//This class contains all the "regular" bitfield classes. It is inherited
//by all BitUnions which give them access to those types.
template<class Type>
class RegularBitfieldTypes
{
protected:
//This class implements ordinary bitfields, that is a span of bits
//who's msb is "first", and who's lsb is "last".
template<int first, int last=first>
class Bitfield : public BitfieldBase<Type>
{
public:
operator uint64_t () const
{
return this->getBits(first, last);
}
uint64_t
operator=(const uint64_t _data)
{
this->setBits(first, last, _data);
return _data;
}
};
//A class which specializes the above so that it can only be read
//from. This is accomplished explicitly making sure the assignment
//operator is blocked. The conversion operator is carried through
//inheritance. This will unfortunately need to be copied into each
//bitfield type due to limitations with how templates work
template<int first, int last=first>
class BitfieldRO : public Bitfield<first, last>
{
private:
uint64_t
operator=(const uint64_t _data);
};
//Similar to the above, but only allows writing.
template<int first, int last=first>
class BitfieldWO : public Bitfield<first, last>
{
private:
operator uint64_t () const;
public:
using Bitfield<first, last>::operator=;
};
};
//This class contains all the "regular" bitfield classes. It is inherited
//by all BitUnions which give them access to those types.
template<class Type>
class SignedBitfieldTypes
{
protected:
//This class implements ordinary bitfields, that is a span of bits
//who's msb is "first", and who's lsb is "last".
template<int first, int last=first>
class SignedBitfield : public BitfieldBase<Type>
{
public:
operator int64_t () const
{
return sext<first - last + 1>(this->getBits(first, last));
}
int64_t
operator=(const int64_t _data)
{
this->setBits(first, last, _data);
return _data;
}
};
//A class which specializes the above so that it can only be read
//from. This is accomplished explicitly making sure the assignment
//operator is blocked. The conversion operator is carried through
//inheritance. This will unfortunately need to be copied into each
//bitfield type due to limitations with how templates work
template<int first, int last=first>
class SignedBitfieldRO : public SignedBitfield<first, last>
{
private:
int64_t
operator=(const int64_t _data);
};
//Similar to the above, but only allows writing.
template<int first, int last=first>
class SignedBitfieldWO : public SignedBitfield<first, last>
{
private:
operator int64_t () const;
public:
int64_t operator=(const int64_t _data)
{
*((SignedBitfield<first, last> *)this) = _data;
return _data;
}
};
};
template<class Type>
class BitfieldTypes : public RegularBitfieldTypes<Type>,
public SignedBitfieldTypes<Type>
{};
//When a BitUnion is set up, an underlying class is created which holds
//the actual union. This class then inherits from it, and provids the
//implementations for various operators. Setting things up this way
//prevents having to redefine these functions in every different BitUnion
//type. More operators could be implemented in the future, as the need
//arises.
template <class Type, class Base>
class BitUnionOperators : public Base
{
public:
BitUnionOperators(Type & _data)
{
Base::__data = _data;
}
BitUnionOperators() {}
operator Type () const
{
return Base::__data;
}
Type
operator=(const Type & _data)
{
Base::__data = _data;
return _data;
}
bool
operator<(const Base & base) const
{
return Base::__data < base.__data;
}
bool
operator==(const Base & base) const
{
return Base::__data == base.__data;
}
};
}
//This macro is a backend for other macros that specialize it slightly.
//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and
//sticks the class which has the actual union in it, which
//BitfieldOperators above inherits from. Putting these classes in a special
//namespace ensures that there will be no collisions with other names as long
//as the BitUnion names themselves are all distinct and nothing else uses
//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself
//creates a typedef of the "type" parameter called __DataType. This allows
//the type to propagate outside of the macro itself in a controlled way.
//Finally, the base storage is defined which BitfieldOperators will refer to
//in the operators it defines. This macro is intended to be followed by
//bitfield definitions which will end up inside it's union. As explained
//above, these is overlayed the __data member in its entirety by each of the
//bitfields which are defined in the union, creating shared storage with no
//overhead.
#define __BitUnion(type, name) \
namespace BitfieldUnderlyingClasses \
{ \
class name; \
} \
class BitfieldUnderlyingClasses::name : \
public BitfieldBackend::BitfieldTypes<type> \
{ \
public: \
typedef type __DataType; \
union { \
type __data;\
//This closes off the class and union started by the above macro. It is
//followed by a typedef which makes "name" refer to a BitfieldOperator
//class inheriting from the class and union just defined, which completes
//building up the type for the user.
#define EndBitUnion(name) \
}; \
}; \
typedef BitfieldBackend::BitUnionOperators< \
BitfieldUnderlyingClasses::name::__DataType, \
BitfieldUnderlyingClasses::name> name;
//This sets up a bitfield which has other bitfields nested inside of it. The
//__data member functions like the "underlying storage" of the top level
//BitUnion. Like everything else, it overlays with the top level storage, so
//making it a regular bitfield type makes the entire thing function as a
//regular bitfield when referred to by itself.
#define __SubBitUnion(fieldType, first, last, name) \
class : public BitfieldBackend::BitfieldTypes<__DataType> \
{ \
public: \
union { \
fieldType<first, last> __data;
//This closes off the union created above and gives it a name. Unlike the top
//level BitUnion, we're interested in creating an object instead of a type.
//The operators are defined in the macro itself instead of a class for
//technical reasons. If someone determines a way to move them to one, please
//do so.
#define EndSubBitUnion(name) \
}; \
inline operator const __DataType () \
{ return __data; } \
\
inline const __DataType operator = (const __DataType & _data) \
{ return __data = _data;} \
} name;
//Regular bitfields
//These define macros for read/write regular bitfield based subbitfields.
#define SubBitUnion(name, first, last) \
__SubBitUnion(Bitfield, first, last, name)
//Regular bitfields
//These define macros for read/write regular bitfield based subbitfields.
#define SignedSubBitUnion(name, first, last) \
__SubBitUnion(SignedBitfield, first, last, name)
//Use this to define an arbitrary type overlayed with bitfields.
#define BitUnion(type, name) __BitUnion(type, name)
//Use this to define conveniently sized values overlayed with bitfields.
#define BitUnion64(name) __BitUnion(uint64_t, name)
#define BitUnion32(name) __BitUnion(uint32_t, name)
#define BitUnion16(name) __BitUnion(uint16_t, name)
#define BitUnion8(name) __BitUnion(uint8_t, name)
#endif // __BASE_BITUNION_HH__

94
src/base/condcodes.hh Normal file
View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __BASE_CONDCODE_HH__
#define __BASE_CONDCODE_HH__
#include "base/bitfield.hh"
#include "base/trace.hh"
/**
* Calculate the carry flag from an addition. This should work even when
* a carry value is also added in.
*/
inline
bool
findCarry(int width, uint64_t dest, uint64_t src1, uint64_t src2) {
int shift = width - 1;
return ((~(dest >> shift) & 1) +
((src1 >> shift) & 1) +
((src2 >> shift) & 1)) & 0x2;
}
/**
* Calculate the overflow flag from an addition.
*/
inline
bool
findOverflow(int width, uint64_t dest, uint64_t src1, uint64_t src2) {
int shift = width - 1;
return ((src1 ^ ~src2) & (src1 ^ dest)) & (1 << shift);
}
/**
* Calculate the parity of a value. 1 is for odd parity and 0 is for even.
*/
inline
bool
findParity(int width, uint64_t dest) {
dest &= width;
dest ^= (dest >> 32);
dest ^= (dest >> 16);
dest ^= (dest >> 8);
dest ^= (dest >> 4);
dest ^= (dest >> 2);
dest ^= (dest >> 1);
return dest & 1;
}
/**
* Calculate the negative flag.
*/
inline
bool
findNegative(int width, uint64_t dest) {
return bits(dest, width - 1, width - 1);
}
/**
* Calculate the zero flag.
*/
inline
bool
findZero(int width, uint64_t dest) {
return !(dest & mask(width));
}
#endif // __BASE_CONDCODE_HH__

View file

@ -53,12 +53,12 @@ typedef Stats::Scalar<> FaultStat;
class FaultBase : public RefCounted
{
public:
virtual FaultName name() = 0;
virtual FaultName name() const = 0;
virtual void invoke(ThreadContext * tc);
// template<typename T>
// bool isA() {return dynamic_cast<T *>(this);}
virtual bool isMachineCheckFault() {return false;}
virtual bool isAlignmentFault() {return false;}
virtual bool isMachineCheckFault() const {return false;}
virtual bool isAlignmentFault() const {return false;}
};
FaultBase * const NoFault = 0;
@ -72,7 +72,7 @@ class UnimpFault : public FaultBase
: panicStr(_str)
{ }
FaultName name() {return "Unimplemented simulator feature";}
FaultName name() const {return "Unimplemented simulator feature";}
void invoke(ThreadContext * tc);
};
@ -82,7 +82,7 @@ class PageTableFault : public FaultBase
private:
Addr vaddr;
public:
FaultName name() {return "M5 page table fault";}
FaultName name() const {return "M5 page table fault";}
PageTableFault(Addr va) : vaddr(va) {}
void invoke(ThreadContext * tc);
};

374
util/style.py Normal file
View file

@ -0,0 +1,374 @@
#! /usr/bin/env python
# Copyright (c) 2007 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
import re
import os
import sys
lead = re.compile(r'^([ \t]+)')
trail = re.compile(r'([ \t]+)$')
any_control = re.compile(r'\b(if|while|for)[ \t]*[(]')
good_control = re.compile(r'\b(if|while|for) [(]')
lang_types = { 'c' : "C",
'h' : "C",
'cc' : "C++",
'hh' : "C++",
'cxx' : "C++",
'hxx' : "C++",
'cpp' : "C++",
'hpp' : "C++",
'C' : "C++",
'H' : "C++",
'i' : "swig",
'py' : "python",
's' : "asm",
'S' : "asm",
'isa' : "isa" }
whitespace_types = ('C', 'C++', 'swig', 'python', 'asm', 'isa')
format_types = ( 'C', 'C++' )
def file_type(filename):
extension = filename.split('.')
extension = len(extension) > 1 and extension[-1]
return lang_types.get(extension, None)
def checkwhite_line(line):
match = lead.search(line)
if match and match.group(1).find('\t') != -1:
return False
match = trail.search(line)
if match:
return False
return True
def checkwhite(filename):
if file_type(filename) not in whitespace_types:
return
try:
f = file(filename, 'r+')
except OSError, msg:
print 'could not open file %s: %s' % (filename, msg)
return
for num,line in enumerate(f):
if not checkwhite_line(line):
yield line,num + 1
def fixwhite_line(line):
if lead.search(line):
newline = ''
for i,c in enumerate(line):
if c == ' ':
newline += ' '
elif c == '\t':
newline += ' ' * (tabsize - len(newline) % tabsize)
else:
newline += line[i:]
break
line = newline
return line.rstrip() + '\n'
def fixwhite(filename, tabsize, fixonly=None):
if file_type(filename) not in whitespace_types:
return
try:
f = file(filename, 'r+')
except OSError, msg:
print 'could not open file %s: %s' % (filename, msg)
return
lines = list(f)
f.seek(0)
f.truncate()
for i,line in enumerate(lines):
if fixonly is None or i in fixonly:
line = fixwhite_line(line)
print >>f, line,
def linelen(line):
tabs = line.count('\t')
if not tabs:
return len(line)
count = 0
for c in line:
if c == '\t':
count += tabsize - count % tabsize
else:
count += 1
return count
class ValidationStats(object):
def __init__(self):
self.toolong = 0
self.toolong80 = 0
self.leadtabs = 0
self.trailwhite = 0
self.badcontrol = 0
self.cret = 0
def dump(self):
print '''\
%d violations of lines over 79 chars. %d of which are 80 chars exactly.
%d cases of whitespace at the end of a line.
%d cases of tabs to indent.
%d bad parens after if/while/for.
%d carriage returns found.
''' % (self.toolong, self.toolong80, self.trailwhite, self.leadtabs,
self.badcontrol, self.cret)
def __nonzero__(self):
return self.toolong or self.toolong80 or self.leadtabs or \
self.trailwhite or self.badcontrol or self.cret
def validate(filename, stats, verbose, exit_code):
if file_type(filename) not in format_types:
return
def msg(lineno, line, message):
print '%s:%d>' % (filename, lineno + 1), message
if verbose > 2:
print line
def bad():
if exit_code is not None:
sys.exit(exit_code)
cpp = filename.endswith('.cc') or filename.endswith('.hh')
py = filename.endswith('.py')
if py + cpp != 1:
raise AttributeError, \
"I don't know how to deal with the file %s" % filename
try:
f = file(filename, 'r')
except OSError:
if verbose > 0:
print 'could not open file %s' % filename
bad()
return
for i,line in enumerate(f):
line = line.rstrip('\n')
# no carriage returns
if line.find('\r') != -1:
self.cret += 1
if verbose > 1:
msg(i, line, 'carriage return found')
bad()
# lines max out at 79 chars
llen = linelen(line)
if llen > 79:
stats.toolong += 1
if llen == 80:
stats.toolong80 += 1
if verbose > 1:
msg(i, line, 'line too long (%d chars)' % llen)
bad()
# no tabs used to indent
match = lead.search(line)
if match and match.group(1).find('\t') != -1:
stats.leadtabs += 1
if verbose > 1:
msg(i, line, 'using tabs to indent')
bad()
# no trailing whitespace
if trail.search(line):
stats.trailwhite +=1
if verbose > 1:
msg(i, line, 'trailing whitespace')
bad()
# for c++, exactly one space betwen if/while/for and (
if cpp:
match = any_control.search(line)
if match and not good_control.search(line):
stats.badcontrol += 1
if verbose > 1:
msg(i, line, 'improper spacing after %s' % match.group(1))
bad()
def check_whitespace(ui, repo, hooktype, node, parent1, parent2):
from mercurial import bdiff, mdiff, util
if hooktype != 'pretxncommit':
raise AttributeError, \
"This hook is only meant for pretxncommit, not %s" % hooktype
tabsize = 8
verbose = ui.configbool('style', 'verbose', False)
def prompt(name, fixonly=None):
result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", "^[aif]$", "a")
if result == 'a':
return True
elif result == 'i':
pass
elif result == 'f':
fixwhite(name, tabsize, fixonly)
else:
raise RepoError, "Invalid response: '%s'" % result
return False
modified, added, removed, deleted, unknown, ignore, clean = repo.status()
for fname in added:
ok = True
for line,num in checkwhite(fname):
ui.write("invalid whitespace in %s:%d\n" % (fname, num))
if verbose:
ui.write(">>%s<<\n" % line[-1])
ok = False
if not ok:
if prompt(fname):
return True
wctx = repo.workingctx()
for fname in modified:
fctx = wctx.filectx(fname)
pctx = fctx.parents()
assert len(pctx) == 1
pdata = pctx[0].data()
fdata = fctx.data()
fixonly = set()
lines = enumerate(mdiff.splitnewlines(fdata))
for pbeg, pend, fbeg, fend in bdiff.blocks(pdata, fdata):
for i, line in lines:
if i < fbeg:
if checkwhite_line(line):
continue
ui.write("invalid whitespace: %s:%d\n" % (fname, i+1))
if verbose:
ui.write(">>%s<<\n" % line[:-1])
fixonly.add(i)
elif i + 1 >= fend:
break
if fixonly:
if prompt(fname, fixonly):
return True
def check_format(ui, repo, hooktype, node, parent1, parent2):
if hooktype != 'pretxncommit':
raise AttributeError, \
"This hook is only meant for pretxncommit, not %s" % hooktype
modified, added, removed, deleted, unknown, ignore, clean = repo.status()
verbose = 0
stats = ValidationStats()
for f in modified + added:
validate(f, stats, verbose, None)
if stats:
stats.dump()
result = ui.prompt("invalid formatting\n(i)gnore or (a)bort?",
"^[ia]$", "a")
if result.startswith('i'):
pass
elif result.startswith('a'):
return True
else:
raise RepoError, "Invalid response: '%s'" % result
return False
if __name__ == '__main__':
import getopt
progname = sys.argv[0]
if len(sys.argv) < 2:
sys.exit('usage: %s <command> [<command args>]' % progname)
fixwhite_usage = '%s fixwhite [-t <tabsize> ] <path> [...] \n' % progname
chkformat_usage = '%s chkformat <path> [...] \n' % progname
chkwhite_usage = '%s chkwhite <path> [...] \n' % progname
command = sys.argv[1]
if command == 'fixwhite':
flags = 't:'
usage = fixwhite_usage
elif command == 'chkwhite':
flags = 'nv'
usage = chkwhite_usage
elif command == 'chkformat':
flags = 'nv'
usage = chkformat_usage
else:
sys.exit(fixwhite_usage + chkwhite_usage + chkformat_usage)
opts, args = getopt.getopt(sys.argv[2:], flags)
code = 1
verbose = 1
tabsize = 8
for opt,arg in opts:
if opt == '-n':
code = None
if opt == '-t':
tabsize = int(arg)
if opt == '-v':
verbose += 1
if command == 'fixwhite':
for filename in args:
fixwhite(filename, tabsize)
elif command == 'chkwhite':
for filename in args:
line = checkwhite(filename)
if line:
print 'invalid whitespace at %s:%d' % (filename, line)
elif command == 'chkformat':
stats = ValidationStats()
for filename in files:
validate(filename, stats=stats, verbose=verbose, exit_code=code)
if verbose > 0:
stats.dump()
else:
sys.exit("command '%s' not found" % command)