summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SConscript41
-rw-r--r--src/arch/alpha/SConscript2
-rw-r--r--src/arch/alpha/isa/branch.isa7
-rw-r--r--src/arch/alpha/isa/fp.isa4
-rw-r--r--src/arch/alpha/isa/int.isa6
-rw-r--r--src/arch/alpha/isa/main.isa5
-rw-r--r--src/arch/alpha/isa/mem.isa94
-rw-r--r--src/arch/alpha/isa/pal.isa7
-rw-r--r--src/arch/alpha/isa_traits.hh2
-rw-r--r--src/arch/alpha/regfile.hh11
-rw-r--r--src/arch/alpha/remote_gdb.cc12
-rw-r--r--src/arch/alpha/syscallreturn.hh45
-rw-r--r--src/arch/alpha/system.cc6
-rw-r--r--src/arch/alpha/system.hh2
-rw-r--r--src/arch/alpha/utility.hh4
-rwxr-xr-xsrc/arch/isa_parser.py216
-rw-r--r--src/arch/mips/isa/decoder.isa41
-rw-r--r--src/arch/mips/isa/formats/basic.isa2
-rw-r--r--src/arch/mips/isa/formats/branch.isa4
-rw-r--r--src/arch/mips/isa/formats/control.isa6
-rw-r--r--src/arch/mips/isa/formats/fp.isa12
-rw-r--r--src/arch/mips/isa/formats/int.isa15
-rw-r--r--src/arch/mips/isa/formats/mem.isa20
-rw-r--r--src/arch/mips/isa/formats/mt.isa2
-rw-r--r--src/arch/mips/isa/formats/noop.isa2
-rw-r--r--src/arch/mips/isa/formats/tlbop.isa4
-rw-r--r--src/arch/mips/isa/formats/trap.isa2
-rw-r--r--src/arch/mips/isa/formats/util.isa74
-rw-r--r--src/arch/mips/regfile/regfile.hh5
-rw-r--r--src/arch/mips/remote_gdb.hh64
-rw-r--r--src/arch/mips/syscallreturn.hh45
-rw-r--r--src/arch/sparc/SConscript2
-rw-r--r--src/arch/sparc/faults.cc32
-rw-r--r--src/arch/sparc/floatregfile.cc16
-rw-r--r--src/arch/sparc/intregfile.cc26
-rw-r--r--src/arch/sparc/intregfile.hh12
-rw-r--r--src/arch/sparc/isa/base.isa253
-rw-r--r--src/arch/sparc/isa/bitfields.isa4
-rw-r--r--src/arch/sparc/isa/decoder.isa425
-rw-r--r--src/arch/sparc/isa/formats/basic.isa7
-rw-r--r--src/arch/sparc/isa/formats/branch.isa18
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa15
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa24
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa30
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa57
-rw-r--r--src/arch/sparc/isa/formats/nop.isa4
-rw-r--r--src/arch/sparc/isa/formats/priv.isa8
-rw-r--r--src/arch/sparc/isa/formats/trap.isa49
-rw-r--r--src/arch/sparc/isa/includes.isa10
-rw-r--r--src/arch/sparc/isa/operands.isa53
-rw-r--r--src/arch/sparc/isa_traits.hh4
-rw-r--r--src/arch/sparc/miscregfile.cc255
-rw-r--r--src/arch/sparc/miscregfile.hh28
-rw-r--r--src/arch/sparc/pagetable.cc9
-rw-r--r--src/arch/sparc/process.cc18
-rw-r--r--src/arch/sparc/regfile.cc84
-rw-r--r--src/arch/sparc/regfile.hh2
-rw-r--r--src/arch/sparc/remote_gdb.cc5
-rw-r--r--src/arch/sparc/sparc_traits.hh3
-rw-r--r--src/arch/sparc/syscallreturn.hh50
-rw-r--r--src/arch/sparc/system.cc6
-rw-r--r--src/arch/sparc/system.hh2
-rw-r--r--src/arch/sparc/tlb.cc56
-rw-r--r--src/arch/sparc/utility.hh2
-rw-r--r--src/base/compiler.hh53
-rw-r--r--src/base/compression/lzss_compression.cc6
-rw-r--r--src/base/compression/null_compression.hh2
-rw-r--r--src/base/cprintf.hh24
-rw-r--r--src/base/cprintf_formats.hh22
-rw-r--r--src/base/hashmap.hh2
-rw-r--r--src/base/hostinfo.cc1
-rw-r--r--src/base/loader/object_file.cc4
-rw-r--r--src/base/misc.hh45
-rw-r--r--src/base/pollevent.cc2
-rw-r--r--src/base/random.cc13
-rw-r--r--src/base/remote_gdb.cc54
-rw-r--r--src/base/remote_gdb.hh5
-rw-r--r--src/base/statistics.hh7
-rw-r--r--src/base/stats/text.cc4
-rw-r--r--src/base/time.cc4
-rw-r--r--src/base/time.hh2
-rw-r--r--src/base/timebuf.hh5
-rw-r--r--src/base/trace.hh28
-rw-r--r--src/cpu/SConscript8
-rw-r--r--src/cpu/activity.cc6
-rw-r--r--src/cpu/base.cc12
-rw-r--r--src/cpu/base.hh6
-rw-r--r--src/cpu/base_dyn_inst.hh165
-rw-r--r--src/cpu/base_dyn_inst_impl.hh11
-rw-r--r--src/cpu/cpuevent.hh1
-rw-r--r--src/cpu/exetrace.cc113
-rw-r--r--src/cpu/exetrace.hh3
-rw-r--r--src/cpu/m5legion_interface.h6
-rw-r--r--src/cpu/o3/alpha/cpu.hh41
-rw-r--r--src/cpu/o3/alpha/cpu_impl.hh29
-rw-r--r--src/cpu/o3/alpha/dyn_inst.hh121
-rw-r--r--src/cpu/o3/alpha/dyn_inst_impl.hh9
-rw-r--r--src/cpu/o3/alpha/thread_context.hh9
-rw-r--r--src/cpu/o3/bpred_unit_impl.hh11
-rw-r--r--src/cpu/o3/comm.hh5
-rw-r--r--src/cpu/o3/commit_impl.hh34
-rw-r--r--src/cpu/o3/cpu.cc8
-rw-r--r--src/cpu/o3/cpu.hh24
-rw-r--r--src/cpu/o3/decode_impl.hh25
-rw-r--r--src/cpu/o3/fetch.hh22
-rw-r--r--src/cpu/o3/fetch_impl.hh200
-rw-r--r--src/cpu/o3/iew_impl.hh50
-rw-r--r--src/cpu/o3/lsq_unit.hh6
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh19
-rw-r--r--src/cpu/o3/mips/cpu_impl.hh12
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst.hh88
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst_impl.hh12
-rw-r--r--src/cpu/o3/rename.hh8
-rw-r--r--src/cpu/o3/rename_impl.hh95
-rw-r--r--src/cpu/o3/sparc/cpu.hh42
-rw-r--r--src/cpu/o3/sparc/cpu_builder.cc4
-rw-r--r--src/cpu/o3/sparc/cpu_impl.hh41
-rw-r--r--src/cpu/o3/sparc/dyn_inst.hh156
-rw-r--r--src/cpu/o3/sparc/dyn_inst_impl.hh14
-rw-r--r--src/cpu/o3/sparc/thread_context.hh8
-rwxr-xr-xsrc/cpu/o3/thread_context.hh8
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh3
-rw-r--r--src/cpu/ozone/cpu.hh12
-rw-r--r--src/cpu/simple/base.hh34
-rw-r--r--src/cpu/simple_thread.hh14
-rw-r--r--src/cpu/static_inst.hh2
-rw-r--r--src/cpu/thread_context.hh2
-rw-r--r--src/dev/alpha/tsunami_io.cc73
-rw-r--r--src/dev/alpha/tsunami_io.hh3
-rw-r--r--src/dev/baddev.cc2
-rw-r--r--src/dev/ide_atareg.h2
-rw-r--r--src/dev/io_device.hh2
-rw-r--r--src/dev/pciconfigall.cc2
-rw-r--r--src/dev/pcidev.hh6
-rw-r--r--src/dev/platform.cc1
-rw-r--r--src/dev/sparc/dtod.cc35
-rw-r--r--src/dev/sparc/dtod.hh19
-rw-r--r--src/dev/sparc/mm_disk.cc5
-rw-r--r--src/dev/sparc/t1000.cc15
-rw-r--r--src/dev/sparc/t1000.hh13
-rw-r--r--src/mem/cache/cache_impl.hh31
-rw-r--r--src/mem/cache/miss/blocking_buffer.cc9
-rw-r--r--src/mem/cache/miss/blocking_buffer.hh2
-rw-r--r--src/mem/cache/tags/iic.cc2
-rw-r--r--src/mem/cache/tags/lru.hh3
-rw-r--r--src/mem/cache/tags/split.hh4
-rw-r--r--src/mem/cache/tags/split_lifo.hh3
-rw-r--r--src/mem/cache/tags/split_lru.hh3
-rw-r--r--src/mem/dram.cc4
-rw-r--r--src/mem/packet.cc8
-rw-r--r--src/mem/packet.hh4
-rw-r--r--src/mem/physical.cc6
-rw-r--r--src/mem/port.cc3
-rw-r--r--src/mem/port.hh8
-rw-r--r--src/python/m5/objects/T1000.py52
-rw-r--r--src/sim/byteswap.hh56
-rw-r--r--src/sim/host.hh4
-rw-r--r--src/sim/param.cc24
-rw-r--r--src/sim/param.hh1
-rw-r--r--src/sim/process.cc8
-rw-r--r--src/sim/process.hh10
-rw-r--r--src/sim/serialize.cc12
-rw-r--r--src/sim/serialize.hh7
-rw-r--r--src/sim/syscallreturn.hh70
-rw-r--r--src/sim/system.cc17
-rw-r--r--src/sim/system.hh6
-rw-r--r--src/unittest/Makefile2
167 files changed, 2807 insertions, 1843 deletions
diff --git a/src/SConscript b/src/SConscript
index 229418703..74bed9a7e 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -62,6 +62,7 @@ base_sources = Split('''
base/pollevent.cc
base/range.cc
base/random.cc
+ base/remote_gdb.cc
base/sat_counter.cc
base/socket.cc
base/statistics.cc
@@ -172,7 +173,6 @@ mysql_sources = Split('''
full_system_sources = Split('''
base/crc.cc
base/inet.cc
- base/remote_gdb.cc
cpu/intr_control.cc
cpu/profile.cc
@@ -304,37 +304,56 @@ def makeEnv(label, objsfx, strip = False, **kwargs):
newEnv.Program(bin, make_objs(sources, newEnv))
if strip:
stripped_bin = bin + '.stripped'
- newEnv.Command(stripped_bin, bin, 'strip $SOURCE -o $TARGET')
+ if sys.platform == 'sunos5':
+ newEnv.Command(stripped_bin, bin, 'cp $SOURCE $TARGET; strip $TARGET')
+ else:
+ newEnv.Command(stripped_bin, bin, 'strip $SOURCE -o $TARGET')
bin = stripped_bin
targets = newEnv.Concat(exe, [bin, 'python/m5py.zip'])
newEnv.M5Binary = targets[0]
envList.append(newEnv)
# Debug binary
-# Solaris seems to have some issue with DWARF2 debugging information, it's ok
-# with stabs though
-if sys.platform == 'sunos5':
- debug_flag = '-gstabs+'
+ccflags = {}
+if env['GCC']:
+ if sys.platform == 'sunos5':
+ ccflags['debug'] = '-gstabs+'
+ else:
+ ccflags['debug'] = '-ggdb3'
+ ccflags['opt'] = '-g -O3'
+ ccflags['fast'] = '-O3'
+ ccflags['prof'] = '-O3 -g -pg'
+elif env['SUNCC']:
+ ccflags['debug'] = '-g0'
+ ccflags['opt'] = '-g -O'
+ ccflags['fast'] = '-fast'
+ ccflags['prof'] = '-fast -g -pg'
+elif env['ICC']:
+ ccflags['debug'] = '-g -O0'
+ ccflags['opt'] = '-g -O'
+ ccflags['fast'] = '-fast'
+ ccflags['prof'] = '-fast -g -pg'
else:
- debug_flag = '-ggdb3'
+ print 'Unknown compiler, please fix compiler options'
+ Exit(1)
makeEnv('debug', '.do',
- CCFLAGS = Split('%s -O0' % debug_flag),
+ CCFLAGS = Split(ccflags['debug']),
CPPDEFINES = ['DEBUG', 'TRACING_ON=1'])
# Optimized binary
makeEnv('opt', '.o',
- CCFLAGS = Split('-g -O3'),
+ CCFLAGS = Split(ccflags['opt']),
CPPDEFINES = ['TRACING_ON=1'])
# "Fast" binary
makeEnv('fast', '.fo', strip = True,
- CCFLAGS = Split('-O3'),
+ CCFLAGS = Split(ccflags['fast']),
CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'])
# Profiled binary
makeEnv('prof', '.po',
- CCFLAGS = Split('-O3 -g -pg'),
+ CCFLAGS = Split(ccflags['prof']),
CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'],
LINKFLAGS = '-pg')
diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript
index 3cc5ec270..addd49884 100644
--- a/src/arch/alpha/SConscript
+++ b/src/arch/alpha/SConscript
@@ -52,6 +52,7 @@ base_sources = Split('''
intregfile.cc
miscregfile.cc
regfile.cc
+ remote_gdb.cc
''')
# Full-system sources
@@ -66,7 +67,6 @@ full_system_sources = Split('''
osfpal.cc
pagetable.cc
stacktrace.cc
- remote_gdb.cc
system.cc
tlb.cc
tru64/system.cc
diff --git a/src/arch/alpha/isa/branch.isa b/src/arch/alpha/isa/branch.isa
index 7438e7e18..974193efd 100644
--- a/src/arch/alpha/isa/branch.isa
+++ b/src/arch/alpha/isa/branch.isa
@@ -218,7 +218,7 @@ def template JumpOrBranchDecode {{
def format CondBranch(code) {{
code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
- iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
+ iop = InstObjParams(name, Name, 'Branch', code,
('IsDirectControl', 'IsCondControl'))
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -230,8 +230,7 @@ let {{
def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
# Declare basic control transfer w/o link (i.e. link reg is R31)
nolink_code = 'NPC = %s;\n' % npc_expr
- nolink_iop = InstObjParams(name, Name, base_class,
- CodeBlock(nolink_code), flags)
+ nolink_iop = InstObjParams(name, Name, base_class, nolink_code, flags)
header_output = BasicDeclare.subst(nolink_iop)
decoder_output = BasicConstructor.subst(nolink_iop)
exec_output = BasicExecute.subst(nolink_iop)
@@ -239,7 +238,7 @@ def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
# Generate declaration of '*AndLink' version, append to decls
link_code = 'Ra = NPC & ~3;\n' + nolink_code
link_iop = InstObjParams(name, Name + 'AndLink', base_class,
- CodeBlock(link_code), flags)
+ link_code, flags)
header_output += BasicDeclare.subst(link_iop)
decoder_output += BasicConstructor.subst(link_iop)
exec_output += BasicExecute.subst(link_iop)
diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa
index 3b5575f62..c845ea442 100644
--- a/src/arch/alpha/isa/fp.isa
+++ b/src/arch/alpha/isa/fp.isa
@@ -293,7 +293,7 @@ def template FloatingPointDecode {{
// currently unimplemented (will fail).
// - Generates NOP if FC == 31.
def format FloatingPointOperate(code, *opt_args) {{
- iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
+ iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
decode_block = FloatingPointDecode.subst(iop)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -303,7 +303,7 @@ def format FloatingPointOperate(code, *opt_args) {{
// Special format for cvttq where rounding mode is pre-decoded
def format FPFixedRounding(code, class_suffix, *opt_args) {{
Name += class_suffix
- iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
+ iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
decode_block = FloatingPointDecode.subst(iop)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/src/arch/alpha/isa/int.isa b/src/arch/alpha/isa/int.isa
index 45e096ebd..bd9c3ccd9 100644
--- a/src/arch/alpha/isa/int.isa
+++ b/src/arch/alpha/isa/int.isa
@@ -113,16 +113,14 @@ def format IntegerOperate(code, *opt_flags) {{
imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code)
# generate declaration for register version
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BasicExecute.subst(iop)
if uses_imm:
# append declaration for imm version
- imm_cblk = CodeBlock(imm_code)
- imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk,
+ imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_code,
opt_flags)
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa
index 6e65cf9d3..d72dfe34a 100644
--- a/src/arch/alpha/isa/main.isa
+++ b/src/arch/alpha/isa/main.isa
@@ -338,7 +338,7 @@ def template BasicDecodeWithMnemonic {{
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
- iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'AlphaStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -424,8 +424,7 @@ def template OperateNopCheckDecode {{
// Like BasicOperate format, but generates NOP if RC/FC == 31
def format BasicOperateWithNopCheck(code, *opt_args) {{
- iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code),
- opt_args)
+ iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_args)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = OperateNopCheckDecode.subst(iop)
diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa
index 02291ed6b..c0bdd2c05 100644
--- a/src/arch/alpha/isa/mem.isa
+++ b/src/arch/alpha/isa/mem.isa
@@ -126,7 +126,7 @@ output decoder {{
}};
def format LoadAddress(code) {{
- iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
+ iop = InstObjParams(name, Name, 'MemoryDisp32', code)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -191,22 +191,28 @@ def template CompleteAccDeclare {{
}};
-def template LoadStoreConstructor {{
+def template EACompConstructor {{
/** TODO: change op_class to AddrGenOp or something (requires
* creating new member of OpClass enum in op_class.hh, updating
* config files, etc.). */
inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
{
- %(ea_constructor)s;
+ %(constructor)s;
}
+}};
+
+def template MemAccConstructor {{
inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
{
- %(memacc_constructor)s;
+ %(constructor)s;
}
+}};
+
+def template LoadStoreConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
new EAComp(machInst), new MemAcc(machInst))
@@ -227,7 +233,7 @@ def template EACompExecute {{
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
- %(code)s;
+ %(ea_code)s;
if (fault == NoFault) {
%(op_wb)s;
@@ -253,7 +259,7 @@ def template LoadMemAccExecute {{
if (fault == NoFault) {
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
- %(code)s;
+ %(memacc_code)s;
}
if (fault == NoFault) {
@@ -352,7 +358,7 @@ def template StoreMemAccExecute {{
EA = xc->getEA();
if (fault == NoFault) {
- %(code)s;
+ %(memacc_code)s;
}
if (fault == NoFault) {
@@ -497,7 +503,7 @@ def template MiscMemAccExecute {{
EA = xc->getEA();
if (fault == NoFault) {
- %(code)s;
+ %(memacc_code)s;
}
return NoFault;
@@ -582,63 +588,24 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
# add hook to get effective addresses into execution trace output.
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
- # generate code block objects
- ea_cblk = CodeBlock(ea_code)
- memacc_cblk = CodeBlock(memacc_code)
- postacc_cblk = CodeBlock(postacc_code)
-
# Some CPU models execute the memory operation as an atomic unit,
# while others want to separate them into an effective address
# computation and a memory access operation. As a result, we need
# to generate three StaticInst objects. Note that the latter two
# are nested inside the larger "atomic" one.
- # generate InstObjParams for EAComp object
- ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
-
- # generate InstObjParams for MemAcc object
- memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
- # in the split execution model, the MemAcc portion is responsible
- # for the post-access code.
- memacc_iop.postacc_code = postacc_cblk.code
-
- # generate InstObjParams for InitiateAcc, CompleteAcc object
- # The code used depends on the template being used
- if (exec_template_base == 'Load'):
- initiateacc_cblk = CodeBlock(ea_code + memacc_code)
- completeacc_cblk = CodeBlock(memacc_code + postacc_code)
- elif (exec_template_base.startswith('Store')):
- initiateacc_cblk = CodeBlock(ea_code + memacc_code)
- completeacc_cblk = CodeBlock(postacc_code)
- else:
- initiateacc_cblk = ''
- completeacc_cblk = ''
-
- initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
- inst_flags)
-
- completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
- inst_flags)
-
- if (exec_template_base == 'Load'):
- initiateacc_iop.ea_code = ea_cblk.code
- initiateacc_iop.memacc_code = memacc_cblk.code
- completeacc_iop.memacc_code = memacc_cblk.code
- completeacc_iop.postacc_code = postacc_cblk.code
- elif (exec_template_base.startswith('Store')):
- initiateacc_iop.ea_code = ea_cblk.code
- initiateacc_iop.memacc_code = memacc_cblk.code
- completeacc_iop.postacc_code = postacc_cblk.code
-
- # generate InstObjParams for unified execution
- cblk = CodeBlock(ea_code + memacc_code + postacc_code)
- iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
-
- iop.ea_constructor = ea_cblk.constructor
- iop.ea_code = ea_cblk.code
- iop.memacc_constructor = memacc_cblk.constructor
- iop.memacc_code = memacc_cblk.code
- iop.postacc_code = postacc_cblk.code
+ # Generate InstObjParams for each of the three objects. Note that
+ # they differ only in the set of code objects contained (which in
+ # turn affects the object's overall operand list).
+ iop = InstObjParams(name, Name, base_class,
+ { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
+ inst_flags)
+ ea_iop = InstObjParams(name, Name, base_class,
+ { 'ea_code':ea_code },
+ inst_flags)
+ memacc_iop = InstObjParams(name, Name, base_class,
+ { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
+ inst_flags)
if mem_flags:
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
@@ -659,13 +626,16 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
# (header_output, decoder_output, decode_block, exec_output)
- return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
+ return (LoadStoreDeclare.subst(iop),
+ EACompConstructor.subst(ea_iop)
+ + MemAccConstructor.subst(memacc_iop)
+ + LoadStoreConstructor.subst(iop),
decode_template.subst(iop),
EACompExecute.subst(ea_iop)
+ memAccExecTemplate.subst(memacc_iop)
+ fullExecTemplate.subst(iop)
- + initiateAccTemplate.subst(initiateacc_iop)
- + completeAccTemplate.subst(completeacc_iop))
+ + initiateAccTemplate.subst(iop)
+ + completeAccTemplate.subst(iop))
}};
def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
diff --git a/src/arch/alpha/isa/pal.isa b/src/arch/alpha/isa/pal.isa
index f4c10da1d..294b92e2f 100644
--- a/src/arch/alpha/isa/pal.isa
+++ b/src/arch/alpha/isa/pal.isa
@@ -68,7 +68,7 @@ output decoder {{
}};
def format EmulatedCallPal(code, *flags) {{
- iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'EmulatedCallPal', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -131,7 +131,7 @@ output decoder {{
}};
def format CallPal(code, *flags) {{
- iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'CallPalBase', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -269,8 +269,7 @@ output decoder {{
def format HwMoveIPR(code, *flags) {{
all_flags = ['IprAccessOp']
all_flags += flags
- iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code),
- all_flags)
+ iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh
index 35d9ce843..a267ac034 100644
--- a/src/arch/alpha/isa_traits.hh
+++ b/src/arch/alpha/isa_traits.hh
@@ -132,7 +132,7 @@ namespace AlphaISA
const int NumPALShadowRegs = 8;
const int NumFloatArchRegs = 32;
// @todo: Figure out what this number really should be.
- const int NumMiscArchRegs = 32;
+ const int NumMiscArchRegs = 77;
const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
const int NumFloatRegs = NumFloatArchRegs;
diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh
index ff5830822..54372da36 100644
--- a/src/arch/alpha/regfile.hh
+++ b/src/arch/alpha/regfile.hh
@@ -78,13 +78,11 @@ namespace AlphaISA
Addr readNextNPC()
{
- return nnpc;
+ return npc + sizeof(MachInst);
}
void setNextNPC(Addr val)
- {
- nnpc = val;
- }
+ { }
protected:
IntRegFile intRegFile; // (signed) integer register file
@@ -189,6 +187,11 @@ namespace AlphaISA
}
};
+ static inline int flattenIntIndex(ThreadContext * tc, int reg)
+ {
+ return reg;
+ }
+
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc
index f23fc3205..4637bd7a6 100644
--- a/src/arch/alpha/remote_gdb.cc
+++ b/src/arch/alpha/remote_gdb.cc
@@ -121,14 +121,18 @@
#include <string>
#include <unistd.h>
+#include "config/full_system.hh"
+#if FULL_SYSTEM
+#include "arch/alpha/vtophys.hh"
+#endif
+
#include "arch/alpha/kgdb.h"
+#include "arch/alpha/utility.hh"
#include "arch/alpha/remote_gdb.hh"
-#include "arch/vtophys.hh"
#include "base/intmath.hh"
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "base/trace.hh"
-#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
#include "mem/physical.hh"
@@ -152,6 +156,9 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
bool
RemoteGDB::acc(Addr va, size_t len)
{
+#if !FULL_SYSTEM
+ panic("acc function needs to be rewritten for SE mode\n");
+#else
Addr last_va;
va = TheISA::TruncPage(va);
@@ -191,6 +198,7 @@ RemoteGDB::acc(Addr va, size_t len)
DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
return true;
+#endif
}
///////////////////////////////////////////////////////////
diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/syscallreturn.hh
index 803c3b7da..47b4ac8c7 100644
--- a/src/arch/alpha/syscallreturn.hh
+++ b/src/arch/alpha/syscallreturn.hh
@@ -32,54 +32,25 @@
#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__
#define __ARCH_ALPHA_SYSCALLRETURN_HH__
-class SyscallReturn {
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s) {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
-
- private:
- uint64_t retval;
- bool success;
-};
+#include "cpu/thread_context.hh"
+#include "sim/syscallreturn.hh"
namespace AlphaISA
{
- static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+ static inline void setSyscallReturn(SyscallReturn return_value,
+ ThreadContext * tc)
{
// check for error condition. Alpha syscall convention is to
// indicate success/failure in reg a3 (r19) and put the
// return value itself in the standard return value reg (v0).
if (return_value.successful()) {
// no error
- regs->setIntReg(SyscallSuccessReg, 0);
- regs->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(SyscallSuccessReg, 0);
+ tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, return details
- regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
- regs->setIntReg(ReturnValueReg, -return_value.value());
+ tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
+ tc->setIntReg(ReturnValueReg, -return_value.value());
}
}
}
diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc
index cd923948c..ed0938aeb 100644
--- a/src/arch/alpha/system.cc
+++ b/src/arch/alpha/system.cc
@@ -195,12 +195,6 @@ AlphaSystem::setAlphaAccess(Addr access)
panic("could not find m5AlphaAccess\n");
}
-bool
-AlphaSystem::breakpoint()
-{
- return remoteGDB[0]->trap(SIGTRAP);
-}
-
void
AlphaSystem::serialize(std::ostream &os)
{
diff --git a/src/arch/alpha/system.hh b/src/arch/alpha/system.hh
index 0c073a68c..f92b71c9a 100644
--- a/src/arch/alpha/system.hh
+++ b/src/arch/alpha/system.hh
@@ -56,8 +56,6 @@ class AlphaSystem : public System
~AlphaSystem();
- virtual bool breakpoint();
-
/**
* Serialization stuff
*/
diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh
index 100736555..9a06cc2a4 100644
--- a/src/arch/alpha/utility.hh
+++ b/src/arch/alpha/utility.hh
@@ -121,9 +121,9 @@ namespace AlphaISA
template <class TC>
void zeroRegisters(TC *tc);
-#if FULL_SYSTEM
// Alpha IPR register accessors
- inline bool PcPAL(Addr addr) { return addr & 0x1; }
+ inline bool PcPAL(Addr addr) { return addr & 0x3; }
+#if FULL_SYSTEM
////////////////////////////////////////////////////////////////////////
//
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index 59eb18c9c..07ae72cb8 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -808,8 +808,7 @@ class GenCode:
# a defineInst() method that generates the code for an instruction
# definition.
-exportContextSymbols = ('InstObjParams', 'CodeBlock',
- 'makeList', 're', 'string')
+exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
exportContext = {}
@@ -1003,27 +1002,80 @@ def substBitOps(code):
# Template objects are format strings that allow substitution from
# the attribute spaces of other objects (e.g. InstObjParams instances).
+labelRE = re.compile(r'[^%]%\(([^\)]+)\)[sd]')
+
class Template:
def __init__(self, t):
self.template = t
def subst(self, d):
+ myDict = None
+
+ # Protect non-Python-dict substitutions (e.g. if there's a printf
+ # in the templated C++ code)
+ template = protect_non_subst_percents(self.template)
+ # CPU-model-specific substitutions are handled later (in GenCode).
+ template = protect_cpu_symbols(template)
+
+ # Build a dict ('myDict') to use for the template substitution.
# Start with the template namespace. Make a copy since we're
# going to modify it.
myDict = templateMap.copy()
- # if the argument is a dictionary, we just use it.
- if isinstance(d, dict):
+
+ if isinstance(d, InstObjParams):
+ # If we're dealing with an InstObjParams object, we need
+ # to be a little more sophisticated. The instruction-wide
+ # parameters are already formed, but the parameters which
+ # are only function wide still need to be generated.
+ compositeCode = ''
+
+ myDict.update(d.__dict__)
+ # The "operands" and "snippets" attributes of the InstObjParams
+ # objects are for internal use and not substitution.
+ del myDict['operands']
+ del myDict['snippets']
+
+ snippetLabels = [l for l in labelRE.findall(template)
+ if d.snippets.has_key(l)]
+
+ snippets = dict([(s, mungeSnippet(d.snippets[s]))
+ for s in snippetLabels])
+
+ myDict.update(snippets)
+
+ compositeCode = ' '.join(map(str, snippets.values()))
+
+ # Add in template itself in case it references any
+ # operands explicitly (like Mem)
+ compositeCode += ' ' + template
+
+ operands = SubOperandList(compositeCode, d.operands)
+
+ myDict['op_decl'] = operands.concatAttrStrings('op_decl')
+
+ is_src = lambda op: op.is_src
+ is_dest = lambda op: op.is_dest
+
+ myDict['op_src_decl'] = \
+ operands.concatSomeAttrStrings(is_src, 'op_src_decl')
+ myDict['op_dest_decl'] = \
+ operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
+
+ myDict['op_rd'] = operands.concatAttrStrings('op_rd')
+ myDict['op_wb'] = operands.concatAttrStrings('op_wb')
+
+ if d.operands.memOperand:
+ myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
+ myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
+
+ elif isinstance(d, dict):
+ # if the argument is a dictionary, we just use it.
myDict.update(d)
- # if the argument is an object, we use its attribute map.
elif hasattr(d, '__dict__'):
+ # if the argument is an object, we use its attribute map.
myDict.update(d.__dict__)
else:
raise TypeError, "Template.subst() arg must be or have dictionary"
- # Protect non-Python-dict substitutions (e.g. if there's a printf
- # in the templated C++ code)
- template = protect_non_subst_percents(self.template)
- # CPU-model-specific substitutions are handled later (in GenCode).
- template = protect_cpu_symbols(template)
return template % myDict
# Convert to string. This handles the case when a template with a
@@ -1296,10 +1348,10 @@ class ControlRegOperand(Operand):
def makeConstructor(self):
c = ''
if self.is_src:
- c += '\n\t_srcRegIdx[%d] = %s;' % \
+ c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
(self.src_reg_idx, self.reg_spec)
if self.is_dest:
- c += '\n\t_destRegIdx[%d] = %s;' % \
+ c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
(self.dest_reg_idx, self.reg_spec)
return c
@@ -1307,7 +1359,7 @@ class ControlRegOperand(Operand):
bit_select = 0
if (self.ctype == 'float' or self.ctype == 'double'):
error(0, 'Attempt to read control register as FP')
- base = 'xc->readMiscRegWithEffect(%s)' % self.reg_spec
+ base = 'xc->readMiscRegOperandWithEffect(this, %s)' % self.src_reg_idx
if self.size == self.dflt_size:
return '%s = %s;\n' % (self.base_name, base)
else:
@@ -1317,7 +1369,8 @@ class ControlRegOperand(Operand):
def makeWrite(self):
if (self.ctype == 'float' or self.ctype == 'double'):
error(0, 'Attempt to write control register as FP')
- wb = 'xc->setMiscRegWithEffect(%s, %s);\n' % (self.reg_spec, self.base_name)
+ wb = 'xc->setMiscRegOperandWithEffect(this, %s, %s);\n' % \
+ (self.dest_reg_idx, self.base_name)
wb += 'if (traceData) { traceData->setData(%s); }' % \
self.base_name
return wb
@@ -1550,6 +1603,48 @@ class OperandList:
def sort(self):
self.items.sort(lambda a, b: a.sort_pri - b.sort_pri)
+class SubOperandList(OperandList):
+
+ # Find all the operands in the given code block. Returns an operand
+ # descriptor list (instance of class OperandList).
+ def __init__(self, code, master_list):
+ self.items = []
+ self.bases = {}
+ # delete comments so we don't match on reg specifiers inside
+ code = commentRE.sub('', code)
+ # search for operands
+ next_pos = 0
+ while 1:
+ match = operandsRE.search(code, next_pos)
+ if not match:
+ # no more matches: we're done
+ break
+ op = match.groups()
+ # regexp groups are operand full name, base, and extension
+ (op_full, op_base, op_ext) = op
+ # find this op in the master list
+ op_desc = master_list.find_base(op_base)
+ if not op_desc:
+ error(0, 'Found operand %s which is not in the master list!' \
+ ' This is an internal error' % \
+ op_base)
+ else:
+ # See if we've already found this operand
+ op_desc = self.find_base(op_base)
+ if not op_desc:
+ # if not, add a reference to it to this sub list
+ self.append(master_list.bases[op_base])
+
+ # start next search after end of current match
+ next_pos = match.end()
+ self.sort()
+ self.memOperand = None
+ for op_desc in self.items:
+ if op_desc.isMem():
+ if self.memOperand:
+ error(0, "Code block has more than one memory operand.")
+ self.memOperand = op_desc
+
# Regular expression object to match C++ comments
# (used in findOperands())
commentRE = re.compile(r'//.*\n')
@@ -1564,8 +1659,12 @@ assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
def substMungedOpNames(code):
return operandsWithExtRE.sub(r'\1', code)
-def joinLists(t):
- return map(string.join, t)
+# Fix up code snippets for final substitution in templates.
+def mungeSnippet(s):
+ if isinstance(s, str):
+ return substMungedOpNames(substBitOps(s))
+ else:
+ return s
def makeFlagConstructor(flag_list):
if len(flag_list) == 0:
@@ -1583,11 +1682,24 @@ def makeFlagConstructor(flag_list):
code = pre + string.join(flag_list, post + pre) + post
return code
-class CodeBlock:
- def __init__(self, code):
- self.orig_code = code
- self.operands = OperandList(code)
- self.code = substMungedOpNames(substBitOps(code))
+# Assume all instruction flags are of the form 'IsFoo'
+instFlagRE = re.compile(r'Is.*')
+
+# OpClass constants end in 'Op' except No_OpClass
+opClassRE = re.compile(r'.*Op|No_OpClass')
+
+class InstObjParams:
+ def __init__(self, mnem, class_name, base_class = '',
+ snippets = {}, opt_args = []):
+ self.mnemonic = mnem
+ self.class_name = class_name
+ self.base_class = base_class
+ if not isinstance(snippets, dict):
+ snippets = {'code' : snippets}
+ compositeCode = ' '.join(map(str, snippets.values()))
+ self.snippets = snippets
+
+ self.operands = OperandList(compositeCode)
self.constructor = self.operands.concatAttrStrings('constructor')
self.constructor += \
'\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs
@@ -1597,28 +1709,10 @@ class CodeBlock:
'\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs
self.constructor += \
'\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs
-
- self.op_decl = self.operands.concatAttrStrings('op_decl')
-
- is_src = lambda op: op.is_src
- is_dest = lambda op: op.is_dest
-
- self.op_src_decl = \
- self.operands.concatSomeAttrStrings(is_src, 'op_src_decl')
- self.op_dest_decl = \
- self.operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
-
- self.op_rd = self.operands.concatAttrStrings('op_rd')
- self.op_wb = self.operands.concatAttrStrings('op_wb')
-
self.flags = self.operands.concatAttrLists('flags')
- if self.operands.memOperand:
- self.mem_acc_size = self.operands.memOperand.mem_acc_size
- self.mem_acc_type = self.operands.memOperand.mem_acc_type
-
# Make a basic guess on the operand class (function unit type).
- # These are good enough for most cases, and will be overridden
+ # These are good enough for most cases, and can be overridden
# later otherwise.
if 'IsStore' in self.flags:
self.op_class = 'MemWriteOp'
@@ -1629,48 +1723,6 @@ class CodeBlock:
else:
self.op_class = 'IntAluOp'
-# Assume all instruction flags are of the form 'IsFoo'
-instFlagRE = re.compile(r'Is.*')
-
-# OpClass constants end in 'Op' except No_OpClass
-opClassRE = re.compile(r'.*Op|No_OpClass')
-
-class InstObjParams:
- def __init__(self, mnem, class_name, base_class = '',
- code = None, opt_args = [], extras = {}):
- self.mnemonic = mnem
- self.class_name = class_name
- self.base_class = base_class
- if code:
- #If the user already made a CodeBlock, pick the parts from it
- if isinstance(code, CodeBlock):
- origCode = code.orig_code
- codeBlock = code
- else:
- origCode = code
- codeBlock = CodeBlock(code)
- stringExtras = {}
- otherExtras = {}
- for (k, v) in extras.items():
- if type(v) == str:
- stringExtras[k] = v
- else:
- otherExtras[k] = v
- compositeCode = "\n".join([origCode] + stringExtras.values())
- # compositeCode = '\n'.join([origCode] +
- # [pair[1] for pair in extras])
- compositeBlock = CodeBlock(compositeCode)
- for code_attr in compositeBlock.__dict__.keys():
- setattr(self, code_attr, getattr(compositeBlock, code_attr))
- for (key, snippet) in stringExtras.items():
- setattr(self, key, CodeBlock(snippet).code)
- for (key, item) in otherExtras.items():
- setattr(self, key, item)
- self.code = codeBlock.code
- self.orig_code = origCode
- else:
- self.constructor = ''
- self.flags = []
# Optional arguments are assumed to be either StaticInst flags
# or an OpClass value. To avoid having to import a complete
# list of these values to match against, we do it ad-hoc
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index d65e3eb94..99c9e1604 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -154,19 +154,22 @@ decode OPCODE_HI default Unknown::unknown() {
0x3: decode FUNCTION_LO {
format HiLoOp {
- 0x0: mult({{ val = Rs.sd * Rt.sd; }});
- 0x1: multu({{ val = Rs.ud * Rt.ud; }});
- }
-
- format HiLoMiscOp {
- 0x2: div({{ if (Rt.sd != 0) {
- HI = Rs.sd % Rt.sd;
- LO = Rs.sd / Rt.sd;
+ 0x0: mult({{ int64_t val = Rs.sd * Rt.sd; }});
+ 0x1: multu({{ uint64_t val = Rs.ud * Rt.ud; }});
+ 0x2: div({{ //Initialized to placate g++
+ int64_t val = 0;
+ if (Rt.sd != 0) {
+ int64_t hi = Rs.sd % Rt.sd;
+ int64_t lo = Rs.sd / Rt.sd;
+ val = (hi << 32) | lo;
}
}});
- 0x3: divu({{ if (Rt.ud != 0) {
- HI = Rs.ud % Rt.ud;
- LO = Rs.ud / Rt.ud;
+ 0x3: divu({{ //Initialized to placate g++
+ uint64_t val = 0;
+ if (Rt.ud != 0) {
+ uint64_t hi = Rs.ud % Rt.ud;
+ uint64_t lo = Rs.ud / Rt.ud;
+ val = (hi << 32) | lo;
}
}});
}
@@ -950,17 +953,17 @@ decode OPCODE_HI default Unknown::unknown() {
}});
format HiLoOp {
- 0x0: madd({{ val = ((int64_t) HI << 32 | LO) +
- (Rs.sd * Rt.sd);
+ 0x0: madd({{ int64_t val = ((int64_t) HI << 32 | LO) +
+ (Rs.sd * Rt.sd);
}});
- 0x1: maddu({{ val = ((uint64_t) HI << 32 | LO) +
- (Rs.ud * Rt.ud);
+ 0x1: maddu({{ uint64_t val = ((uint64_t) HI << 32 | LO) +
+ (Rs.ud * Rt.ud);
}});
- 0x4: msub({{ val = ((int64_t) HI << 32 | LO) -
- (Rs.sd * Rt.sd);
+ 0x4: msub({{ int64_t val = ((int64_t) HI << 32 | LO) -
+ (Rs.sd * Rt.sd);
}});
- 0x5: msubu({{ val = ((uint64_t) HI << 32 | LO) -
- (Rs.ud * Rt.ud);
+ 0x5: msubu({{ uint64_t val = ((uint64_t) HI << 32 | LO) -
+ (Rs.ud * Rt.ud);
}});
}
}
diff --git a/src/arch/mips/isa/formats/basic.isa b/src/arch/mips/isa/formats/basic.isa
index 29a445b2c..ec065b865 100644
--- a/src/arch/mips/isa/formats/basic.isa
+++ b/src/arch/mips/isa/formats/basic.isa
@@ -88,7 +88,7 @@ def template BasicDecodeWithMnemonic {{
// The most basic instruction format...
def format BasicOp(code, *flags) {{
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa
index 8c89fbfa2..a67f04dca 100644
--- a/src/arch/mips/isa/formats/branch.isa
+++ b/src/arch/mips/isa/formats/branch.isa
@@ -247,7 +247,7 @@ def format Branch(code,*opt_flags) {{
code += '} else {\n'
code += not_taken_code
- iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), inst_flags)
+ iop = InstObjParams(name, Name, 'Branch', code, inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -266,7 +266,7 @@ def format Jump(code, *opt_flags) {{
else:
inst_flags += (x, )
- iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), inst_flags)
+ iop = InstObjParams(name, Name, 'Jump', code, inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/mips/isa/formats/control.isa b/src/arch/mips/isa/formats/control.isa
index 6c7d396f3..1c63a6e22 100644
--- a/src/arch/mips/isa/formats/control.isa
+++ b/src/arch/mips/isa/formats/control.isa
@@ -130,7 +130,7 @@ output decoder {{
}};
def format System(code, *flags) {{
- iop = InstObjParams(name, Name, 'Control', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'Control', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -138,7 +138,7 @@ def format System(code, *flags) {{
}};
def format CP0Control(code, *flags) {{
- iop = InstObjParams(name, Name, 'CP0Control', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'CP0Control', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -146,7 +146,7 @@ def format CP0Control(code, *flags) {{
}};
def format CP1Control(code, *flags) {{
- iop = InstObjParams(name, Name, 'CP1Control', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'CP1Control', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa
index 153f3f949..ac6805cc7 100644
--- a/src/arch/mips/isa/formats/fp.isa
+++ b/src/arch/mips/isa/formats/fp.isa
@@ -209,7 +209,7 @@ def template FloatingPointExecute {{
// Primary format for float point operate instructions:
def format FloatOp(code, *flags) {{
- iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'FPOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -248,7 +248,7 @@ def format FloatCompareOp(cond_code, *flags) {{
code += cond_code + '}'
code += 'FCSR = genCCVector(FCSR, CC, cond);\n'
- iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
+ iop = InstObjParams(name, Name, 'FPCompareOp', code)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -299,7 +299,7 @@ def format FloatConvertOp(code, *flags) {{
else:
code += 'val); '
- iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code))
+ iop = InstObjParams(name, Name, 'FPOp', code)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -307,7 +307,7 @@ def format FloatConvertOp(code, *flags) {{
}};
def format FloatAccOp(code, *flags) {{
- iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'FPOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -316,7 +316,7 @@ def format FloatAccOp(code, *flags) {{
// Primary format for float64 operate instructions:
def format Float64Op(code, *flags) {{
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -364,7 +364,7 @@ def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{
code += cond_code2
code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}'
- iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
+ iop = InstObjParams(name, Name, 'FPCompareOp', code)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa
index 654dd8921..2f131f6d9 100644
--- a/src/arch/mips/isa/formats/int.isa
+++ b/src/arch/mips/isa/formats/int.isa
@@ -224,7 +224,7 @@ output decoder {{
}};
def format IntOp(code, *opt_flags) {{
- iop = InstObjParams(name, Name, 'IntOp', CodeBlock(code), opt_flags)
+ iop = InstObjParams(name, Name, 'IntOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = RegNopCheckDecode.subst(iop)
@@ -232,7 +232,7 @@ def format IntOp(code, *opt_flags) {{
}};
def format IntImmOp(code, *opt_flags) {{
- iop = InstObjParams(name, Name, 'IntImmOp', CodeBlock(code), opt_flags)
+ iop = InstObjParams(name, Name, 'IntImmOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = ImmNopCheckDecode.subst(iop)
@@ -240,15 +240,10 @@ def format IntImmOp(code, *opt_flags) {{
}};
def format HiLoOp(code, *opt_flags) {{
- if '.sd' in code:
- code = 'int64_t ' + code
- elif '.ud' in code:
- code = 'uint64_t ' + code
-
code += 'HI = val<63:32>;\n'
code += 'LO = val<31:0>;\n'
- iop = InstObjParams(name, Name, 'HiLoOp', CodeBlock(code), opt_flags)
+ iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -256,11 +251,11 @@ def format HiLoOp(code, *opt_flags) {{
}};
def format HiLoMiscOp(code, *opt_flags) {{
- iop = InstObjParams(name, Name, 'HiLoMiscOp', CodeBlock(code), opt_flags)
+ iop = InstObjParams(name, Name, 'HiLoMiscOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
- exec_output = HiLoExecute.subst(iop)
+ exec_output = BasicExecute.subst(iop)
}};
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index e786cfbe2..fccda2775 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -166,22 +166,28 @@ def template CompleteAccDeclare {{
}};
-def template LoadStoreConstructor {{
+def template EACompConstructor {{
/** TODO: change op_class to AddrGenOp or something (requires
* creating new member of OpClass enum in op_class.hh, updating
* config files, etc.). */
inline %(class_name)s::EAComp::EAComp(MachInst machInst)
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
{
- %(ea_constructor)s;
+ %(constructor)s;
}
+}};
+
+def template MemAccConstructor {{
inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
{
- %(memacc_constructor)s;
+ %(constructor)s;
}
+}};
+
+def template LoadStoreConstructor {{
inline %(class_name)s::%(class_name)s(MachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
new EAComp(machInst), new MemAcc(machInst))
@@ -202,7 +208,7 @@ def template EACompExecute {{
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
- %(code)s;
+ %(ea_code)s;
if (fault == NoFault) {
%(op_wb)s;
@@ -228,7 +234,7 @@ def template LoadMemAccExecute {{
if (fault == NoFault) {
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
- %(code)s;
+ %(memacc_code)s;
}
if (fault == NoFault) {
@@ -327,7 +333,7 @@ def template StoreMemAccExecute {{
EA = xc->getEA();
if (fault == NoFault) {
- %(code)s;
+ %(memacc_code)s;
}
if (fault == NoFault) {
@@ -471,7 +477,7 @@ def template MiscMemAccExecute {{
EA = xc->getEA();
if (fault == NoFault) {
- %(code)s;
+ %(memacc_code)s;
}
return NoFault;
diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa
index 96435f8c9..d7240335e 100644
--- a/src/arch/mips/isa/formats/mt.isa
+++ b/src/arch/mips/isa/formats/mt.isa
@@ -74,7 +74,7 @@ def template MTExecute {{
// Primary format for integer operate instructions:
def format MipsMT() {{
code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n'
- iop = InstObjParams(name, Name, 'MT', CodeBlock(code))
+ iop = InstObjParams(name, Name, 'MT', code)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/mips/isa/formats/noop.isa b/src/arch/mips/isa/formats/noop.isa
index 7f3d313ad..a8995d658 100644
--- a/src/arch/mips/isa/formats/noop.isa
+++ b/src/arch/mips/isa/formats/noop.isa
@@ -125,7 +125,7 @@ def template ImmNopCheckDecode {{
// Like BasicOperate format, but generates NOP if RC/FC == 31
def format BasicOperateWithNopCheck(code, *opt_args) {{
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code),
+ iop = InstObjParams(name, Name, 'MipsStaticInst', code,
opt_args)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/src/arch/mips/isa/formats/tlbop.isa b/src/arch/mips/isa/formats/tlbop.isa
index b974ccbed..dbfbb8ce1 100644
--- a/src/arch/mips/isa/formats/tlbop.isa
+++ b/src/arch/mips/isa/formats/tlbop.isa
@@ -70,9 +70,7 @@ def template TlbOpExecute {{
// Primary format for integer operate instructions:
def format TlbOp(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'MipsStaticInst', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecodeWithMnemonic.subst(iop)
diff --git a/src/arch/mips/isa/formats/trap.isa b/src/arch/mips/isa/formats/trap.isa
index b9066f374..96d1167d2 100644
--- a/src/arch/mips/isa/formats/trap.isa
+++ b/src/arch/mips/isa/formats/trap.isa
@@ -73,7 +73,7 @@ def format Trap(code, *flags) {{
code = 'warn(\"'
code += 'Trap Exception Handler Is Currently Not Implemented.'
code += '\");'
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa
index 73164bc0d..ec524113d 100644
--- a/src/arch/mips/isa/formats/util.isa
+++ b/src/arch/mips/isa/formats/util.isa
@@ -40,63 +40,24 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
# add hook to get effective addresses into execution trace output.
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
- # generate code block objects
- ea_cblk = CodeBlock(ea_code)
- memacc_cblk = CodeBlock(memacc_code)
- postacc_cblk = CodeBlock(postacc_code)
-
# Some CPU models execute the memory operation as an atomic unit,
# while others want to separate them into an effective address
# computation and a memory access operation. As a result, we need
# to generate three StaticInst objects. Note that the latter two
# are nested inside the larger "atomic" one.
- # generate InstObjParams for EAComp object
- ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
-
- # generate InstObjParams for MemAcc object
- memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
- # in the split execution model, the MemAcc portion is responsible
- # for the post-access code.
- memacc_iop.postacc_code = postacc_cblk.code
-
- # generate InstObjParams for InitiateAcc, CompleteAcc object
- # The code used depends on the template being used
- if (exec_template_base == 'Load'):
- initiateacc_cblk = CodeBlock(ea_code + memacc_code)
- completeacc_cblk = CodeBlock(memacc_code + postacc_code)
- elif (exec_template_base.startswith('Store')):
- initiateacc_cblk = CodeBlock(ea_code + memacc_code)
- completeacc_cblk = CodeBlock(postacc_code)
- else:
- initiateacc_cblk = ''
- completeacc_cblk = ''
-
- initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
- inst_flags)
-
- completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
- inst_flags)
-
- if (exec_template_base == 'Load'):
- initiateacc_iop.ea_code = ea_cblk.code
- initiateacc_iop.memacc_code = memacc_cblk.code
- completeacc_iop.memacc_code = memacc_cblk.code
- completeacc_iop.postacc_code = postacc_cblk.code
- elif (exec_template_base.startswith('Store')):
- initiateacc_iop.ea_code = ea_cblk.code
- initiateacc_iop.memacc_code = memacc_cblk.code
- completeacc_iop.postacc_code = postacc_cblk.code
-
- # generate InstObjParams for unified execution
- cblk = CodeBlock(ea_code + memacc_code + postacc_code)
- iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
-
- iop.ea_constructor = ea_cblk.constructor
- iop.ea_code = ea_cblk.code
- iop.memacc_constructor = memacc_cblk.constructor
- iop.memacc_code = memacc_cblk.code
- iop.postacc_code = postacc_cblk.code
+ # Generate InstObjParams for each of the three objects. Note that
+ # they differ only in the set of code objects contained (which in
+ # turn affects the object's overall operand list).
+ iop = InstObjParams(name, Name, base_class,
+ { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
+ inst_flags)
+ ea_iop = InstObjParams(name, Name, base_class,
+ { 'ea_code':ea_code },
+ inst_flags)
+ memacc_iop = InstObjParams(name, Name, base_class,
+ { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
+ inst_flags)
if mem_flags:
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
@@ -117,14 +78,19 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
# (header_output, decoder_output, decode_block, exec_output)
- return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
+ return (LoadStoreDeclare.subst(iop),
+ EACompConstructor.subst(ea_iop)
+ + MemAccConstructor.subst(memacc_iop)
+ + LoadStoreConstructor.subst(iop),
decode_template.subst(iop),
EACompExecute.subst(ea_iop)
+ memAccExecTemplate.subst(memacc_iop)
+ fullExecTemplate.subst(iop)
- + initiateAccTemplate.subst(initiateacc_iop)
- + completeAccTemplate.subst(completeacc_iop))
+ + initiateAccTemplate.subst(iop)
+ + completeAccTemplate.subst(iop))
}};
+
+
output header {{
std::string inst2string(MachInst machInst);
}};
diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh
index dee883c4a..7b57b31f5 100644
--- a/src/arch/mips/regfile/regfile.hh
+++ b/src/arch/mips/regfile/regfile.hh
@@ -173,6 +173,11 @@ namespace MipsISA
}
};
+ static inline int flattenIntIndex(ThreadContext * tc, int reg)
+ {
+ return reg;
+ }
+
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
diff --git a/src/arch/mips/remote_gdb.hh b/src/arch/mips/remote_gdb.hh
new file mode 100644
index 000000000..5886ab849
--- /dev/null
+++ b/src/arch/mips/remote_gdb.hh
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2002-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: Nathan Binkert
+ */
+
+#ifndef __ARCH_MIPS_REMOTE_GDB_HH__
+#define __ARCH_MIPS_REMOTE_GDB_HH__
+
+#include "base/remote_gdb.hh"
+
+namespace MipsISA
+{
+ class RemoteGDB : public BaseRemoteGDB
+ {
+ public:
+ //These needs to be written to suit MIPS
+
+ RemoteGDB(System *system, ThreadContext *context)
+ : BaseRemoteGDB(system, context, 1)
+ {}
+
+ bool acc(Addr, size_t)
+ { panic("acc not implemented for MIPS!"); }
+
+ void getregs()
+ { panic("getregs not implemented for MIPS!"); }
+
+ void setregs()
+ { panic("setregs not implemented for MIPS!"); }
+
+ void clearSingleStep()
+ { panic("clearSingleStep not implemented for MIPS!"); }
+
+ void setSingleStep()
+ { panic("setSingleStep not implemented for MIPS!"); }
+ };
+}
+
+#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
diff --git a/src/arch/mips/syscallreturn.hh b/src/arch/mips/syscallreturn.hh
index ef1093caf..47290b634 100644
--- a/src/arch/mips/syscallreturn.hh
+++ b/src/arch/mips/syscallreturn.hh
@@ -32,51 +32,22 @@
#ifndef __ARCH_MIPS_SYSCALLRETURN_HH__
#define __ARCH_MIPS_SYSCALLRETURN_HH__
-class SyscallReturn {
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint32_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint32_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s) {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
-
- private:
- uint64_t retval;
- bool success;
-};
+#include "sim/syscallreturn.hh"
+#include "cpu/thread_context.hh"
namespace MipsISA
{
- static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+ static inline void setSyscallReturn(SyscallReturn return_value,
+ ThreadContext *tc)
{
if (return_value.successful()) {
// no error
- regs->setIntReg(SyscallSuccessReg, 0);
- regs->setIntReg(ReturnValueReg1, return_value.value());
+ tc->setIntReg(SyscallSuccessReg, 0);
+ tc->setIntReg(ReturnValueReg1, return_value.value());
} else {
// got an error, return details
- regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
- regs->setIntReg(ReturnValueReg1, -return_value.value());
+ tc->setIntReg(SyscallSuccessReg, (IntReg) -1);
+ tc->setIntReg(ReturnValueReg1, -return_value.value());
}
}
}
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index c2ef97bfa..555bfba3d 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -50,12 +50,12 @@ base_sources = Split('''
intregfile.cc
miscregfile.cc
regfile.cc
+ remote_gdb.cc
''')
# Full-system sources
full_system_sources = Split('''
arguments.cc
- remote_gdb.cc
pagetable.cc
stacktrace.cc
system.cc
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 825ff40f6..a6f4343ae 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -302,10 +302,12 @@ void doREDFault(ThreadContext *tc, TrapType tt)
MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
- MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ //MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
- MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ MiscReg CANSAVE = tc->readMiscReg(NumIntArchRegs + 3);
MiscReg GL = tc->readMiscReg(MISCREG_GL);
MiscReg PC = tc->readPC();
MiscReg NPC = tc->readNextPC();
@@ -387,10 +389,12 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
- MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ //MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
- MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
MiscReg GL = tc->readMiscReg(MISCREG_GL);
MiscReg PC = tc->readPC();
MiscReg NPC = tc->readNextPC();
@@ -656,19 +660,21 @@ void PageTableFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
- // address is higher than the stack region or in the current stack region
- if (vaddr > p->stack_base || vaddr > p->stack_min)
- FaultBase::invoke(tc);
-
- // We've accessed the next page
- if (vaddr > p->stack_min - PageBytes) {
+ // We've accessed the next page of the stack, so extend the stack
+ // to cover it.
+ if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes)
+ {
p->stack_min -= PageBytes;
- if (p->stack_base - p->stack_min > 8*1024*1024)
+ if(p->stack_base - p->stack_min > 8*1024*1024)
fatal("Over max stack size for one thread\n");
p->pTable->allocate(p->stack_min, PageBytes);
warn("Increasing stack size by one page.");
- } else {
- FaultBase::invoke(tc);
+ }
+ // Otherwise, we have an unexpected page fault. Report that fact,
+ // and what address was accessed to cause the fault.
+ else
+ {
+ panic("Page table fault when accessing virtual address %#x\n", vaddr);
}
}
diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc
index 7f3d5a758..585782ddb 100644
--- a/src/arch/sparc/floatregfile.cc
+++ b/src/arch/sparc/floatregfile.cc
@@ -72,16 +72,19 @@ FloatReg FloatRegFile::readReg(int floatReg, int width)
float32_t result32;
memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
result = htog(result32);
+ DPRINTF(Sparc, "Read FP32 register %d = 0x%x\n", floatReg, result);
break;
case DoubleWidth:
float64_t result64;
memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
result = htog(result64);
+ DPRINTF(Sparc, "Read FP64 register %d = 0x%x\n", floatReg, result);
break;
case QuadWidth:
float128_t result128;
memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
result = htog(result128);
+ DPRINTF(Sparc, "Read FP128 register %d = 0x%x\n", floatReg, result);
break;
default:
panic("Attempted to read a %d bit floating point register!", width);
@@ -101,16 +104,19 @@ FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
uint32_t result32;
memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
result = htog(result32);
+ DPRINTF(Sparc, "Read FP32 bits register %d = 0x%x\n", floatReg, result);
break;
case DoubleWidth:
uint64_t result64;
memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
result = htog(result64);
+ DPRINTF(Sparc, "Read FP64 bits register %d = 0x%x\n", floatReg, result);
break;
case QuadWidth:
uint64_t result128;
memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
result = htog(result128);
+ DPRINTF(Sparc, "Read FP128 bits register %d = 0x%x\n", floatReg, result);
break;
default:
panic("Attempted to read a %d bit floating point register!", width);
@@ -131,10 +137,12 @@ Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
case SingleWidth:
result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
+ DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result32);
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
+ DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result64);
break;
case QuadWidth:
panic("Quad width FP not implemented.");
@@ -157,10 +165,12 @@ Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
case SingleWidth:
result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
+ DPRINTF(Sparc, "Write FP64 bits register %d = 0x%x\n", floatReg, result32);
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
+ DPRINTF(Sparc, "Write FP64 bits register %d = 0x%x\n", floatReg, result64);
break;
case QuadWidth:
panic("Quad width FP not implemented.");
@@ -173,13 +183,15 @@ Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
void FloatRegFile::serialize(std::ostream &os)
{
- SERIALIZE_ARRAY((unsigned char *)regSpace,
+ uint8_t *float_reg = (uint8_t*)regSpace;
+ SERIALIZE_ARRAY(float_reg,
SingleWidth / 8 * NumFloatRegs);
}
void FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
- UNSERIALIZE_ARRAY((unsigned char *)regSpace,
+ uint8_t *float_reg = (uint8_t*)regSpace;
+ UNSERIALIZE_ARRAY(float_reg,
SingleWidth / 8 * NumFloatRegs);
}
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc
index 60856d3fa..39a613a0d 100644
--- a/src/arch/sparc/intregfile.cc
+++ b/src/arch/sparc/intregfile.cc
@@ -66,6 +66,7 @@ void IntRegFile::clear()
memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame);
for(int x = 0; x < 2 * NWindows; x++)
memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame);
+ memset(regs, 0, sizeof(IntReg) * NumIntRegs);
}
IntRegFile::IntRegFile()
@@ -78,6 +79,10 @@ IntRegFile::IntRegFile()
IntReg IntRegFile::readReg(int intReg)
{
+ DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]);
+ return regs[intReg];
+ /* XXX Currently not used. When used again regView/offset need to be
+ * serialized!
IntReg val;
if(intReg < NumIntArchRegs)
val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
@@ -89,6 +94,7 @@ IntReg IntRegFile::readReg(int intReg)
DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
return val;
+ */
}
void IntRegFile::setReg(int intReg, const IntReg &val)
@@ -96,13 +102,21 @@ void IntRegFile::setReg(int intReg, const IntReg &val)
if(intReg)
{
DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
+ regs[intReg] = val;
+ }
+ return;
+ /* XXX Currently not used. When used again regView/offset need to be
+ * serialized!
+ if(intReg)
+ {
+ DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
if(intReg < NumIntArchRegs)
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
else if((intReg -= NumIntArchRegs) < NumMicroIntRegs)
microRegs[intReg] = val;
else
panic("Tried to set non-existant integer register\n");
- }
+ } */
}
//This doesn't effect the actual CWP register.
@@ -139,20 +153,26 @@ void IntRegFile::setGlobals(int gl)
void IntRegFile::serialize(std::ostream &os)
{
+ SERIALIZE_ARRAY(regs, NumIntRegs);
+ SERIALIZE_ARRAY(microRegs, NumMicroIntRegs);
+
+ /* the below doesn't seem needed unless gabe makes regview work*/
unsigned int x;
for(x = 0; x < MaxGL; x++)
SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
for(x = 0; x < 2 * NWindows; x++)
SERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
- SERIALIZE_ARRAY(microRegs, NumMicroIntRegs);
}
void IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
+ UNSERIALIZE_ARRAY(regs, NumIntRegs);
+ UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs);
+
+ /* the below doesn't seem needed unless gabe makes regview work*/
unsigned int x;
for(x = 0; x < MaxGL; x++)
UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
for(unsigned int x = 0; x < 2 * NWindows; x++)
UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
- UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs);
}
diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh
index d66d0fcb7..665c7aa31 100644
--- a/src/arch/sparc/intregfile.hh
+++ b/src/arch/sparc/intregfile.hh
@@ -34,6 +34,7 @@
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/types.hh"
+#include "base/bitfield.hh"
#include <string>
@@ -47,22 +48,26 @@ namespace SparcISA
std::string getIntRegName(RegIndex);
const int NumIntArchRegs = 32;
- const int NumIntRegs = MaxGL * 8 + NWindows * 16 + NumMicroIntRegs;
+ const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
class IntRegFile
{
private:
friend class RegFile;
protected:
+ //The number of bits needed to index into each 8 register frame
static const int FrameOffsetBits = 3;
+ //The number of bits to choose between the 4 sets of 8 registers
static const int FrameNumBits = 2;
+ //The number of registers per "frame" (8)
static const int RegsPerFrame = 1 << FrameOffsetBits;
- static const int FrameNumMask =
+ //A mask to get the frame number
+ static const uint64_t FrameNumMask =
(FrameNumBits == sizeof(int)) ?
(unsigned int)(-1) :
(1 << FrameNumBits) - 1;
- static const int FrameOffsetMask =
+ static const uint64_t FrameOffsetMask =
(FrameOffsetBits == sizeof(int)) ?
(unsigned int)(-1) :
(1 << FrameOffsetBits) - 1;
@@ -70,6 +75,7 @@ namespace SparcISA
IntReg regGlobals[MaxGL+1][RegsPerFrame];
IntReg regSegments[2 * NWindows][RegsPerFrame];
IntReg microRegs[NumMicroIntRegs];
+ IntReg regs[NumIntRegs];
enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index 4a806bfd0..693cc6876 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -67,6 +67,26 @@ output header {{
OverflowSet=0x7
};
+ enum FpCondTest
+ {
+ FAlways=0x8,
+ FNever=0x0,
+ FUnordered=0x7,
+ FGreater=0x6,
+ FUnorderedOrGreater=0x5,
+ FLess=0x4,
+ FUnorderedOrLess=0x3,
+ FLessOrGreater=0x2,
+ FNotEqual=0x1,
+ FEqual=0x9,
+ FUnorderedOrEqual=0xA,
+ FGreaterOrEqual=0xB,
+ FUnorderedOrGreaterOrEqual=0xC,
+ FLessOrEqual=0xD,
+ FUnorderedOrLessOrEqual=0xE,
+ FOrdered=0xF
+ };
+
extern char * CondTestAbbrev[];
/**
@@ -93,6 +113,8 @@ output header {{
const RegIndex indexArray[], int num) const;
};
+ bool passesFpCondition(uint32_t fcc, uint32_t condition);
+
bool passesCondition(uint32_t codes, uint32_t condition);
inline int64_t sign_ext(uint64_t data, int origWidth)
@@ -189,23 +211,149 @@ output decoder {{
const int MaxOutput = 16;
const int MaxLocal = 24;
const int MaxInput = 32;
- const int MaxMicroReg = 33;
- if (reg == FramePointerReg)
- ccprintf(os, "%%fp");
- else if (reg == StackPointerReg)
- ccprintf(os, "%%sp");
- else if(reg < MaxGlobal)
- ccprintf(os, "%%g%d", reg);
- else if(reg < MaxOutput)
- ccprintf(os, "%%o%d", reg - MaxGlobal);
- else if(reg < MaxLocal)
- ccprintf(os, "%%l%d", reg - MaxOutput);
- else if(reg < MaxInput)
- ccprintf(os, "%%i%d", reg - MaxLocal);
- else if(reg < MaxMicroReg)
- ccprintf(os, "%%u%d", reg - MaxInput);
- else {
- ccprintf(os, "%%f%d", reg - MaxMicroReg);
+ const int MaxMicroReg = 40;
+ if (reg < FP_Base_DepTag) {
+ //If we used a register from the next or previous window,
+ //take out the offset.
+ while (reg >= MaxMicroReg)
+ reg -= MaxMicroReg;
+ if (reg == FramePointerReg)
+ ccprintf(os, "%%fp");
+ else if (reg == StackPointerReg)
+ ccprintf(os, "%%sp");
+ else if(reg < MaxGlobal)
+ ccprintf(os, "%%g%d", reg);
+ else if(reg < MaxOutput)
+ ccprintf(os, "%%o%d", reg - MaxGlobal);
+ else if(reg < MaxLocal)
+ ccprintf(os, "%%l%d", reg - MaxOutput);
+ else if(reg < MaxInput)
+ ccprintf(os, "%%i%d", reg - MaxLocal);
+ else if(reg < MaxMicroReg)
+ ccprintf(os, "%%u%d", reg - MaxInput);
+ //The fake int regs that are really control regs
+ else {
+ switch (reg - MaxMicroReg) {
+ case 1:
+ ccprintf(os, "%%y");
+ break;
+ case 2:
+ ccprintf(os, "%%ccr");
+ break;
+ case 3:
+ ccprintf(os, "%%cansave");
+ break;
+ case 4:
+ ccprintf(os, "%%canrestore");
+ break;
+ case 5:
+ ccprintf(os, "%%cleanwin");
+ break;
+ case 6:
+ ccprintf(os, "%%otherwin");
+ break;
+ case 7:
+ ccprintf(os, "%%wstate");
+ break;
+ }
+ }
+ } else if (reg < Ctrl_Base_DepTag) {
+ ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
+ } else {
+ switch (reg - Ctrl_Base_DepTag) {
+ case MISCREG_ASI:
+ ccprintf(os, "%%asi");
+ break;
+ case MISCREG_FPRS:
+ ccprintf(os, "%%fprs");
+ break;
+ case MISCREG_PCR:
+ ccprintf(os, "%%pcr");
+ break;
+ case MISCREG_PIC:
+ ccprintf(os, "%%pic");
+ break;
+ case MISCREG_GSR:
+ ccprintf(os, "%%gsr");
+ break;
+ case MISCREG_SOFTINT:
+ ccprintf(os, "%%softint");
+ break;
+ case MISCREG_SOFTINT_SET:
+ ccprintf(os, "%%softint_set");
+ break;
+ case MISCREG_SOFTINT_CLR:
+ ccprintf(os, "%%softint_clr");
+ break;
+ case MISCREG_TICK_CMPR:
+ ccprintf(os, "%%tick_cmpr");
+ break;
+ case MISCREG_STICK:
+ ccprintf(os, "%%stick");
+ break;
+ case MISCREG_STICK_CMPR:
+ ccprintf(os, "%%stick_cmpr");
+ break;
+ case MISCREG_TPC:
+ ccprintf(os, "%%tpc");
+ break;
+ case MISCREG_TNPC:
+ ccprintf(os, "%%tnpc");
+ break;
+ case MISCREG_TSTATE:
+ ccprintf(os, "%%tstate");
+ break;
+ case MISCREG_TT:
+ ccprintf(os, "%%tt");
+ break;
+ case MISCREG_TICK:
+ ccprintf(os, "%%tick");
+ break;
+ case MISCREG_TBA:
+ ccprintf(os, "%%tba");
+ break;
+ case MISCREG_PSTATE:
+ ccprintf(os, "%%pstate");
+ break;
+ case MISCREG_TL:
+ ccprintf(os, "%%tl");
+ break;
+ case MISCREG_PIL:
+ ccprintf(os, "%%pil");
+ break;
+ case MISCREG_CWP:
+ ccprintf(os, "%%cwp");
+ break;
+ case MISCREG_GL:
+ ccprintf(os, "%%gl");
+ break;
+ case MISCREG_HPSTATE:
+ ccprintf(os, "%%hpstate");
+ break;
+ case MISCREG_HTSTATE:
+ ccprintf(os, "%%htstate");
+ break;
+ case MISCREG_HINTP:
+ ccprintf(os, "%%hintp");
+ break;
+ case MISCREG_HTBA:
+ ccprintf(os, "%%htba");
+ break;
+ case MISCREG_HSTICK_CMPR:
+ ccprintf(os, "%%hstick_cmpr");
+ break;
+ case MISCREG_HVER:
+ ccprintf(os, "%%hver");
+ break;
+ case MISCREG_STRAND_STS_REG:
+ ccprintf(os, "%%strand_sts_reg");
+ break;
+ case MISCREG_FSR:
+ ccprintf(os, "%%fsr");
+ break;
+ default:
+ ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
+ }
}
}
@@ -241,6 +389,51 @@ output decoder {{
return ss.str();
}
+ bool passesFpCondition(uint32_t fcc, uint32_t condition)
+ {
+ bool u = (fcc == 3);
+ bool g = (fcc == 2);
+ bool l = (fcc == 1);
+ bool e = (fcc == 0);
+ switch(condition)
+ {
+ case FAlways:
+ return 1;
+ case FNever:
+ return 0;
+ case FUnordered:
+ return u;
+ case FGreater:
+ return g;
+ case FUnorderedOrGreater:
+ return u || g;
+ case FLess:
+ return l;
+ case FUnorderedOrLess:
+ return u || l;
+ case FLessOrGreater:
+ return l || g;
+ case FNotEqual:
+ return l || g || u;
+ case FEqual:
+ return e;
+ case FUnorderedOrEqual:
+ return u || e;
+ case FGreaterOrEqual:
+ return g || e;
+ case FUnorderedOrGreaterOrEqual:
+ return u || g || e;
+ case FLessOrEqual:
+ return l || e;
+ case FUnorderedOrLessOrEqual:
+ return u || l || e;
+ case FOrdered:
+ return e || l || g;
+ }
+ panic("Tried testing condition nonexistant "
+ "condition code %d", condition);
+ }
+
bool passesCondition(uint32_t codes, uint32_t condition)
{
CondCodes condCodes;
@@ -290,3 +483,27 @@ output decoder {{
}
}};
+output exec {{
+ /// Check "FP enabled" machine status bit. Called when executing any FP
+ /// instruction in full-system mode.
+ /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
+ /// if not. Non-full-system mode: always returns NoFault.
+#if FULL_SYSTEM
+ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+ {
+ Fault fault = NoFault; // dummy... this ipr access should not fault
+ if (xc->readMiscRegWithEffect(MISCREG_PSTATE) & PSTATE::pef &&
+ xc->readMiscRegWithEffect(MISCREG_FPRS) & 0x4)
+ return NoFault;
+ else
+ return new FpDisabled;
+ }
+#else
+ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+ {
+ return NoFault;
+ }
+#endif
+}};
+
+
diff --git a/src/arch/sparc/isa/bitfields.isa b/src/arch/sparc/isa/bitfields.isa
index 7e884866c..e75680d2b 100644
--- a/src/arch/sparc/isa/bitfields.isa
+++ b/src/arch/sparc/isa/bitfields.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
def bitfield A <29>;
def bitfield BPCC <21:20>; // for BPcc & FBPcc
-def bitfield FCMPCC <26:56>; // for FCMP & FCMPEa
+def bitfield FCMPCC <26:25>; // for FCMP & FCMPEa
def bitfield FMOVCC <13:11>; // for FMOVcc
def bitfield CC <12:11>; // for MOVcc & Tcc
def bitfield MOVCC3 <18>; // also for MOVcc
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index 425ebc9d0..81443fecb 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -62,8 +62,8 @@ decode OP default Unknown::unknown()
NNPC = NNPC;//Don't do anything
}});
0x1: bpn(19, {{
- NPC = xc->readNextPC() + 4;
- NNPC = NPC + 4;
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
}}, ',a');
}
default: decode BPCC
@@ -103,8 +103,8 @@ decode OP default Unknown::unknown()
NNPC = NNPC;//Don't do anything
}});
0x1: bn(22, {{
- NPC = xc->readNextPC() + 4;
- NNPC = NPC + 4;
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
}}, ',a');
}
default: bicc(22, {{
@@ -159,8 +159,92 @@ decode OP default Unknown::unknown()
}
//SETHI (or NOP if rd == 0 and imm == 0)
0x4: SetHi::sethi({{Rd.udw = imm;}});
- 0x5: Trap::fbpfcc({{fault = new FpDisabled;}});
- 0x6: Trap::fbfcc({{fault = new FpDisabled;}});
+ //fbpfcc
+ 0x5: decode COND2 {
+ format BranchN {
+ //Branch Always
+ 0x8: decode A
+ {
+ 0x0: fbpa(22, {{
+ NNPC = xc->readPC() + disp;
+ }});
+ 0x1: fbpa(22, {{
+ NPC = xc->readPC() + disp;
+ NNPC = NPC + 4;
+ }}, ',a');
+ }
+ //Branch Never
+ 0x0: decode A
+ {
+ 0x0: fbpn(22, {{
+ NNPC = NNPC;//Don't do anything
+ }});
+ 0x1: fbpn(22, {{
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
+ }}, ',a');
+ }
+ default: decode BPCC {
+ 0x0: fbpcc0(22, {{
+ if(passesFpCondition(Fsr<11:10>, COND2))
+ NNPC = xc->readPC() + disp;
+ else
+ handle_annul
+ }});
+ 0x1: fbpcc1(22, {{
+ if(passesFpCondition(Fsr<33:32>, COND2))
+ NNPC = xc->readPC() + disp;
+ else
+ handle_annul
+ }});
+ 0x2: fbpcc2(22, {{
+ if(passesFpCondition(Fsr<35:34>, COND2))
+ NNPC = xc->readPC() + disp;
+ else
+ handle_annul
+ }});
+ 0x3: fbpcc3(22, {{
+ if(passesFpCondition(Fsr<37:36>, COND2))
+ NNPC = xc->readPC() + disp;
+ else
+ handle_annul
+ }});
+ }
+ }
+ }
+ //fbfcc
+ 0x6: decode COND2 {
+ format BranchN {
+ //Branch Always
+ 0x8: decode A
+ {
+ 0x0: fba(22, {{
+ NNPC = xc->readPC() + disp;
+ }});
+ 0x1: fba(22, {{
+ NPC = xc->readPC() + disp;
+ NNPC = NPC + 4;
+ }}, ',a');
+ }
+ //Branch Never
+ 0x0: decode A
+ {
+ 0x0: fbn(22, {{
+ NNPC = NNPC;//Don't do anything
+ }});
+ 0x1: fbn(22, {{
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
+ }}, ',a');
+ }
+ default: fbfcc(22, {{
+ if(passesFpCondition(Fsr<11:10>, COND2))
+ NNPC = xc->readPC() + disp;
+ else
+ handle_annul
+ }});
+ }
+ }
}
0x1: BranchN::call(30, {{
if (Pstate<3:>)
@@ -186,7 +270,7 @@ decode OP default Unknown::unknown()
Y = Rd<63:32>;
}});
0x0B: smul({{
- Rd.sdw = sext<32>(Rs1.sdw) * sext<32>(Rs2_or_imm13);
+ Rd.sdw = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
Y = Rd.sdw<63:32>;
}});
0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}});
@@ -246,33 +330,29 @@ decode OP default Unknown::unknown()
Rd = resTemp = Rs1 + val2 + carryin;}},
{{(Rs1<31:0> + val2<31:0> + carryin)<32:>}},
{{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{(Rs1<63:1> + val2<63:1> +
- ((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}},
+ {{((Rs1 & val2) | (~resTemp & (Rs1 | val2)))<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
);
- 0x1A: umulcc({{
+ 0x1A: IntOpCcRes::umulcc({{
uint64_t resTemp;
Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>;
- Y = resTemp<63:32>;}},
- {{0}},{{0}},{{0}},{{0}});
- 0x1B: smulcc({{
+ Y = resTemp<63:32>;}});
+ 0x1B: IntOpCcRes::smulcc({{
int64_t resTemp;
- Rd = resTemp = sext<32>(Rs1.sdw) * sext<32>(Rs2_or_imm13);
- Y = resTemp<63:32>;}},
- {{0}},{{0}},{{0}},{{0}});
+ Rd = resTemp = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
+ Y = resTemp<63:32>;}});
0x1C: subccc({{
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = Ccr<0:0>;
Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}},
- {{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}},
+ {{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<31:>}},
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}},
+ {{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<63:>}},
{{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
);
- 0x1D: udivxcc({{
+ 0x1D: IntOpCcRes::udivxcc({{
if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero;
- else Rd = Rs1.udw / Rs2_or_imm13.udw;}}
- ,{{0}},{{0}},{{0}},{{0}});
+ else Rd = Rs1.udw / Rs2_or_imm13.udw;}});
0x1E: udivcc({{
uint32_t resTemp, val2 = Rs2_or_imm13.udw;
int32_t overflow = 0;
@@ -502,20 +582,7 @@ decode OP default Unknown::unknown()
if(Rs2_or_imm13.sdw == 0) fault = new DivisionByZero;
else Rd.sdw = Rs1.sdw / Rs2_or_imm13.sdw;
}});
- 0x2E: decode RS1 {
- 0x0: IntOp::popc({{
- int64_t count = 0;
- uint64_t temp = Rs2_or_imm13;
- //Count the 1s in the front 4bits until none are left
- uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
- while(temp)
- {
- count += oneBits[temp & 0xF];
- temp = temp >> 4;
- }
- Rd = count;
- }});
- }
+ 0x2E: Trap::popc({{fault = new IllegalInstruction;}});
0x2F: decode RCOND3
{
0x1: movreq({{Rd = (Rs1.sdw == 0) ? Rs2_or_imm10 : Rd;}});
@@ -664,7 +731,7 @@ decode OP default Unknown::unknown()
Fsr &= ~(7 << 14);
Fsr &= ~(0x1F);
}});
- 0x03: Trap::fmovq({{fault = new FpDisabled;}});
+ 0x03: FpUnimpl::fmovq();
0x05: fnegs({{
Frds.uw = Frs2s.uw ^ (1UL << 31);
//fsr.ftt = fsr.cexc = 0
@@ -677,7 +744,7 @@ decode OP default Unknown::unknown()
Fsr &= ~(7 << 14);
Fsr &= ~(0x1F);
}});
- 0x07: Trap::fnegq({{fault = new FpDisabled;}});
+ 0x07: FpUnimpl::fnegq();
0x09: fabss({{
Frds.uw = ((1UL << 31) - 1) & Frs2s.uw;
//fsr.ftt = fsr.cexc = 0
@@ -690,106 +757,168 @@ decode OP default Unknown::unknown()
Fsr &= ~(7 << 14);
Fsr &= ~(0x1F);
}});
- 0x0B: Trap::fabsq({{fault = new FpDisabled;}});
- 0x29: fsqrts({{Frds.sf = sqrt(Frs2s.sf);}});
- 0x2A: fsqrtd({{Frd.df = sqrt(Frs2.df);}});
- 0x2B: Trap::fsqrtq({{fault = new FpDisabled;}});
+ 0x0B: FpUnimpl::fabsq();
+ 0x29: fsqrts({{Frds.sf = std::sqrt(Frs2s.sf);}});
+ 0x2A: fsqrtd({{Frd.df = std::sqrt(Frs2.df);}});
+ 0x2B: FpUnimpl::fsqrtq();
0x41: fadds({{Frds.sf = Frs1s.sf + Frs2s.sf;}});
0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}});
- 0x43: Trap::faddq({{fault = new FpDisabled;}});
+ 0x43: FpUnimpl::faddq();
0x45: fsubs({{Frds.sf = Frs1s.sf - Frs2s.sf;}});
0x46: fsubd({{Frd.df = Frs1.df - Frs2.df;}});
- 0x47: Trap::fsubq({{fault = new FpDisabled;}});
+ 0x47: FpUnimpl::fsubq();
0x49: fmuls({{Frds.sf = Frs1s.sf * Frs2s.sf;}});
0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}});
- 0x4B: Trap::fmulq({{fault = new FpDisabled;}});
+ 0x4B: FpUnimpl::fmulq();
0x4D: fdivs({{Frds.sf = Frs1s.sf / Frs2s.sf;}});
0x4E: fdivd({{Frd.df = Frs1.df / Frs2.df;}});
- 0x4F: Trap::fdivq({{fault = new FpDisabled;}});
+ 0x4F: FpUnimpl::fdivq();
0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}});
- 0x6E: Trap::fdmulq({{fault = new FpDisabled;}});
+ 0x6E: FpUnimpl::fdmulq();
0x81: fstox({{
Frd.df = (double)static_cast<int64_t>(Frs2s.sf);
}});
0x82: fdtox({{
Frd.df = (double)static_cast<int64_t>(Frs2.df);
}});
- 0x83: Trap::fqtox({{fault = new FpDisabled;}});
+ 0x83: FpUnimpl::fqtox();
0x84: fxtos({{
Frds.sf = static_cast<float>((int64_t)Frs2.df);
}});
0x88: fxtod({{
Frd.df = static_cast<double>((int64_t)Frs2.df);
}});
- 0x8C: Trap::fxtoq({{fault = new FpDisabled;}});
+ 0x8C: FpUnimpl::fxtoq();
0xC4: fitos({{
Frds.sf = static_cast<float>((int32_t)Frs2s.sf);
}});
0xC6: fdtos({{Frds.sf = Frs2.df;}});
- 0xC7: Trap::fqtos({{fault = new FpDisabled;}});
+ 0xC7: FpUnimpl::fqtos();
0xC8: fitod({{
Frd.df = static_cast<double>((int32_t)Frs2s.sf);
}});
0xC9: fstod({{Frd.df = Frs2s.sf;}});
- 0xCB: Trap::fqtod({{fault = new FpDisabled;}});
- 0xCC: Trap::fitoq({{fault = new FpDisabled;}});
- 0xCD: Trap::fstoq({{fault = new FpDisabled;}});
- 0xCE: Trap::fdtoq({{fault = new FpDisabled;}});
+ 0xCB: FpUnimpl::fqtod();
+ 0xCC: FpUnimpl::fitoq();
+ 0xCD: FpUnimpl::fstoq();
+ 0xCE: FpUnimpl::fdtoq();
0xD1: fstoi({{
Frds.sf = (float)static_cast<int32_t>(Frs2s.sf);
}});
0xD2: fdtoi({{
Frds.sf = (float)static_cast<int32_t>(Frs2.df);
}});
- 0xD3: Trap::fqtoi({{fault = new FpDisabled;}});
- default: Trap::fpop1({{fault = new FpDisabled;}});
+ 0xD3: FpUnimpl::fqtoi();
+ default: FailUnimpl::fpop1();
+ }
+ }
+ 0x35: decode OPF{
+ format BasicOperate{
+ 0x51: fcmps({{
+ uint8_t fcc;
+ if(isnan(Frs1s) || isnan(Frs2s))
+ fcc = 3;
+ else if(Frs1s < Frs2s)
+ fcc = 1;
+ else if(Frs1s > Frs2s)
+ fcc = 2;
+ else
+ fcc = 0;
+ uint8_t firstbit = 10;
+ if(FCMPCC)
+ firstbit = FCMPCC * 2 + 30;
+ Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
+ }});
+ 0x52: fcmpd({{
+ uint8_t fcc;
+ if(isnan(Frs1s) || isnan(Frs2s))
+ fcc = 3;
+ else if(Frs1s < Frs2s)
+ fcc = 1;
+ else if(Frs1s > Frs2s)
+ fcc = 2;
+ else
+ fcc = 0;
+ uint8_t firstbit = 10;
+ if(FCMPCC)
+ firstbit = FCMPCC * 2 + 30;
+ Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
+ }});
+ 0x53: FpUnimpl::fcmpq();
+ 0x55: fcmpes({{
+ uint8_t fcc = 0;
+ if(isnan(Frs1s) || isnan(Frs2s))
+ fault = new FpExceptionIEEE754;
+ if(Frs1s < Frs2s)
+ fcc = 1;
+ else if(Frs1s > Frs2s)
+ fcc = 2;
+ uint8_t firstbit = 10;
+ if(FCMPCC)
+ firstbit = FCMPCC * 2 + 30;
+ Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
+ }});
+ 0x56: fcmped({{
+ uint8_t fcc = 0;
+ if(isnan(Frs1s) || isnan(Frs2s))
+ fault = new FpExceptionIEEE754;
+ if(Frs1s < Frs2s)
+ fcc = 1;
+ else if(Frs1s > Frs2s)
+ fcc = 2;
+ uint8_t firstbit = 10;
+ if(FCMPCC)
+ firstbit = FCMPCC * 2 + 30;
+ Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
+ }});
+ 0x57: FpUnimpl::fcmpeq();
+ default: FailUnimpl::fpop2();
}
}
- 0x35: Trap::fpop2({{fault = new FpDisabled;}});
//This used to be just impdep1, but now it's a whole bunch
//of instructions
0x36: decode OPF{
- 0x00: Trap::edge8({{fault = new IllegalInstruction;}});
- 0x01: Trap::edge8n({{fault = new IllegalInstruction;}});
- 0x02: Trap::edge8l({{fault = new IllegalInstruction;}});
- 0x03: Trap::edge8ln({{fault = new IllegalInstruction;}});
- 0x04: Trap::edge16({{fault = new IllegalInstruction;}});
- 0x05: Trap::edge16n({{fault = new IllegalInstruction;}});
- 0x06: Trap::edge16l({{fault = new IllegalInstruction;}});
- 0x07: Trap::edge16ln({{fault = new IllegalInstruction;}});
- 0x08: Trap::edge32({{fault = new IllegalInstruction;}});
- 0x09: Trap::edge32n({{fault = new IllegalInstruction;}});
- 0x0A: Trap::edge32l({{fault = new IllegalInstruction;}});
- 0x0B: Trap::edge32ln({{fault = new IllegalInstruction;}});
- 0x10: Trap::array8({{fault = new IllegalInstruction;}});
- 0x12: Trap::array16({{fault = new IllegalInstruction;}});
- 0x14: Trap::array32({{fault = new IllegalInstruction;}});
+ 0x00: FailUnimpl::edge8();
+ 0x01: FailUnimpl::edge8n();
+ 0x02: FailUnimpl::edge8l();
+ 0x03: FailUnimpl::edge8ln();
+ 0x04: FailUnimpl::edge16();
+ 0x05: FailUnimpl::edge16n();
+ 0x06: FailUnimpl::edge16l();
+ 0x07: FailUnimpl::edge16ln();
+ 0x08: FailUnimpl::edge32();
+ 0x09: FailUnimpl::edge32n();
+ 0x0A: FailUnimpl::edge32l();
+ 0x0B: FailUnimpl::edge32ln();
+ 0x10: FailUnimpl::array8();
+ 0x12: FailUnimpl::array16();
+ 0x14: FailUnimpl::array32();
0x18: BasicOperate::alignaddr({{
uint64_t sum = Rs1 + Rs2;
Rd = sum & ~7;
Gsr = (Gsr & ~7) | (sum & 7);
}});
- 0x19: Trap::bmask({{fault = new IllegalInstruction;}});
+ 0x19: FailUnimpl::bmask();
0x1A: BasicOperate::alignaddresslittle({{
uint64_t sum = Rs1 + Rs2;
Rd = sum & ~7;
Gsr = (Gsr & ~7) | ((~sum + 1) & 7);
}});
- 0x20: Trap::fcmple16({{fault = new IllegalInstruction;}});
- 0x22: Trap::fcmpne16({{fault = new IllegalInstruction;}});
- 0x24: Trap::fcmple32({{fault = new IllegalInstruction;}});
- 0x26: Trap::fcmpne32({{fault = new IllegalInstruction;}});
- 0x28: Trap::fcmpgt16({{fault = new IllegalInstruction;}});
- 0x2A: Trap::fcmpeq16({{fault = new IllegalInstruction;}});
- 0x2C: Trap::fcmpgt32({{fault = new IllegalInstruction;}});
- 0x2E: Trap::fcmpeq32({{fault = new IllegalInstruction;}});
- 0x31: Trap::fmul8x16({{fault = new IllegalInstruction;}});
- 0x33: Trap::fmul8x16au({{fault = new IllegalInstruction;}});
- 0x35: Trap::fmul8x16al({{fault = new IllegalInstruction;}});
- 0x36: Trap::fmul8sux16({{fault = new IllegalInstruction;}});
- 0x37: Trap::fmul8ulx16({{fault = new IllegalInstruction;}});
- 0x38: Trap::fmuld8sux16({{fault = new IllegalInstruction;}});
- 0x39: Trap::fmuld8ulx16({{fault = new IllegalInstruction;}});
+ 0x20: FailUnimpl::fcmple16();
+ 0x22: FailUnimpl::fcmpne16();
+ 0x24: FailUnimpl::fcmple32();
+ 0x26: FailUnimpl::fcmpne32();
+ 0x28: FailUnimpl::fcmpgt16();
+ 0x2A: FailUnimpl::fcmpeq16();
+ 0x2C: FailUnimpl::fcmpgt32();
+ 0x2E: FailUnimpl::fcmpeq32();
+ 0x31: FailUnimpl::fmul8x16();
+ 0x33: FailUnimpl::fmul8x16au();
+ 0x35: FailUnimpl::fmul8x16al();
+ 0x36: FailUnimpl::fmul8sux16();
+ 0x37: FailUnimpl::fmul8ulx16();
+ 0x38: FailUnimpl::fmuld8sux16();
+ 0x39: FailUnimpl::fmuld8ulx16();
0x3A: Trap::fpack32({{fault = new IllegalInstruction;}});
0x3B: Trap::fpack16({{fault = new IllegalInstruction;}});
0x3D: Trap::fpackfix({{fault = new IllegalInstruction;}});
@@ -821,58 +950,58 @@ decode OP default Unknown::unknown()
}
}});
0x4B: Trap::fpmerge({{fault = new IllegalInstruction;}});
- 0x4C: Trap::bshuffle({{fault = new IllegalInstruction;}});
- 0x4D: Trap::fexpand({{fault = new IllegalInstruction;}});
- 0x50: Trap::fpadd16({{fault = new IllegalInstruction;}});
- 0x51: Trap::fpadd16s({{fault = new IllegalInstruction;}});
- 0x52: Trap::fpadd32({{fault = new IllegalInstruction;}});
- 0x53: Trap::fpadd32s({{fault = new IllegalInstruction;}});
- 0x54: Trap::fpsub16({{fault = new IllegalInstruction;}});
- 0x55: Trap::fpsub16s({{fault = new IllegalInstruction;}});
- 0x56: Trap::fpsub32({{fault = new IllegalInstruction;}});
- 0x57: Trap::fpsub32s({{fault = new IllegalInstruction;}});
+ 0x4C: FailUnimpl::bshuffle();
+ 0x4D: FailUnimpl::fexpand();
+ 0x50: FailUnimpl::fpadd16();
+ 0x51: FailUnimpl::fpadd16s();
+ 0x52: FailUnimpl::fpadd32();
+ 0x53: FailUnimpl::fpadd32s();
+ 0x54: FailUnimpl::fpsub16();
+ 0x55: FailUnimpl::fpsub16s();
+ 0x56: FailUnimpl::fpsub32();
+ 0x57: FailUnimpl::fpsub32s();
0x60: BasicOperate::fzero({{Frd.df = 0;}});
0x61: BasicOperate::fzeros({{Frds.sf = 0;}});
- 0x62: Trap::fnor({{fault = new IllegalInstruction;}});
- 0x63: Trap::fnors({{fault = new IllegalInstruction;}});
- 0x64: Trap::fandnot2({{fault = new IllegalInstruction;}});
- 0x65: Trap::fandnot2s({{fault = new IllegalInstruction;}});
+ 0x62: FailUnimpl::fnor();
+ 0x63: FailUnimpl::fnors();
+ 0x64: FailUnimpl::fandnot2();
+ 0x65: FailUnimpl::fandnot2s();
0x66: BasicOperate::fnot2({{
Frd.df = (double)(~((uint64_t)Frs2.df));
}});
0x67: BasicOperate::fnot2s({{
Frds.sf = (float)(~((uint32_t)Frs2s.sf));
}});
- 0x68: Trap::fandnot1({{fault = new IllegalInstruction;}});
- 0x69: Trap::fandnot1s({{fault = new IllegalInstruction;}});
+ 0x68: FailUnimpl::fandnot1();
+ 0x69: FailUnimpl::fandnot1s();
0x6A: BasicOperate::fnot1({{
Frd.df = (double)(~((uint64_t)Frs1.df));
}});
0x6B: BasicOperate::fnot1s({{
Frds.sf = (float)(~((uint32_t)Frs1s.sf));
}});
- 0x6C: Trap::fxor({{fault = new IllegalInstruction;}});
- 0x6D: Trap::fxors({{fault = new IllegalInstruction;}});
- 0x6E: Trap::fnand({{fault = new IllegalInstruction;}});
- 0x6F: Trap::fnands({{fault = new IllegalInstruction;}});
- 0x70: Trap::fand({{fault = new IllegalInstruction;}});
- 0x71: Trap::fands({{fault = new IllegalInstruction;}});
- 0x72: Trap::fxnor({{fault = new IllegalInstruction;}});
- 0x73: Trap::fxnors({{fault = new IllegalInstruction;}});
+ 0x6C: FailUnimpl::fxor();
+ 0x6D: FailUnimpl::fxors();
+ 0x6E: FailUnimpl::fnand();
+ 0x6F: FailUnimpl::fnands();
+ 0x70: FailUnimpl::fand();
+ 0x71: FailUnimpl::fands();
+ 0x72: FailUnimpl::fxnor();
+ 0x73: FailUnimpl::fxnors();
0x74: BasicOperate::fsrc1({{Frd.udw = Frs1.udw;}});
- 0x75: BasicOperate::fsrc1s({{Frd.uw = Frs1.uw;}});
- 0x76: Trap::fornot2({{fault = new IllegalInstruction;}});
- 0x77: Trap::fornot2s({{fault = new IllegalInstruction;}});
+ 0x75: BasicOperate::fsrc1s({{Frds.uw = Frs1s.uw;}});
+ 0x76: FailUnimpl::fornot2();
+ 0x77: FailUnimpl::fornot2s();
0x78: BasicOperate::fsrc2({{Frd.udw = Frs2.udw;}});
- 0x79: BasicOperate::fsrc2s({{Frd.uw = Frs2.uw;}});
- 0x7A: Trap::fornot1({{fault = new IllegalInstruction;}});
- 0x7B: Trap::fornot1s({{fault = new IllegalInstruction;}});
- 0x7C: Trap::for({{fault = new IllegalInstruction;}});
- 0x7D: Trap::fors({{fault = new IllegalInstruction;}});
- 0x7E: Trap::fone({{fault = new IllegalInstruction;}});
- 0x7F: Trap::fones({{fault = new IllegalInstruction;}});
+ 0x79: BasicOperate::fsrc2s({{Frds.uw = Frs2s.uw;}});
+ 0x7A: FailUnimpl::fornot1();
+ 0x7B: FailUnimpl::fornot1s();
+ 0x7C: FailUnimpl::for();
+ 0x7D: FailUnimpl::fors();
+ 0x7E: BasicOperate::fone({{Frd.udw = std::numeric_limits<uint64_t>::max();}});
+ 0x7F: BasicOperate::fones({{Frds.uw = std::numeric_limits<uint32_t>::max();}});
0x80: Trap::shutdown({{fault = new IllegalInstruction;}});
- 0x81: Trap::siam({{fault = new IllegalInstruction;}});
+ 0x81: FailUnimpl::siam();
}
0x37: Trap::impdep2({{fault = new IllegalInstruction;}});
0x38: Branch::jmpl({{
@@ -889,16 +1018,11 @@ decode OP default Unknown::unknown()
}
}});
0x39: Branch::return({{
- //If both MemAddressNotAligned and
- //a fill trap happen, it's not clear
- //which one should be returned.
Addr target = Rs1 + Rs2_or_imm13;
- if(target & 0x3)
- fault = new MemAddressNotAligned;
- else
- NNPC = target;
if(fault == NoFault)
{
+ //Check for fills which are higher priority than alignment
+ //faults.
if(Canrestore == 0)
{
if(Otherwin)
@@ -906,18 +1030,15 @@ decode OP default Unknown::unknown()
else
fault = new FillNNormal(4*Wstate<2:0>);
}
+ //Check for alignment faults
+ else if(target & 0x3)
+ fault = new MemAddressNotAligned;
else
{
- //CWP should be set directly so that it always happens
- //Also, this will allow writing to the new window and
- //reading from the old one
+ NNPC = target;
Cwp = (Cwp - 1 + NWindows) % NWindows;
Cansave = Cansave + 1;
Canrestore = Canrestore - 1;
- //This is here to make sure the CWP is written
- //no matter what. This ensures that the results
- //are written in the new window as well.
- xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
}
}
}});
@@ -935,7 +1056,7 @@ decode OP default Unknown::unknown()
xc->syscall(R1);
#endif
}
- }});
+ }}, IsSerializeAfter, IsNonSpeculative);
0x2: Trap::tccx({{
if(passesCondition(Ccr<7:4>, COND2))
{
@@ -948,36 +1069,27 @@ decode OP default Unknown::unknown()
xc->syscall(R1);
#endif
}
- }});
+ }}, IsSerializeAfter, IsNonSpeculative);
}
0x3B: Nop::flush({{/*Instruction memory flush*/}});
0x3C: save({{
- //CWP should be set directly so that it always happens
- //Also, this will allow writing to the new window and
- //reading from the old one
if(Cansave == 0)
{
if(Otherwin)
fault = new SpillNOther(4*Wstate<5:3>);
else
fault = new SpillNNormal(4*Wstate<2:0>);
- //Cwp = (Cwp + 2) % NWindows;
}
else if(Cleanwin - Canrestore == 0)
{
- //Cwp = (Cwp + 1) % NWindows;
fault = new CleanWindow;
}
else
{
Cwp = (Cwp + 1) % NWindows;
- Rd = Rs1 + Rs2_or_imm13;
+ Rd_next = Rs1 + Rs2_or_imm13;
Cansave = Cansave - 1;
Canrestore = Canrestore + 1;
- //This is here to make sure the CWP is written
- //no matter what. This ensures that the results
- //are written in the new window as well.
- xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
}
}});
0x3D: restore({{
@@ -990,17 +1102,10 @@ decode OP default Unknown::unknown()
}
else
{
- //CWP should be set directly so that it always happens
- //Also, this will allow writing to the new window and
- //reading from the old one
Cwp = (Cwp - 1 + NWindows) % NWindows;
- Rd = Rs1 + Rs2_or_imm13;
+ Rd_prev = Rs1 + Rs2_or_imm13;
Cansave = Cansave + 1;
Canrestore = Canrestore - 1;
- //This is here to make sure the CWP is written
- //no matter what. This ensures that the results
- //are written in the new window as well.
- xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
}
}});
0x3E: decode FCN {
@@ -1130,14 +1235,14 @@ decode OP default Unknown::unknown()
{{ Mem.uw = Rd.uw;
Rd.uw = uReg0;}}, {{EXT_ASI}});
format Trap {
- 0x20: Load::ldf({{Frd.uw = Mem.uw;}});
+ 0x20: Load::ldf({{Frds.uw = Mem.uw;}});
0x21: decode X {
0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}});
0x1: Load::ldxfsr({{Fsr = Mem.udw;}});
}
0x22: ldqf({{fault = new FpDisabled;}});
0x23: Load::lddf({{Frd.udw = Mem.udw;}});
- 0x24: Store::stf({{Mem.uw = Frd.uw;}});
+ 0x24: Store::stf({{Mem.uw = Frds.uw;}});
0x25: decode X {
0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;}});
0x1: Store::stxfsr({{Mem.udw = Fsr;}});
@@ -1145,7 +1250,7 @@ decode OP default Unknown::unknown()
0x26: stqf({{fault = new FpDisabled;}});
0x27: Store::stdf({{Mem.udw = Frd.udw;}});
0x2D: Nop::prefetch({{ }});
- 0x30: LoadAlt::ldfa({{Frd.uw = Mem.uw;}}, {{EXT_ASI}});
+ 0x30: LoadAlt::ldfa({{Frds.uw = Mem.uw;}}, {{EXT_ASI}});
0x32: ldqfa({{fault = new FpDisabled;}});
format LoadAlt {
0x33: decode EXT_ASI {
@@ -1228,7 +1333,7 @@ decode OP default Unknown::unknown()
{{fault = new DataAccessException;}});
}
}
- 0x34: Store::stfa({{Mem.uw = Frd.uw;}});
+ 0x34: Store::stfa({{Mem.uw = Frds.uw;}});
0x36: stqfa({{fault = new FpDisabled;}});
format StoreAlt {
0x37: decode EXT_ASI {
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index a4c05387b..e8762a205 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@ def template BasicExecPanic {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
panic("Execute method called when it shouldn't!");
+ M5_DUMMY_RETURN
}
}};
@@ -71,6 +72,7 @@ def template BasicExecute {{
{
Fault fault = NoFault;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
@@ -95,8 +97,7 @@ def template BasicDecodeWithMnemonic {{
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
- iop = InstObjParams(name, Name, 'SparcStaticInst',
- CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index 5fb7ade2d..5cd3ab598 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -170,7 +170,7 @@ output decoder {{
printMnemonic(response, mnemonic);
ccprintf(response, "0x%x", target);
- if(symtab->findNearestSymbol(target, symbol, symbolAddr))
+ if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr))
{
ccprintf(response, " <%s", symbol);
if(symbolAddr != target)
@@ -211,13 +211,13 @@ let {{
{
if(A)
{
- NPC = xc->readNextNPC();
- NNPC = NPC + 4;
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
}
else
{
- NPC = xc->readNextPC();
- NNPC = xc->readNextNPC();
+ NPC = NPC;
+ NNPC = NNPC;
}
}'''
}};
@@ -244,7 +244,6 @@ def format Branch(code, *opt_flags) {{
// Primary format for branch instructions:
def format BranchN(bits, code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
new_opt_flags = []
for flag in opt_flags:
if flag == ',a':
@@ -252,7 +251,7 @@ def format BranchN(bits, code, *opt_flags) {{
Name += 'Annul'
else:
new_opt_flags += flag
- iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags)
+ iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)
@@ -262,8 +261,7 @@ def format BranchN(bits, code, *opt_flags) {{
// Primary format for branch instructions:
def format BranchSplit(code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags)
+ iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)
diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa
index 4f8ebebcc..f877b8790 100644
--- a/src/arch/sparc/isa/formats/integerop.isa
+++ b/src/arch/sparc/isa/formats/integerop.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -154,7 +154,7 @@ output decoder {{
bool IntOp::printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symbab) const
{
- if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
+ if(!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
{
printMnemonic(os, "mov");
printSrcReg(os, 1);
@@ -168,7 +168,7 @@ output decoder {{
bool IntOpImm::printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symbab) const
{
- if(!strcmp(mnemonic, "or"))
+ if(!std::strcmp(mnemonic, "or"))
{
if(_numSrcRegs > 0 && _srcRegIdx[0] == 0)
{
@@ -263,14 +263,15 @@ let {{
def doIntFormat(code, ccCode, name, Name, opt_flags):
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
- iop = InstObjParams(name, Name, 'IntOp', code,
- opt_flags, {"cc_code": ccCode})
+ iop = InstObjParams(name, Name, 'IntOp',
+ {"code": code, "cc_code": ccCode},
+ opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
- immCode, opt_flags, {"cc_code": ccCode})
+ {"code": immCode, "cc_code": ccCode}, opt_flags)
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += IntOpExecute.subst(imm_iop)
@@ -341,7 +342,7 @@ def format IntOpCcRes(code, *opt_flags) {{
def format SetHi(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SetHi',
- code, opt_flags, {"cc_code": ''})
+ {"code": code, "cc_code": ''}, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa
index 55e9fba45..1d9075a57 100644
--- a/src/arch/sparc/isa/formats/mem/basicmem.isa
+++ b/src/arch/sparc/isa/formats/mem/basicmem.isa
@@ -55,16 +55,20 @@ let {{
def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags):
addrCalcReg = 'EA = Rs1 + Rs2;'
addrCalcImm = 'EA = Rs1 + imm;'
- iop = InstObjParams(name, Name, 'Mem', code,
- opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg})
- iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code,
- opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm})
+ iop = InstObjParams(name, Name, 'Mem',
+ {"code": code, "fault_check": faultCode,
+ "ea_code": addrCalcReg},
+ opt_flags)
+ iop_imm = InstObjParams(name, Name + "Imm", 'MemImm',
+ {"code": code, "fault_check": faultCode,
+ "ea_code": addrCalcImm},
+ opt_flags)
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
decode_block = ROrImmDecode.subst(iop)
exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm,
- execute, faultCode, name, name + "Imm", Name, Name + "Imm",
- asi, opt_flags)
+ execute, faultCode, name, name + "Imm",
+ Name, Name + "Imm", asi, opt_flags)
return (header_output, decoder_output, exec_output, decode_block)
}};
@@ -72,7 +76,7 @@ def format LoadAlt(code, asi, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code, LoadExecute,
+ decode_block) = doMemFormat(code, LoadFuncs,
AlternateASIPrivFaultCheck, name, Name, asi, opt_flags)
}};
@@ -80,7 +84,7 @@ def format StoreAlt(code, asi, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code, StoreExecute,
+ decode_block) = doMemFormat(code, StoreFuncs,
AlternateASIPrivFaultCheck, name, Name, asi, opt_flags)
}};
@@ -89,7 +93,7 @@ def format Load(code, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
- LoadExecute, '', name, Name, 0, opt_flags)
+ LoadFuncs, '', name, Name, 0, opt_flags)
}};
def format Store(code, *opt_flags) {{
@@ -97,5 +101,5 @@ def format Store(code, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
- StoreExecute, '', name, Name, 0, opt_flags)
+ StoreFuncs, '', name, Name, 0, opt_flags)
}};
diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
index c36fede2e..9795d2342 100644
--- a/src/arch/sparc/isa/formats/mem/blockmem.isa
+++ b/src/arch/sparc/isa/formats/mem/blockmem.isa
@@ -456,14 +456,14 @@ let {{
else:
flag_code = "flags[IsDelayedCommit] = true;"
pcedCode = matcher.sub("Frd_%d" % microPc, code)
- iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
- opt_flags, {"ea_code": addrCalcReg,
+ iop = InstObjParams(name, Name, 'BlockMem',
+ {"code": pcedCode, "ea_code": addrCalcReg,
"fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code})
- iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
- opt_flags, {"ea_code": addrCalcImm,
+ "set_flags": flag_code}, opt_flags)
+ iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
+ {"code": pcedCode, "ea_code": addrCalcImm,
"fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code})
+ "set_flags": flag_code}, opt_flags)
decoder_output += BlockMemMicroConstructor.subst(iop)
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
exec_output += doDualSplitExecute(
@@ -496,18 +496,18 @@ let {{
else:
flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;"
pcedCode = matcher.sub("uReg0", code)
- iop = InstObjParams(name, Name, 'TwinMem', pcedCode,
- opt_flags, {"ea_code": addrCalcReg,
+ iop = InstObjParams(name, Name, 'TwinMem',
+ {"code": pcedCode, "ea_code": addrCalcReg,
"fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code})
- iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', pcedCode,
- opt_flags, {"ea_code": addrCalcImm,
+ "set_flags": flag_code}, opt_flags)
+ iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm',
+ {"code": pcedCode, "ea_code": addrCalcImm,
"fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code})
+ "set_flags": flag_code}, opt_flags)
decoder_output += BlockMemMicroConstructor.subst(iop)
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
exec_output += doDualSplitExecute(
- pcedCode, addrCalcReg, addrCalcImm, LoadExecute, faultCode,
+ pcedCode, addrCalcReg, addrCalcImm, LoadFuncs, faultCode,
makeMicroName(name, microPc),
makeMicroName(name + "Imm", microPc),
makeMicroName(Name, microPc),
@@ -527,7 +527,7 @@ def format BlockLoad(code, asi, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
- LoadExecute, name, Name, asi, opt_flags)
+ LoadFuncs, name, Name, asi, opt_flags)
}};
def format BlockStore(code, asi, *opt_flags) {{
@@ -539,7 +539,7 @@ def format BlockStore(code, asi, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
- StoreExecute, name, Name, asi, opt_flags)
+ StoreFuncs, name, Name, asi, opt_flags)
}};
def format TwinLoad(code, asi, *opt_flags) {{
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
index b6e0945b7..dbaabdca4 100644
--- a/src/arch/sparc/isa/formats/mem/util.isa
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -141,10 +141,11 @@ def template LoadExecute {{
{
Fault fault = NoFault;
Addr EA;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if(fault == NoFault)
{
@@ -162,16 +163,19 @@ def template LoadExecute {{
return fault;
}
+}};
+def template LoadInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
Addr EA;
- uint%(mem_acc_size)s_t Mem;
- %(ea_decl)s;
- %(ea_rd)s;
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
%(ea_code)s;
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if(fault == NoFault)
{
@@ -179,18 +183,20 @@ def template LoadExecute {{
}
return fault;
}
+}};
+def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
- %(code_decl)s;
- %(code_rd)s;
+ %(op_decl)s;
+ %(op_rd)s;
Mem = pkt->get<typeof(Mem)>();
%(code)s;
if(fault == NoFault)
{
- %(code_wb)s;
+ %(op_wb)s;
}
return fault;
}
@@ -206,10 +212,11 @@ def template StoreExecute {{
//It should be optomized out in all the others
bool storeCond = true;
Addr EA;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if(fault == NoFault)
{
@@ -228,17 +235,20 @@ def template StoreExecute {{
return fault;
}
+}};
+def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
bool storeCond = true;
Addr EA;
+ %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if(fault == NoFault)
{
@@ -256,7 +266,9 @@ def template StoreExecute {{
}
return fault;
}
+}};
+def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
@@ -276,6 +288,8 @@ def template CompleteAccDeclare {{
//Here are some code snippets which check for various fault conditions
let {{
+ LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
+ StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
# The LSB can be zero, since it's really the MSB in doubles and quads
# and we're dealing with doubles
BlockAlignmentFaultCheck = '''
@@ -316,21 +330,11 @@ let {{
//and in the other they're distributed across two. Also note that for
//execute functions, the name of the base class doesn't matter.
let {{
- def doSplitExecute(code, execute, name, Name, asi, opt_flags, microParam):
+ def doSplitExecute(execute, name, Name, asi, opt_flags, microParam):
microParam["asi_val"] = asi;
- codeParam = microParam.copy()
- codeParam["ea_code"] = ''
- codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam)
- eaIop = InstObjParams(name, Name, '', microParam["ea_code"],
- opt_flags, microParam)
- iop = InstObjParams(name, Name, '', code, opt_flags, microParam)
- (iop.ea_decl,
- iop.ea_rd,
- iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
- (iop.code_decl,
- iop.code_rd,
- iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
- return execute.subst(iop)
+ iop = InstObjParams(name, Name, '', microParam, opt_flags)
+ (execf, initf, compf) = execute
+ return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
def doDualSplitExecute(code, eaRegCode, eaImmCode, execute,
@@ -339,8 +343,9 @@ let {{
for (eaCode, name, Name) in (
(eaRegCode, nameReg, NameReg),
(eaImmCode, nameImm, NameImm)):
- microParams = {"ea_code" : eaCode, "fault_check": faultCode}
- executeCode += doSplitExecute(code, execute, name, Name,
+ microParams = {"code": code, "ea_code": eaCode,
+ "fault_check": faultCode}
+ executeCode += doSplitExecute(execute, name, Name,
asi, opt_flags, microParams)
return executeCode
}};
diff --git a/src/arch/sparc/isa/formats/nop.isa b/src/arch/sparc/isa/formats/nop.isa
index 37ef2e8d0..de2ba2f54 100644
--- a/src/arch/sparc/isa/formats/nop.isa
+++ b/src/arch/sparc/isa/formats/nop.isa
@@ -88,9 +88,7 @@ def template NopExecute {{
// Primary format for integer operate instructions:
def format Nop(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Nop', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'Nop', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index 3d47ca02f..36403afb4 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -235,8 +235,9 @@ let {{
name = mnem
regBase = 'WrPriv'
break
- iop = InstObjParams(name, Name, regBase, code,
- opt_flags, {"check": checkCode, "reg_name": regName})
+ iop = InstObjParams(name, Name, regBase,
+ {"code": code, "check": checkCode, "reg_name": regName},
+ opt_flags)
header_output = BasicDeclare.subst(iop)
if regName == '':
decoder_output = BasicConstructor.subst(iop)
@@ -245,7 +246,8 @@ let {{
exec_output = PrivExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
- immCode, opt_flags, {"check": checkCode, "reg_name": regName})
+ {"code": immCode, "check": checkCode, "reg_name": regName},
+ opt_flags)
header_output += BasicDeclare.subst(imm_iop)
if regName == '':
decoder_output += BasicConstructor.subst(imm_iop)
diff --git a/src/arch/sparc/isa/formats/trap.isa b/src/arch/sparc/isa/formats/trap.isa
index 04d467cfe..66eff35d4 100644
--- a/src/arch/sparc/isa/formats/trap.isa
+++ b/src/arch/sparc/isa/formats/trap.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -82,12 +82,53 @@ def template TrapExecute {{
}
}};
+def template FpUnimplExecute {{
+ 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
+ %(op_wb)s;
+ return fault;
+ }
+}};
+
def format Trap(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Trap', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'Trap', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = TrapExecute.subst(iop)
}};
+
+output header {{
+ class FpUnimpl : public SparcStaticInst
+ {
+ protected:
+ FpUnimpl(const char *mnem,
+ ExtMachInst _machInst, OpClass __opClass)
+ : SparcStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return mnemonic;
+ }
+ };
+}};
+
+def format FpUnimpl(*flags) {{
+ fpunimpl_code = '''
+ Fsr = insertBits(Fsr, 16, 14, 3);
+ fault = new FpExceptionOther;
+ '''
+ iop = InstObjParams(name, Name, 'FpUnimpl', fpunimpl_code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = FpUnimplExecute.subst(iop)
+}};
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 0c112d481..a6dca9bf1 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -34,15 +34,17 @@
//
output header {{
+#include <cstring>
#include <sstream>
#include <iostream>
-#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
-#include "mem/request.hh" // some constructors use MemReq flags
-#include "mem/packet.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/regfile.hh"
+#include "base/misc.hh"
+#include "cpu/static_inst.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh" // some constructors use MemReq flags
}};
output decoder {{
@@ -65,6 +67,7 @@ output exec {{
#endif
#include <limits>
+#include <cmath>
#include "arch/sparc/asi.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
@@ -73,5 +76,6 @@ output exec {{
#include "mem/packet_access.hh"
using namespace SparcISA;
+using namespace std;
}};
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index abb82f88c..140055010 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -1,4 +1,4 @@
-// Copyright (c) 2006 The Regents of The University of Michigan
+// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -56,15 +56,26 @@ def operands {{
# Int regs default to unsigned, but code should not count on this.
# For clarity, descriptions that depend on unsigned behavior should
# explicitly specify '.uq'.
+
'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1),
+ # The Rd from the previous window
+ 'Rd_prev': ('IntReg', 'udw', 'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2),
+ # The Rd from the next window
+ 'Rd_next': ('IntReg', 'udw', 'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3),
# For microcoded twin load instructions, RdTwin appears in the "code"
- # for the instruction and is replaced by RdLow or RdHigh by the format
+ # for the instruction is replaced by RdLow or RdHigh by the format
# before it's processed by the iop.
- 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 2),
- 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3),
- 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4),
- 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5),
- 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 6),
+ # The low (even) register of a two register pair
+ 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 4),
+ # The high (odd) register of a two register pair
+ 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 5),
+ 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 6),
+ 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 7),
+ # A microcode register. Right now, this is the only one.
+ 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8),
+ # Because double and quad precision register numbers are decoded
+ # differently, they get different operands. The single precision versions
+ # have an s post pended to their name.
'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10),
'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
# Each Frd_N refers to the Nth double precision register from Frd.
@@ -77,20 +88,23 @@ def operands {{
'Frd_5': ('FloatReg', 'df', 'dfpr(RD) + 10', 'IsFloating', 10),
'Frd_6': ('FloatReg', 'df', 'dfpr(RD) + 12', 'IsFloating', 10),
'Frd_7': ('FloatReg', 'df', 'dfpr(RD) + 14', 'IsFloating', 10),
- 'Frs1s': ('FloatReg', 'df', 'RS1', 'IsFloating', 11),
+ 'Frs1s': ('FloatReg', 'sf', 'RS1', 'IsFloating', 11),
'Frs1': ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11),
- 'Frs2s': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
+ 'Frs2s': ('FloatReg', 'sf', 'RS2', 'IsFloating', 12),
'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
+ # Registers which are used explicitly in instructions
'R0': ('IntReg', 'udw', '0', None, 6),
'R1': ('IntReg', 'udw', '1', None, 7),
'R15': ('IntReg', 'udw', '15', 'IsInteger', 8),
'R16': ('IntReg', 'udw', '16', None, 9),
# Control registers
- 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
- 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
+# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
+# 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
+ 'Y': ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40),
+ 'Ccr': ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41),
'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42),
'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43),
'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44),
@@ -112,12 +126,17 @@ def operands {{
'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59),
'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60),
'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61),
- 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62),
- 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63),
- 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64),
- 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65),
- 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66),
- 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67),
+ 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 62),
+# 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63),
+# 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64),
+# 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65),
+# 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66),
+# 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67),
+ 'Cansave': ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63),
+ 'Canrestore': ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64),
+ 'Cleanwin': ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65),
+ 'Otherwin': ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66),
+ 'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67),
'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68),
'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69),
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 8aa8ea7f3..64ae6abd8 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -58,8 +58,8 @@ namespace SparcISA
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
- FP_Base_DepTag = 33,
- Ctrl_Base_DepTag = 97,
+ FP_Base_DepTag = 32*3+8,
+ Ctrl_Base_DepTag = FP_Base_DepTag + 64
};
// semantically meaningful register indices
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index d9fcb0280..0fe3e96b2 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -46,15 +46,16 @@ class Checkpoint;
string SparcISA::getMiscRegName(RegIndex index)
{
static::string miscRegName[NumMiscRegs] =
- {"y", "ccr", "asi", "tick", "fprs", "pcr", "pic",
- "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
- "stick", "stick_cmpr",
- "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
- "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
- "wstate", "gl",
- "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
- "hstick_cmpr",
- "fsr"};
+ {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
+ "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
+ "stick", "stick_cmpr",
+ "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
+ "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
+ "wstate",*/ "gl",
+ "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
+ "hstick_cmpr",
+ "fsr"};
+
return miscRegName[index];
}
@@ -65,8 +66,8 @@ enum RegMask
void MiscRegFile::clear()
{
- y = 0;
- ccr = 0;
+ //y = 0;
+ //ccr = 0;
asi = 0;
tick = ULL(1) << 63;
fprs = 0;
@@ -83,11 +84,11 @@ void MiscRegFile::clear()
tl = 0;
pil = 0;
cwp = 0;
- cansave = 0;
- canrestore = 0;
- cleanwin = 0;
- otherwin = 0;
- wstate = 0;
+ //cansave = 0;
+ //canrestore = 0;
+ //cleanwin = 0;
+ //otherwin = 0;
+ //wstate = 0;
gl = 0;
//In a T1, bit 11 is apparently always 1
hpstate = (1 << 11);
@@ -124,6 +125,11 @@ void MiscRegFile::clear()
dTlbTagAccess = 0;
memset(scratchPad, 0, sizeof(scratchPad));
+#if FULL_SYSTEM
+ tickCompare = NULL;
+ sTickCompare = NULL;
+ hSTickCompare = NULL;
+#endif
}
MiscReg MiscRegFile::readReg(int miscReg)
@@ -149,10 +155,10 @@ MiscReg MiscRegFile::readReg(int miscReg)
(uint64_t)priContext << 32 |
(uint64_t)secContext << 48;
- case MISCREG_Y:
- return y;
- case MISCREG_CCR:
- return ccr;
+ //case MISCREG_Y:
+ // return y;
+ //case MISCREG_CCR:
+ // return ccr;
case MISCREG_ASI:
return asi;
case MISCREG_FPRS:
@@ -195,16 +201,16 @@ MiscReg MiscRegFile::readReg(int miscReg)
return pil;
case MISCREG_CWP:
return cwp;
- case MISCREG_CANSAVE:
- return cansave;
- case MISCREG_CANRESTORE:
- return canrestore;
- case MISCREG_CLEANWIN:
- return cleanwin;
- case MISCREG_OTHERWIN:
- return otherwin;
- case MISCREG_WSTATE:
- return wstate;
+ //case MISCREG_CANSAVE:
+ // return cansave;
+ //case MISCREG_CANRESTORE:
+ // return canrestore;
+ //case MISCREG_CLEANWIN:
+ // return cleanwin;
+ //case MISCREG_OTHERWIN:
+ // return otherwin;
+ //case MISCREG_WSTATE:
+ // return wstate;
case MISCREG_GL:
return gl;
@@ -375,12 +381,12 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
void MiscRegFile::setReg(int miscReg, const MiscReg &val)
{
switch (miscReg) {
- case MISCREG_Y:
- y = val;
- break;
- case MISCREG_CCR:
- ccr = val;
- break;
+// case MISCREG_Y:
+// y = val;
+// break;
+// case MISCREG_CCR:
+// ccr = val;
+// break;
case MISCREG_ASI:
asi = val;
break;
@@ -441,21 +447,21 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
case MISCREG_CWP:
cwp = val;
break;
- case MISCREG_CANSAVE:
- cansave = val;
- break;
- case MISCREG_CANRESTORE:
- canrestore = val;
- break;
- case MISCREG_CLEANWIN:
- cleanwin = val;
- break;
- case MISCREG_OTHERWIN:
- otherwin = val;
- break;
- case MISCREG_WSTATE:
- wstate = val;
- break;
+// case MISCREG_CANSAVE:
+// cansave = val;
+// break;
+// case MISCREG_CANRESTORE:
+// canrestore = val;
+// break;
+// case MISCREG_CLEANWIN:
+// cleanwin = val;
+// break;
+// case MISCREG_OTHERWIN:
+// otherwin = val;
+// break;
+// case MISCREG_WSTATE:
+// wstate = val;
+// break;
case MISCREG_GL:
gl = val;
break;
@@ -674,32 +680,31 @@ void MiscRegFile::setRegWithEffect(int miscReg,
void MiscRegFile::serialize(std::ostream & os)
{
- SERIALIZE_SCALAR(pstate);
- SERIALIZE_SCALAR(tba);
- SERIALIZE_SCALAR(y);
- SERIALIZE_SCALAR(pil);
- SERIALIZE_SCALAR(gl);
- SERIALIZE_SCALAR(cwp);
- SERIALIZE_ARRAY(tt, MaxTL);
- SERIALIZE_SCALAR(ccr);
SERIALIZE_SCALAR(asi);
- SERIALIZE_SCALAR(tl);
- SERIALIZE_ARRAY(tpc, MaxTL);
- SERIALIZE_ARRAY(tnpc, MaxTL);
- SERIALIZE_ARRAY(tstate, MaxTL);
SERIALIZE_SCALAR(tick);
- SERIALIZE_SCALAR(cansave);
- SERIALIZE_SCALAR(canrestore);
- SERIALIZE_SCALAR(otherwin);
- SERIALIZE_SCALAR(cleanwin);
- SERIALIZE_SCALAR(wstate);
- SERIALIZE_SCALAR(fsr);
SERIALIZE_SCALAR(fprs);
+ SERIALIZE_SCALAR(gsr);
+ SERIALIZE_SCALAR(softint);
+ SERIALIZE_SCALAR(tick_cmpr);
+ SERIALIZE_SCALAR(stick);
+ SERIALIZE_SCALAR(stick_cmpr);
+ SERIALIZE_ARRAY(tpc,MaxTL);
+ SERIALIZE_ARRAY(tnpc,MaxTL);
+ SERIALIZE_ARRAY(tstate,MaxTL);
+ SERIALIZE_ARRAY(tt,MaxTL);
+ SERIALIZE_SCALAR(tba);
+ SERIALIZE_SCALAR(pstate);
+ SERIALIZE_SCALAR(tl);
+ SERIALIZE_SCALAR(pil);
+ SERIALIZE_SCALAR(cwp);
+ SERIALIZE_SCALAR(gl);
SERIALIZE_SCALAR(hpstate);
- SERIALIZE_ARRAY(htstate, MaxTL);
+ SERIALIZE_ARRAY(htstate,MaxTL);
+ SERIALIZE_SCALAR(hintp);
SERIALIZE_SCALAR(htba);
SERIALIZE_SCALAR(hstick_cmpr);
SERIALIZE_SCALAR(strandStatusReg);
+ SERIALIZE_SCALAR(fsr);
SERIALIZE_SCALAR(priContext);
SERIALIZE_SCALAR(secContext);
SERIALIZE_SCALAR(partId);
@@ -717,6 +722,7 @@ void MiscRegFile::serialize(std::ostream & os)
SERIALIZE_SCALAR(dTlbC0Config);
SERIALIZE_SCALAR(dTlbCXTsbPs0);
SERIALIZE_SCALAR(dTlbCXTsbPs1);
+ SERIALIZE_SCALAR(dTlbCXConfig);
SERIALIZE_SCALAR(dTlbSfsr);
SERIALIZE_SCALAR(dTlbSfar);
SERIALIZE_SCALAR(dTlbTagAccess);
@@ -729,36 +735,70 @@ void MiscRegFile::serialize(std::ostream & os)
SERIALIZE_SCALAR(res_error_tail);
SERIALIZE_SCALAR(nres_error_head);
SERIALIZE_SCALAR(nres_error_tail);
+#if FULL_SYSTEM
+ Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
+ ThreadContext *tc = NULL;
+ BaseCPU *cpu = NULL;
+ int tc_num = 0;
+ bool tick_intr_sched = true;
+
+ if (tickCompare)
+ tc = tickCompare->getTC();
+ else if (sTickCompare)
+ tc = sTickCompare->getTC();
+ else if (hSTickCompare)
+ tc = hSTickCompare->getTC();
+ else
+ tick_intr_sched = false;
+
+ SERIALIZE_SCALAR(tick_intr_sched);
+
+ if (tc) {
+ cpu = tc->getCpuPtr();
+ tc_num = cpu->findContext(tc);
+ if (tickCompare && tickCompare->scheduled())
+ tick_cmp = tickCompare->when();
+ if (sTickCompare && sTickCompare->scheduled())
+ stick_cmp = sTickCompare->when();
+ if (hSTickCompare && hSTickCompare->scheduled())
+ hstick_cmp = hSTickCompare->when();
+
+ SERIALIZE_OBJPTR(cpu);
+ SERIALIZE_SCALAR(tc_num);
+ SERIALIZE_SCALAR(tick_cmp);
+ SERIALIZE_SCALAR(stick_cmp);
+ SERIALIZE_SCALAR(hstick_cmp);
+ }
+#endif
}
void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
{
- UNSERIALIZE_SCALAR(pstate);
- UNSERIALIZE_SCALAR(tba);
- UNSERIALIZE_SCALAR(y);
- UNSERIALIZE_SCALAR(pil);
- UNSERIALIZE_SCALAR(gl);
- UNSERIALIZE_SCALAR(cwp);
- UNSERIALIZE_ARRAY(tt, MaxTL);
- UNSERIALIZE_SCALAR(ccr);
UNSERIALIZE_SCALAR(asi);
- UNSERIALIZE_SCALAR(tl);
- UNSERIALIZE_ARRAY(tpc, MaxTL);
- UNSERIALIZE_ARRAY(tnpc, MaxTL);
- UNSERIALIZE_ARRAY(tstate, MaxTL);
UNSERIALIZE_SCALAR(tick);
- UNSERIALIZE_SCALAR(cansave);
- UNSERIALIZE_SCALAR(canrestore);
- UNSERIALIZE_SCALAR(otherwin);
- UNSERIALIZE_SCALAR(cleanwin);
- UNSERIALIZE_SCALAR(wstate);
- UNSERIALIZE_SCALAR(fsr);
UNSERIALIZE_SCALAR(fprs);
+ UNSERIALIZE_SCALAR(gsr);
+ UNSERIALIZE_SCALAR(softint);
+ UNSERIALIZE_SCALAR(tick_cmpr);
+ UNSERIALIZE_SCALAR(stick);
+ UNSERIALIZE_SCALAR(stick_cmpr);
+ UNSERIALIZE_ARRAY(tpc,MaxTL);
+ UNSERIALIZE_ARRAY(tnpc,MaxTL);
+ UNSERIALIZE_ARRAY(tstate,MaxTL);
+ UNSERIALIZE_ARRAY(tt,MaxTL);
+ UNSERIALIZE_SCALAR(tba);
+ UNSERIALIZE_SCALAR(pstate);
+ UNSERIALIZE_SCALAR(tl);
+ UNSERIALIZE_SCALAR(pil);
+ UNSERIALIZE_SCALAR(cwp);
+ UNSERIALIZE_SCALAR(gl);
UNSERIALIZE_SCALAR(hpstate);
- UNSERIALIZE_ARRAY(htstate, MaxTL);
+ UNSERIALIZE_ARRAY(htstate,MaxTL);
+ UNSERIALIZE_SCALAR(hintp);
UNSERIALIZE_SCALAR(htba);
UNSERIALIZE_SCALAR(hstick_cmpr);
UNSERIALIZE_SCALAR(strandStatusReg);
+ UNSERIALIZE_SCALAR(fsr);
UNSERIALIZE_SCALAR(priContext);
UNSERIALIZE_SCALAR(secContext);
UNSERIALIZE_SCALAR(partId);
@@ -776,6 +816,7 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
UNSERIALIZE_SCALAR(dTlbC0Config);
UNSERIALIZE_SCALAR(dTlbCXTsbPs0);
UNSERIALIZE_SCALAR(dTlbCXTsbPs1);
+ UNSERIALIZE_SCALAR(dTlbCXConfig);
UNSERIALIZE_SCALAR(dTlbSfsr);
UNSERIALIZE_SCALAR(dTlbSfar);
UNSERIALIZE_SCALAR(dTlbTagAccess);
@@ -787,4 +828,38 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
UNSERIALIZE_SCALAR(res_error_head);
UNSERIALIZE_SCALAR(res_error_tail);
UNSERIALIZE_SCALAR(nres_error_head);
- UNSERIALIZE_SCALAR(nres_error_tail);}
+ UNSERIALIZE_SCALAR(nres_error_tail);
+
+#if FULL_SYSTEM
+ Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
+ ThreadContext *tc = NULL;
+ BaseCPU *cpu = NULL;
+ int tc_num;
+ bool tick_intr_sched;
+ UNSERIALIZE_SCALAR(tick_intr_sched);
+ if (tick_intr_sched) {
+ UNSERIALIZE_OBJPTR(cpu);
+ if (cpu) {
+ UNSERIALIZE_SCALAR(tc_num);
+ UNSERIALIZE_SCALAR(tick_cmp);
+ UNSERIALIZE_SCALAR(stick_cmp);
+ UNSERIALIZE_SCALAR(hstick_cmp);
+ tc = cpu->getContext(tc_num);
+
+ if (tick_cmp) {
+ tickCompare = new TickCompareEvent(this, tc);
+ tickCompare->schedule(tick_cmp);
+ }
+ if (stick_cmp) {
+ sTickCompare = new STickCompareEvent(this, tc);
+ sTickCompare->schedule(stick_cmp);
+ }
+ if (hstick_cmp) {
+ hSTickCompare = new HSTickCompareEvent(this, tc);
+ hSTickCompare->schedule(hstick_cmp);
+ }
+ }
+ }
+
+ #endif
+}
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index 8a2e8e810..66c9f17df 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -47,8 +47,8 @@ namespace SparcISA
enum MiscRegIndex
{
/** Ancillary State Registers */
- MISCREG_Y, /* 0 */
- MISCREG_CCR,
+// MISCREG_Y,
+// MISCREG_CCR,
MISCREG_ASI,
MISCREG_TICK,
MISCREG_FPRS,
@@ -73,11 +73,11 @@ namespace SparcISA
MISCREG_TL,
MISCREG_PIL,
MISCREG_CWP,
- MISCREG_CANSAVE,
- MISCREG_CANRESTORE,
- MISCREG_CLEANWIN,
- MISCREG_OTHERWIN,
- MISCREG_WSTATE,
+// MISCREG_CANSAVE,
+// MISCREG_CANRESTORE,
+// MISCREG_CLEANWIN,
+// MISCREG_OTHERWIN,
+// MISCREG_WSTATE,
MISCREG_GL,
/** Hyper privileged registers */
@@ -171,8 +171,8 @@ namespace SparcISA
private:
/* ASR Registers */
- uint64_t y; // Y (used in obsolete multiplication)
- uint8_t ccr; // Condition Code Register
+ //uint64_t y; // Y (used in obsolete multiplication)
+ //uint8_t ccr; // Condition Code Register
uint8_t asi; // Address Space Identifier
uint64_t tick; // Hardware clock-tick counter
uint8_t fprs; // Floating-Point Register State
@@ -197,11 +197,11 @@ namespace SparcISA
uint8_t tl; // Trap Level
uint8_t pil; // Process Interrupt Register
uint8_t cwp; // Current Window Pointer
- uint8_t cansave; // Savable windows
- uint8_t canrestore; // Restorable windows
- uint8_t cleanwin; // Clean windows
- uint8_t otherwin; // Other windows
- uint8_t wstate; // Window State
+ //uint8_t cansave; // Savable windows
+ //uint8_t canrestore; // Restorable windows
+ //uint8_t cleanwin; // Clean windows
+ //uint8_t otherwin; // Other windows
+ //uint8_t wstate; // Window State
uint8_t gl; // Global level register
/** Hyperprivileged Registers */
diff --git a/src/arch/sparc/pagetable.cc b/src/arch/sparc/pagetable.cc
index 22130d41c..e91c0599f 100644
--- a/src/arch/sparc/pagetable.cc
+++ b/src/arch/sparc/pagetable.cc
@@ -41,9 +41,12 @@ TlbEntry::serialize(std::ostream &os)
SERIALIZE_SCALAR(range.contextId);
SERIALIZE_SCALAR(range.partitionId);
SERIALIZE_SCALAR(range.real);
- uint64_t entry4u = pte();
+ uint64_t entry4u = 0;
+ if (valid)
+ entry4u = pte();
SERIALIZE_SCALAR(entry4u);
SERIALIZE_SCALAR(used);
+ SERIALIZE_SCALAR(valid);
}
@@ -57,8 +60,10 @@ TlbEntry::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(range.real);
uint64_t entry4u;
UNSERIALIZE_SCALAR(entry4u);
- pte.populate(entry4u);
+ if (entry4u)
+ pte.populate(entry4u);
UNSERIALIZE_SCALAR(used);
+ UNSERIALIZE_SCALAR(valid);
}
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 405e408e5..1e639b9a5 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -95,17 +95,22 @@ SparcLiveProcess::startup()
*/
//No windows contain info from other programs
- threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0);
+ //threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0);
//There are no windows to pop
- threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0);
+ //threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0);
//All windows are available to save into
- threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2);
+ //threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2);
//All windows are "clean"
- threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows);
+ //threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows);
//Start with register window 0
threadContexts[0]->setMiscReg(MISCREG_CWP, 0);
//Always use spill and fill traps 0
- threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0);
+ //threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0);
//Set the trap level to 0
threadContexts[0]->setMiscReg(MISCREG_TL, 0);
//Set the ASI register to something fixed
@@ -427,5 +432,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+ //Align the "stack_min" to a page boundary.
+ stack_min = roundDown(stack_min, pageSize);
+
// num_processes++;
}
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
index b36133544..827e22c31 100644
--- a/src/arch/sparc/regfile.cc
+++ b/src/arch/sparc/regfile.cc
@@ -151,6 +151,74 @@ void RegFile::setIntReg(int intReg, const IntReg &val)
intRegFile.setReg(intReg, val);
}
+int SparcISA::flattenIntIndex(ThreadContext * tc, int reg)
+{
+ int gl = tc->readMiscReg(MISCREG_GL);
+ int cwp = tc->readMiscReg(MISCREG_CWP);
+ //DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp);
+ int newReg;
+ //The total number of global registers
+ int numGlobals = (MaxGL + 1) * 8;
+ if(reg < 8)
+ {
+ //Global register
+ //Put it in the appropriate set of globals
+ newReg = reg + gl * 8;
+ }
+ else if(reg < NumIntArchRegs)
+ {
+ //Regular windowed register
+ //Put it in the window pointed to by cwp
+ newReg = numGlobals +
+ ((reg - 8 - cwp * 16 + NWindows * 16) % (NWindows * 16));
+ }
+ else if(reg < NumIntArchRegs + NumMicroIntRegs)
+ {
+ //Microcode register
+ //Displace from the end of the regular registers
+ newReg = reg - NumIntArchRegs + numGlobals + NWindows * 16;
+ }
+ else if(reg < 2 * NumIntArchRegs + NumMicroIntRegs)
+ {
+ reg -= (NumIntArchRegs + NumMicroIntRegs);
+ if(reg < 8)
+ {
+ //Global register from the next window
+ //Put it in the appropriate set of globals
+ newReg = reg + gl * 8;
+ }
+ else
+ {
+ //Windowed register from the previous window
+ //Put it in the window before the one pointed to by cwp
+ newReg = numGlobals +
+ ((reg - 8 - (cwp - 1) * 16 + NWindows * 16) % (NWindows * 16));
+ }
+ }
+ else if(reg < 3 * NumIntArchRegs + NumMicroIntRegs)
+ {
+ reg -= (2 * NumIntArchRegs + NumMicroIntRegs);
+ if(reg < 8)
+ {
+ //Global register from the previous window
+ //Put it in the appropriate set of globals
+ newReg = reg + gl * 8;
+ }
+ else
+ {
+ //Windowed register from the next window
+ //Put it in the window after the one pointed to by cwp
+ newReg = numGlobals +
+ ((reg - 8 - (cwp + 1) * 16 + NWindows * 16) % (NWindows * 16));
+ }
+ }
+ else
+ panic("Tried to flatten invalid register index %d!\n", reg);
+ DPRINTF(Sparc, "Flattened register %d to %d.\n", reg, newReg);
+ return newReg;
+ //return intRegFile.flattenIndex(reg);
+}
+
void RegFile::serialize(std::ostream &os)
{
intRegFile.serialize(os);
@@ -158,6 +226,7 @@ void RegFile::serialize(std::ostream &os)
miscRegFile.serialize(os);
SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
+ SERIALIZE_SCALAR(nnpc);
}
void RegFile::unserialize(Checkpoint *cp, const std::string &section)
@@ -167,6 +236,7 @@ void RegFile::unserialize(Checkpoint *cp, const std::string &section)
miscRegFile.unserialize(cp, section);
UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
+ UNSERIALIZE_SCALAR(nnpc);
}
void RegFile::changeContext(RegContextParam param, RegContextVal val)
@@ -220,8 +290,8 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
// ASRs
- dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
- dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
+// dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
+// dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
@@ -236,11 +306,11 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
- dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
- dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
- dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
- dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
- dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
+// dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
+// dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
+// dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
+// dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
+// dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
// Hyperprivilged registers
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index 0a09d0f66..d9af0757c 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -120,6 +120,8 @@ namespace SparcISA
void changeContext(RegContextParam param, RegContextVal val);
};
+ int flattenIntIndex(ThreadContext * tc, int reg);
+
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc
index c76f8b820..21c4a468c 100644
--- a/src/arch/sparc/remote_gdb.cc
+++ b/src/arch/sparc/remote_gdb.cc
@@ -193,11 +193,12 @@ RemoteGDB::setregs()
void
RemoteGDB::clearSingleStep()
{
- panic("SPARC does not support hardware single stepping\n");
+ warn("SPARC single stepping not implemented, "
+ "but clearSingleStep called\n");
}
void
RemoteGDB::setSingleStep()
{
- panic("SPARC does not support hardware single stepping\n");
+ panic("SPARC single stepping not implemented.\n");
}
diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh
index a3d29ea8a..d89ec1119 100644
--- a/src/arch/sparc/sparc_traits.hh
+++ b/src/arch/sparc/sparc_traits.hh
@@ -41,7 +41,8 @@ namespace SparcISA
// Number of register windows, can legally be 3 to 32
const int NWindows = 8;
- const int NumMicroIntRegs = 1;
+ //const int NumMicroIntRegs = 1;
+ const int NumMicroIntRegs = 8;
// const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16;
// const int NumMicroIntRegs = 1;
diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh
index 75a063da1..d92b12790 100644
--- a/src/arch/sparc/syscallreturn.hh
+++ b/src/arch/sparc/syscallreturn.hh
@@ -33,58 +33,30 @@
#include <inttypes.h>
+#include "sim/syscallreturn.hh"
#include "arch/sparc/regfile.hh"
-
-class SyscallReturn
-{
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s)
- {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
- private:
- uint64_t retval;
- bool success;
-};
+#include "cpu/thread_context.hh"
namespace SparcISA
{
static inline void setSyscallReturn(SyscallReturn return_value,
- RegFile *regs)
+ ThreadContext * tc)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
if (return_value.successful()) {
// no error, clear XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEE);
- regs->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(NumIntArchRegs + 2,
+ tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
+ //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) & 0xEE);
+ tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, set XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x11);
- regs->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(NumIntArchRegs + 2,
+ tc->readIntReg(NumIntArchRegs + 2) | 0x11);
+ //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) | 0x11);
+ tc->setIntReg(ReturnValueReg, -return_value.value());
}
}
};
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index da83d86fc..2600213fd 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -191,12 +191,6 @@ SparcSystem::~SparcSystem()
delete partition_desc;
}
-bool
-SparcSystem::breakpoint()
-{
- panic("Need to implement");
-}
-
void
SparcSystem::serialize(std::ostream &os)
{
diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh
index c81b093e8..ac4d34279 100644
--- a/src/arch/sparc/system.hh
+++ b/src/arch/sparc/system.hh
@@ -68,8 +68,6 @@ class SparcSystem : public System
~SparcSystem();
- virtual bool breakpoint();
-
/**
* Serialization stuff
*/
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index bf57c894f..ebc8c0e7a 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -28,6 +28,8 @@
* Authors: Ali Saidi
*/
+#include <cstring>
+
#include "arch/sparc/asi.hh"
#include "arch/sparc/miscregfile.hh"
#include "arch/sparc/tlb.hh"
@@ -53,7 +55,7 @@ TLB::TLB(const std::string &name, int s)
fatal("SPARC T1 TLB registers don't support more than 64 TLB entries.");
tlb = new TlbEntry[size];
- memset(tlb, 0, sizeof(TlbEntry) * size);
+ std::memset(tlb, 0, sizeof(TlbEntry) * size);
for (int x = 0; x < size; x++)
freeList.push_back(&tlb[x]);
@@ -174,8 +176,6 @@ insertAllLocked:
lookupTable.erase(new_entry->range);
- DPRINTF(TLB, "Using entry: %#X\n", new_entry);
-
assert(PTE.valid());
new_entry->range.va = va;
new_entry->range.size = PTE.size() - 1;
@@ -285,7 +285,6 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id)
usedEntries--;
}
freeList.push_front(i->second);
- DPRINTF(TLB, "Freeing TLB entry : %#X\n", i->second);
lookupTable.erase(i);
}
}
@@ -302,7 +301,6 @@ TLB::demapContext(int partition_id, int context_id)
tlb[x].range.partitionId == partition_id) {
if (tlb[x].valid == true) {
freeList.push_front(&tlb[x]);
- DPRINTF(TLB, "Freeing TLB entry : %#X\n", &tlb[x]);
}
tlb[x].valid = false;
if (tlb[x].used) {
@@ -324,7 +322,6 @@ TLB::demapAll(int partition_id)
if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) {
if (tlb[x].valid == true){
freeList.push_front(&tlb[x]);
- DPRINTF(TLB, "Freeing TLB entry : %#X\n", &tlb[x]);
}
tlb[x].valid = false;
if (tlb[x].used) {
@@ -902,7 +899,6 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG));
break;
case ASI_SPARC_ERROR_STATUS_REG:
- warn("returning 0 for SPARC ERROR regsiter read\n");
pkt->set((uint64_t)0);
break;
case ASI_HYP_SCRATCHPAD:
@@ -1253,13 +1249,55 @@ doMmuWriteError:
void
TLB::serialize(std::ostream &os)
{
- panic("Need to implement serialize tlb for SPARC\n");
+ SERIALIZE_SCALAR(size);
+ SERIALIZE_SCALAR(usedEntries);
+ SERIALIZE_SCALAR(lastReplaced);
+
+ // convert the pointer based free list into an index based one
+ int *free_list = (int*)malloc(sizeof(int) * size);
+ int cntr = 0;
+ std::list<TlbEntry*>::iterator i;
+ i = freeList.begin();
+ while (i != freeList.end()) {
+ free_list[cntr++] = ((size_t)*i - (size_t)tlb)/ sizeof(TlbEntry);
+ i++;
+ }
+ SERIALIZE_SCALAR(cntr);
+ SERIALIZE_ARRAY(free_list, cntr);
+
+ for (int x = 0; x < size; x++) {
+ nameOut(os, csprintf("%s.PTE%d", name(), x));
+ tlb[x].serialize(os);
+ }
}
void
TLB::unserialize(Checkpoint *cp, const std::string &section)
{
- panic("Need to implement unserialize tlb for SPARC\n");
+ int oldSize;
+
+ paramIn(cp, section, "size", oldSize);
+ if (oldSize != size)
+ panic("Don't support unserializing different sized TLBs\n");
+ UNSERIALIZE_SCALAR(usedEntries);
+ UNSERIALIZE_SCALAR(lastReplaced);
+
+ int cntr;
+ UNSERIALIZE_SCALAR(cntr);
+
+ int *free_list = (int*)malloc(sizeof(int) * cntr);
+ freeList.clear();
+ UNSERIALIZE_ARRAY(free_list, cntr);
+ for (int x = 0; x < cntr; x++)
+ freeList.push_back(&tlb[free_list[x]]);
+
+ lookupTable.clear();
+ for (int x = 0; x < size; x++) {
+ tlb[x].unserialize(cp, csprintf("%s.PTE%d", section, x));
+ if (tlb[x].valid)
+ lookupTable.insert(tlb[x].range, &tlb[x]);
+
+ }
}
diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh
index 5c7fe343d..3c8bdcd01 100644
--- a/src/arch/sparc/utility.hh
+++ b/src/arch/sparc/utility.hh
@@ -50,7 +50,7 @@ namespace SparcISA
inline ExtMachInst
makeExtMI(MachInst inst, ThreadContext * xc) {
- ExtMachInst emi = (unsigned MachInst) inst;
+ ExtMachInst emi = (MachInst) inst;
//The I bit, bit 13, is used to figure out where the ASI
//should come from. Use that in the ExtMachInst. This is
//slightly redundant, but it removes the need to put a condition
diff --git a/src/base/compiler.hh b/src/base/compiler.hh
new file mode 100644
index 000000000..dc23ed7b3
--- /dev/null
+++ b/src/base/compiler.hh
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006 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: Ali Saidi
+ */
+
+#ifndef __BASE_COMPILER_HH__
+#define __BASE_COMPILER_HH__
+
+//http://msdn2.microsoft.com/en-us/library/ms937669.aspx
+//http://msdn2.microsoft.com/en-us/library/aa448724.aspx
+//http://docs.sun.com/source/819-3688/sun.specific.html#marker-998278
+//http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Function-Attributes.html#Function%20Attributes
+
+#if defined(__GNUC__)
+#define M5_ATTR_NORETURN __attribute__((noreturn))
+#define M5_PRAGMA_NORETURN(x)
+#define M5_DUMMY_RETURN
+#elif defined(__SUNPRO_CC)
+// this doesn't do anything with sun cc, but why not
+#define M5_ATTR_NORETURN __sun_attr__((__noreturn__))
+#define M5_DUMMY_RETURN return (0);
+#define DO_PRAGMA(x) _Pragma(#x)
+#define M5_PRAGMA_NORETURN(x) DO_PRAGMA(does_not_return(x))
+#else
+#error "Need to define compiler options in base/compiler.hh"
+#endif
+
+#endif // __BASE_COMPILER_HH__
diff --git a/src/base/compression/lzss_compression.cc b/src/base/compression/lzss_compression.cc
index eb35fb8f1..bd16d82c9 100644
--- a/src/base/compression/lzss_compression.cc
+++ b/src/base/compression/lzss_compression.cc
@@ -32,8 +32,8 @@
* LZSSCompression definitions.
*/
-#include <assert.h>
-
+#include <cassert>
+#include <cstring>
#include "base/compression/lzss_compression.hh"
#include "base/misc.hh" //for fatal
@@ -134,7 +134,7 @@ LZSSCompression::compress(uint8_t *dest, uint8_t *src, int size)
if (dest_index >= size) {
// Have expansion instead of compression, just copy.
- memcpy(dest,src,size);
+ std::memcpy(dest,src,size);
return size;
}
return dest_index;
diff --git a/src/base/compression/null_compression.hh b/src/base/compression/null_compression.hh
index ff110807a..798acb77a 100644
--- a/src/base/compression/null_compression.hh
+++ b/src/base/compression/null_compression.hh
@@ -50,11 +50,13 @@ class NullCompression : public CompressionAlgorithm
int uncompress(uint8_t * dest, uint8_t *src, int size)
{
fatal("Can't uncompress data");
+ M5_DUMMY_RETURN
}
int compress(uint8_t *dest, uint8_t *src, int size)
{
fatal("Can't compress data");
+ M5_DUMMY_RETURN
}
};
diff --git a/src/base/cprintf.hh b/src/base/cprintf.hh
index 9967b0578..dd2256e69 100644
--- a/src/base/cprintf.hh
+++ b/src/base/cprintf.hh
@@ -136,10 +136,10 @@ operator,(ArgList &alist, ArgListNull)
inline void
__cprintf(const std::string &format, ArgList &args)
{ args.dump(format); delete &args; }
-#define __cprintf__(format, args...) \
- cp::__cprintf(format, (*(new cp::ArgList), args))
-#define cprintf(args...) \
- __cprintf__(args, cp::ArgListNull())
+#define __cprintf__(format, ...) \
+ cp::__cprintf(format, (*(new cp::ArgList), __VA_ARGS__))
+#define cprintf(...) \
+ __cprintf__(__VA_ARGS__, cp::ArgListNull())
//
// ccprintf(stream, format, args, ...) prints to the specified stream
@@ -148,10 +148,10 @@ __cprintf(const std::string &format, ArgList &args)
inline void
__ccprintf(std::ostream &stream, const std::string &format, ArgList &args)
{ args.dump(stream, format); delete &args; }
-#define __ccprintf__(stream, format, args...) \
- cp::__ccprintf(stream, format, (*(new cp::ArgList), args))
-#define ccprintf(stream, args...) \
- __ccprintf__(stream, args, cp::ArgListNull())
+#define __ccprintf__(stream, format, ...) \
+ cp::__ccprintf(stream, format, (*(new cp::ArgList), __VA_ARGS__))
+#define ccprintf(stream, ...) \
+ __ccprintf__(stream, __VA_ARGS__, cp::ArgListNull())
//
// csprintf(format, args, ...) returns a string
@@ -160,10 +160,10 @@ __ccprintf(std::ostream &stream, const std::string &format, ArgList &args)
inline std::string
__csprintf(const std::string &format, ArgList &args)
{ std::string s = args.dumpToString(format); delete &args; return s; }
-#define __csprintf__(format, args...) \
- cp::__csprintf(format, (*(new cp::ArgList), args))
-#define csprintf(args...) \
- __csprintf__(args, cp::ArgListNull())
+#define __csprintf__(format, ...) \
+ cp::__csprintf(format, (*(new cp::ArgList), __VA_ARGS__))
+#define csprintf(...) \
+ __csprintf__(__VA_ARGS__, cp::ArgListNull())
}
diff --git a/src/base/cprintf_formats.hh b/src/base/cprintf_formats.hh
index 3ea20446d..0af493217 100644
--- a/src/base/cprintf_formats.hh
+++ b/src/base/cprintf_formats.hh
@@ -84,21 +84,21 @@ _format_integer(std::ostream &out, const T &data, Format &fmt)
switch (fmt.base) {
case Format::hex:
- out.setf(ios::hex, ios::basefield);
+ out.setf(std::ios::hex, std::ios::basefield);
break;
case Format::oct:
- out.setf(ios::oct, ios::basefield);
+ out.setf(std::ios::oct, std::ios::basefield);
break;
case Format::dec:
- out.setf(ios::dec, ios::basefield);
+ out.setf(std::ios::dec, std::ios::basefield);
break;
}
if (fmt.alternate_form) {
if (!fmt.fill_zero)
- out.setf(ios::showbase);
+ out.setf(std::ios::showbase);
else {
switch (fmt.base) {
case Format::hex:
@@ -122,13 +122,13 @@ _format_integer(std::ostream &out, const T &data, Format &fmt)
out.width(fmt.width);
if (fmt.flush_left && !fmt.fill_zero)
- out.setf(ios::left);
+ out.setf(std::ios::left);
if (fmt.print_sign)
- out.setf(ios::showpos);
+ out.setf(std::ios::showpos);
if (fmt.uppercase)
- out.setf(ios::uppercase);
+ out.setf(std::ios::uppercase);
out << data;
}
@@ -148,7 +148,7 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
if (fmt.precision == 0)
fmt.precision = 1;
else
- out.setf(ios::scientific);
+ out.setf(std::ios::scientific);
out.precision(fmt.precision);
} else
@@ -156,7 +156,7 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
out.width(fmt.width);
if (fmt.uppercase)
- out.setf(ios::uppercase);
+ out.setf(std::ios::uppercase);
break;
case Format::fixed:
@@ -164,7 +164,7 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
if (fmt.width > 0)
out.width(fmt.width);
- out.setf(ios::fixed);
+ out.setf(std::ios::fixed);
out.precision(fmt.precision);
} else
if (fmt.width > 0)
@@ -216,7 +216,7 @@ _format_string(std::ostream &out, const T &data, Format &fmt)
if (fmt.width > 0)
out.width(fmt.width);
if (fmt.flush_left)
- out.setf(ios::left);
+ out.setf(std::ios::left);
out << data;
#endif
diff --git a/src/base/hashmap.hh b/src/base/hashmap.hh
index 570cbc152..b78cc02e8 100644
--- a/src/base/hashmap.hh
+++ b/src/base/hashmap.hh
@@ -59,7 +59,7 @@ namespace m5 {
//
namespace __hash_namespace {
-#if !defined(__LP64__) && !defined(__alpha__)
+#if !defined(__LP64__) && !defined(__alpha__) && !defined(__SUNPRO_CC)
template<>
struct hash<uint64_t> {
size_t operator()(uint64_t r) const {
diff --git a/src/base/hostinfo.cc b/src/base/hostinfo.cc
index a7c93e712..7cc07c11e 100644
--- a/src/base/hostinfo.cc
+++ b/src/base/hostinfo.cc
@@ -33,6 +33,7 @@
#include <math.h>
#include <unistd.h>
+#include <stdio.h>
#include <cstdlib>
#include <cstring>
#include <string>
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index da5aa9552..7424b9305 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -101,7 +101,7 @@ ObjectFile::close()
}
if (fileData) {
- ::munmap(fileData, len);
+ ::munmap((char*)fileData, len);
fileData = NULL;
}
}
@@ -147,7 +147,7 @@ createObjectFile(const string &fname, bool raw)
// don't know what it is
close(fd);
- munmap(fileData, len);
+ munmap((char*)fileData, len);
return NULL;
}
diff --git a/src/base/misc.hh b/src/base/misc.hh
index 1c5720ce1..c12c2fe20 100644
--- a/src/base/misc.hh
+++ b/src/base/misc.hh
@@ -33,8 +33,13 @@
#define __MISC_HH__
#include <assert.h>
+#include "base/compiler.hh"
#include "base/cprintf.hh"
+#if defined(__SUNPRO_CC)
+#define __FUNCTION__ "how to fix me?"
+#endif
+
//
// This implements a cprintf based panic() function. panic() should
// be called when something happens that should never ever happen
@@ -43,12 +48,13 @@
//
//
void __panic(const std::string&, cp::ArgList &, const char*, const char*, int)
- __attribute__((noreturn));
-#define __panic__(format, args...) \
- __panic(format, (*(new cp::ArgList), args), \
- __FUNCTION__, __FILE__, __LINE__)
-#define panic(args...) \
- __panic__(args, cp::ArgListNull())
+ M5_ATTR_NORETURN;
+#define __panic__(format, ...) \
+ __panic(format, (*(new cp::ArgList), __VA_ARGS__), \
+ __FUNCTION__ , __FILE__, __LINE__)
+#define panic(...) \
+ __panic__(__VA_ARGS__, cp::ArgListNull())
+M5_PRAGMA_NORETURN(__panic)
//
// This implements a cprintf based fatal() function. fatal() should
@@ -59,32 +65,33 @@ void __panic(const std::string&, cp::ArgList &, const char*, const char*, int)
// panic() does.
//
void __fatal(const std::string&, cp::ArgList &, const char*, const char*, int)
- __attribute__((noreturn));
-#define __fatal__(format, args...) \
- __fatal(format, (*(new cp::ArgList), args), \
- __FUNCTION__, __FILE__, __LINE__)
-#define fatal(args...) \
- __fatal__(args, cp::ArgListNull())
+ M5_ATTR_NORETURN;
+#define __fatal__(format, ...) \
+ __fatal(format, (*(new cp::ArgList), __VA_ARGS__), \
+ __FUNCTION__ , __FILE__, __LINE__)
+#define fatal(...) \
+ __fatal__(__VA_ARGS__, cp::ArgListNull())
+M5_PRAGMA_NORETURN(__fatal)
//
// This implements a cprintf based warn
//
void __warn(const std::string&, cp::ArgList &, const char*, const char*, int);
-#define __warn__(format, args...) \
- __warn(format, (*(new cp::ArgList), args), \
- __FUNCTION__, __FILE__, __LINE__)
-#define warn(args...) \
- __warn__(args, cp::ArgListNull())
+#define __warn__(format, ...) \
+ __warn(format, (*(new cp::ArgList), __VA_ARGS__), \
+ __FUNCTION__ , __FILE__, __LINE__)
+#define warn(...) \
+ __warn__(__VA_ARGS__, cp::ArgListNull())
// Only print the warning message the first time it is seen. This
// doesn't check the warning string itself, it just only lets one
// warning come from the statement. So, even if the arguments change
// and that would have resulted in a different warning message,
// subsequent messages would still be supressed.
-#define warn_once(args...) do { \
+#define warn_once(...) do { \
static bool once = false; \
if (!once) { \
- __warn__(args, cp::ArgListNull()); \
+ __warn__(__VA_ARGS__, cp::ArgListNull()); \
once = true; \
} \
} while (0)
diff --git a/src/base/pollevent.cc b/src/base/pollevent.cc
index fd5b09d28..32724b74d 100644
--- a/src/base/pollevent.cc
+++ b/src/base/pollevent.cc
@@ -30,7 +30,7 @@
#include <sys/ioctl.h>
#include <sys/types.h>
-#if defined(__sun__)
+#if defined(__sun__) || defined(__SUNPRO_CC)
#include <sys/file.h>
#endif
diff --git a/src/base/random.cc b/src/base/random.cc
index 82c9e3566..0ccedcb00 100644
--- a/src/base/random.cc
+++ b/src/base/random.cc
@@ -29,12 +29,17 @@
* Ali Saidi
*/
+#if defined(__sun)
+#include <ieeefp.h>
+#endif
+#ifdef __SUNPRO_CC
+#include <stdlib.h>
+#include <math.h>
+#endif
+
#include <cstdlib>
#include <cmath>
-#if defined(__sun__)
-#include <ieeefp.h>
-#endif
#include "sim/param.hh"
#include "base/random.hh"
@@ -72,7 +77,7 @@ getLong()
double
m5round(double r)
{
-#if defined(__sun__)
+#if defined(__sun)
double val;
fp_rnd oldrnd = fpsetround(FP_RN);
val = rint(r);
diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc
index 59a9b87d5..b28beba89 100644
--- a/src/base/remote_gdb.cc
+++ b/src/base/remote_gdb.cc
@@ -121,16 +121,21 @@
#include <string>
#include <unistd.h>
+#include "config/full_system.hh"
+
+#if FULL_SYSTEM
#include "arch/vtophys.hh"
+#endif
+
#include "base/intmath.hh"
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "base/trace.hh"
-#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
-#include "mem/physical.hh"
+//#include "mem/physical.hh"
#include "mem/port.hh"
+#include "mem/translating_port.hh"
#include "sim/system.hh"
using namespace std;
@@ -448,9 +453,17 @@ BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
- VirtualPort *vp = context->getVirtPort(context);
- vp->readBlob(vaddr, (uint8_t*)data, size);
- context->delVirtPort(vp);
+#if FULL_SYSTEM
+ VirtualPort *port = context->getVirtPort(context);
+#else
+ TranslatingPort *port = context->getMemPort();
+#endif
+ port->readBlob(vaddr, (uint8_t*)data, size);
+#if FULL_SYSTEM
+ context->delVirtPort(port);
+#else
+ delete port;
+#endif
#if TRACING_ON
if (DTRACE(GDBRead)) {
@@ -487,9 +500,17 @@ BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
} else
DPRINTFNR("\n");
}
- VirtualPort *vp = context->getVirtPort(context);
- vp->writeBlob(vaddr, (uint8_t*)data, size);
- context->delVirtPort(vp);
+#if FULL_SYSTEM
+ VirtualPort *port = context->getVirtPort(context);
+#else
+ TranslatingPort *port = context->getMemPort();
+#endif
+ port->writeBlob(vaddr, (uint8_t*)data, size);
+#if FULL_SYSTEM
+ context->delVirtPort(port);
+#else
+ delete port;
+#endif
return true;
}
@@ -610,7 +631,8 @@ BaseRemoteGDB::trap(int type)
uint64_t val;
size_t datalen, len;
char data[GDBPacketBufLen + 1];
- char buffer[gdbregs.bytes() * 2 + 256];
+ char *buffer;
+ int bufferSize;
const char *p;
char command, subcmd;
string var;
@@ -619,6 +641,9 @@ BaseRemoteGDB::trap(int type)
if (!attached)
return false;
+ bufferSize = gdbregs.bytes() * 2 + 256;
+ buffer = (char*)malloc(bufferSize);
+
DPRINTF(GDBMisc, "trap: PC=%#x NPC=%#x\n",
context->readPC(), context->readNextPC());
@@ -638,7 +663,7 @@ BaseRemoteGDB::trap(int type)
active = true;
else
// Tell remote host that an exception has occurred.
- snprintf((char *)buffer, sizeof(buffer), "S%02x", type);
+ snprintf((char *)buffer, bufferSize, "S%02x", type);
send(buffer);
// Stick frame regs into our reg cache.
@@ -656,13 +681,13 @@ BaseRemoteGDB::trap(int type)
// if this command came from a running gdb, answer it --
// the other guy has no way of knowing if we're in or out
// of this loop when he issues a "remote-signal".
- snprintf((char *)buffer, sizeof(buffer),
+ snprintf((char *)buffer, bufferSize,
"S%02x", type);
send(buffer);
continue;
case GDBRegR:
- if (2 * gdbregs.bytes() > sizeof(buffer))
+ if (2 * gdbregs.bytes() > bufferSize)
panic("buffer too small");
mem2hex(buffer, gdbregs.regs, gdbregs.bytes());
@@ -709,7 +734,7 @@ BaseRemoteGDB::trap(int type)
send("E03");
continue;
}
- if (len > sizeof(buffer)) {
+ if (len > bufferSize) {
send("E04");
continue;
}
@@ -745,7 +770,7 @@ BaseRemoteGDB::trap(int type)
send("E08");
continue;
}
- p = hex2mem(buffer, p, sizeof(buffer));
+ p = hex2mem(buffer, p, bufferSize);
if (p == NULL) {
send("E09");
continue;
@@ -916,6 +941,7 @@ BaseRemoteGDB::trap(int type)
}
out:
+ free(buffer);
return true;
}
diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh
index 9a3201c95..92e599585 100644
--- a/src/base/remote_gdb.hh
+++ b/src/base/remote_gdb.hh
@@ -32,6 +32,7 @@
#define __REMOTE_GDB_HH__
#include <map>
+#include <sys/signal.h>
#include "arch/types.hh"
#include "cpu/pc_event.hh"
@@ -177,6 +178,10 @@ class BaseRemoteGDB
virtual bool acc(Addr addr, size_t len) = 0;
bool trap(int type);
+ virtual bool breakpoint()
+ {
+ return trap(SIGTRAP);
+ }
protected:
virtual void getregs() = 0;
diff --git a/src/base/statistics.hh b/src/base/statistics.hh
index 577ea5eab..2b1b327e5 100644
--- a/src/base/statistics.hh
+++ b/src/base/statistics.hh
@@ -50,6 +50,9 @@
#include <algorithm>
#include <cassert>
+#ifdef __SUNPRO_CC
+#include <math.h>
+#endif
#include <cmath>
#include <functional>
#include <iosfwd>
@@ -395,7 +398,7 @@ class Wrap : public Child
public:
Wrap()
{
- map(new Data<Child>(*this));
+ this->map(new Data<Child>(*this));
}
/**
@@ -1410,7 +1413,7 @@ struct DistStor
else if (val > params.max)
overflow += number;
else {
- int index = (int)floor((val - params.min) / params.bucket_size);
+ int index = (int)std::floor((val - params.min) / params.bucket_size);
assert(index < size(params));
cvec[index] += number;
}
diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc
index c4448efc9..ae0d65537 100644
--- a/src/base/stats/text.cc
+++ b/src/base/stats/text.cc
@@ -32,6 +32,10 @@
#define _GLIBCPP_USE_C99 1
#endif
+#if defined(__sun)
+#include <math.h>
+#endif
+
#include <iostream>
#include <sstream>
#include <fstream>
diff --git a/src/base/time.cc b/src/base/time.cc
index cbc7256ee..76ba355b7 100644
--- a/src/base/time.cc
+++ b/src/base/time.cc
@@ -105,7 +105,11 @@ Time::date(string format) const
char buf[256];
if (format.empty()) {
+#ifdef __SUNPRO_CC
+ ctime_r(&sec, buf, 256);
+#else
ctime_r(&sec, buf);
+#endif
buf[24] = '\0';
return buf;
}
diff --git a/src/base/time.hh b/src/base/time.hh
index 7aa4c50db..f10cc5d6c 100644
--- a/src/base/time.hh
+++ b/src/base/time.hh
@@ -97,7 +97,7 @@ std::ostream &operator<<(std::ostream &out, const Time &time);
* @(#)time.h 8.2 (Berkeley) 7/10/94
*/
-#if defined(__sun__)
+#if defined(__sun)
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
diff --git a/src/base/timebuf.hh b/src/base/timebuf.hh
index 1d0de8278..348f7a673 100644
--- a/src/base/timebuf.hh
+++ b/src/base/timebuf.hh
@@ -33,6 +33,7 @@
#define __BASE_TIMEBUF_HH__
#include <cassert>
+#include <cstring>
#include <vector>
template <class T>
@@ -143,7 +144,7 @@ class TimeBuffer
char *ptr = data;
for (int i = 0; i < size; i++) {
index[i] = ptr;
- memset(ptr, 0, sizeof(T));
+ std::memset(ptr, 0, sizeof(T));
new (ptr) T;
ptr += sizeof(T);
}
@@ -171,7 +172,7 @@ class TimeBuffer
if (ptr >= size)
ptr -= size;
(reinterpret_cast<T *>(index[ptr]))->~T();
- memset(index[ptr], 0, sizeof(T));
+ std::memset(index[ptr], 0, sizeof(T));
new (index[ptr]) T;
}
diff --git a/src/base/trace.hh b/src/base/trace.hh
index 9b053990c..a46643159 100644
--- a/src/base/trace.hh
+++ b/src/base/trace.hh
@@ -186,39 +186,39 @@ do { \
Trace::dataDump(curTick, name(), data, count); \
} while (0)
-#define __dprintf(cycle, name, format, args...) \
- Trace::dprintf(format, (*(new cp::ArgList), args), cycle, name)
+#define __dprintf(cycle, name, format, ...) \
+ Trace::dprintf(format, (*(new cp::ArgList), __VA_ARGS__), cycle, name)
-#define DPRINTF(x, args...) \
+#define DPRINTF(x, ...) \
do { \
if (Trace::IsOn(Trace::x)) \
- __dprintf(curTick, name(), args, cp::ArgListNull()); \
+ __dprintf(curTick, name(), __VA_ARGS__, cp::ArgListNull()); \
} while (0)
-#define DPRINTFR(x, args...) \
+#define DPRINTFR(x, ...) \
do { \
if (Trace::IsOn(Trace::x)) \
- __dprintf((Tick)-1, std::string(), args, cp::ArgListNull()); \
+ __dprintf((Tick)-1, std::string(), __VA_ARGS__, cp::ArgListNull()); \
} while (0)
-#define DPRINTFN(args...) \
+#define DPRINTFN(...) \
do { \
- __dprintf(curTick, name(), args, cp::ArgListNull()); \
+ __dprintf(curTick, name(), __VA_ARGS__, cp::ArgListNull()); \
} while (0)
-#define DPRINTFNR(args...) \
+#define DPRINTFNR(...) \
do { \
- __dprintf((Tick)-1, string(), args, cp::ArgListNull()); \
+ __dprintf((Tick)-1, string(), __VA_ARGS__, cp::ArgListNull()); \
} while (0)
#else // !TRACING_ON
#define DTRACE(x) (false)
#define DCOUT(x) if (0) DebugOut()
-#define DPRINTF(x, args...) do {} while (0)
-#define DPRINTFR(args...) do {} while (0)
-#define DPRINTFN(args...) do {} while (0)
-#define DPRINTFNR(args...) do {} while (0)
+#define DPRINTF(x, ...) do {} while (0)
+#define DPRINTFR(...) do {} while (0)
+#define DPRINTFN(...) do {} while (0)
+#define DPRINTFNR(...) do {} while (0)
#define DDUMP(x, data, count) do {} while (0)
#endif // TRACING_ON
diff --git a/src/cpu/SConscript b/src/cpu/SConscript
index 5771a7904..4d4b7574c 100644
--- a/src/cpu/SConscript
+++ b/src/cpu/SConscript
@@ -54,18 +54,18 @@ execfile(models_db.srcnode().abspath)
exec_sig_template = '''
virtual Fault execute(%s *xc, Trace::InstRecord *traceData) const = 0;
virtual Fault initiateAcc(%s *xc, Trace::InstRecord *traceData) const
-{ panic("initiateAcc not defined!"); };
+{ panic("initiateAcc not defined!"); M5_DUMMY_RETURN };
virtual Fault completeAcc(Packet *pkt, %s *xc,
Trace::InstRecord *traceData) const
-{ panic("completeAcc not defined!"); };
+{ panic("completeAcc not defined!"); M5_DUMMY_RETURN };
'''
mem_ini_sig_template = '''
-virtual Fault initiateAcc(%s *xc, Trace::InstRecord *traceData) const { panic("Not defined!"); };
+virtual Fault initiateAcc(%s *xc, Trace::InstRecord *traceData) const { panic("Not defined!"); M5_DUMMY_RETURN };
'''
mem_comp_sig_template = '''
-virtual Fault completeAcc(uint8_t *data, %s *xc, Trace::InstRecord *traceData) const { panic("Not defined!"); return NoFault; };
+virtual Fault completeAcc(uint8_t *data, %s *xc, Trace::InstRecord *traceData) const { panic("Not defined!"); return NoFault; M5_DUMMY_RETURN };
'''
# Generate a temporary CPU list, including the CheckerCPU if
diff --git a/src/cpu/activity.cc b/src/cpu/activity.cc
index 9a0f6d98d..15e0556ad 100644
--- a/src/cpu/activity.cc
+++ b/src/cpu/activity.cc
@@ -28,6 +28,8 @@
* Authors: Kevin Lim
*/
+#include <cstring>
+
#include "base/timebuf.hh"
#include "cpu/activity.hh"
@@ -37,7 +39,7 @@ ActivityRecorder::ActivityRecorder(int num_stages, int longest_latency,
activityCount(activity), numStages(num_stages)
{
stageActive = new bool[numStages];
- memset(stageActive, 0, numStages);
+ std::memset(stageActive, 0, numStages);
}
void
@@ -114,7 +116,7 @@ void
ActivityRecorder::reset()
{
activityCount = 0;
- memset(stageActive, 0, numStages);
+ std::memset(stageActive, 0, numStages);
for (int i = 0; i < longestLatency + 1; ++i)
activityBuffer.advance();
}
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index deb4e02c4..8440d2320 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -298,6 +298,16 @@ BaseCPU::registerThreadContexts()
}
+int
+BaseCPU::findContext(ThreadContext *tc)
+{
+ for (int i = 0; i < threadContexts.size(); ++i) {
+ if (tc == threadContexts[i])
+ return i;
+ }
+ return 0;
+}
+
void
BaseCPU::switchOut()
{
@@ -389,12 +399,14 @@ BaseCPU::clear_interrupts()
void
BaseCPU::serialize(std::ostream &os)
{
+ SERIALIZE_SCALAR(instCnt);
interrupts.serialize(os);
}
void
BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
{
+ UNSERIALIZE_SCALAR(instCnt);
interrupts.unserialize(cp, section);
}
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 3ae9c60b6..a1265b748 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -142,6 +142,12 @@ class BaseCPU : public MemObject
/// Notify the CPU that the indicated context is now halted.
virtual void haltContext(int thread_num) {}
+ /// Given a Thread Context pointer return the thread num
+ int findContext(ThreadContext *tc);
+
+ /// Given a thread num get tho thread context for it
+ ThreadContext *getContext(int tn) { return threadContexts[tn]; }
+
public:
struct Params
{
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 9037c96df..515cd0836 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -39,6 +39,7 @@
#include "base/fast_alloc.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
+#include "cpu/o3/comm.hh"
#include "cpu/exetrace.hh"
#include "cpu/inst_seq.hh"
#include "cpu/op_class.hh"
@@ -62,10 +63,6 @@ class BaseDynInst : public FastAlloc, public RefCounted
typedef typename Impl::CPUType ImplCPU;
typedef typename ImplCPU::ImplState ImplState;
- // Binary machine instruction type.
- typedef TheISA::MachInst MachInst;
- // Extended machine instruction type
- typedef TheISA::ExtMachInst ExtMachInst;
// Logical register index type.
typedef TheISA::RegIndex RegIndex;
// Integer register type.
@@ -212,6 +209,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** PC of this instruction. */
Addr PC;
+ protected:
/** Next non-speculative PC. It is not filled in at fetch, but rather
* once the target of the branch is truly known (either decode or
* execute).
@@ -224,6 +222,14 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Predicted next PC. */
Addr predPC;
+ /** Predicted next NPC. */
+ Addr predNPC;
+
+ /** If this is a branch that was predicted taken */
+ bool predTaken;
+
+ public:
+
/** Count of total number of dynamic instructions. */
static int instcount;
@@ -236,16 +242,116 @@ class BaseDynInst : public FastAlloc, public RefCounted
*/
bool _readySrcRegIdx[MaxInstSrcRegs];
+ protected:
+ /** Flattened register index of the destination registers of this
+ * instruction.
+ */
+ TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs];
+
+ /** Flattened register index of the source registers of this
+ * instruction.
+ */
+ TheISA::RegIndex _flatSrcRegIdx[TheISA::MaxInstSrcRegs];
+
+ /** Physical register index of the destination registers of this
+ * instruction.
+ */
+ PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs];
+
+ /** Physical register index of the source registers of this
+ * instruction.
+ */
+ PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs];
+
+ /** Physical register index of the previous producers of the
+ * architected destinations.
+ */
+ PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs];
+
public:
+
+ /** Returns the physical register index of the i'th destination
+ * register.
+ */
+ PhysRegIndex renamedDestRegIdx(int idx) const
+ {
+ return _destRegIdx[idx];
+ }
+
+ /** Returns the physical register index of the i'th source register. */
+ PhysRegIndex renamedSrcRegIdx(int idx) const
+ {
+ return _srcRegIdx[idx];
+ }
+
+ /** Returns the flattened register index of the i'th destination
+ * register.
+ */
+ TheISA::RegIndex flattenedDestRegIdx(int idx) const
+ {
+ return _flatDestRegIdx[idx];
+ }
+
+ /** Returns the flattened register index of the i'th source register */
+ TheISA::RegIndex flattenedSrcRegIdx(int idx) const
+ {
+ return _flatSrcRegIdx[idx];
+ }
+
+ /** Returns the physical register index of the previous physical register
+ * that remapped to the same logical register index.
+ */
+ PhysRegIndex prevDestRegIdx(int idx) const
+ {
+ return _prevDestRegIdx[idx];
+ }
+
+ /** Renames a destination register to a physical register. Also records
+ * the previous physical register that the logical register mapped to.
+ */
+ void renameDestReg(int idx,
+ PhysRegIndex renamed_dest,
+ PhysRegIndex previous_rename)
+ {
+ _destRegIdx[idx] = renamed_dest;
+ _prevDestRegIdx[idx] = previous_rename;
+ }
+
+ /** Renames a source logical register to the physical register which
+ * has/will produce that logical register's result.
+ * @todo: add in whether or not the source register is ready.
+ */
+ void renameSrcReg(int idx, PhysRegIndex renamed_src)
+ {
+ _srcRegIdx[idx] = renamed_src;
+ }
+
+ /** Flattens a source architectural register index into a logical index.
+ */
+ void flattenSrcReg(int idx, TheISA::RegIndex flattened_src)
+ {
+ _flatSrcRegIdx[idx] = flattened_src;
+ }
+
+ /** Flattens a destination architectural register index into a logical
+ * index.
+ */
+ void flattenDestReg(int idx, TheISA::RegIndex flattened_dest)
+ {
+ _flatDestRegIdx[idx] = flattened_dest;
+ }
+
/** BaseDynInst constructor given a binary instruction.
* @param inst The binary instruction.
* @param PC The PC of the instruction.
* @param pred_PC The predicted next PC.
+ * @param pred_NPC The predicted next NPC.
* @param seq_num The sequence number of the instruction.
* @param cpu Pointer to the instruction's CPU.
*/
- BaseDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num,
- ImplCPU *cpu);
+ BaseDynInst(TheISA::ExtMachInst inst, Addr PC, Addr NPC,
+ Addr pred_PC, Addr pred_NPC,
+ InstSeqNum seq_num, ImplCPU *cpu);
/** BaseDynInst constructor given a StaticInst pointer.
* @param _staticInst The StaticInst for this BaseDynInst.
@@ -287,29 +393,46 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Returns the next NPC. This could be the speculative next NPC if it is
* called prior to the actual branch target being calculated.
*/
- Addr readNextNPC() { return nextNPC; }
+ Addr readNextNPC()
+ {
+#if ISA_HAS_DELAY_SLOT
+ return nextNPC;
+#else
+ return nextPC + sizeof(TheISA::MachInst);
+#endif
+ }
/** Set the predicted target of this current instruction. */
- void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; }
+ void setPredTarg(Addr predicted_PC, Addr predicted_NPC)
+ {
+ predPC = predicted_PC;
+ predNPC = predicted_NPC;
+ }
+
+ /** Returns the predicted PC immediately after the branch. */
+ Addr readPredPC() { return predPC; }
- /** Returns the predicted target of the branch. */
- Addr readPredTarg() { return predPC; }
+ /** Returns the predicted PC two instructions after the branch */
+ Addr readPredNPC() { return predNPC; }
/** Returns whether the instruction was predicted taken or not. */
- bool predTaken()
-#if ISA_HAS_DELAY_SLOT
- { return predPC != (nextPC + sizeof(MachInst)); }
-#else
- { return predPC != (PC + sizeof(MachInst)); }
-#endif
+ bool readPredTaken()
+ {
+ return predTaken;
+ }
+
+ void setPredTaken(bool predicted_taken)
+ {
+ predTaken = predicted_taken;
+ }
/** Returns whether the instruction mispredicted. */
bool mispredicted()
-#if ISA_HAS_DELAY_SLOT
- { return predPC != nextNPC; }
-#else
- { return predPC != nextPC; }
-#endif
+ {
+ return readPredPC() != readNextPC() ||
+ readPredNPC() != readNextNPC();
+ }
+
//
// Instruction types. Forward checks to StaticInst object.
//
diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh
index 2f6859de2..c3d71e428 100644
--- a/src/cpu/base_dyn_inst_impl.hh
+++ b/src/cpu/base_dyn_inst_impl.hh
@@ -62,17 +62,20 @@ my_hash_t thishash;
#endif
template <class Impl>
-BaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst machInst, Addr inst_PC,
- Addr pred_PC, InstSeqNum seq_num,
- ImplCPU *cpu)
+BaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst machInst,
+ Addr inst_PC, Addr inst_NPC,
+ Addr pred_PC, Addr pred_NPC,
+ InstSeqNum seq_num, ImplCPU *cpu)
: staticInst(machInst), traceData(NULL), cpu(cpu)
{
seqNum = seq_num;
PC = inst_PC;
- nextPC = PC + sizeof(TheISA::MachInst);
+ nextPC = inst_NPC;
nextNPC = nextPC + sizeof(TheISA::MachInst);
predPC = pred_PC;
+ predNPC = pred_NPC;
+ predTaken = false;
initVars();
}
diff --git a/src/cpu/cpuevent.hh b/src/cpu/cpuevent.hh
index c973621c0..5816c6ca1 100644
--- a/src/cpu/cpuevent.hh
+++ b/src/cpu/cpuevent.hh
@@ -71,6 +71,7 @@ class CpuEvent : public Event
*/
static void replaceThreadContext(ThreadContext *oldTc,
ThreadContext *newTc);
+ ThreadContext* getTC() { return tc; }
};
template <class T, void (T::* F)(ThreadContext *tc)>
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index 26e8b6b44..e34ae3731 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -147,13 +147,15 @@ Trace::InstRecord::dump(ostream &outs)
outs << hex;
outs << "PC = " << thread->readNextPC();
outs << " NPC = " << thread->readNextNPC();
- newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
+ newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
+ //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
if(newVal != ccr)
{
outs << " CCR = " << newVal;
ccr = newVal;
}
- newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
+ newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1);
+ //newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
if(newVal != y)
{
outs << " Y = " << newVal;
@@ -293,7 +295,8 @@ Trace::InstRecord::dump(ostream &outs)
bool diffPC = false;
bool diffCC = false;
bool diffInst = false;
- bool diffRegs = false;
+ bool diffIntRegs = false;
+ bool diffFpRegs = false;
bool diffTpc = false;
bool diffTnpc = false;
bool diffTstate = false;
@@ -304,6 +307,7 @@ Trace::InstRecord::dump(ostream &outs)
bool diffHtba = false;
bool diffPstate = false;
bool diffY = false;
+ bool diffFsr = false;
bool diffCcr = false;
bool diffTl = false;
bool diffGl = false;
@@ -355,12 +359,18 @@ Trace::InstRecord::dump(ostream &outs)
(SparcISA::MachInst)staticInst->machInst) {
diffInst = true;
}
- for (int i = 0; i < TheISA::NumIntArchRegs; i++) {
+ // assume we have %g0 working correctly
+ for (int i = 1; i < TheISA::NumIntArchRegs; i++) {
if (thread->readIntReg(i) != shared_data->intregs[i]) {
- diffRegs = true;
+ diffIntRegs = true;
}
}
- uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
+ for (int i = 0; i < TheISA::NumFloatRegs/2; i++) {
+ if (thread->readFloatRegBits(i*2,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) {
+ diffFpRegs = true;
+ }
+ }
+ uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
if (oldTl != shared_data->tl)
diffTl = true;
for (int i = 1; i <= MaxTL; i++) {
@@ -397,9 +407,15 @@ Trace::InstRecord::dump(ostream &outs)
diffHtba = true;
if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
diffPstate = true;
- if(shared_data->y != thread->readMiscReg(MISCREG_Y))
+ //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
+ if(shared_data->y !=
+ thread->readIntReg(NumIntArchRegs + 1))
diffY = true;
- if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
+ if(shared_data->fsr != thread->readMiscReg(MISCREG_FSR))
+ diffFsr = true;
+ //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
+ if(shared_data->ccr !=
+ thread->readIntReg(NumIntArchRegs + 2))
diffCcr = true;
if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
diffGl = true;
@@ -409,14 +425,22 @@ Trace::InstRecord::dump(ostream &outs)
diffPil = true;
if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
diffCwp = true;
- if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
+ //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
+ if(shared_data->cansave !=
+ thread->readIntReg(NumIntArchRegs + 3))
diffCansave = true;
+ //if(shared_data->canrestore !=
+ // thread->readMiscReg(MISCREG_CANRESTORE))
if(shared_data->canrestore !=
- thread->readMiscReg(MISCREG_CANRESTORE))
+ thread->readIntReg(NumIntArchRegs + 4))
diffCanrestore = true;
- if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
+ //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
+ if(shared_data->otherwin !=
+ thread->readIntReg(NumIntArchRegs + 6))
diffOtherwin = true;
- if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
+ //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
+ if(shared_data->cleanwin !=
+ thread->readIntReg(NumIntArchRegs + 5))
diffCleanwin = true;
for (int i = 0; i < 64; i++) {
@@ -426,12 +450,12 @@ Trace::InstRecord::dump(ostream &outs)
diffTlb = true;
}
- if ((diffPC || diffCC || diffInst || diffRegs || diffTpc ||
- diffTnpc || diffTstate || diffTt || diffHpstate ||
- diffHtstate || diffHtba || diffPstate || diffY ||
- diffCcr || diffTl || diffGl || diffAsi || diffPil ||
- diffCwp || diffCansave || diffCanrestore ||
- diffOtherwin || diffCleanwin || diffTlb)
+ if ((diffPC || diffCC || diffInst || diffIntRegs ||
+ diffFpRegs || diffTpc || diffTnpc || diffTstate ||
+ diffTt || diffHpstate || diffHtstate || diffHtba ||
+ diffPstate || diffY || diffCcr || diffTl || diffFsr ||
+ diffGl || diffAsi || diffPil || diffCwp || diffCansave ||
+ diffCanrestore || diffOtherwin || diffCleanwin || diffTlb)
&& !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
&& !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
&& shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
@@ -444,8 +468,10 @@ Trace::InstRecord::dump(ostream &outs)
outs << " [CC]";
if (diffInst)
outs << " [Instruction]";
- if (diffRegs)
+ if (diffIntRegs)
outs << " [IntRegs]";
+ if (diffFpRegs)
+ outs << " [FpRegs]";
if (diffTpc)
outs << " [Tpc]";
if (diffTnpc)
@@ -464,6 +490,8 @@ Trace::InstRecord::dump(ostream &outs)
outs << " [Pstate]";
if (diffY)
outs << " [Y]";
+ if (diffFsr)
+ outs << " [FSR]";
if (diffCcr)
outs << " [Ccr]";
if (diffTl)
@@ -530,10 +558,15 @@ Trace::InstRecord::dump(ostream &outs)
thread->readMiscReg(MISCREG_PSTATE),
shared_data->pstate);
printRegPair(outs, "Y",
- thread->readMiscReg(MISCREG_Y),
+ //thread->readMiscReg(MISCREG_Y),
+ thread->readIntReg(NumIntArchRegs + 1),
shared_data->y);
+ printRegPair(outs, "FSR",
+ thread->readMiscReg(MISCREG_FSR),
+ shared_data->fsr);
printRegPair(outs, "Ccr",
- thread->readMiscReg(MISCREG_CCR),
+ //thread->readMiscReg(MISCREG_CCR),
+ thread->readIntReg(NumIntArchRegs + 2),
shared_data->ccr);
printRegPair(outs, "Tl",
thread->readMiscReg(MISCREG_TL),
@@ -551,16 +584,20 @@ Trace::InstRecord::dump(ostream &outs)
thread->readMiscReg(MISCREG_CWP),
shared_data->cwp);
printRegPair(outs, "Cansave",
- thread->readMiscReg(MISCREG_CANSAVE),
+ //thread->readMiscReg(MISCREG_CANSAVE),
+ thread->readIntReg(NumIntArchRegs + 3),
shared_data->cansave);
printRegPair(outs, "Canrestore",
- thread->readMiscReg(MISCREG_CANRESTORE),
+ //thread->readMiscReg(MISCREG_CANRESTORE),
+ thread->readIntReg(NumIntArchRegs + 4),
shared_data->canrestore);
printRegPair(outs, "Otherwin",
- thread->readMiscReg(MISCREG_OTHERWIN),
+ //thread->readMiscReg(MISCREG_OTHERWIN),
+ thread->readIntReg(NumIntArchRegs + 6),
shared_data->otherwin);
printRegPair(outs, "Cleanwin",
- thread->readMiscReg(MISCREG_CLEANWIN),
+ //thread->readMiscReg(MISCREG_CLEANWIN),
+ thread->readIntReg(NumIntArchRegs + 5),
shared_data->cleanwin);
outs << endl;
for (int i = 1; i <= MaxTL; i++) {
@@ -588,26 +625,22 @@ Trace::InstRecord::dump(ostream &outs)
printSectionHeader(outs, "General Purpose Registers");
static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
- for(int y = 0; y < 4; y++)
- {
- for(int x = 0; x < 8; x++)
- {
+ for(int y = 0; y < 4; y++) {
+ for(int x = 0; x < 8; x++) {
char label[8];
sprintf(label, "%s%d", regtypes[y], x);
printRegPair(outs, label,
thread->readIntReg(y*8+x),
shared_data->intregs[y*8+x]);
- /*outs << regtypes[y] << x << " " ;
- outs << "0x" << hex << setw(16)
- << thread->readIntReg(y*8+x);
- if (thread->readIntReg(y*8 + x)
- != shared_data->intregs[y*8+x])
- outs << " X ";
- else
- outs << " | ";
- outs << "0x" << setw(16) << hex
- << shared_data->intregs[y*8+x]
- << endl;*/
+ }
+ }
+ if (diffFpRegs) {
+ for (int x = 0; x < 32; x++) {
+ char label[8];
+ sprintf(label, "%%f%d", x);
+ printRegPair(outs, label,
+ thread->readFloatRegBits(x,FloatRegFile::DoubleWidth),
+ shared_data->fpregs[x]);
}
}
if (diffTlb) {
diff --git a/src/cpu/exetrace.hh b/src/cpu/exetrace.hh
index 6562e5265..a825f6a82 100644
--- a/src/cpu/exetrace.hh
+++ b/src/cpu/exetrace.hh
@@ -32,6 +32,7 @@
#ifndef __EXETRACE_HH__
#define __EXETRACE_HH__
+#include <cstring>
#include <fstream>
#include <vector>
@@ -169,7 +170,7 @@ InstRecord::setRegs(const IntRegFile &regs)
if (!iregs)
iregs = new iRegFile;
- memcpy(&iregs->regs, &regs, sizeof(IntRegFile));
+ std::memcpy(&iregs->regs, &regs, sizeof(IntRegFile));
regs_valid = true;
}
diff --git a/src/cpu/m5legion_interface.h b/src/cpu/m5legion_interface.h
index c3ba5986e..373dc5cdc 100644
--- a/src/cpu/m5legion_interface.h
+++ b/src/cpu/m5legion_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2006-2007 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
#include <unistd.h>
-#define VERSION 0xA1000007
+#define VERSION 0xA1000009
#define OWN_M5 0x000000AA
#define OWN_LEGION 0x00000055
@@ -47,6 +47,7 @@ typedef struct {
uint32_t instruction;
uint32_t new_instruction;
uint64_t intregs[32];
+ uint64_t fpregs[32];
uint64_t tpc[8];
uint64_t tnpc[8];
@@ -60,6 +61,7 @@ typedef struct {
uint16_t pstate;
uint64_t y;
+ uint64_t fsr;
uint8_t ccr;
uint8_t tl;
uint8_t gl;
diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh
index 0078db69f..4a2086296 100644
--- a/src/cpu/o3/alpha/cpu.hh
+++ b/src/cpu/o3/alpha/cpu.hh
@@ -37,12 +37,6 @@
#include "cpu/o3/cpu.hh"
#include "sim/byteswap.hh"
-namespace TheISA
-{
- class ITB;
- class DTB;
-}
-
class EndQuiesceEvent;
namespace Kernel {
class Statistics;
@@ -61,14 +55,6 @@ class TranslatingPort;
template <class Impl>
class AlphaO3CPU : public FullO3CPU<Impl>
{
- protected:
- typedef TheISA::IntReg IntReg;
- typedef TheISA::FloatReg FloatReg;
- typedef TheISA::FloatRegBits FloatRegBits;
- typedef TheISA::MiscReg MiscReg;
- typedef TheISA::RegFile RegFile;
- typedef TheISA::MiscRegFile MiscRegFile;
-
public:
typedef O3ThreadState<Impl> ImplState;
typedef O3ThreadState<Impl> Thread;
@@ -77,13 +63,6 @@ class AlphaO3CPU : public FullO3CPU<Impl>
/** Constructs an AlphaO3CPU with the given parameters. */
AlphaO3CPU(Params *params);
-#if FULL_SYSTEM
- /** ITB pointer. */
- AlphaISA::ITB *itb;
- /** DTB pointer. */
- AlphaISA::DTB *dtb;
-#endif
-
/** Registers statistics. */
void regStats();
@@ -91,19 +70,19 @@ class AlphaO3CPU : public FullO3CPU<Impl>
/** Translates instruction requestion. */
Fault translateInstReq(RequestPtr &req, Thread *thread)
{
- return itb->translate(req, thread->getTC());
+ return this->itb->translate(req, thread->getTC());
}
/** Translates data read request. */
Fault translateDataReadReq(RequestPtr &req, Thread *thread)
{
- return dtb->translate(req, thread->getTC(), false);
+ return this->dtb->translate(req, thread->getTC(), false);
}
/** Translates data write request. */
Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
{
- return dtb->translate(req, thread->getTC(), true);
+ return this->dtb->translate(req, thread->getTC(), true);
}
#else
@@ -127,20 +106,22 @@ class AlphaO3CPU : public FullO3CPU<Impl>
#endif
/** Reads a miscellaneous register. */
- MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid);
+ void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
+ unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid);
+ void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val,
+ unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
@@ -175,10 +156,10 @@ class AlphaO3CPU : public FullO3CPU<Impl>
*/
void syscall(int64_t callnum, int tid);
/** Gets a syscall argument. */
- IntReg getSyscallArg(int i, int tid);
+ TheISA::IntReg getSyscallArg(int i, int tid);
/** Used to shift args for indirect syscall. */
- void setSyscallArg(int i, IntReg val, int tid);
+ void setSyscallArg(int i, TheISA::IntReg val, int tid);
/** Sets the return value of a syscall. */
void setSyscallReturn(SyscallReturn return_value, int tid);
diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh
index 980e70fdd..41f149963 100644
--- a/src/cpu/o3/alpha/cpu_impl.hh
+++ b/src/cpu/o3/alpha/cpu_impl.hh
@@ -55,12 +55,7 @@
#endif
template <class Impl>
-AlphaO3CPU<Impl>::AlphaO3CPU(Params *params)
-#if FULL_SYSTEM
- : FullO3CPU<Impl>(params), itb(params->itb), dtb(params->dtb)
-#else
- : FullO3CPU<Impl>(params)
-#endif
+AlphaO3CPU<Impl>::AlphaO3CPU(Params *params) : FullO3CPU<Impl>(params)
{
DPRINTF(O3CPU, "Creating AlphaO3CPU object.\n");
@@ -173,15 +168,16 @@ AlphaO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
template <class Impl>
void
-AlphaO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
+AlphaO3CPU<Impl>::setMiscReg(int misc_reg, const TheISA::MiscReg &val,
+ unsigned tid)
{
this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
void
-AlphaO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
- unsigned tid)
+AlphaO3CPU<Impl>::setMiscRegWithEffect(int misc_reg,
+ const TheISA::MiscReg &val, unsigned tid)
{
this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
}
@@ -312,7 +308,7 @@ AlphaO3CPU<Impl>::getSyscallArg(int i, int tid)
template <class Impl>
void
-AlphaO3CPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
+AlphaO3CPU<Impl>::setSyscallArg(int i, TheISA::IntReg val, int tid)
{
this->setArchIntReg(AlphaISA::ArgumentReg0 + i, val, tid);
}
@@ -321,17 +317,6 @@ template <class Impl>
void
AlphaO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
- // check for error condition. Alpha syscall convention is to
- // indicate success/failure in reg a3 (r19) and put the
- // return value itself in the standard return value reg (v0).
- if (return_value.successful()) {
- // no error
- this->setArchIntReg(TheISA::SyscallSuccessReg, 0, tid);
- this->setArchIntReg(TheISA::ReturnValueReg, return_value.value(), tid);
- } else {
- // got an error, return details
- this->setArchIntReg(TheISA::SyscallSuccessReg, (IntReg) -1, tid);
- this->setArchIntReg(TheISA::ReturnValueReg, -return_value.value(), tid);
- }
+ TheISA::setSyscallReturn(return_value, this->tcBase(tid));
}
#endif
diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh
index 49cc5a201..603a1b52d 100644
--- a/src/cpu/o3/alpha/dyn_inst.hh
+++ b/src/cpu/o3/alpha/dyn_inst.hh
@@ -73,8 +73,9 @@ class AlphaDynInst : public BaseDynInst<Impl>
public:
/** BaseDynInst constructor given a binary instruction. */
- AlphaDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC, InstSeqNum seq_num,
- O3CPU *cpu);
+ AlphaDynInst(ExtMachInst inst, Addr PC, Addr NPC,
+ Addr Pred_PC, Addr Pred_NPC,
+ InstSeqNum seq_num, O3CPU *cpu);
/** BaseDynInst constructor given a static inst pointer. */
AlphaDynInst(StaticInstPtr &_staticInst);
@@ -123,6 +124,44 @@ class AlphaDynInst : public BaseDynInst<Impl>
this->threadNumber);
}
+ /** Reads a miscellaneous register. */
+ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+ {
+ return this->cpu->readMiscReg(
+ si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+ this->threadNumber);
+ }
+
+ /** Reads a misc. register, including any side-effects the read
+ * might have as defined by the architecture.
+ */
+ TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ {
+ return this->cpu->readMiscRegWithEffect(
+ si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+ this->threadNumber);
+ }
+
+ /** Sets a misc. register. */
+ void setMiscRegOperand(const StaticInst * si, int idx, const MiscReg &val)
+ {
+ this->instResult.integer = val;
+ return this->cpu->setMiscReg(
+ si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+ val, this->threadNumber);
+ }
+
+ /** Sets a misc. register, including any side-effects the write
+ * might have as defined by the architecture.
+ */
+ void setMiscRegOperandWithEffect(const StaticInst *si, int idx,
+ const MiscReg &val)
+ {
+ return this->cpu->setMiscRegWithEffect(
+ si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+ val, this->threadNumber);
+ }
+
#if FULL_SYSTEM
/** Calls hardware return from error interrupt. */
Fault hwrei();
@@ -134,22 +173,6 @@ class AlphaDynInst : public BaseDynInst<Impl>
void syscall(int64_t callnum);
#endif
- private:
- /** Physical register index of the destination registers of this
- * instruction.
- */
- PhysRegIndex _destRegIdx[MaxInstDestRegs];
-
- /** Physical register index of the source registers of this
- * instruction.
- */
- PhysRegIndex _srcRegIdx[MaxInstSrcRegs];
-
- /** Physical register index of the previous producers of the
- * architected destinations.
- */
- PhysRegIndex _prevDestRegIdx[MaxInstDestRegs];
-
public:
// The register accessor methods provide the index of the
@@ -165,28 +188,28 @@ class AlphaDynInst : public BaseDynInst<Impl>
uint64_t readIntRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readIntReg(_srcRegIdx[idx]);
+ return this->cpu->readIntReg(this->_srcRegIdx[idx]);
}
FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width)
{
- return this->cpu->readFloatReg(_srcRegIdx[idx], width);
+ return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
}
FloatReg readFloatRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readFloatReg(_srcRegIdx[idx]);
+ return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
}
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx,
int width)
{
- return this->cpu->readFloatRegBits(_srcRegIdx[idx], width);
+ return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
}
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
{
- return this->cpu->readFloatRegBits(_srcRegIdx[idx]);
+ return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
}
/** @todo: Make results into arrays so they can handle multiple dest
@@ -194,79 +217,37 @@ class AlphaDynInst : public BaseDynInst<Impl>
*/
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
{
- this->cpu->setIntReg(_destRegIdx[idx], val);
+ this->cpu->setIntReg(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
}
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
int width)
{
- this->cpu->setFloatReg(_destRegIdx[idx], val, width);
+ this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
}
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
{
- this->cpu->setFloatReg(_destRegIdx[idx], val);
+ this->cpu->setFloatReg(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
}
void setFloatRegOperandBits(const StaticInst *si, int idx,
FloatRegBits val, int width)
{
- this->cpu->setFloatRegBits(_destRegIdx[idx], val, width);
+ this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
void setFloatRegOperandBits(const StaticInst *si, int idx,
FloatRegBits val)
{
- this->cpu->setFloatRegBits(_destRegIdx[idx], val);
+ this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
- /** Returns the physical register index of the i'th destination
- * register.
- */
- PhysRegIndex renamedDestRegIdx(int idx) const
- {
- return _destRegIdx[idx];
- }
-
- /** Returns the physical register index of the i'th source register. */
- PhysRegIndex renamedSrcRegIdx(int idx) const
- {
- return _srcRegIdx[idx];
- }
-
- /** Returns the physical register index of the previous physical register
- * that remapped to the same logical register index.
- */
- PhysRegIndex prevDestRegIdx(int idx) const
- {
- return _prevDestRegIdx[idx];
- }
-
- /** Renames a destination register to a physical register. Also records
- * the previous physical register that the logical register mapped to.
- */
- void renameDestReg(int idx,
- PhysRegIndex renamed_dest,
- PhysRegIndex previous_rename)
- {
- _destRegIdx[idx] = renamed_dest;
- _prevDestRegIdx[idx] = previous_rename;
- }
-
- /** Renames a source logical register to the physical register which
- * has/will produce that logical register's result.
- * @todo: add in whether or not the source register is ready.
- */
- void renameSrcReg(int idx, PhysRegIndex renamed_src)
- {
- _srcRegIdx[idx] = renamed_src;
- }
-
public:
/** Calculates EA part of a memory instruction. Currently unused,
* though it may be useful in the future if we want to split
diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh
index 6fc548a85..50cdec408 100644
--- a/src/cpu/o3/alpha/dyn_inst_impl.hh
+++ b/src/cpu/o3/alpha/dyn_inst_impl.hh
@@ -31,9 +31,10 @@
#include "cpu/o3/alpha/dyn_inst.hh"
template <class Impl>
-AlphaDynInst<Impl>::AlphaDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC,
+AlphaDynInst<Impl>::AlphaDynInst(ExtMachInst inst, Addr PC, Addr NPC,
+ Addr Pred_PC, Addr Pred_NPC,
InstSeqNum seq_num, O3CPU *cpu)
- : BaseDynInst<Impl>(inst, PC, Pred_PC, seq_num, cpu)
+ : BaseDynInst<Impl>(inst, PC, NPC, Pred_PC, Pred_NPC, seq_num, cpu)
{
initVars();
}
@@ -53,11 +54,11 @@ AlphaDynInst<Impl>::initVars()
// as the normal register entries. It will allow the IQ to work
// without any modifications.
for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
- _destRegIdx[i] = this->staticInst->destRegIdx(i);
+ this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
}
for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
- _srcRegIdx[i] = this->staticInst->srcRegIdx(i);
+ this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
this->_readySrcRegIdx[i] = 0;
}
}
diff --git a/src/cpu/o3/alpha/thread_context.hh b/src/cpu/o3/alpha/thread_context.hh
index bcecb7087..6d61501ac 100644
--- a/src/cpu/o3/alpha/thread_context.hh
+++ b/src/cpu/o3/alpha/thread_context.hh
@@ -36,12 +36,6 @@ class AlphaTC : public O3ThreadContext<Impl>
{
public:
#if FULL_SYSTEM
- /** Returns a pointer to the ITB. */
- virtual AlphaISA::ITB *getITBPtr() { return this->cpu->itb; }
-
- /** Returns a pointer to the DTB. */
- virtual AlphaISA::DTB *getDTBPtr() { return this->cpu->dtb; }
-
/** Returns pointer to the quiesce event. */
virtual EndQuiesceEvent *getQuiesceEvent()
{
@@ -51,8 +45,7 @@ class AlphaTC : public O3ThreadContext<Impl>
virtual uint64_t readNextNPC()
{
- panic("Alpha has no NextNPC!");
- return 0;
+ return this->readNextPC() + sizeof(TheISA::MachInst);
}
virtual void setNextNPC(uint64_t val)
diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh
index 477c8e4cb..84c50b4da 100644
--- a/src/cpu/o3/bpred_unit_impl.hh
+++ b/src/cpu/o3/bpred_unit_impl.hh
@@ -149,7 +149,7 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC, unsigned tid)
using TheISA::MachInst;
bool pred_taken = false;
- Addr target;
+ Addr target = PC;
++lookups;
@@ -233,14 +233,7 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC, unsigned tid)
}
}
- if (pred_taken) {
- // Set the PC and the instruction's predicted target.
- PC = target;
- inst->setPredTarg(target);
- } else {
- PC = PC + sizeof(MachInst);
- inst->setPredTarg(PC);
- }
+ PC = target;
predHist[tid].push_front(predict_record);
diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh
index aa58fc20e..d96919007 100644
--- a/src/cpu/o3/comm.hh
+++ b/src/cpu/o3/comm.hh
@@ -87,9 +87,10 @@ struct DefaultIEWDefaultCommit {
bool squash[Impl::MaxThreads];
bool branchMispredict[Impl::MaxThreads];
bool branchTaken[Impl::MaxThreads];
- bool condDelaySlotBranch[Impl::MaxThreads];
+ bool squashDelaySlot[Impl::MaxThreads];
uint64_t mispredPC[Impl::MaxThreads];
uint64_t nextPC[Impl::MaxThreads];
+ uint64_t nextNPC[Impl::MaxThreads];
InstSeqNum squashedSeqNum[Impl::MaxThreads];
bool includeSquashInst[Impl::MaxThreads];
@@ -121,6 +122,7 @@ struct TimeBufStruct {
bool branchTaken;
uint64_t mispredPC;
uint64_t nextPC;
+ uint64_t nextNPC;
unsigned branchCount;
};
@@ -160,6 +162,7 @@ struct TimeBufStruct {
bool branchTaken;
uint64_t mispredPC;
uint64_t nextPC;
+ uint64_t nextNPC;
// Represents the instruction that has either been retired or
// squashed. Similar to having a single bus that broadcasts the
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 483c2f71b..f1457922c 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -519,6 +519,7 @@ DefaultCommit<Impl>::squashAll(unsigned tid)
toIEW->commitInfo[tid].branchMispredict = false;
toIEW->commitInfo[tid].nextPC = PC[tid];
+ toIEW->commitInfo[tid].nextNPC = nextPC[tid];
}
template <class Impl>
@@ -734,27 +735,15 @@ DefaultCommit<Impl>::commit()
InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
#if ISA_HAS_DELAY_SLOT
- InstSeqNum bdelay_done_seq_num;
- bool squash_bdelay_slot;
-
- if (fromIEW->branchMispredict[tid]) {
- if (fromIEW->branchTaken[tid] &&
- fromIEW->condDelaySlotBranch[tid]) {
- DPRINTF(Commit, "[tid:%i]: Cond. delay slot branch"
- "mispredicted as taken. Squashing after previous "
- "inst, [sn:%i]\n",
- tid, squashed_inst);
- bdelay_done_seq_num = squashed_inst;
- squash_bdelay_slot = true;
- } else {
- DPRINTF(Commit, "[tid:%i]: Branch Mispredict. Squashing "
- "after delay slot [sn:%i]\n", tid, squashed_inst+1);
- bdelay_done_seq_num = squashed_inst + 1;
- squash_bdelay_slot = false;
- }
- } else {
- bdelay_done_seq_num = squashed_inst;
- squash_bdelay_slot = true;
+ InstSeqNum bdelay_done_seq_num = squashed_inst;
+ bool squash_bdelay_slot = fromIEW->squashDelaySlot[tid];
+ bool branchMispredict = fromIEW->branchMispredict[tid];
+
+ // Squashing/not squashing the branch delay slot only makes
+ // sense when you're squashing from a branch, ie from a branch
+ // mispredict.
+ if (branchMispredict && !squash_bdelay_slot) {
+ bdelay_done_seq_num++;
}
#endif
@@ -793,6 +782,7 @@ DefaultCommit<Impl>::commit()
fromIEW->branchTaken[tid];
toIEW->commitInfo[tid].nextPC = fromIEW->nextPC[tid];
+ toIEW->commitInfo[tid].nextNPC = fromIEW->nextNPC[tid];
toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid];
@@ -1122,7 +1112,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// Update the commit rename map
for (int i = 0; i < head_inst->numDestRegs(); i++) {
- renameMap[tid]->setEntry(head_inst->destRegIdx(i),
+ renameMap[tid]->setEntry(head_inst->flattenedDestRegIdx(i),
head_inst->renamedDestRegIdx(i));
}
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 18cc87c0b..66c75a12d 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -150,6 +150,10 @@ FullO3CPU<Impl>::DeallocateContextEvent::description()
template <class Impl>
FullO3CPU<Impl>::FullO3CPU(Params *params)
: BaseO3CPU(params),
+#if FULL_SYSTEM
+ itb(params->itb),
+ dtb(params->dtb),
+#endif
tickEvent(this),
removeInstsThisCycle(false),
fetch(params),
@@ -657,9 +661,7 @@ FullO3CPU<Impl>::insertThread(unsigned tid)
//Set PC/NPC/NNPC
setPC(src_tc->readPC(), tid);
setNextPC(src_tc->readNextPC(), tid);
-#if ISA_HAS_DELAY_SLOT
setNextNPC(src_tc->readNextNPC(), tid);
-#endif
src_tc->setStatus(ThreadContext::Active);
@@ -698,7 +700,7 @@ FullO3CPU<Impl>::removeThread(unsigned tid)
// Squash Throughout Pipeline
InstSeqNum squash_seq_num = commit.rob->readHeadInst(tid)->seqNum;
- fetch.squash(0, squash_seq_num, true, tid);
+ fetch.squash(0, sizeof(TheISA::MachInst), squash_seq_num, true, tid);
decode.squash(tid);
rename.squash(squash_seq_num, tid);
iew.squash(tid);
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 2bf9cb23b..d217a3e85 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -91,9 +91,6 @@ template <class Impl>
class FullO3CPU : public BaseO3CPU
{
public:
- typedef TheISA::FloatReg FloatReg;
- typedef TheISA::FloatRegBits FloatRegBits;
-
// Typedefs from the Impl here.
typedef typename Impl::CPUPol CPUPolicy;
typedef typename Impl::Params Params;
@@ -114,6 +111,11 @@ class FullO3CPU : public BaseO3CPU
SwitchedOut
};
+#if FULL_SYSTEM
+ TheISA::ITB * itb;
+ TheISA::DTB * dtb;
+#endif
+
/** Overall CPU status. */
Status _status;
@@ -382,23 +384,23 @@ class FullO3CPU : public BaseO3CPU
/** Register accessors. Index refers to the physical register index. */
uint64_t readIntReg(int reg_idx);
- FloatReg readFloatReg(int reg_idx);
+ TheISA::FloatReg readFloatReg(int reg_idx);
- FloatReg readFloatReg(int reg_idx, int width);
+ TheISA::FloatReg readFloatReg(int reg_idx, int width);
- FloatRegBits readFloatRegBits(int reg_idx);
+ TheISA::FloatRegBits readFloatRegBits(int reg_idx);
- FloatRegBits readFloatRegBits(int reg_idx, int width);
+ TheISA::FloatRegBits readFloatRegBits(int reg_idx, int width);
void setIntReg(int reg_idx, uint64_t val);
- void setFloatReg(int reg_idx, FloatReg val);
+ void setFloatReg(int reg_idx, TheISA::FloatReg val);
- void setFloatReg(int reg_idx, FloatReg val, int width);
+ void setFloatReg(int reg_idx, TheISA::FloatReg val, int width);
- void setFloatRegBits(int reg_idx, FloatRegBits val);
+ void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val);
- void setFloatRegBits(int reg_idx, FloatRegBits val, int width);
+ void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val, int width);
uint64_t readArchIntReg(int reg_idx, unsigned tid);
diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh
index 26ed40c67..79a0bfdbf 100644
--- a/src/cpu/o3/decode_impl.hh
+++ b/src/cpu/o3/decode_impl.hh
@@ -282,6 +282,10 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
toFetch->decodeInfo[tid].squash = true;
toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
+ ///FIXME There needs to be a way to set the nextPC and nextNPC
+ ///explicitly for ISAs with delay slots.
+ toFetch->decodeInfo[tid].nextNPC =
+ inst->branchTarget() + sizeof(TheISA::MachInst);
#if ISA_HAS_DELAY_SLOT
toFetch->decodeInfo[tid].branchTaken = inst->readNextNPC() !=
(inst->readNextPC() + sizeof(TheISA::MachInst));
@@ -743,9 +747,9 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
// Ensure that if it was predicted as a branch, it really is a
// branch.
- if (inst->predTaken() && !inst->isControl()) {
- DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n",inst->predPC,
- inst->nextPC + 4);
+ if (inst->readPredTaken() && !inst->isControl()) {
+ DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n",
+ inst->readPredPC(), inst->readNextPC() + 4);
panic("Instruction predicted as a branch!");
@@ -762,26 +766,29 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
++decodeBranchResolved;
- if (inst->branchTarget() != inst->readPredTarg()) {
+ if (inst->branchTarget() != inst->readPredPC()) {
++decodeBranchMispred;
// Might want to set some sort of boolean and just do
// a check at the end
#if !ISA_HAS_DELAY_SLOT
squash(inst, inst->threadNumber);
- inst->setPredTarg(inst->branchTarget());
+ Addr target = inst->branchTarget();
+ inst->setPredTarg(target, target + sizeof(TheISA::MachInst));
break;
#else
// If mispredicted as taken, then ignore delay slot
// instruction... else keep delay slot and squash
// after it is sent to rename
- if (inst->predTaken() && inst->isCondDelaySlot()) {
+ if (inst->readPredTaken() && inst->isCondDelaySlot()) {
DPRINTF(Decode, "[tid:%i]: Conditional delay slot inst."
"[sn:%i] PC %#x mispredicted as taken.\n", tid,
inst->seqNum, inst->PC);
bdelayDoneSeqNum[tid] = inst->seqNum;
squash(inst, inst->threadNumber);
- inst->setPredTarg(inst->branchTarget());
+ Addr target = inst->branchTarget();
+ inst->setPredTarg(target,
+ target + sizeof(TheISA::MachInst));
break;
} else {
DPRINTF(Decode, "[tid:%i]: Misprediction detected at "
@@ -800,7 +807,9 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
if (squashAfterDelaySlot[tid]) {
assert(!inst->isSquashed());
squash(squashInst[tid], squashInst[tid]->threadNumber);
- squashInst[tid]->setPredTarg(squashInst[tid]->branchTarget());
+ Addr target = squashInst[tid]->branchTarget();
+ squashInst[tid]->setPredTarg(target,
+ target + sizeof(TheISA::MachInst));
assert(!inst->isSquashed());
break;
}
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index e880e14e4..8347ed775 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -239,13 +239,13 @@ class DefaultFetch
bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid);
/** Squashes a specific thread and resets the PC. */
- inline void doSquash(const Addr &new_PC, unsigned tid);
+ inline void doSquash(const Addr &new_PC, const Addr &new_NPC, unsigned tid);
/** Squashes a specific thread and resets the PC. Also tells the CPU to
* remove any instructions between fetch and decode that should be sqaushed.
*/
- void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num,
- unsigned tid);
+ void squashFromDecode(const Addr &new_PC, const Addr &new_NPC,
+ const InstSeqNum &seq_num, unsigned tid);
/** Checks if a thread is stalled. */
bool checkStall(unsigned tid) const;
@@ -259,7 +259,8 @@ class DefaultFetch
* remove any instructions that are not in the ROB. The source of this
* squash should be the commit stage.
*/
- void squash(const Addr &new_PC, const InstSeqNum &seq_num,
+ void squash(const Addr &new_PC, const Addr &new_NPC,
+ const InstSeqNum &seq_num,
bool squash_delay_slot, unsigned tid);
/** Ticks the fetch stage, processing all inputs signals and fetching
@@ -361,19 +362,6 @@ class DefaultFetch
/** Tracks how many instructions has been fetched this cycle. */
int numInst;
- /** Tracks delay slot information for threads in ISAs which use
- * delay slots;
- */
- struct DelaySlotInfo {
- InstSeqNum delaySlotSeqNum;
- InstSeqNum branchSeqNum;
- int numInsts;
- Addr targetAddr;
- bool targetReady;
- };
-
- DelaySlotInfo delaySlotInfo[Impl::MaxThreads];
-
/** Source of possible stalls. */
struct Stalls {
bool decode;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index fe320fa79..b80fc72e1 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -319,9 +319,7 @@ DefaultFetch<Impl>::initStage()
for (int tid = 0; tid < numThreads; tid++) {
PC[tid] = cpu->readPC(tid);
nextPC[tid] = cpu->readNextPC(tid);
-#if ISA_HAS_DELAY_SLOT
nextNPC[tid] = cpu->readNextNPC(tid);
-#endif
}
// Size of cache block.
@@ -343,11 +341,6 @@ DefaultFetch<Impl>::initStage()
cacheDataPC[tid] = 0;
cacheDataValid[tid] = false;
- delaySlotInfo[tid].branchSeqNum = -1;
- delaySlotInfo[tid].numInsts = 0;
- delaySlotInfo[tid].targetAddr = 0;
- delaySlotInfo[tid].targetReady = false;
-
stalls[tid].decode = false;
stalls[tid].rename = false;
stalls[tid].iew = false;
@@ -441,10 +434,8 @@ DefaultFetch<Impl>::takeOverFrom()
nextPC[i] = cpu->readNextPC(i);
#if ISA_HAS_DELAY_SLOT
nextNPC[i] = cpu->readNextNPC(i);
- delaySlotInfo[i].branchSeqNum = -1;
- delaySlotInfo[i].numInsts = 0;
- delaySlotInfo[i].targetAddr = 0;
- delaySlotInfo[i].targetReady = false;
+#else
+ nextNPC[i] = nextPC[i] + sizeof(TheISA::MachInst);
#endif
fetchStatus[i] = Running;
}
@@ -503,54 +494,41 @@ DefaultFetch<Impl>::lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC,
bool predict_taken;
if (!inst->isControl()) {
-#if ISA_HAS_DELAY_SLOT
- Addr cur_PC = next_PC;
- next_PC = cur_PC + instSize; //next_NPC;
- next_NPC = cur_PC + (2 * instSize);//next_NPC + instSize;
- inst->setPredTarg(next_NPC);
-#else
- next_PC = next_PC + instSize;
- inst->setPredTarg(next_PC);
-#endif
+ next_PC = next_NPC;
+ next_NPC = next_NPC + instSize;
+ inst->setPredTarg(next_PC, next_NPC);
+ inst->setPredTaken(false);
return false;
}
int tid = inst->threadNumber;
-#if ISA_HAS_DELAY_SLOT
Addr pred_PC = next_PC;
predict_taken = branchPred.predict(inst, pred_PC, tid);
- if (predict_taken) {
- DPRINTF(Fetch, "[tid:%i]: Branch predicted to be true.\n", tid);
+/* if (predict_taken) {
+ DPRINTF(Fetch, "[tid:%i]: Branch predicted to be taken to %#x.\n",
+ tid, pred_PC);
} else {
- DPRINTF(Fetch, "[tid:%i]: Branch predicted to be false.\n", tid);
- }
+ DPRINTF(Fetch, "[tid:%i]: Branch predicted to be not taken.\n", tid);
+ }*/
- if (predict_taken) {
- next_PC = next_NPC;
+#if ISA_HAS_DELAY_SLOT
+ next_PC = next_NPC;
+ if (predict_taken)
next_NPC = pred_PC;
-
- // Update delay slot info
- ++delaySlotInfo[tid].numInsts;
- delaySlotInfo[tid].targetAddr = pred_PC;
- DPRINTF(Fetch, "[tid:%i]: %i delay slot inst(s) to process.\n", tid,
- delaySlotInfo[tid].numInsts);
- } else { // !predict_taken
- if (inst->isCondDelaySlot()) {
- next_PC = pred_PC;
- // The delay slot is skipped here if there is on
- // prediction
- } else {
- next_PC = next_NPC;
- // No need to declare a delay slot here since
- // there is no for the pred. target to jump
- }
-
- next_NPC = next_NPC + instSize;
- }
+ else
+ next_NPC += instSize;
#else
- predict_taken = branchPred.predict(inst, next_PC, tid);
+ if (predict_taken)
+ next_PC = pred_PC;
+ else
+ next_PC += instSize;
+ next_NPC = next_PC + instSize;
#endif
+/* DPRINTF(Fetch, "[tid:%i]: Branch predicted to go to %#x and then %#x.\n",
+ tid, next_PC, next_NPC);*/
+ inst->setPredTarg(next_PC, next_NPC);
+ inst->setPredTaken(predict_taken);
++fetchedBranches;
@@ -671,14 +649,15 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
template <class Impl>
inline void
-DefaultFetch<Impl>::doSquash(const Addr &new_PC, unsigned tid)
+DefaultFetch<Impl>::doSquash(const Addr &new_PC,
+ const Addr &new_NPC, unsigned tid)
{
- DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %#x.\n",
- tid, new_PC);
+ DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %#x, NPC to: %#x.\n",
+ tid, new_PC, new_NPC);
PC[tid] = new_PC;
- nextPC[tid] = new_PC + instSize;
- nextNPC[tid] = new_PC + (2 * instSize);
+ nextPC[tid] = new_NPC;
+ nextNPC[tid] = new_NPC + instSize;
// Clear the icache miss if it's outstanding.
if (fetchStatus[tid] == IcacheWaitResponse) {
@@ -704,21 +683,13 @@ DefaultFetch<Impl>::doSquash(const Addr &new_PC, unsigned tid)
template<class Impl>
void
-DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC,
+DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC, const Addr &new_NPC,
const InstSeqNum &seq_num,
unsigned tid)
{
DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid);
- doSquash(new_PC, tid);
-
-#if ISA_HAS_DELAY_SLOT
- if (seq_num <= delaySlotInfo[tid].branchSeqNum) {
- delaySlotInfo[tid].numInsts = 0;
- delaySlotInfo[tid].targetAddr = 0;
- delaySlotInfo[tid].targetReady = false;
- }
-#endif
+ doSquash(new_PC, new_NPC, tid);
// Tell the CPU to remove any instructions that are in flight between
// fetch and decode.
@@ -793,20 +764,15 @@ DefaultFetch<Impl>::updateFetchStatus()
template <class Impl>
void
-DefaultFetch<Impl>::squash(const Addr &new_PC, const InstSeqNum &seq_num,
+DefaultFetch<Impl>::squash(const Addr &new_PC, const Addr &new_NPC,
+ const InstSeqNum &seq_num,
bool squash_delay_slot, unsigned tid)
{
DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid);
- doSquash(new_PC, tid);
+ doSquash(new_PC, new_NPC, tid);
#if ISA_HAS_DELAY_SLOT
- if (seq_num <= delaySlotInfo[tid].branchSeqNum) {
- delaySlotInfo[tid].numInsts = 0;
- delaySlotInfo[tid].targetAddr = 0;
- delaySlotInfo[tid].targetReady = false;
- }
-
// Tell the CPU to remove any instructions that are not in the ROB.
cpu->removeInstsNotInROB(tid, squash_delay_slot, seq_num);
#else
@@ -929,6 +895,7 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(unsigned tid)
#endif
// In any case, squash.
squash(fromCommit->commitInfo[tid].nextPC,
+ fromCommit->commitInfo[tid].nextNPC,
doneSeqNum,
fromCommit->commitInfo[tid].squashDelaySlot,
tid);
@@ -984,8 +951,12 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(unsigned tid)
#else
InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum;
#endif
+ DPRINTF(Fetch, "Squashing from decode with PC = %#x, NPC = %#x\n",
+ fromDecode->decodeInfo[tid].nextPC,
+ fromDecode->decodeInfo[tid].nextNPC);
// Squash unless we're already squashing
squashFromDecode(fromDecode->decodeInfo[tid].nextPC,
+ fromDecode->decodeInfo[tid].nextNPC,
doneSeqNum,
tid);
@@ -1042,6 +1013,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// The current PC.
Addr &fetch_PC = PC[tid];
+ Addr &fetch_NPC = nextPC[tid];
+
// Fault code for memory access.
Fault fault = NoFault;
@@ -1098,7 +1071,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
}
Addr next_PC = fetch_PC;
- Addr next_NPC = next_PC + instSize;
+ Addr next_NPC = fetch_NPC;
+
InstSeqNum inst_seq;
MachInst inst;
ExtMachInst ext_inst;
@@ -1117,15 +1091,22 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// ended this fetch block.
bool predicted_branch = false;
- // Need to keep track of whether or not a delay slot
- // instruction has been fetched
-
for (;
offset < cacheBlkSize &&
numInst < fetchWidth &&
- (!predicted_branch || delaySlotInfo[tid].numInsts > 0);
+ !predicted_branch;
++numInst) {
+ // If we're branching after this instruction, quite fetching
+ // from the same block then.
+ predicted_branch =
+ (fetch_PC + sizeof(TheISA::MachInst) != fetch_NPC);
+ if (predicted_branch) {
+ DPRINTF(Fetch, "Branch detected with PC = %#x, NPC = %#x\n",
+ fetch_PC, fetch_NPC);
+ }
+
+
// Get a sequence number.
inst_seq = cpu->getAndIncrementInstSeq();
@@ -1145,8 +1126,9 @@ DefaultFetch<Impl>::fetch(bool &status_change)
#endif
// Create a new DynInst from the instruction fetched.
- DynInstPtr instruction = new DynInst(ext_inst, fetch_PC,
- next_PC,
+ DynInstPtr instruction = new DynInst(ext_inst,
+ fetch_PC, fetch_NPC,
+ next_PC, next_NPC,
inst_seq, cpu);
instruction->setTid(tid);
@@ -1158,6 +1140,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
"[sn:%lli]\n",
tid, instruction->readPC(), inst_seq);
+ //DPRINTF(Fetch, "[tid:%i]: MachInst is %#x\n", tid, ext_inst);
+
DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n",
tid, instruction->staticInst->disassemble(fetch_PC));
@@ -1166,8 +1150,12 @@ DefaultFetch<Impl>::fetch(bool &status_change)
instruction->staticInst,
instruction->readPC());
- predicted_branch = lookupAndUpdateNextPC(instruction, next_PC,
- next_NPC);
+ ///FIXME This needs to be more robust in dealing with delay slots
+#if !ISA_HAS_DELAY_SLOT
+ predicted_branch |=
+#endif
+ lookupAndUpdateNextPC(instruction, next_PC, next_NPC);
+ predicted_branch |= (next_PC != fetch_NPC);
// Add instruction to the CPU's list of instructions.
instruction->setInstListIt(cpu->addInst(instruction));
@@ -1183,6 +1171,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// Move to the next instruction, unless we have a branch.
fetch_PC = next_PC;
+ fetch_NPC = next_NPC;
if (instruction->isQuiesce()) {
DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!",
@@ -1194,29 +1183,6 @@ DefaultFetch<Impl>::fetch(bool &status_change)
}
offset += instSize;
-
-#if ISA_HAS_DELAY_SLOT
- if (predicted_branch) {
- delaySlotInfo[tid].branchSeqNum = inst_seq;
-
- DPRINTF(Fetch, "[tid:%i]: Delay slot branch set to [sn:%i]\n",
- tid, inst_seq);
- continue;
- } else if (delaySlotInfo[tid].numInsts > 0) {
- --delaySlotInfo[tid].numInsts;
-
- // It's OK to set PC to target of branch
- if (delaySlotInfo[tid].numInsts == 0) {
- delaySlotInfo[tid].targetReady = true;
-
- // Break the looping condition
- predicted_branch = true;
- }
-
- DPRINTF(Fetch, "[tid:%i]: %i delay slot inst(s) left to"
- " process.\n", tid, delaySlotInfo[tid].numInsts);
- }
-#endif
}
if (offset >= cacheBlkSize) {
@@ -1225,7 +1191,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
} else if (numInst >= fetchWidth) {
DPRINTF(Fetch, "[tid:%i]: Done fetching, reached fetch bandwidth "
"for this cycle.\n", tid);
- } else if (predicted_branch && delaySlotInfo[tid].numInsts <= 0) {
+ } else if (predicted_branch) {
DPRINTF(Fetch, "[tid:%i]: Done fetching, predicted branch "
"instruction encountered.\n", tid);
}
@@ -1238,26 +1204,13 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// Now that fetching is completed, update the PC to signify what the next
// cycle will be.
if (fault == NoFault) {
+ PC[tid] = next_PC;
+ nextPC[tid] = next_NPC;
+ nextNPC[tid] = next_NPC + instSize;
#if ISA_HAS_DELAY_SLOT
- if (delaySlotInfo[tid].targetReady &&
- delaySlotInfo[tid].numInsts == 0) {
- // Set PC to target
- PC[tid] = delaySlotInfo[tid].targetAddr; //next_PC
- nextPC[tid] = next_PC + instSize; //next_NPC
- nextNPC[tid] = next_PC + (2 * instSize);
-
- delaySlotInfo[tid].targetReady = false;
- } else {
- PC[tid] = next_PC;
- nextPC[tid] = next_NPC;
- nextNPC[tid] = next_NPC + instSize;
- }
-
DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]);
#else
- DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC);
- PC[tid] = next_PC;
- nextPC[tid] = next_PC + instSize;
+ DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, next_PC);
#endif
} else {
// We shouldn't be in an icache miss and also have a fault (an ITB
@@ -1277,10 +1230,11 @@ DefaultFetch<Impl>::fetch(bool &status_change)
ext_inst = TheISA::NoopMachInst;
// Create a new DynInst from the dummy nop.
- DynInstPtr instruction = new DynInst(ext_inst, fetch_PC,
- next_PC,
+ DynInstPtr instruction = new DynInst(ext_inst,
+ fetch_PC, fetch_NPC,
+ next_PC, next_NPC,
inst_seq, cpu);
- instruction->setPredTarg(next_PC + instSize);
+ instruction->setPredTarg(next_PC, next_NPC);
instruction->setTid(tid);
instruction->setASID(tid);
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index a8962f2f7..f24eaf2c4 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -480,23 +480,37 @@ DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid)
toCommit->mispredPC[tid] = inst->readPC();
toCommit->branchMispredict[tid] = true;
+ int instSize = sizeof(TheISA::MachInst);
#if ISA_HAS_DELAY_SLOT
- bool branch_taken = inst->readNextNPC() !=
- (inst->readNextPC() + sizeof(TheISA::MachInst));
+ bool branch_taken =
+ !(inst->readNextPC() + instSize == inst->readNextNPC() &&
+ (inst->readNextPC() == inst->readPC() + instSize ||
+ inst->readNextPC() == inst->readPC() + 2 * instSize));
+ DPRINTF(Sparc, "Branch taken = %s [sn:%i]\n",
+ branch_taken ? "true": "false", inst->seqNum);
toCommit->branchTaken[tid] = branch_taken;
- toCommit->condDelaySlotBranch[tid] = inst->isCondDelaySlot();
-
- if (inst->isCondDelaySlot() && branch_taken) {
+ bool squashDelaySlot = true;
+// (inst->readNextPC() != inst->readPC() + sizeof(TheISA::MachInst));
+ DPRINTF(Sparc, "Squash delay slot = %s [sn:%i]\n",
+ squashDelaySlot ? "true": "false", inst->seqNum);
+ toCommit->squashDelaySlot[tid] = squashDelaySlot;
+ //If we're squashing the delay slot, we need to pick back up at NextPC.
+ //Otherwise, NextPC isn't being squashed, so we should pick back up at
+ //NextNPC.
+ if (squashDelaySlot) {
toCommit->nextPC[tid] = inst->readNextPC();
+ toCommit->nextNPC[tid] = inst->readNextNPC();
} else {
toCommit->nextPC[tid] = inst->readNextNPC();
+ toCommit->nextNPC[tid] = inst->readNextNPC() + instSize;
}
#else
toCommit->branchTaken[tid] = inst->readNextPC() !=
(inst->readPC() + sizeof(TheISA::MachInst));
toCommit->nextPC[tid] = inst->readNextPC();
+ toCommit->nextNPC[tid] = inst->readNextPC() + instSize;
#endif
toCommit->includeSquashInst[tid] = false;
@@ -514,6 +528,11 @@ DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
toCommit->nextPC[tid] = inst->readNextPC();
+#if ISA_HAS_DELAY_SLOT
+ toCommit->nextNPC[tid] = inst->readNextNPC();
+#else
+ toCommit->nextNPC[tid] = inst->readNextPC() + sizeof(TheISA::MachInst);
+#endif
toCommit->branchMispredict[tid] = false;
toCommit->includeSquashInst[tid] = false;
@@ -531,6 +550,11 @@ DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
toCommit->nextPC[tid] = inst->readPC();
+#if ISA_HAS_DELAY_SLOT
+ toCommit->nextNPC[tid] = inst->readNextPC();
+#else
+ toCommit->nextNPC[tid] = inst->readPC() + sizeof(TheISA::MachInst);
+#endif
toCommit->branchMispredict[tid] = false;
// Must include the broadcasted SN in the squash.
@@ -1341,17 +1365,15 @@ DefaultIEW<Impl>::executeInsts()
fetchRedirect[tid] = true;
DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
-#if ISA_HAS_DELAY_SLOT
- DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
- inst->nextNPC);
-#else
- DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
- inst->nextPC);
-#endif
+ DPRINTF(IEW, "Predicted target was %#x, %#x.\n",
+ inst->readPredPC(), inst->readPredNPC());
+ DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
+ " NPC: %#x.\n", inst->readNextPC(),
+ inst->readNextNPC());
// If incorrect, then signal the ROB that it must be squashed.
squashDueToBranch(inst, tid);
- if (inst->predTaken()) {
+ if (inst->readPredTaken()) {
predictedTakenIncorrect++;
} else {
predictedNotTakenIncorrect++;
@@ -1421,7 +1443,7 @@ DefaultIEW<Impl>::writebackInsts()
// mark scoreboard that this instruction is finally complete.
// Either have IEW have direct access to scoreboard, or have this
// as part of backwards communication.
- for (int inst_num = 0; inst_num < issueWidth &&
+ for (int inst_num = 0; inst_num < wbWidth &&
toCommit->insts[inst_num]; inst_num++) {
DynInstPtr inst = toCommit->insts[inst_num];
int tid = inst->threadNumber;
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 14f9d5031..9c7eb7780 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -559,6 +559,12 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
// Cast this to type T?
data = storeQueue[store_idx].data >> shift_amt;
+ // When the data comes from the store queue entry, it's in host
+ // order. When it gets sent to the load, it needs to be in guest
+ // order so when the load converts it again, it ends up back
+ // in host order like the inst expects.
+ data = TheISA::htog(data);
+
assert(!load_inst->memData);
load_inst->memData = new uint8_t[64];
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index 3b84d3411..ebd9301f6 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -597,8 +597,21 @@ LSQUnit<Impl>::writebackStores()
assert(!inst->memData);
inst->memData = new uint8_t[64];
- memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data,
- req->getSize());
+
+ TheISA::IntReg convertedData =
+ TheISA::htog(storeQueue[storeWBIdx].data);
+
+ //FIXME This is a hack to get SPARC working. It, along with endianness
+ //in the memory system in general, need to be straightened out more
+ //formally. The problem is that the data's endianness is swapped when
+ //it's in the 64 bit data field in the store queue. The data that you
+ //want won't start at the beginning of the field anymore unless it was
+ //a 64 bit access.
+ memcpy(inst->memData,
+ (uint8_t *)&convertedData +
+ (TheISA::ByteOrderDiffers ?
+ (sizeof(TheISA::IntReg) - req->getSize()) : 0),
+ req->getSize());
PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
data_pkt->dataStatic(inst->memData);
@@ -612,7 +625,7 @@ LSQUnit<Impl>::writebackStores()
DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x "
"to Addr:%#x, data:%#x [sn:%lli]\n",
storeWBIdx, inst->readPC(),
- req->getPaddr(), *(inst->memData),
+ req->getPaddr(), (int)*(inst->memData),
inst->seqNum);
// @todo: Remove this SC hack once the memory system handles it.
diff --git a/src/cpu/o3/mips/cpu_impl.hh b/src/cpu/o3/mips/cpu_impl.hh
index 08e9ba483..e7dbd3aba 100644
--- a/src/cpu/o3/mips/cpu_impl.hh
+++ b/src/cpu/o3/mips/cpu_impl.hh
@@ -220,16 +220,6 @@ template <class Impl>
void
MipsO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
- // check for error condition.
- if (return_value.successful()) {
- // no error
- this->setArchIntReg(TheISA::SyscallSuccessReg, 0, tid);
- this->setArchIntReg(TheISA::ReturnValueReg, return_value.value(), tid);
- } else {
- // got an error, return details
- this->setArchIntReg(TheISA::SyscallSuccessReg,
- (TheISA::IntReg) -1, tid);
- this->setArchIntReg(TheISA::ReturnValueReg, -return_value.value(), tid);
- }
+ TheISA::setSyscallReturn(return_value, this->tcBase(tid));
}
#endif
diff --git a/src/cpu/o3/mips/dyn_inst.hh b/src/cpu/o3/mips/dyn_inst.hh
index 833371e00..f53530908 100755
--- a/src/cpu/o3/mips/dyn_inst.hh
+++ b/src/cpu/o3/mips/dyn_inst.hh
@@ -54,10 +54,6 @@ class MipsDynInst : public BaseDynInst<Impl>
/** Typedef for the CPU. */
typedef typename Impl::O3CPU O3CPU;
- /** Binary machine instruction type. */
- typedef TheISA::MachInst MachInst;
- /** Extended machine instruction type. */
- typedef TheISA::ExtMachInst ExtMachInst;
/** Logical register index type. */
typedef TheISA::RegIndex RegIndex;
/** Integer register index type. */
@@ -74,8 +70,10 @@ class MipsDynInst : public BaseDynInst<Impl>
public:
/** BaseDynInst constructor given a binary instruction. */
- MipsDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC, InstSeqNum seq_num,
- O3CPU *cpu);
+ MipsDynInst(ExtMachInst inst,
+ Addr PC, Addr NPC,
+ Addr Pred_PC, Addr Pred_NPC,
+ InstSeqNum seq_num, O3CPU *cpu);
/** BaseDynInst constructor given a static inst pointer. */
MipsDynInst(StaticInstPtr &_staticInst);
@@ -127,22 +125,6 @@ class MipsDynInst : public BaseDynInst<Impl>
/** Calls a syscall. */
void syscall(int64_t callnum);
- private:
- /** Physical register index of the destination registers of this
- * instruction.
- */
- PhysRegIndex _destRegIdx[MaxInstDestRegs];
-
- /** Physical register index of the source registers of this
- * instruction.
- */
- PhysRegIndex _srcRegIdx[MaxInstSrcRegs];
-
- /** Physical register index of the previous producers of the
- * architected destinations.
- */
- PhysRegIndex _prevDestRegIdx[MaxInstDestRegs];
-
public:
// The register accessor methods provide the index of the
@@ -158,28 +140,28 @@ class MipsDynInst : public BaseDynInst<Impl>
uint64_t readIntRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readIntReg(_srcRegIdx[idx]);
+ return this->cpu->readIntReg(this->_srcRegIdx[idx]);
}
FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width)
{
- return this->cpu->readFloatReg(_srcRegIdx[idx], width);
+ return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
}
FloatReg readFloatRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readFloatReg(_srcRegIdx[idx]);
+ return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
}
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx,
int width)
{
- return this->cpu->readFloatRegBits(_srcRegIdx[idx], width);
+ return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
}
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
{
- return this->cpu->readFloatRegBits(_srcRegIdx[idx]);
+ return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
}
/** @todo: Make results into arrays so they can handle multiple dest
@@ -187,79 +169,37 @@ class MipsDynInst : public BaseDynInst<Impl>
*/
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
{
- this->cpu->setIntReg(_destRegIdx[idx], val);
+ this->cpu->setIntReg(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
}
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
int width)
{
- this->cpu->setFloatReg(_destRegIdx[idx], val, width);
+ this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
}
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
{
- this->cpu->setFloatReg(_destRegIdx[idx], val);
+ this->cpu->setFloatReg(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
}
void setFloatRegOperandBits(const StaticInst *si, int idx,
FloatRegBits val, int width)
{
- this->cpu->setFloatRegBits(_destRegIdx[idx], val, width);
+ this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
void setFloatRegOperandBits(const StaticInst *si, int idx,
FloatRegBits val)
{
- this->cpu->setFloatRegBits(_destRegIdx[idx], val);
+ this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
- /** Returns the physical register index of the i'th destination
- * register.
- */
- PhysRegIndex renamedDestRegIdx(int idx) const
- {
- return _destRegIdx[idx];
- }
-
- /** Returns the physical register index of the i'th source register. */
- PhysRegIndex renamedSrcRegIdx(int idx) const
- {
- return _srcRegIdx[idx];
- }
-
- /** Returns the physical register index of the previous physical register
- * that remapped to the same logical register index.
- */
- PhysRegIndex prevDestRegIdx(int idx) const
- {
- return _prevDestRegIdx[idx];
- }
-
- /** Renames a destination register to a physical register. Also records
- * the previous physical register that the logical register mapped to.
- */
- void renameDestReg(int idx,
- PhysRegIndex renamed_dest,
- PhysRegIndex previous_rename)
- {
- _destRegIdx[idx] = renamed_dest;
- _prevDestRegIdx[idx] = previous_rename;
- }
-
- /** Renames a source logical register to the physical register which
- * has/will produce that logical register's result.
- * @todo: add in whether or not the source register is ready.
- */
- void renameSrcReg(int idx, PhysRegIndex renamed_src)
- {
- _srcRegIdx[idx] = renamed_src;
- }
-
public:
/** Calculates EA part of a memory instruction. Currently unused,
* though it may be useful in the future if we want to split
diff --git a/src/cpu/o3/mips/dyn_inst_impl.hh b/src/cpu/o3/mips/dyn_inst_impl.hh
index 5bc01b9b3..c0f9ae771 100755
--- a/src/cpu/o3/mips/dyn_inst_impl.hh
+++ b/src/cpu/o3/mips/dyn_inst_impl.hh
@@ -31,9 +31,11 @@
#include "cpu/o3/mips/dyn_inst.hh"
template <class Impl>
-MipsDynInst<Impl>::MipsDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC,
- InstSeqNum seq_num, O3CPU *cpu)
- : BaseDynInst<Impl>(inst, PC, Pred_PC, seq_num, cpu)
+MipsDynInst<Impl>::MipsDynInst(ExtMachInst inst,
+ Addr PC, Addr NPC,
+ Addr Pred_PC, Addr Pred_NPC,
+ InstSeqNum seq_num, O3CPU *cpu)
+ : BaseDynInst<Impl>(inst, PC, NPC, Pred_PC, Pred_NPC, seq_num, cpu)
{
initVars();
}
@@ -53,11 +55,11 @@ MipsDynInst<Impl>::initVars()
// as the normal register entries. It will allow the IQ to work
// without any modifications.
for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
- _destRegIdx[i] = this->staticInst->destRegIdx(i);
+ this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
}
for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
- _srcRegIdx[i] = this->staticInst->srcRegIdx(i);
+ this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
this->_readySrcRegIdx[i] = 0;
}
}
diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh
index 177b9cb87..6b4628f92 100644
--- a/src/cpu/o3/rename.hh
+++ b/src/cpu/o3/rename.hh
@@ -411,6 +411,14 @@ class DefaultRename
/** Whether or not rename needs to block this cycle. */
bool blockThisCycle;
+ /** Whether or not rename needs to resume a serialize instruction
+ * after squashing. */
+ bool resumeSerialize;
+
+ /** Whether or not rename needs to resume clearing out the skidbuffer
+ * after squashing. */
+ bool resumeUnblocking;
+
/** The number of threads active in rename. */
unsigned numThreads;
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index 3a8e503a0..e303f1cee 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -31,6 +31,8 @@
#include <list>
+#include "arch/isa_traits.hh"
+#include "arch/regfile.hh"
#include "config/full_system.hh"
#include "cpu/o3/rename.hh"
@@ -41,6 +43,8 @@ DefaultRename<Impl>::DefaultRename(Params *params)
commitToRenameDelay(params->commitToRenameDelay),
renameWidth(params->renameWidth),
commitWidth(params->commitWidth),
+ resumeSerialize(false),
+ resumeUnblocking(false),
numThreads(params->numberOfThreads),
maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs)
{
@@ -332,12 +336,22 @@ DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, unsigned tid)
// If it still needs to block, the blocking should happen the next
// cycle and there should be space to hold everything due to the squash.
if (renameStatus[tid] == Blocked ||
- renameStatus[tid] == Unblocking ||
- renameStatus[tid] == SerializeStall) {
-
+ renameStatus[tid] == Unblocking) {
toDecode->renameUnblock[tid] = 1;
+ resumeSerialize = false;
serializeInst[tid] = NULL;
+ } else if (renameStatus[tid] == SerializeStall) {
+ if (serializeInst[tid]->seqNum <= squash_seq_num) {
+ DPRINTF(Rename, "Rename will resume serializing after squash\n");
+ resumeSerialize = true;
+ assert(serializeInst[tid]);
+ } else {
+ resumeSerialize = false;
+ toDecode->renameUnblock[tid] = 1;
+
+ serializeInst[tid] = NULL;
+ }
}
// Set the status to Squashing.
@@ -392,6 +406,9 @@ DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, unsigned tid)
}
slist_it++;
}
+ resumeUnblocking = (skidBuffer[tid].size() != 0);
+ DPRINTF(Rename, "Resume unblocking set to %s\n",
+ resumeUnblocking ? "true" : "false");
#else
skidBuffer[tid].clear();
#endif
@@ -476,6 +493,20 @@ DefaultRename<Impl>::rename(bool &status_change, unsigned tid)
++renameSquashCycles;
} else if (renameStatus[tid] == SerializeStall) {
++renameSerializeStallCycles;
+ // If we are currently in SerializeStall and resumeSerialize
+ // was set, then that means that we are resuming serializing
+ // this cycle. Tell the previous stages to block.
+ if (resumeSerialize) {
+ resumeSerialize = false;
+ block(tid);
+ toDecode->renameUnblock[tid] = false;
+ }
+ } else if (renameStatus[tid] == Unblocking) {
+ if (resumeUnblocking) {
+ block(tid);
+ resumeUnblocking = false;
+ toDecode->renameUnblock[tid] = false;
+ }
}
if (renameStatus[tid] == Running ||
@@ -741,7 +772,17 @@ DefaultRename<Impl>::skidInsert(unsigned tid)
}
if (skidBuffer[tid].size() > skidBufferMax)
+ {
+ typename InstQueue::iterator it;
+ warn("Skidbuffer contents:\n");
+ for(it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++)
+ {
+ warn("[tid:%u]: %s [sn:%i].\n", tid,
+ (*it)->staticInst->disassemble(inst->readPC()),
+ (*it)->seqNum);
+ }
panic("Skidbuffer Exceeded Max Size");
+ }
}
template <class Impl>
@@ -830,7 +871,10 @@ DefaultRename<Impl>::block(unsigned tid)
// Only signal backwards to block if the previous stages do not think
// rename is already blocked.
if (renameStatus[tid] != Blocked) {
- if (renameStatus[tid] != Unblocking) {
+ // If resumeUnblocking is set, we unblocked during the squash,
+ // but now we're have unblocking status. We need to tell earlier
+ // stages to block.
+ if (resumeUnblocking || renameStatus[tid] != Unblocking) {
toDecode->renameBlock[tid] = true;
toDecode->renameUnblock[tid] = false;
wroteToTimeBuffer = true;
@@ -963,13 +1007,19 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid)
// Will need to mark dependencies though.
for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
RegIndex src_reg = inst->srcRegIdx(src_idx);
+ RegIndex flat_src_reg = src_reg;
+ if (src_reg < TheISA::FP_Base_DepTag) {
+ flat_src_reg = TheISA::flattenIntIndex(inst->tcBase(), src_reg);
+ DPRINTF(Rename, "Flattening index %d to %d.\n", (int)src_reg, (int)flat_src_reg);
+ }
+ inst->flattenSrcReg(src_idx, flat_src_reg);
// Look up the source registers to get the phys. register they've
// been renamed to, and set the sources to those registers.
- PhysRegIndex renamed_reg = renameMap[tid]->lookup(src_reg);
+ PhysRegIndex renamed_reg = renameMap[tid]->lookup(flat_src_reg);
DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got "
- "physical reg %i.\n", tid, (int)src_reg,
+ "physical reg %i.\n", tid, (int)flat_src_reg,
(int)renamed_reg);
inst->renameSrcReg(src_idx, renamed_reg);
@@ -996,20 +1046,27 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst,unsigned tid)
// Rename the destination registers.
for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
RegIndex dest_reg = inst->destRegIdx(dest_idx);
+ RegIndex flat_dest_reg = dest_reg;
+ if (dest_reg < TheISA::FP_Base_DepTag) {
+ flat_dest_reg = TheISA::flattenIntIndex(inst->tcBase(), dest_reg);
+ DPRINTF(Rename, "Flattening index %d to %d.\n", (int)dest_reg, (int)flat_dest_reg);
+ }
+
+ inst->flattenDestReg(dest_idx, flat_dest_reg);
// Get the physical register that the destination will be
// renamed to.
- rename_result = renameMap[tid]->rename(dest_reg);
+ rename_result = renameMap[tid]->rename(flat_dest_reg);
//Mark Scoreboard entry as not ready
scoreboard->unsetReg(rename_result.first);
DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
- "reg %i.\n", tid, (int)dest_reg,
+ "reg %i.\n", tid, (int)flat_dest_reg,
(int)rename_result.first);
// Record the rename information so that a history can be kept.
- RenameHistory hb_entry(inst->seqNum, dest_reg,
+ RenameHistory hb_entry(inst->seqNum, flat_dest_reg,
rename_result.first,
rename_result.second);
@@ -1233,12 +1290,24 @@ DefaultRename<Impl>::checkSignalsAndUpdate(unsigned tid)
if (renameStatus[tid] == Squashing) {
// Switch status to running if rename isn't being told to block or
// squash this cycle.
- DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n",
- tid);
+ if (resumeSerialize) {
+ DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n",
+ tid);
- renameStatus[tid] = Running;
+ renameStatus[tid] = SerializeStall;
+ return true;
+ } else if (resumeUnblocking) {
+ DPRINTF(Rename, "[tid:%u]: Done squashing, switching to unblocking.\n",
+ tid);
+ renameStatus[tid] = Unblocking;
+ return true;
+ } else {
+ DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n",
+ tid);
- return false;
+ renameStatus[tid] = Running;
+ return false;
+ }
}
if (renameStatus[tid] == SerializeStall) {
diff --git a/src/cpu/o3/sparc/cpu.hh b/src/cpu/o3/sparc/cpu.hh
index c4df79832..08ebd2710 100644
--- a/src/cpu/o3/sparc/cpu.hh
+++ b/src/cpu/o3/sparc/cpu.hh
@@ -37,12 +37,6 @@
#include "cpu/o3/cpu.hh"
#include "sim/byteswap.hh"
-namespace TheISA
-{
- class ITB;
- class DTB;
-}
-
class EndQuiesceEvent;
namespace Kernel {
class Statistics;
@@ -61,14 +55,6 @@ class TranslatingPort;
template <class Impl>
class SparcO3CPU : public FullO3CPU<Impl>
{
- protected:
- typedef TheISA::IntReg IntReg;
- typedef TheISA::FloatReg FloatReg;
- typedef TheISA::FloatRegBits FloatRegBits;
- typedef TheISA::MiscReg MiscReg;
- typedef TheISA::RegFile RegFile;
- typedef TheISA::MiscRegFile MiscRegFile;
-
public:
typedef O3ThreadState<Impl> ImplState;
typedef O3ThreadState<Impl> Thread;
@@ -77,13 +63,6 @@ class SparcO3CPU : public FullO3CPU<Impl>
/** Constructs an AlphaO3CPU with the given parameters. */
SparcO3CPU(Params *params);
-#if FULL_SYSTEM
- /** ITB pointer. */
- SparcISA::ITB *itb;
- /** DTB pointer. */
- SparcISA::DTB *dtb;
-#endif
-
/** Registers statistics. */
void regStats();
@@ -91,19 +70,19 @@ class SparcO3CPU : public FullO3CPU<Impl>
/** Translates instruction requestion. */
Fault translateInstReq(RequestPtr &req, Thread *thread)
{
- return itb->translate(req, thread->getTC());
+ return this->itb->translate(req, thread->getTC());
}
/** Translates data read request. */
Fault translateDataReadReq(RequestPtr &req, Thread *thread)
{
- return dtb->translate(req, thread->getTC(), false);
+ return this->dtb->translate(req, thread->getTC(), false);
}
/** Translates data write request. */
Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
{
- return dtb->translate(req, thread->getTC(), true);
+ return this->dtb->translate(req, thread->getTC(), true);
}
#else
@@ -127,20 +106,21 @@ class SparcO3CPU : public FullO3CPU<Impl>
#endif
/** Reads a miscellaneous register. */
- MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid);
+ void setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid);
+ void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val,
+ unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
@@ -175,10 +155,10 @@ class SparcO3CPU : public FullO3CPU<Impl>
*/
void syscall(int64_t callnum, int tid);
/** Gets a syscall argument. */
- IntReg getSyscallArg(int i, int tid);
+ TheISA::IntReg getSyscallArg(int i, int tid);
/** Used to shift args for indirect syscall. */
- void setSyscallArg(int i, IntReg val, int tid);
+ void setSyscallArg(int i, TheISA::IntReg val, int tid);
/** Sets the return value of a syscall. */
void setSyscallReturn(SyscallReturn return_value, int tid);
@@ -204,4 +184,4 @@ class SparcO3CPU : public FullO3CPU<Impl>
bool lockFlag;
};
-#endif // __CPU_O3_ALPHA_CPU_HH__
+#endif // __CPU_O3_SPARC_CPU_HH__
diff --git a/src/cpu/o3/sparc/cpu_builder.cc b/src/cpu/o3/sparc/cpu_builder.cc
index 81f419ee0..3cac89bad 100644
--- a/src/cpu/o3/sparc/cpu_builder.cc
+++ b/src/cpu/o3/sparc/cpu_builder.cc
@@ -55,8 +55,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU)
#if FULL_SYSTEM
SimObjectParam<System *> system;
Param<int> cpu_id;
- SimObjectParam<AlphaISA::ITB *> itb;
- SimObjectParam<AlphaISA::DTB *> dtb;
+ SimObjectParam<SparcISA::ITB *> itb;
+ SimObjectParam<SparcISA::DTB *> dtb;
Param<Tick> profile;
Param<bool> do_quiesce;
diff --git a/src/cpu/o3/sparc/cpu_impl.hh b/src/cpu/o3/sparc/cpu_impl.hh
index 66bf7d1c0..c039a8fec 100644
--- a/src/cpu/o3/sparc/cpu_impl.hh
+++ b/src/cpu/o3/sparc/cpu_impl.hh
@@ -55,12 +55,7 @@
#endif
template <class Impl>
-SparcO3CPU<Impl>::SparcO3CPU(Params *params)
-#if FULL_SYSTEM
- : FullO3CPU<Impl>(params), itb(params->itb), dtb(params->dtb)
-#else
- : FullO3CPU<Impl>(params)
-#endif
+SparcO3CPU<Impl>::SparcO3CPU(Params *params) : FullO3CPU<Impl>(params)
{
DPRINTF(O3CPU, "Creating SparcO3CPU object.\n");
@@ -172,15 +167,16 @@ SparcO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
template <class Impl>
void
-SparcO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
+SparcO3CPU<Impl>::setMiscReg(int misc_reg,
+ const SparcISA::MiscReg &val, unsigned tid)
{
this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
void
-SparcO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
- unsigned tid)
+SparcO3CPU<Impl>::setMiscRegWithEffect(int misc_reg,
+ const SparcISA::MiscReg &val, unsigned tid)
{
this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
}
@@ -284,35 +280,24 @@ template <class Impl>
TheISA::IntReg
SparcO3CPU<Impl>::getSyscallArg(int i, int tid)
{
- return this->readArchIntReg(SparcISA::ArgumentReg0 + i, tid);
+ TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
+ SparcISA::ArgumentReg0 + i);
+ return this->readArchIntReg(idx, tid);
}
template <class Impl>
void
-SparcO3CPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
+SparcO3CPU<Impl>::setSyscallArg(int i, TheISA::IntReg val, int tid)
{
- this->setArchIntReg(SparcISA::ArgumentReg0 + i, val, tid);
+ TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
+ SparcISA::ArgumentReg0 + i);
+ this->setArchIntReg(idx, val, tid);
}
template <class Impl>
void
SparcO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
- // check for error condition. SPARC syscall convention is to
- // indicate success/failure in reg the carry bit of the ccr
- // and put the return value itself in the standard return value reg ().
- if (return_value.successful()) {
- // no error, clear XCC.C
- this->setMiscReg(SparcISA::MISCREG_CCR,
- this->readMiscReg(SparcISA::MISCREG_CCR, tid) & 0xEE, tid);
- this->setArchIntReg(SparcISA::ReturnValueReg,
- return_value.value(), tid);
- } else {
- // got an error, set XCC.C
- this->setMiscReg(SparcISA::MISCREG_CCR,
- this->readMiscReg(SparcISA::MISCREG_CCR, tid) | 0x11, tid);
- this->setArchIntReg(SparcISA::ReturnValueReg,
- return_value.value(), tid);
- }
+ TheISA::setSyscallReturn(return_value, this->tcBase(tid));
}
#endif
diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh
index f8d6bb63f..4314488b5 100644
--- a/src/cpu/o3/sparc/dyn_inst.hh
+++ b/src/cpu/o3/sparc/dyn_inst.hh
@@ -32,6 +32,7 @@
#define __CPU_O3_SPARC_DYN_INST_HH__
#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/sparc/cpu.hh"
@@ -55,8 +56,8 @@ class SparcDynInst : public BaseDynInst<Impl>
public:
/** BaseDynInst constructor given a binary instruction. */
- SparcDynInst(TheISA::ExtMachInst inst, Addr PC,
- Addr Pred_PC, InstSeqNum seq_num, O3CPU *cpu);
+ SparcDynInst(TheISA::ExtMachInst inst, Addr PC, Addr NPC,
+ Addr Pred_PC, Addr Pred_NPC, InstSeqNum seq_num, O3CPU *cpu);
/** BaseDynInst constructor given a static inst pointer. */
SparcDynInst(StaticInstPtr &_staticInst);
@@ -105,6 +106,45 @@ class SparcDynInst : public BaseDynInst<Impl>
this->threadNumber);
}
+ /** Reads a miscellaneous register. */
+ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+ {
+ return this->cpu->readMiscReg(
+ si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+ this->threadNumber);
+ }
+
+ /** Reads a misc. register, including any side-effects the read
+ * might have as defined by the architecture.
+ */
+ TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ {
+ return this->cpu->readMiscRegWithEffect(
+ si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+ this->threadNumber);
+ }
+
+ /** Sets a misc. register. */
+ void setMiscRegOperand(const StaticInst * si,
+ int idx, const TheISA::MiscReg &val)
+ {
+ this->instResult.integer = val;
+ return this->cpu->setMiscReg(
+ si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+ val, this->threadNumber);
+ }
+
+ /** Sets a misc. register, including any side-effects the write
+ * might have as defined by the architecture.
+ */
+ void setMiscRegOperandWithEffect(
+ const StaticInst *si, int idx, const TheISA::MiscReg &val)
+ {
+ return this->cpu->setMiscRegWithEffect(
+ si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
+ val, this->threadNumber);
+ }
+
#if FULL_SYSTEM
/** Calls hardware return from error interrupt. */
Fault hwrei();
@@ -116,22 +156,6 @@ class SparcDynInst : public BaseDynInst<Impl>
void syscall(int64_t callnum);
#endif
- private:
- /** Physical register index of the destination registers of this
- * instruction.
- */
- PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs];
-
- /** Physical register index of the source registers of this
- * instruction.
- */
- PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs];
-
- /** Physical register index of the previous producers of the
- * architected destinations.
- */
- PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs];
-
public:
// The register accessor methods provide the index of the
@@ -145,108 +169,70 @@ class SparcDynInst : public BaseDynInst<Impl>
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntReg(const StaticInst *si, int idx)
+ uint64_t readIntRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readIntReg(_srcRegIdx[idx]);
+ uint64_t val = this->cpu->readIntReg(this->_srcRegIdx[idx]);
+ DPRINTF(Sparc, "Reading int reg %d (%d, %d) as %x\n", (int)this->_flatSrcRegIdx[idx], (int)this->_srcRegIdx[idx], idx, val);
+ return val;
}
- TheISA::FloatReg readFloatReg(const StaticInst *si, int idx, int width)
+ TheISA::FloatReg readFloatRegOperand(const StaticInst *si,
+ int idx, int width)
{
- return this->cpu->readFloatReg(_srcRegIdx[idx], width);
+ return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
}
- TheISA::FloatReg readFloatReg(const StaticInst *si, int idx)
+ TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readFloatReg(_srcRegIdx[idx]);
+ return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
}
- TheISA::FloatRegBits readFloatRegBits(const StaticInst *si,
+ TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si,
int idx, int width)
{
- return this->cpu->readFloatRegBits(_srcRegIdx[idx], width);
+ return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
}
- TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
+ TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
{
- return this->cpu->readFloatRegBits(_srcRegIdx[idx]);
+ return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
}
/** @todo: Make results into arrays so they can handle multiple dest
* registers.
*/
- void setIntReg(const StaticInst *si, int idx, uint64_t val)
+ void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
{
- this->cpu->setIntReg(_destRegIdx[idx], val);
- BaseDynInst<Impl>::setIntReg(si, idx, val);
+ DPRINTF(Sparc, "Setting int reg %d (%d, %d) to %x\n", (int)this->_flatDestRegIdx[idx], (int)this->_destRegIdx[idx], idx, val);
+ this->cpu->setIntReg(this->_destRegIdx[idx], val);
+ BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
}
- void setFloatReg(const StaticInst *si, int idx,
+ void setFloatRegOperand(const StaticInst *si, int idx,
TheISA::FloatReg val, int width)
{
- this->cpu->setFloatReg(_destRegIdx[idx], val, width);
- BaseDynInst<Impl>::setFloatReg(si, idx, val, width);
+ this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
+ BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
}
- void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val)
+ void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val)
{
- this->cpu->setFloatReg(_destRegIdx[idx], val);
- BaseDynInst<Impl>::setFloatReg(si, idx, val);
+ this->cpu->setFloatReg(this->_destRegIdx[idx], val);
+ BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
}
- void setFloatRegBits(const StaticInst *si, int idx,
+ void setFloatRegOperandBits(const StaticInst *si, int idx,
TheISA::FloatRegBits val, int width)
{
- this->cpu->setFloatRegBits(_destRegIdx[idx], val, width);
- BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
+ this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
+ BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
- void setFloatRegBits(const StaticInst *si,
+ void setFloatRegOperandBits(const StaticInst *si,
int idx, TheISA::FloatRegBits val)
{
- this->cpu->setFloatRegBits(_destRegIdx[idx], val);
- BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
- }
-
- /** Returns the physical register index of the i'th destination
- * register.
- */
- PhysRegIndex renamedDestRegIdx(int idx) const
- {
- return _destRegIdx[idx];
- }
-
- /** Returns the physical register index of the i'th source register. */
- PhysRegIndex renamedSrcRegIdx(int idx) const
- {
- return _srcRegIdx[idx];
- }
-
- /** Returns the physical register index of the previous physical register
- * that remapped to the same logical register index.
- */
- PhysRegIndex prevDestRegIdx(int idx) const
- {
- return _prevDestRegIdx[idx];
- }
-
- /** Renames a destination register to a physical register. Also records
- * the previous physical register that the logical register mapped to.
- */
- void renameDestReg(int idx,
- PhysRegIndex renamed_dest,
- PhysRegIndex previous_rename)
- {
- _destRegIdx[idx] = renamed_dest;
- _prevDestRegIdx[idx] = previous_rename;
- }
-
- /** Renames a source logical register to the physical register which
- * has/will produce that logical register's result.
- * @todo: add in whether or not the source register is ready.
- */
- void renameSrcReg(int idx, PhysRegIndex renamed_src)
- {
- _srcRegIdx[idx] = renamed_src;
+ this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
+ BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
public:
diff --git a/src/cpu/o3/sparc/dyn_inst_impl.hh b/src/cpu/o3/sparc/dyn_inst_impl.hh
index 210daace2..c4d30b6f4 100644
--- a/src/cpu/o3/sparc/dyn_inst_impl.hh
+++ b/src/cpu/o3/sparc/dyn_inst_impl.hh
@@ -31,9 +31,10 @@
#include "cpu/o3/sparc/dyn_inst.hh"
template <class Impl>
-SparcDynInst<Impl>::SparcDynInst(TheISA::ExtMachInst inst, Addr PC,
- Addr Pred_PC, InstSeqNum seq_num, O3CPU *cpu)
- : BaseDynInst<Impl>(inst, PC, Pred_PC, seq_num, cpu)
+SparcDynInst<Impl>::SparcDynInst(TheISA::ExtMachInst inst,
+ Addr PC, Addr NPC, Addr Pred_PC, Addr Pred_NPC,
+ InstSeqNum seq_num, O3CPU *cpu)
+ : BaseDynInst<Impl>(inst, PC, NPC, Pred_PC, Pred_NPC, seq_num, cpu)
{
initVars();
}
@@ -53,11 +54,11 @@ SparcDynInst<Impl>::initVars()
// as the normal register entries. It will allow the IQ to work
// without any modifications.
for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
- _destRegIdx[i] = this->staticInst->destRegIdx(i);
+ this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
}
for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
- _srcRegIdx[i] = this->staticInst->srcRegIdx(i);
+ this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
this->_readySrcRegIdx[i] = 0;
}
}
@@ -126,7 +127,8 @@ template <class Impl>
bool
SparcDynInst<Impl>::simPalCheck(int palFunc)
{
- return this->cpu->simPalCheck(palFunc, this->threadNumber);
+ panic("simPalCheck called, but there's no PAL in SPARC!\n");
+ return false;
}
#else
template <class Impl>
diff --git a/src/cpu/o3/sparc/thread_context.hh b/src/cpu/o3/sparc/thread_context.hh
index 69d1e2d04..7497959e4 100644
--- a/src/cpu/o3/sparc/thread_context.hh
+++ b/src/cpu/o3/sparc/thread_context.hh
@@ -36,12 +36,6 @@ class SparcTC : public O3ThreadContext<Impl>
{
public:
#if FULL_SYSTEM
- /** Returns a pointer to the ITB. */
- virtual SparcISA::ITB *getITBPtr() { return this->cpu->itb; }
-
- /** Returns a pointer to the DTB. */
- virtual SparcISA::DTB *getDTBPtr() { return this->cpu->dtb; }
-
/** Returns pointer to the quiesce event. */
virtual EndQuiesceEvent *getQuiesceEvent()
{
@@ -62,7 +56,7 @@ class SparcTC : public O3ThreadContext<Impl>
virtual void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{
- panic("This doesn't make sense!\n");
+ //XXX Ignore this for now. This -really- needs to get fixed.
}
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 390569c3d..4987d6eb4 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -66,6 +66,14 @@ class O3ThreadContext : public ThreadContext
/** Pointer to the thread state that this TC corrseponds to. */
O3ThreadState<Impl> *thread;
+#if FULL_SYSTEM
+ /** Returns a pointer to the ITB. */
+ TheISA::ITB *getITBPtr() { return cpu->itb; }
+
+ /** Returns a pointer to the DTB. */
+ TheISA::DTB *getDTBPtr() { return cpu->dtb; }
+#endif
+
/** Returns a pointer to this CPU. */
virtual BaseCPU *getCpuPtr() { return cpu; }
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index afebf294f..af98fa1f5 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -29,6 +29,7 @@
* Korey Sewell
*/
+#include "arch/regfile.hh"
#include "cpu/o3/thread_context.hh"
#include "cpu/quiesce_event.hh"
@@ -305,6 +306,7 @@ template <class Impl>
uint64_t
O3ThreadContext<Impl>::readIntReg(int reg_idx)
{
+ reg_idx = TheISA::flattenIntIndex(this, reg_idx);
return cpu->readArchIntReg(reg_idx, thread->readTid());
}
@@ -349,6 +351,7 @@ template <class Impl>
void
O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val)
{
+ reg_idx = TheISA::flattenIntIndex(this, reg_idx);
cpu->setArchIntReg(reg_idx, val, thread->readTid());
// Squash if we're not already in a state update mode.
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index 0da446c9c..baea7a546 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -219,11 +219,19 @@ class OzoneCPU : public BaseCPU
uint64_t readNextNPC()
{
- return 0;
+#if ISA_HAS_DELAY_SLOT
+ panic("Ozone needs to support nextNPC");
+#else
+ return thread->nextPC + sizeof(TheISA::MachInst);
+#endif
}
void setNextNPC(uint64_t val)
- { }
+ {
+#if ISA_HAS_DELAY_SLOT
+ panic("Ozone needs to support nextNPC");
+#endif
+ }
public:
// ISA stuff:
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index c39bfa9cd..c4853b916 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -54,15 +54,15 @@ namespace TheISA
}
class MemObject;
-class RemoteGDB;
-class GDBListener;
-
#else
class Process;
#endif // FULL_SYSTEM
+class RemoteGDB;
+class GDBListener;
+
class ThreadContext;
class Checkpoint;
@@ -186,7 +186,8 @@ class BaseSimpleCPU : public BaseCPU
// These functions are only used in CPU models that split
// effective address computation from the actual memory access.
void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
- Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); }
+ Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n");
+ M5_DUMMY_RETURN}
void prefetch(Addr addr, unsigned flags)
{
@@ -303,6 +304,31 @@ class BaseSimpleCPU : public BaseCPU
return thread->setMiscRegWithEffect(misc_reg, val);
}
+ MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+ {
+ int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+ return thread->readMiscReg(reg_idx);
+ }
+
+ MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ {
+ int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+ return thread->readMiscRegWithEffect(reg_idx);
+ }
+
+ void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val)
+ {
+ int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+ return thread->setMiscReg(reg_idx, val);
+ }
+
+ void setMiscRegOperandWithEffect(
+ const StaticInst *si, int idx, const MiscReg &val)
+ {
+ int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+ return thread->setMiscRegWithEffect(reg_idx, val);
+ }
+
#if FULL_SYSTEM
Fault hwrei() { return thread->hwrei(); }
void ev5_trap(Fault fault) { fault->invoke(tc); }
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 10bbe292c..f2f79c070 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -33,6 +33,8 @@
#define __CPU_SIMPLE_THREAD_HH__
#include "arch/isa_traits.hh"
+#include "arch/regfile.hh"
+#include "arch/syscallreturn.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
@@ -250,7 +252,7 @@ class SimpleThread : public ThreadState
//
uint64_t readIntReg(int reg_idx)
{
- return regs.readIntReg(reg_idx);
+ return regs.readIntReg(TheISA::flattenIntIndex(getTC(), reg_idx));
}
FloatReg readFloatReg(int reg_idx, int width)
@@ -275,7 +277,7 @@ class SimpleThread : public ThreadState
void setIntReg(int reg_idx, uint64_t val)
{
- regs.setIntReg(reg_idx, val);
+ regs.setIntReg(TheISA::flattenIntIndex(getTC(), reg_idx), val);
}
void setFloatReg(int reg_idx, FloatReg val, int width)
@@ -376,18 +378,20 @@ class SimpleThread : public ThreadState
#if !FULL_SYSTEM
TheISA::IntReg getSyscallArg(int i)
{
- return regs.readIntReg(TheISA::ArgumentReg0 + i);
+ return regs.readIntReg(TheISA::flattenIntIndex(getTC(),
+ TheISA::ArgumentReg0 + i));
}
// used to shift args for indirect syscall
void setSyscallArg(int i, TheISA::IntReg val)
{
- regs.setIntReg(TheISA::ArgumentReg0 + i, val);
+ regs.setIntReg(TheISA::flattenIntIndex(getTC(),
+ TheISA::ArgumentReg0 + i), val);
}
void setSyscallReturn(SyscallReturn return_value)
{
- TheISA::setSyscallReturn(return_value, &regs);
+ TheISA::setSyscallReturn(return_value, getTC());
}
void syscall(int64_t callnum)
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 5928eea76..416c8ab56 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -379,6 +379,7 @@ class StaticInst : public StaticInstBase
{
panic("StaticInst::branchTarget() called on instruction "
"that is not a PC-relative branch.");
+ M5_DUMMY_RETURN
}
/**
@@ -393,6 +394,7 @@ class StaticInst : public StaticInstBase
panic("StaticInst::branchTarget() called on instruction "
"that is not an indirect branch.");
}
+ M5_DUMMY_RETURN
/**
* Return true if the instruction is a control transfer, and if so,
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index bb9cc9e16..16e491fd3 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -32,13 +32,13 @@
#define __CPU_THREAD_CONTEXT_HH__
#include "arch/regfile.hh"
-#include "arch/syscallreturn.hh"
#include "arch/types.hh"
#include "config/full_system.hh"
#include "mem/request.hh"
#include "sim/faults.hh"
#include "sim/host.hh"
#include "sim/serialize.hh"
+#include "sim/syscallreturn.hh"
#include "sim/byteswap.hh"
// @todo: Figure out a more architecture independent way to obtain the ITB and
diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc
index d701dc98f..58933428c 100644
--- a/src/dev/alpha/tsunami_io.cc
+++ b/src/dev/alpha/tsunami_io.cc
@@ -65,69 +65,32 @@ TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, const vector<int> &t,
stat_regA = RTCA_32768HZ | RTCA_1024HZ;
stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR;
- if (year_is_bcd) {
- // The RTC uses BCD for the last two digits in the year.
- // They python year is a full year.
- int _year = t[0] % 100;
- int tens = _year / 10;
- int ones = _year % 10;
-
- year = (tens << 4) + ones;
- } else {
- // Even though the datasheet says that the year field should be
- // interpreted as BCD, we just enter the number of years since
- // 1900 since linux seems to be happy with that (and I believe
- // that Tru64 was as well)
- year = t[0] - 1900;
- }
-
- mon = t[1];
- mday = t[2];
- hour = t[3];
- min = t[4];
- sec = t[5];
-
- // wday is defined to be in the range from 1 - 7 with 1 being Sunday.
- // the value coming from python is in the range from 0 - 6 with 0 being
- // Monday. Fix that here.
- wday = t[6] + 2;
- if (wday > 7)
- wday -= 7;
-
- DPRINTFN("Real-time clock set to %s", getDateString());
-}
-
-std::string
-TsunamiIO::RTC::getDateString()
-{
struct tm tm;
+ parseTime(t, &tm);
- memset(&tm, 0, sizeof(tm));
+ year = tm.tm_year;
if (year_is_bcd) {
- // undo the BCD and conver to years since 1900 guessing that
- // anything before 1970 is actually after 2000
- int _year = (year >> 4) * 10 + (year & 0xf);
- if (_year < 70)
- _year += 100;
-
- tm.tm_year = _year;
- } else {
- // number of years since 1900
- tm.tm_year = year;
+ // The datasheet says that the year field can be either BCD or
+ // years since 1900. Linux seems to be happy with years since
+ // 1900.
+ year = year % 100;
+ int tens = year / 10;
+ int ones = year % 10;
+ year = (tens << 4) + ones;
}
- // unix is 0-11 for month
- tm.tm_mon = mon - 1;
- tm.tm_mday = mday;
- tm.tm_hour = hour;
- tm.tm_min = min;
- tm.tm_sec = sec;
+ // Unix is 0-11 for month, data seet says start at 1
+ mon = tm.tm_mon + 1;
+ mday = tm.tm_mday;
+ hour = tm.tm_hour;
+ min = tm.tm_min;
+ sec = tm.tm_sec;
- // to add more annoyance unix is 0 - 6 with 0 as sunday
- tm.tm_wday = wday - 1;
+ // Datasheet says 1 is sunday
+ wday = tm.tm_wday + 1;
- return asctime(&tm);
+ DPRINTFN("Real-time clock set to %s", asctime(&tm));
}
void
diff --git a/src/dev/alpha/tsunami_io.hh b/src/dev/alpha/tsunami_io.hh
index f42af4197..f4fa62a68 100644
--- a/src/dev/alpha/tsunami_io.hh
+++ b/src/dev/alpha/tsunami_io.hh
@@ -125,9 +125,6 @@ class TsunamiIO : public BasicPioDevice
/** RTC read data */
uint8_t readData();
- /** RTC get the date */
- std::string getDateString();
-
/**
* Serialize this object to the given output stream.
* @param base The base name of the counter object.
diff --git a/src/dev/baddev.cc b/src/dev/baddev.cc
index 6a7060455..a2d2650cb 100644
--- a/src/dev/baddev.cc
+++ b/src/dev/baddev.cc
@@ -56,12 +56,14 @@ Tick
BadDevice::read(PacketPtr pkt)
{
panic("Device %s not imlpmented\n", devname);
+ M5_DUMMY_RETURN
}
Tick
BadDevice::write(PacketPtr pkt)
{
panic("Device %s not imlpmented\n", devname);
+ M5_DUMMY_RETURN
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
diff --git a/src/dev/ide_atareg.h b/src/dev/ide_atareg.h
index df16d09d5..b9f1d9e0f 100644
--- a/src/dev/ide_atareg.h
+++ b/src/dev/ide_atareg.h
@@ -35,7 +35,7 @@
#if defined(linux)
#include <endian.h>
-#elif defined(__sun__)
+#elif defined(__sun)
#include <sys/isa_defs.h>
#else
#include <machine/endian.h>
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh
index aa242d170..c56eba267 100644
--- a/src/dev/io_device.hh
+++ b/src/dev/io_device.hh
@@ -109,7 +109,7 @@ class DmaPort : public Port
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt)
- { panic("dma port shouldn't be used for pio access."); }
+ { panic("dma port shouldn't be used for pio access."); M5_DUMMY_RETURN }
virtual void recvFunctional(PacketPtr pkt)
{ panic("dma port shouldn't be used for pio access."); }
diff --git a/src/dev/pciconfigall.cc b/src/dev/pciconfigall.cc
index 39c8f0fa0..bd1855847 100644
--- a/src/dev/pciconfigall.cc
+++ b/src/dev/pciconfigall.cc
@@ -83,8 +83,10 @@ PciConfigAll::write(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
panic("Attempting to write to config space on non-existant device\n");
+ M5_DUMMY_RETURN
}
+
void
PciConfigAll::addressRanges(AddrRangeList &range_list)
{
diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh
index fbfdbb65c..56e3ffb4a 100644
--- a/src/dev/pcidev.hh
+++ b/src/dev/pcidev.hh
@@ -37,6 +37,8 @@
#ifndef __DEV_PCIDEV_HH__
#define __DEV_PCIDEV_HH__
+#include <cstring>
+
#include "dev/io_device.hh"
#include "dev/pcireg.h"
#include "dev/platform.hh"
@@ -62,8 +64,8 @@ class PciConfigData : public SimObject
PciConfigData(const std::string &name)
: SimObject(name)
{
- memset(config.data, 0, sizeof(config.data));
- memset(BARSize, 0, sizeof(BARSize));
+ std::memset(config.data, 0, sizeof(config.data));
+ std::memset(BARSize, 0, sizeof(BARSize));
}
/** The first 64 bytes */
diff --git a/src/dev/platform.cc b/src/dev/platform.cc
index 07288249c..b2b8695a7 100644
--- a/src/dev/platform.cc
+++ b/src/dev/platform.cc
@@ -62,6 +62,7 @@ Addr
Platform::pciToDma(Addr pciAddr) const
{
panic("No PCI dma support in platform.");
+ M5_DUMMY_RETURN
}
void
diff --git a/src/dev/sparc/dtod.cc b/src/dev/sparc/dtod.cc
index 30c7baaf5..42275c60a 100644
--- a/src/dev/sparc/dtod.cc
+++ b/src/dev/sparc/dtod.cc
@@ -49,12 +49,24 @@ using namespace std;
using namespace TheISA;
DumbTOD::DumbTOD(Params *p)
- : BasicPioDevice(p), todTime(p->init_time)
+ : BasicPioDevice(p)
{
+ struct tm tm;
+ char *tz;
+
pioSize = 0x08;
- struct tm tm;
- gmtime_r((time_t*)&todTime, &tm);
+ parseTime(p->init_time, &tm);
+ tz = getenv("TZ");
+ setenv("TZ", "", 1);
+ tzset();
+ todTime = mktime(&tm);
+ if (tz)
+ setenv("TZ", tz, 1);
+ else
+ unsetenv("TZ");
+ tzset();
+
DPRINTFN("Real-time clock set to %s\n", asctime(&tm));
DPRINTFN("Real-time clock set to %d\n", todTime);
}
@@ -80,13 +92,26 @@ DumbTOD::write(PacketPtr pkt)
panic("Dumb tod device doesn't support writes\n");
}
+void
+DumbTOD::serialize(std::ostream &os)
+{
+ SERIALIZE_SCALAR(todTime);
+}
+
+void
+DumbTOD::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_SCALAR(todTime);
+}
+
+
BEGIN_DECLARE_SIM_OBJECT_PARAMS(DumbTOD)
Param<Addr> pio_addr;
Param<Tick> pio_latency;
SimObjectParam<Platform *> platform;
SimObjectParam<System *> system;
- Param<time_t> time;
+ VectorParam<int> time;
END_DECLARE_SIM_OBJECT_PARAMS(DumbTOD)
@@ -96,7 +121,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DumbTOD)
INIT_PARAM(pio_latency, "Programmed IO latency"),
INIT_PARAM(platform, "platform"),
INIT_PARAM(system, "system object"),
- INIT_PARAM(time, "System time to use (0 for actual time")
+ INIT_PARAM(time, "")
END_INIT_SIM_OBJECT_PARAMS(DumbTOD)
diff --git a/src/dev/sparc/dtod.hh b/src/dev/sparc/dtod.hh
index 7d3a9f628..ddf9fcc96 100644
--- a/src/dev/sparc/dtod.hh
+++ b/src/dev/sparc/dtod.hh
@@ -36,6 +36,8 @@
#ifndef __DEV_SPARC_DTOD_HH__
#define __DEV_SPARC_DTOD_HH__
+#include <vector>
+
#include "base/range.hh"
#include "dev/io_device.hh"
@@ -52,7 +54,7 @@ class DumbTOD : public BasicPioDevice
public:
struct Params : public BasicPioDevice::Params
{
- time_t init_time;
+ std::vector<int> init_time;
};
protected:
const Params *params() const { return (const Params *)_params; }
@@ -62,6 +64,21 @@ class DumbTOD : public BasicPioDevice
virtual Tick read(PacketPtr pkt);
virtual Tick write(PacketPtr pkt);
+
+ /**
+ * Serialize this object to the given output stream.
+ * @param os The stream to serialize to.
+ */
+ virtual void serialize(std::ostream &os);
+
+ /**
+ * Reconstruct the state of this object from a checkpoint.
+ * @param cp The checkpoint use.
+ * @param section The section name of this object
+ */
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+
};
#endif // __DEV_BADDEV_HH__
diff --git a/src/dev/sparc/mm_disk.cc b/src/dev/sparc/mm_disk.cc
index 9057c28be..018415f6c 100644
--- a/src/dev/sparc/mm_disk.cc
+++ b/src/dev/sparc/mm_disk.cc
@@ -33,6 +33,8 @@
* in legion. Any access is translated to an offset in the disk image.
*/
+#include <cstring>
+
#include "base/trace.hh"
#include "dev/sparc/mm_disk.hh"
#include "dev/platform.hh"
@@ -45,7 +47,7 @@
MmDisk::MmDisk(Params *p)
: BasicPioDevice(p), image(p->image), curSector((uint64_t)-1), dirty(false)
{
- memset(&bytes, 0, SectorSize);
+ std::memset(&bytes, 0, SectorSize);
pioSize = image->size() * SectorSize;
}
@@ -99,6 +101,7 @@ Tick
MmDisk::write(PacketPtr pkt)
{
panic("need to implement\n");
+ M5_DUMMY_RETURN
}
diff --git a/src/dev/sparc/t1000.cc b/src/dev/sparc/t1000.cc
index 4a8de77a5..3a2f881f1 100644
--- a/src/dev/sparc/t1000.cc
+++ b/src/dev/sparc/t1000.cc
@@ -57,6 +57,7 @@ Tick
T1000::intrFrequency()
{
panic("Need implementation\n");
+ M5_DUMMY_RETURN
}
void
@@ -89,6 +90,7 @@ Addr
T1000::pciToDma(Addr pciAddr) const
{
panic("Need implementation\n");
+ M5_DUMMY_RETURN
}
@@ -96,18 +98,7 @@ Addr
T1000::calcConfigAddr(int bus, int dev, int func)
{
panic("Need implementation\n");
-}
-
-void
-T1000::serialize(std::ostream &os)
-{
- panic("Need implementation\n");
-}
-
-void
-T1000::unserialize(Checkpoint *cp, const std::string &section)
-{
- panic("Need implementation\n");
+ M5_DUMMY_RETURN
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(T1000)
diff --git a/src/dev/sparc/t1000.hh b/src/dev/sparc/t1000.hh
index 2955763a9..8e28d90e5 100644
--- a/src/dev/sparc/t1000.hh
+++ b/src/dev/sparc/t1000.hh
@@ -90,19 +90,6 @@ class T1000 : public Platform
* Calculate the configuration address given a bus/dev/func.
*/
virtual Addr calcConfigAddr(int bus, int dev, int func);
-
- /**
- * Serialize this object to the given output stream.
- * @param os The stream to serialize to.
- */
- virtual void serialize(std::ostream &os);
-
- /**
- * Reconstruct the state of this object from a checkpoint.
- * @param cp The checkpoint use.
- * @param section The section name of this object
- */
- virtual void unserialize(Checkpoint *cp, const std::string &section);
};
#endif // __DEV_T1000_HH__
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 9c41983fc..b8c896498 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -40,6 +40,7 @@
#include <cassert>
#include <iostream>
+#include <cstring>
#include <string>
#include "sim/host.hh"
@@ -125,7 +126,7 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
assert(offset < blkSize);
assert(pkt->getSize() <= blkSize);
assert(offset+pkt->getSize() <= blkSize);
- memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
+ std::memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
pkt->getSize());
} else if (!(pkt->flags & SATISFIED)) {
pkt->flags |= SATISFIED;
@@ -133,7 +134,7 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
assert(offset < blkSize);
assert(pkt->getSize() <= blkSize);
assert(offset + pkt->getSize() <=blkSize);
- memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
+ std::memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
pkt->getSize());
}
return blk;
@@ -176,7 +177,7 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
if (blk->checkWrite(pkt->req)) {
write_data = true;
blk->status |= BlkDirty;
- memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
+ std::memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
pkt->getSize());
}
} else {
@@ -184,7 +185,7 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
if (pkt->req->isLocked()) {
blk->trackLoadLocked(pkt->req);
}
- memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
+ std::memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
pkt->getSize());
}
@@ -228,7 +229,7 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
if (pkt->isRead()) {
- memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
+ std::memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
}
blk->whenReady = pkt->finishTime;
@@ -249,14 +250,14 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
if (target->isWrite()) {
if (blk->checkWrite(pkt->req)) {
blk->status |= BlkDirty;
- memcpy(blk->data + target->getOffset(blkSize),
+ std::memcpy(blk->data + target->getOffset(blkSize),
target->getPtr<uint8_t>(), target->getSize());
}
} else {
if (pkt->req->isLocked()) {
blk->trackLoadLocked(pkt->req);
}
- memcpy(target->getPtr<uint8_t>(),
+ std::memcpy(target->getPtr<uint8_t>(),
blk->data + target->getOffset(blkSize),
target->getSize());
}
@@ -285,7 +286,7 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, MSHR * mshr,
blk = doReplacement(blk, pkt, new_state, writebacks);
if (pkt->isRead()) {
- memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
+ std::memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
}
blk->whenReady = pkt->finishTime;
@@ -337,14 +338,14 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, MSHR * mshr,
if (target->isWrite()) {
if (blk->checkWrite(pkt->req)) {
blk->status |= BlkDirty;
- memcpy(blk->data + target->getOffset(blkSize),
+ std::memcpy(blk->data + target->getOffset(blkSize),
target->getPtr<uint8_t>(), target->getSize());
}
} else {
if (pkt->req->isLocked()) {
blk->trackLoadLocked(pkt->req);
}
- memcpy(target->getPtr<uint8_t>(),
+ std::memcpy(target->getPtr<uint8_t>(),
blk->data + target->getOffset(blkSize),
target->getSize());
}
@@ -384,7 +385,7 @@ Cache<TagStore,Coherence>::handleSnoop(BlkType *blk,
assert(offset < blkSize);
assert(pkt->getSize() <= blkSize);
assert(offset + pkt->getSize() <=blkSize);
- memcpy(pkt->getPtr<uint8_t>(), blk->data + offset, pkt->getSize());
+ std::memcpy(pkt->getPtr<uint8_t>(), blk->data + offset, pkt->getSize());
handleSnoop(blk, new_state);
}
@@ -431,7 +432,7 @@ Cache<TagStore,Coherence>::writebackBlk(BlkType *blk)
new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0);
PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1);
writeback->allocate();
- memcpy(writeback->getPtr<uint8_t>(),blk->data,blkSize);
+ std::memcpy(writeback->getPtr<uint8_t>(),blk->data,blkSize);
blk->status &= ~BlkDirty;
return writeback;
@@ -463,7 +464,7 @@ Cache<TagStore,Coherence>::verifyData(BlkType *blk)
assert(blkSize == blk->size);
}
- retval = memcmp(tmp_data, blk->data, blkSize) == 0;
+ retval = std::memcmp(tmp_data, blk->data, blkSize) == 0;
delete [] tmp_data;
return retval;
}
@@ -664,7 +665,7 @@ Cache<TagStore,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
DPRINTF(Cache, "Block for blk addr %x moving from state "
"%i to %i\n", pkt->getAddr(), old_state, new_state);
//Set the state on the upgrade
- memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
+ std::memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
PacketList writebacks;
handleFill(blk, mshr, new_state, writebacks, pkt);
assert(writebacks.empty());
@@ -839,7 +840,7 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
assert(offset < blkSize);
assert(pkt->getSize() <= blkSize);
assert(offset + pkt->getSize() <=blkSize);
- memcpy(pkt->getPtr<uint8_t>(), mshr->pkt->getPtr<uint8_t>() + offset, pkt->getSize());
+ std::memcpy(pkt->getPtr<uint8_t>(), mshr->pkt->getPtr<uint8_t>() + offset, pkt->getSize());
respondToSnoop(pkt, curTick + hitLatency);
}
diff --git a/src/mem/cache/miss/blocking_buffer.cc b/src/mem/cache/miss/blocking_buffer.cc
index 4a431d82d..a1af88341 100644
--- a/src/mem/cache/miss/blocking_buffer.cc
+++ b/src/mem/cache/miss/blocking_buffer.cc
@@ -32,6 +32,7 @@
* @file
* Definitions of a simple buffer for a blocking cache.
*/
+#include <cstring>
#include "mem/cache/base_cache.hh"
#include "mem/cache/miss/blocking_buffer.hh"
@@ -60,7 +61,7 @@ BlockingBuffer::handleMiss(PacketPtr &pkt, int blk_size, Tick time)
wb.allocate(pkt->cmd, blk_addr, blk_size, pkt);
}
- memcpy(wb.pkt->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), blk_size);
+ std::memcpy(wb.pkt->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), blk_size);
cache->setBlocked(Blocked_NoWBBuffers);
cache->setMasterRequest(Request_WB, time);
@@ -147,7 +148,7 @@ BlockingBuffer::handleResponse(PacketPtr &pkt, Tick time)
PacketPtr target = ((MSHR*)(pkt->senderState))->getTarget();
((MSHR*)(pkt->senderState))->popTarget();
if (pkt->isRead()) {
- memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), target->getSize());
+ std::memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), target->getSize());
}
cache->respond(target, time);
assert(!((MSHR*)(pkt->senderState))->hasTargets());
@@ -191,7 +192,7 @@ BlockingBuffer::doWriteback(Addr addr,
PacketPtr pkt = new Packet(req, Packet::Writeback, -1);
pkt->allocate();
if (data) {
- memcpy(pkt->getPtr<uint8_t>(), data, size);
+ std::memcpy(pkt->getPtr<uint8_t>(), data, size);
}
if (compressed) {
@@ -217,7 +218,7 @@ BlockingBuffer::doWriteback(PacketPtr &pkt)
// Since allocate as buffer copies the request,
// need to copy data here.
- memcpy(wb.pkt->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), pkt->getSize());
+ std::memcpy(wb.pkt->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), pkt->getSize());
cache->setBlocked(Blocked_NoWBBuffers);
cache->setMasterRequest(Request_WB, curTick);
diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh
index 205068a8c..24386a249 100644
--- a/src/mem/cache/miss/blocking_buffer.hh
+++ b/src/mem/cache/miss/blocking_buffer.hh
@@ -90,6 +90,7 @@ public:
PacketPtr &target)
{
fatal("Unimplemented");
+ M5_DUMMY_RETURN
}
/**
@@ -201,6 +202,7 @@ public:
MSHR* allocateTargetList(Addr addr)
{
fatal("Unimplemented");
+ M5_DUMMY_RETURN
}
};
diff --git a/src/mem/cache/tags/iic.cc b/src/mem/cache/tags/iic.cc
index 38f9662ea..e547e112e 100644
--- a/src/mem/cache/tags/iic.cc
+++ b/src/mem/cache/tags/iic.cc
@@ -527,7 +527,7 @@ IIC::hash(Addr addr) const {
tag = extractTag(addr);
mask = hashSets-1; /* assumes iic_hash_size is a power of 2 */
x = tag & mask;
- y = (tag >> (int)(::log(hashSets)/::log(2))) & mask;
+ y = (tag >> (int)(::log((double)hashSets)/::log((double)2))) & mask;
assert (x < hashSets && y < hashSets);
return x ^ y;
#endif
diff --git a/src/mem/cache/tags/lru.hh b/src/mem/cache/tags/lru.hh
index 4b94adca6..75272544c 100644
--- a/src/mem/cache/tags/lru.hh
+++ b/src/mem/cache/tags/lru.hh
@@ -36,6 +36,7 @@
#ifndef __LRU_HH__
#define __LRU_HH__
+#include <cstring>
#include <list>
#include "mem/cache/cache_blk.hh" // base class
@@ -273,7 +274,7 @@ public:
*/
void readData(LRUBlk *blk, uint8_t *data)
{
- memcpy(data, blk->data, blk->size);
+ std::memcpy(data, blk->data, blk->size);
}
/**
diff --git a/src/mem/cache/tags/split.hh b/src/mem/cache/tags/split.hh
index e6ace0921..840b68940 100644
--- a/src/mem/cache/tags/split.hh
+++ b/src/mem/cache/tags/split.hh
@@ -36,6 +36,7 @@
#ifndef __SPLIT_HH__
#define __SPLIT_HH__
+#include <cstring>
#include <list>
#include "mem/cache/cache_blk.hh" // base class
@@ -234,6 +235,7 @@ class Split : public BaseTags
int extractSet(Addr addr) const
{
panic("should never call this!\n");
+ M5_DUMMY_RETURN
}
/**
@@ -281,7 +283,7 @@ class Split : public BaseTags
*/
void readData(SplitBlk *blk, uint8_t *data)
{
- memcpy(data, blk->data, blk->size);
+ std::memcpy(data, blk->data, blk->size);
}
/**
diff --git a/src/mem/cache/tags/split_lifo.hh b/src/mem/cache/tags/split_lifo.hh
index 9001cdb14..0f8adf18d 100644
--- a/src/mem/cache/tags/split_lifo.hh
+++ b/src/mem/cache/tags/split_lifo.hh
@@ -36,6 +36,7 @@
#ifndef __SPLIT_LIFO_HH__
#define __SPLIT_LIFO_HH__
+#include <cstring>
#include <list>
#include "mem/cache/cache_blk.hh" // base class
@@ -296,7 +297,7 @@ public:
*/
void readData(SplitBlk *blk, uint8_t *data)
{
- memcpy(data, blk->data, blk->size);
+ std::memcpy(data, blk->data, blk->size);
}
/**
diff --git a/src/mem/cache/tags/split_lru.hh b/src/mem/cache/tags/split_lru.hh
index e17a478d3..eb65445ea 100644
--- a/src/mem/cache/tags/split_lru.hh
+++ b/src/mem/cache/tags/split_lru.hh
@@ -36,6 +36,7 @@
#ifndef __SPLIT_LRU_HH__
#define __SPLIT_LRU_HH__
+#include <cstring>
#include <list>
#include "mem/cache/cache_blk.hh" // base class
@@ -279,7 +280,7 @@ public:
*/
void readData(SplitBlk *blk, uint8_t *data)
{
- memcpy(data, blk->data, blk->size);
+ std::memcpy(data, blk->data, blk->size);
}
/**
diff --git a/src/mem/dram.cc b/src/mem/dram.cc
index 873ca5b97..394c70db6 100644
--- a/src/mem/dram.cc
+++ b/src/mem/dram.cc
@@ -102,7 +102,7 @@ Kluwer Academic, pages 291-310, March, 2000.
#include "mem/dram.hh"
#include "sim/builder.hh"
-
+#include <stdlib.h>
#include <string>
extern int maxThreadsPerCPU;
@@ -203,7 +203,7 @@ DRAMMemory::DRAMMemory(Params *p)
last_bank = num_banks+1;
last_row = num_rows;
busy_until = new Tick[num_banks];
- memset(busy_until,0,sizeof(Tick)*num_banks); /* initiliaze */
+ std::memset(busy_until,0,sizeof(Tick)*num_banks); /* initiliaze */
}
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index e2faf4527..44805236c 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -36,7 +36,7 @@
*/
#include <iostream>
-
+#include <cstring>
#include "base/misc.hh"
#include "base/trace.hh"
#include "mem/packet.hh"
@@ -183,7 +183,7 @@ fixPacket(PacketPtr func, PacketPtr timing)
if (func->isRead()) {
if (funcStart >= timingStart && funcEnd <= timingEnd) {
func->allocate();
- memcpy(func->getPtr<uint8_t>(), timing->getPtr<uint8_t>() +
+ std::memcpy(func->getPtr<uint8_t>(), timing->getPtr<uint8_t>() +
funcStart - timingStart, func->getSize());
func->result = Packet::Success;
func->flags |= SATISFIED;
@@ -199,11 +199,11 @@ fixPacket(PacketPtr func, PacketPtr timing)
}
} else if (func->isWrite()) {
if (funcStart >= timingStart) {
- memcpy(timing->getPtr<uint8_t>() + (funcStart - timingStart),
+ std::memcpy(timing->getPtr<uint8_t>() + (funcStart - timingStart),
func->getPtr<uint8_t>(),
(std::min(funcEnd, timingEnd) - funcStart) + 1);
} else { // timingStart > funcStart
- memcpy(timing->getPtr<uint8_t>(),
+ std::memcpy(timing->getPtr<uint8_t>(),
func->getPtr<uint8_t>() + (timingStart - funcStart),
(std::min(funcEnd, timingEnd) - timingStart) + 1);
}
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 19251941f..15f605ca7 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -41,10 +41,12 @@
#include <cassert>
#include <list>
+#include "base/misc.hh"
#include "mem/request.hh"
#include "sim/host.hh"
#include "sim/root.hh"
+
struct Packet;
typedef Packet *PacketPtr;
typedef uint8_t* PacketDataPtr;
@@ -238,7 +240,7 @@ class Packet
bool isNoAllocate() const { return (flags & NO_ALLOCATE) != 0; }
bool isCompressed() const { return (flags & COMPRESSED) != 0; }
- bool nic_pkt() { assert("Unimplemented\n" && 0); return false; }
+ bool nic_pkt() { panic("Unimplemented"); M5_DUMMY_RETURN }
/** Possible results of a packet's request. */
enum Result
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 7d616a4e5..eccd42bec 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -59,7 +59,7 @@ PhysicalMemory::PhysicalMemory(Params *p)
int map_flags = MAP_ANON | MAP_PRIVATE;
pmemAddr = (uint8_t *)mmap(NULL, params()->addrRange.size(), PROT_READ | PROT_WRITE,
- map_flags, -1, 0);
+ map_flags, -1, 0);
if (pmemAddr == (void *)MAP_FAILED) {
perror("mmap");
@@ -84,7 +84,7 @@ PhysicalMemory::init()
PhysicalMemory::~PhysicalMemory()
{
if (pmemAddr)
- munmap(pmemAddr, params()->addrRange.size());
+ munmap((char*)pmemAddr, params()->addrRange.size());
//Remove memPorts?
}
@@ -430,7 +430,7 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
// unmap file that was mmaped in the constructor
// This is done here to make sure that gzip and open don't muck with our
// nice large space of memory before we reallocate it
- munmap(pmemAddr, params()->addrRange.size());
+ munmap((char*)pmemAddr, params()->addrRange.size());
pmemAddr = (uint8_t *)mmap(NULL, params()->addrRange.size(), PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/src/mem/port.cc b/src/mem/port.cc
index bbc98c160..da719bbd9 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -32,6 +32,7 @@
* @file
* Port object definitions.
*/
+#include <cstring>
#include "base/chunk_generator.hh"
#include "base/trace.hh"
@@ -78,7 +79,7 @@ Port::memsetBlob(Addr addr, uint8_t val, int size)
// quick and dirty...
uint8_t *buf = new uint8_t[size];
- memset(buf, val, size);
+ std::memset(buf, val, size);
blobHelper(addr, buf, size, Packet::WriteReq);
delete [] buf;
diff --git a/src/mem/port.hh b/src/mem/port.hh
index 75afc04e6..5e55225bf 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -159,7 +159,7 @@ class Port
this function to be called, a DMA interface doesn't really have a
block size, so it is defaulted to a panic.
*/
- virtual int deviceBlockSize() { panic("??"); }
+ virtual int deviceBlockSize() { panic("??"); M5_DUMMY_RETURN }
/** The peer port is requesting us to reply with a list of the ranges we
are responsible for.
@@ -261,8 +261,10 @@ class FunctionalPort : public Port
{}
protected:
- virtual bool recvTiming(PacketPtr pkt) { panic("FuncPort is UniDir"); }
- virtual Tick recvAtomic(PacketPtr pkt) { panic("FuncPort is UniDir"); }
+ virtual bool recvTiming(PacketPtr pkt) { panic("FuncPort is UniDir");
+ M5_DUMMY_RETURN }
+ virtual Tick recvAtomic(PacketPtr pkt) { panic("FuncPort is UniDir");
+ M5_DUMMY_RETURN }
virtual void recvFunctional(PacketPtr pkt) { panic("FuncPort is UniDir"); }
virtual void recvStatusChange(Status status) {}
diff --git a/src/python/m5/objects/T1000.py b/src/python/m5/objects/T1000.py
index 7b93268ac..85c4db6df 100644
--- a/src/python/m5/objects/T1000.py
+++ b/src/python/m5/objects/T1000.py
@@ -21,53 +21,53 @@ class T1000(Platform):
type = 'T1000'
system = Param.System(Parent.any, "system")
- fake_clk = IsaFake(pio_addr=0x9600000000, pio_size=0x100000000,
- warn_access="Accessing Clock Unit -- Unimplemented!")
+ fake_clk = IsaFake(pio_addr=0x9600000000, pio_size=0x100000000)
+ #warn_access="Accessing Clock Unit -- Unimplemented!")
fake_membnks = IsaFake(pio_addr=0x9700000000, pio_size=16384,
- ret_data64=0x0000000000000000, update_data=False,
- warn_access="Accessing Memory Banks -- Unimplemented!")
+ ret_data64=0x0000000000000000, update_data=False)
+ #warn_access="Accessing Memory Banks -- Unimplemented!")
- fake_iob = IsaFake(pio_addr=0x9800000000, pio_size=0x100000000,
- warn_access="Accessing IOB -- Unimplemented!")
+ fake_iob = IsaFake(pio_addr=0x9800000000, pio_size=0x100000000)
+ #warn_access="Accessing IOB -- Unimplemented!")
- fake_jbi = IsaFake(pio_addr=0x8000000000, pio_size=0x100000000,
- warn_access="Accessing JBI -- Unimplemented!")
+ fake_jbi = IsaFake(pio_addr=0x8000000000, pio_size=0x100000000)
+ #warn_access="Accessing JBI -- Unimplemented!")
fake_l2_1 = IsaFake(pio_addr=0xA900000000, pio_size=0x8,
- ret_data64=0x0000000000000001, update_data=True,
- warn_access="Accessing L2 Cache Banks -- Unimplemented!")
+ ret_data64=0x0000000000000001, update_data=True)
+ #warn_access="Accessing L2 Cache Banks -- Unimplemented!")
fake_l2_2 = IsaFake(pio_addr=0xA900000040, pio_size=0x8,
- ret_data64=0x0000000000000001, update_data=True,
- warn_access="Accessing L2 Cache Banks -- Unimplemented!")
+ ret_data64=0x0000000000000001, update_data=True)
+ #warn_access="Accessing L2 Cache Banks -- Unimplemented!")
fake_l2_3 = IsaFake(pio_addr=0xA900000080, pio_size=0x8,
- ret_data64=0x0000000000000001, update_data=True,
- warn_access="Accessing L2 Cache Banks -- Unimplemented!")
+ ret_data64=0x0000000000000001, update_data=True)
+ #warn_access="Accessing L2 Cache Banks -- Unimplemented!")
fake_l2_4 = IsaFake(pio_addr=0xA9000000C0, pio_size=0x8,
- ret_data64=0x0000000000000001, update_data=True,
- warn_access="Accessing L2 Cache Banks -- Unimplemented!")
+ ret_data64=0x0000000000000001, update_data=True)
+ #warn_access="Accessing L2 Cache Banks -- Unimplemented!")
fake_l2esr_1 = IsaFake(pio_addr=0xAB00000000, pio_size=0x8,
- ret_data64=0x0000000000000000, update_data=True,
- warn_access="Accessing L2 ESR Cache Banks -- Unimplemented!")
+ ret_data64=0x0000000000000000, update_data=True)
+ #warn_access="Accessing L2 ESR Cache Banks -- Unimplemented!")
fake_l2esr_2 = IsaFake(pio_addr=0xAB00000040, pio_size=0x8,
- ret_data64=0x0000000000000000, update_data=True,
- warn_access="Accessing L2 ESR Cache Banks -- Unimplemented!")
+ ret_data64=0x0000000000000000, update_data=True)
+ #warn_access="Accessing L2 ESR Cache Banks -- Unimplemented!")
fake_l2esr_3 = IsaFake(pio_addr=0xAB00000080, pio_size=0x8,
- ret_data64=0x0000000000000000, update_data=True,
- warn_access="Accessing L2 ESR Cache Banks -- Unimplemented!")
+ ret_data64=0x0000000000000000, update_data=True)
+ #warn_access="Accessing L2 ESR Cache Banks -- Unimplemented!")
fake_l2esr_4 = IsaFake(pio_addr=0xAB000000C0, pio_size=0x8,
- ret_data64=0x0000000000000000, update_data=True,
- warn_access="Accessing L2 ESR Cache Banks -- Unimplemented!")
+ ret_data64=0x0000000000000000, update_data=True)
+ #warn_access="Accessing L2 ESR Cache Banks -- Unimplemented!")
- fake_ssi = IsaFake(pio_addr=0xff00000000, pio_size=0x10000000,
- warn_access="Accessing SSI -- Unimplemented!")
+ fake_ssi = IsaFake(pio_addr=0xff00000000, pio_size=0x10000000)
+ #warn_access="Accessing SSI -- Unimplemented!")
hvuart = Uart8250(pio_addr=0xfff0c2c000)
htod = DumbTOD()
diff --git a/src/sim/byteswap.hh b/src/sim/byteswap.hh
index 4ac1ee711..cbc0b5088 100644
--- a/src/sim/byteswap.hh
+++ b/src/sim/byteswap.hh
@@ -47,7 +47,7 @@
// If one doesn't exist, we pretty much get what is listed below, so it all
// works out
#include <byteswap.h>
-#elif defined (__sun__)
+#elif defined (__sun)
#include <sys/isa_defs.h>
#else
#include <machine/endian.h>
@@ -57,6 +57,8 @@
#include <libkern/OSByteOrder.h>
#endif
+enum ByteOrder {BigEndianByteOrder, LittleEndianByteOrder};
+
//These functions actually perform the swapping for parameters
//of various bit lengths
static inline uint64_t
@@ -131,11 +133,13 @@ template <typename T> static inline T letobe(T value) {return swap_byte(value);}
//For conversions not involving the guest system, we can define the functions
//conditionally based on the BYTE_ORDER macro and outside of the namespaces
#if defined(_BIG_ENDIAN) || !defined(_LITTLE_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
+const ByteOrder HostByteOrder = BigEndianByteOrder;
template <typename T> static inline T htole(T value) {return swap_byte(value);}
template <typename T> static inline T letoh(T value) {return swap_byte(value);}
template <typename T> static inline T htobe(T value) {return value;}
template <typename T> static inline T betoh(T value) {return value;}
#elif defined(_LITTLE_ENDIAN) || BYTE_ORDER == LITTLE_ENDIAN
+const ByteOrder HostByteOrder = LittleEndianByteOrder;
template <typename T> static inline T htole(T value) {return value;}
template <typename T> static inline T letoh(T value) {return value;}
template <typename T> static inline T htobe(T value) {return swap_byte(value);}
@@ -146,33 +150,35 @@ template <typename T> static inline T betoh(T value) {return swap_byte(value);}
namespace BigEndianGuest
{
- template <typename T>
- static inline T gtole(T value) {return betole(value);}
- template <typename T>
- static inline T letog(T value) {return letobe(value);}
- template <typename T>
- static inline T gtobe(T value) {return value;}
- template <typename T>
- static inline T betog(T value) {return value;}
- template <typename T>
- static inline T htog(T value) {return htobe(value);}
- template <typename T>
- static inline T gtoh(T value) {return betoh(value);}
+ const bool ByteOrderDiffers = (HostByteOrder != BigEndianByteOrder);
+ template <typename T>
+ static inline T gtole(T value) {return betole(value);}
+ template <typename T>
+ static inline T letog(T value) {return letobe(value);}
+ template <typename T>
+ static inline T gtobe(T value) {return value;}
+ template <typename T>
+ static inline T betog(T value) {return value;}
+ template <typename T>
+ static inline T htog(T value) {return htobe(value);}
+ template <typename T>
+ static inline T gtoh(T value) {return betoh(value);}
}
namespace LittleEndianGuest
{
- template <typename T>
- static inline T gtole(T value) {return value;}
- template <typename T>
- static inline T letog(T value) {return value;}
- template <typename T>
- static inline T gtobe(T value) {return letobe(value);}
- template <typename T>
- static inline T betog(T value) {return betole(value);}
- template <typename T>
- static inline T htog(T value) {return htole(value);}
- template <typename T>
- static inline T gtoh(T value) {return letoh(value);}
+ const bool ByteOrderDiffers = (HostByteOrder != LittleEndianByteOrder);
+ template <typename T>
+ static inline T gtole(T value) {return value;}
+ template <typename T>
+ static inline T letog(T value) {return value;}
+ template <typename T>
+ static inline T gtobe(T value) {return letobe(value);}
+ template <typename T>
+ static inline T betog(T value) {return betole(value);}
+ template <typename T>
+ static inline T htog(T value) {return htole(value);}
+ template <typename T>
+ static inline T gtoh(T value) {return letoh(value);}
}
#endif // __SIM_BYTE_SWAP_HH__
diff --git a/src/sim/host.hh b/src/sim/host.hh
index 8b1ddbfe7..93a5fe7f2 100644
--- a/src/sim/host.hh
+++ b/src/sim/host.hh
@@ -38,6 +38,8 @@
#define __HOST_HH__
#include <inttypes.h>
+#include <limits>
+
/** uint64_t constant */
#define ULL(N) ((uint64_t)N##ULL)
@@ -56,7 +58,7 @@ typedef int64_t Counter;
*/
typedef int64_t Tick;
-const Tick MaxTick = (1LL << 63) - 1;
+const Tick MaxTick = std::numeric_limits<Tick>::max();
/**
* Address type
diff --git a/src/sim/param.cc b/src/sim/param.cc
index b1c50946b..5cc69b161 100644
--- a/src/sim/param.cc
+++ b/src/sim/param.cc
@@ -777,3 +777,27 @@ ParamContext::describeAllContexts(ostream &os)
os << endl;
}
}
+
+void
+parseTime(const std::vector<int> &time, struct tm *tm)
+{
+ memset(tm, 0, sizeof(struct tm));
+
+ // UNIX is years since 1900
+ tm->tm_year = time[0] - 1900;
+
+ // Python starts at 1, UNIX starts at 0
+ tm->tm_mon = time[1] - 1;
+ tm->tm_mday = time[2];
+ tm->tm_hour = time[3];
+ tm->tm_min = time[4];
+ tm->tm_sec = time[5];
+
+ // Python has 0 as Monday, UNIX is 0 as sunday
+ tm->tm_wday = time[6] + 1;
+ if (tm->tm_wday > 6)
+ tm->tm_wday -= 7;
+
+ // Python starts at 1, Unix starts at 0
+ tm->tm_yday = time[7] - 1;
+}
diff --git a/src/sim/param.hh b/src/sim/param.hh
index 2aa0456da..8a4670e27 100644
--- a/src/sim/param.hh
+++ b/src/sim/param.hh
@@ -781,4 +781,5 @@ SimObjectVectorParam<OBJ_CLASS *>::showType(std::ostream &os) const \
template <class T> bool parseParam(const std::string &str, T &data);
template <class T> void showParam(std::ostream &os, const T &data);
+void parseTime(const std::vector<int> &time, struct tm *tm);
#endif // _SIM_PARAM_HH_
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 63ff33969..e5d868115 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -35,6 +35,7 @@
#include <string>
+#include "arch/remote_gdb.hh"
#include "base/intmath.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
@@ -154,6 +155,13 @@ Process::registerThreadContext(ThreadContext *tc)
int myIndex = threadContexts.size();
threadContexts.push_back(tc);
+ RemoteGDB *rgdb = new RemoteGDB(system, tc);
+ GDBListener *gdbl = new GDBListener(rgdb, 7000 + myIndex);
+ gdbl->listen();
+ //gdbl->accept();
+
+ remoteGDB.push_back(rgdb);
+
// return CPU number to caller
return myIndex;
}
diff --git a/src/sim/process.hh b/src/sim/process.hh
index 616c02c00..bf65c6e06 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -51,6 +51,11 @@ class SyscallDesc;
class PageTable;
class TranslatingPort;
class System;
+class GDBListener;
+namespace TheISA
+{
+ class RemoteGDB;
+}
void
copyStringArray(std::vector<std::string> &strings, Addr array_ptr,
@@ -72,6 +77,11 @@ class Process : public SimObject
// thread contexts associated with this process
std::vector<ThreadContext *> threadContexts;
+ // remote gdb objects
+ std::vector<TheISA::RemoteGDB *> remoteGDB;
+ std::vector<GDBListener *> gdbListen;
+ bool breakpoint();
+
// number of CPUs (esxec contexts, really) assigned to this process.
unsigned int numCpus() { return threadContexts.size(); }
diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc
index 941f0b1c6..1ff16976d 100644
--- a/src/sim/serialize.cc
+++ b/src/sim/serialize.cc
@@ -57,6 +57,8 @@
using namespace std;
+extern SimObject *resolveSimObject(const string &);
+
int Serializable::ckptMaxCount = 0;
int Serializable::ckptCount = 0;
int Serializable::ckptPrevCount = -1;
@@ -158,7 +160,7 @@ arrayParamIn(Checkpoint *cp, const std::string &section,
void
objParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, Serializable * &param)
+ const std::string &name, SimObject * &param)
{
if (!cp->findObj(section, name, param)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
@@ -388,17 +390,15 @@ Checkpoint::find(const std::string &section, const std::string &entry,
bool
Checkpoint::findObj(const std::string &section, const std::string &entry,
- Serializable *&value)
+ SimObject *&value)
{
string path;
if (!db->find(section, entry, path))
return false;
- if ((value = objMap[path]) != NULL)
- return true;
-
- return false;
+ value = resolveSimObject(path);
+ return true;
}
diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh
index 880fb0785..43cd4ecf4 100644
--- a/src/sim/serialize.hh
+++ b/src/sim/serialize.hh
@@ -47,6 +47,7 @@
class IniFile;
class Serializable;
class Checkpoint;
+class SimObject;
template <class T>
void paramOut(std::ostream &os, const std::string &name, const T &param);
@@ -65,7 +66,7 @@ void arrayParamIn(Checkpoint *cp, const std::string &section,
void
objParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, Serializable * &param);
+ const std::string &name, SimObject * &param);
//
@@ -96,7 +97,7 @@ objParamIn(Checkpoint *cp, const std::string &section,
#define UNSERIALIZE_OBJPTR(objptr) \
do { \
- Serializable *sptr; \
+ SimObject *sptr; \
objParamIn(cp, section, #objptr, sptr); \
objptr = dynamic_cast<typeof(objptr)>(sptr); \
} while (0)
@@ -225,7 +226,7 @@ class Checkpoint
std::string &value);
bool findObj(const std::string &section, const std::string &entry,
- Serializable *&value);
+ SimObject *&value);
bool sectionExists(const std::string &section);
diff --git a/src/sim/syscallreturn.hh b/src/sim/syscallreturn.hh
new file mode 100644
index 000000000..d1c43f584
--- /dev/null
+++ b/src/sim/syscallreturn.hh
@@ -0,0 +1,70 @@
+/*
+ * 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 __SIM_SYSCALLRETURN_HH__
+#define __SIM_SYSCALLRETURN_HH__
+
+#include <inttypes.h>
+
+class SyscallReturn
+{
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s)
+ {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+
+#endif
diff --git a/src/sim/system.cc b/src/sim/system.cc
index b3ba1b8f1..f6febe4b1 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -32,6 +32,7 @@
*/
#include "arch/isa_traits.hh"
+#include "arch/remote_gdb.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
@@ -43,7 +44,6 @@
#include "sim/system.hh"
#if FULL_SYSTEM
#include "arch/vtophys.hh"
-#include "arch/remote_gdb.hh"
#include "kern/kernel_stats.hh"
#endif
@@ -141,14 +141,8 @@ System::~System()
#endif // FULL_SYSTEM}
}
-#if FULL_SYSTEM
-
-
int rgdb_wait = -1;
-#endif // FULL_SYSTEM
-
-
void
System::setMemoryMode(MemoryMode mode)
{
@@ -156,6 +150,11 @@ System::setMemoryMode(MemoryMode mode)
memoryMode = mode;
}
+bool System::breakpoint()
+{
+ return remoteGDB[0]->breakpoint();
+}
+
int
System::registerThreadContext(ThreadContext *tc, int id)
{
@@ -175,7 +174,6 @@ System::registerThreadContext(ThreadContext *tc, int id)
threadContexts[id] = tc;
numcpus++;
-#if FULL_SYSTEM
RemoteGDB *rgdb = new RemoteGDB(this, tc);
GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
gdbl->listen();
@@ -191,7 +189,6 @@ System::registerThreadContext(ThreadContext *tc, int id)
}
remoteGDB[id] = rgdb;
-#endif // FULL_SYSTEM
return id;
}
@@ -213,9 +210,7 @@ System::replaceThreadContext(ThreadContext *tc, int id)
}
threadContexts[id] = tc;
-#if FULL_SYSTEM
remoteGDB[id]->replaceThreadContext(tc);
-#endif // FULL_SYSTEM
}
#if !FULL_SYSTEM
diff --git a/src/sim/system.hh b/src/sim/system.hh
index b3a67bf7a..758da709e 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -55,12 +55,12 @@ class PhysicalMemory;
#if FULL_SYSTEM
class Platform;
+#endif
class GDBListener;
namespace TheISA
{
class RemoteGDB;
}
-#endif
class System : public SimObject
{
@@ -159,11 +159,9 @@ class System : public SimObject
#endif
public:
-#if FULL_SYSTEM
std::vector<TheISA::RemoteGDB *> remoteGDB;
std::vector<GDBListener *> gdbListen;
- virtual bool breakpoint() = 0;
-#endif // FULL_SYSTEM
+ bool breakpoint();
public:
struct Params
diff --git a/src/unittest/Makefile b/src/unittest/Makefile
index 0c11b9563..e22b80b48 100644
--- a/src/unittest/Makefile
+++ b/src/unittest/Makefile
@@ -1,4 +1,4 @@
-# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without