merge
This commit is contained in:
commit
279f179bab
682 changed files with 26213 additions and 20254 deletions
|
@ -7,3 +7,4 @@ cscope.out
|
||||||
*.pyc
|
*.pyc
|
||||||
*~
|
*~
|
||||||
.*.swp
|
.*.swp
|
||||||
|
m5out
|
||||||
|
|
92
SConstruct
92
SConstruct
|
@ -96,6 +96,7 @@ For more details, see:
|
||||||
"""
|
"""
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
# Global Python includes
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -106,55 +107,18 @@ from os.path import abspath, basename, dirname, expanduser, normpath
|
||||||
from os.path import exists, isdir, isfile
|
from os.path import exists, isdir, isfile
|
||||||
from os.path import join as joinpath, split as splitpath
|
from os.path import join as joinpath, split as splitpath
|
||||||
|
|
||||||
|
# SCons includes
|
||||||
import SCons
|
import SCons
|
||||||
import SCons.Node
|
import SCons.Node
|
||||||
|
|
||||||
def read_command(cmd, **kwargs):
|
extra_python_paths = [
|
||||||
"""run the command cmd, read the results and return them
|
Dir('src/python').srcnode().abspath, # M5 includes
|
||||||
this is sorta like `cmd` in shell"""
|
Dir('ext/ply').srcnode().abspath, # ply is used by several files
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
]
|
||||||
|
|
||||||
if isinstance(cmd, str):
|
|
||||||
cmd = cmd.split()
|
|
||||||
|
|
||||||
no_exception = 'exception' in kwargs
|
|
||||||
exception = kwargs.pop('exception', None)
|
|
||||||
|
|
||||||
kwargs.setdefault('shell', False)
|
sys.path[1:1] = extra_python_paths
|
||||||
kwargs.setdefault('stdout', PIPE)
|
|
||||||
kwargs.setdefault('stderr', STDOUT)
|
|
||||||
kwargs.setdefault('close_fds', True)
|
|
||||||
try:
|
|
||||||
subp = Popen(cmd, **kwargs)
|
|
||||||
except Exception, e:
|
|
||||||
if no_exception:
|
|
||||||
return exception
|
|
||||||
raise
|
|
||||||
|
|
||||||
return subp.communicate()[0]
|
from m5.util import compareVersions, readCommand
|
||||||
|
|
||||||
# helper function: compare arrays or strings of version numbers.
|
|
||||||
# E.g., compare_version((1,3,25), (1,4,1)')
|
|
||||||
# returns -1, 0, 1 if v1 is <, ==, > v2
|
|
||||||
def compare_versions(v1, v2):
|
|
||||||
def make_version_list(v):
|
|
||||||
if isinstance(v, (list,tuple)):
|
|
||||||
return v
|
|
||||||
elif isinstance(v, str):
|
|
||||||
return map(lambda x: int(re.match('\d+', x).group()), v.split('.'))
|
|
||||||
else:
|
|
||||||
raise TypeError
|
|
||||||
|
|
||||||
v1 = make_version_list(v1)
|
|
||||||
v2 = make_version_list(v2)
|
|
||||||
# Compare corresponding elements of lists
|
|
||||||
for n1,n2 in zip(v1, v2):
|
|
||||||
if n1 < n2: return -1
|
|
||||||
if n1 > n2: return 1
|
|
||||||
# all corresponding values are equal... see if one has extra values
|
|
||||||
if len(v1) < len(v2): return -1
|
|
||||||
if len(v1) > len(v2): return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
#
|
#
|
||||||
|
@ -162,7 +126,7 @@ def compare_versions(v1, v2):
|
||||||
#
|
#
|
||||||
########################################################################
|
########################################################################
|
||||||
use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 'PATH',
|
use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 'PATH',
|
||||||
'RANLIB' ])
|
'PYTHONPATH', 'RANLIB' ])
|
||||||
|
|
||||||
use_env = {}
|
use_env = {}
|
||||||
for key,val in os.environ.iteritems():
|
for key,val in os.environ.iteritems():
|
||||||
|
@ -173,6 +137,10 @@ main = Environment(ENV=use_env)
|
||||||
main.root = Dir(".") # The current directory (where this file lives).
|
main.root = Dir(".") # The current directory (where this file lives).
|
||||||
main.srcdir = Dir("src") # The source directory
|
main.srcdir = Dir("src") # The source directory
|
||||||
|
|
||||||
|
# add useful python code PYTHONPATH so it can be used by subprocesses
|
||||||
|
# as well
|
||||||
|
main.AppendENVPath('PYTHONPATH', extra_python_paths)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
#
|
#
|
||||||
# Mercurial Stuff.
|
# Mercurial Stuff.
|
||||||
|
@ -217,7 +185,7 @@ if hgdir.exists():
|
||||||
# 1) Grab repository revision if we know it.
|
# 1) Grab repository revision if we know it.
|
||||||
cmd = "hg id -n -i -t -b"
|
cmd = "hg id -n -i -t -b"
|
||||||
try:
|
try:
|
||||||
hg_info = read_command(cmd, cwd=main.root.abspath).strip()
|
hg_info = readCommand(cmd, cwd=main.root.abspath).strip()
|
||||||
except OSError:
|
except OSError:
|
||||||
print mercurial_bin_not_found
|
print mercurial_bin_not_found
|
||||||
|
|
||||||
|
@ -378,11 +346,8 @@ Export('extras_dir_list')
|
||||||
# the ext directory should be on the #includes path
|
# the ext directory should be on the #includes path
|
||||||
main.Append(CPPPATH=[Dir('ext')])
|
main.Append(CPPPATH=[Dir('ext')])
|
||||||
|
|
||||||
# M5_PLY is used by isa_parser.py to find the PLY package.
|
CXX_version = readCommand([main['CXX'],'--version'], exception=False)
|
||||||
main.Append(ENV = { 'M5_PLY' : Dir('ext/ply').abspath })
|
CXX_V = readCommand([main['CXX'],'-V'], exception=False)
|
||||||
|
|
||||||
CXX_version = read_command([main['CXX'],'--version'], exception=False)
|
|
||||||
CXX_V = read_command([main['CXX'],'-V'], exception=False)
|
|
||||||
|
|
||||||
main['GCC'] = CXX_version and CXX_version.find('g++') >= 0
|
main['GCC'] = CXX_version and CXX_version.find('g++') >= 0
|
||||||
main['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0
|
main['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0
|
||||||
|
@ -426,7 +391,7 @@ if main['BATCH']:
|
||||||
|
|
||||||
if sys.platform == 'cygwin':
|
if sys.platform == 'cygwin':
|
||||||
# cygwin has some header file issues...
|
# cygwin has some header file issues...
|
||||||
main.Append(CCFLAGS=Split("-Wno-uninitialized"))
|
main.Append(CCFLAGS="-Wno-uninitialized")
|
||||||
|
|
||||||
# Check for SWIG
|
# Check for SWIG
|
||||||
if not main.has_key('SWIG'):
|
if not main.has_key('SWIG'):
|
||||||
|
@ -435,7 +400,7 @@ if not main.has_key('SWIG'):
|
||||||
Exit(1)
|
Exit(1)
|
||||||
|
|
||||||
# Check for appropriate SWIG version
|
# Check for appropriate SWIG version
|
||||||
swig_version = read_command(('swig', '-version'), exception='').split()
|
swig_version = readCommand(('swig', '-version'), exception='').split()
|
||||||
# First 3 words should be "SWIG Version x.y.z"
|
# First 3 words should be "SWIG Version x.y.z"
|
||||||
if len(swig_version) < 3 or \
|
if len(swig_version) < 3 or \
|
||||||
swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
|
swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
|
||||||
|
@ -443,7 +408,7 @@ if len(swig_version) < 3 or \
|
||||||
Exit(1)
|
Exit(1)
|
||||||
|
|
||||||
min_swig_version = '1.3.28'
|
min_swig_version = '1.3.28'
|
||||||
if compare_versions(swig_version[2], min_swig_version) < 0:
|
if compareVersions(swig_version[2], min_swig_version) < 0:
|
||||||
print 'Error: SWIG version', min_swig_version, 'or newer required.'
|
print 'Error: SWIG version', min_swig_version, 'or newer required.'
|
||||||
print ' Installed version:', swig_version[2]
|
print ' Installed version:', swig_version[2]
|
||||||
Exit(1)
|
Exit(1)
|
||||||
|
@ -514,8 +479,8 @@ conf.CheckLeading()
|
||||||
try:
|
try:
|
||||||
import platform
|
import platform
|
||||||
uname = platform.uname()
|
uname = platform.uname()
|
||||||
if uname[0] == 'Darwin' and compare_versions(uname[2], '9.0.0') >= 0:
|
if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0:
|
||||||
if int(read_command('sysctl -n hw.cpu64bit_capable')[0]):
|
if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]):
|
||||||
main.Append(CCFLAGS='-arch x86_64')
|
main.Append(CCFLAGS='-arch x86_64')
|
||||||
main.Append(CFLAGS='-arch x86_64')
|
main.Append(CFLAGS='-arch x86_64')
|
||||||
main.Append(LINKFLAGS='-arch x86_64')
|
main.Append(LINKFLAGS='-arch x86_64')
|
||||||
|
@ -615,9 +580,9 @@ have_mysql = bool(mysql_config)
|
||||||
|
|
||||||
# Check MySQL version.
|
# Check MySQL version.
|
||||||
if have_mysql:
|
if have_mysql:
|
||||||
mysql_version = read_command(mysql_config + ' --version')
|
mysql_version = readCommand(mysql_config + ' --version')
|
||||||
min_mysql_version = '4.1'
|
min_mysql_version = '4.1'
|
||||||
if compare_versions(mysql_version, min_mysql_version) < 0:
|
if compareVersions(mysql_version, min_mysql_version) < 0:
|
||||||
print 'Warning: MySQL', min_mysql_version, 'or newer required.'
|
print 'Warning: MySQL', min_mysql_version, 'or newer required.'
|
||||||
print ' Version', mysql_version, 'detected.'
|
print ' Version', mysql_version, 'detected.'
|
||||||
have_mysql = False
|
have_mysql = False
|
||||||
|
@ -777,17 +742,10 @@ def make_switching_dir(dname, switch_headers, env):
|
||||||
# list of ISAs from env['ALL_ISA_LIST'].
|
# list of ISAs from env['ALL_ISA_LIST'].
|
||||||
def gen_switch_hdr(target, source, env):
|
def gen_switch_hdr(target, source, env):
|
||||||
fname = str(target[0])
|
fname = str(target[0])
|
||||||
bname = basename(fname)
|
|
||||||
f = open(fname, 'w')
|
f = open(fname, 'w')
|
||||||
f.write('#include "arch/isa_specific.hh"\n')
|
isa = env['TARGET_ISA'].lower()
|
||||||
cond = '#if'
|
print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname))
|
||||||
for isa in all_isa_list:
|
|
||||||
f.write('%s THE_ISA == %s_ISA\n#include "%s/%s/%s"\n'
|
|
||||||
% (cond, isa.upper(), dname, isa, bname))
|
|
||||||
cond = '#elif'
|
|
||||||
f.write('#else\n#error "THE_ISA not set"\n#endif\n')
|
|
||||||
f.close()
|
f.close()
|
||||||
return 0
|
|
||||||
|
|
||||||
# String to print when generating header
|
# String to print when generating header
|
||||||
def gen_switch_hdr_string(target, source, env):
|
def gen_switch_hdr_string(target, source, env):
|
||||||
|
|
3
build_opts/ARM_FS
Normal file
3
build_opts/ARM_FS
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
TARGET_ISA = 'arm'
|
||||||
|
CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU'
|
||||||
|
FULL_SYSTEM = 1
|
3
build_opts/POWER_SE
Normal file
3
build_opts/POWER_SE
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
TARGET_ISA = 'power'
|
||||||
|
FULL_SYSTEM = 0
|
||||||
|
CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU,O3CPU'
|
|
@ -26,7 +26,6 @@
|
||||||
#
|
#
|
||||||
# Authors: Lisa Hsu
|
# Authors: Lisa Hsu
|
||||||
|
|
||||||
import m5
|
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
|
|
||||||
class L1Cache(BaseCache):
|
class L1Cache(BaseCache):
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
#
|
#
|
||||||
# Authors: Kevin Lim
|
# Authors: Kevin Lim
|
||||||
|
|
||||||
import m5
|
|
||||||
from m5 import makeList
|
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
from Benchmarks import *
|
from Benchmarks import *
|
||||||
|
|
||||||
|
@ -81,6 +79,50 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def makeLinuxAlphaRubySystem(mem_mode, rubymem, mdesc = None):
|
||||||
|
class BaseTsunami(Tsunami):
|
||||||
|
ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0)
|
||||||
|
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
|
||||||
|
pci_func=0, pci_dev=0, pci_bus=0)
|
||||||
|
|
||||||
|
|
||||||
|
self = LinuxAlphaSystem(physmem = rubymem)
|
||||||
|
if not mdesc:
|
||||||
|
# generic system
|
||||||
|
mdesc = SysConfig()
|
||||||
|
self.readfile = mdesc.script()
|
||||||
|
|
||||||
|
# Create pio bus to connect all device pio ports to rubymem's pio port
|
||||||
|
self.piobus = Bus(bus_id=0)
|
||||||
|
|
||||||
|
self.disk0 = CowIdeDisk(driveID='master')
|
||||||
|
self.disk2 = CowIdeDisk(driveID='master')
|
||||||
|
self.disk0.childImage(mdesc.disk())
|
||||||
|
self.disk2.childImage(disk('linux-bigswap2.img'))
|
||||||
|
self.tsunami = BaseTsunami()
|
||||||
|
self.tsunami.attachIO(self.piobus)
|
||||||
|
self.tsunami.ide.pio = self.piobus.port
|
||||||
|
self.tsunami.ethernet.pio = self.piobus.port
|
||||||
|
|
||||||
|
# connect the dma ports directly to ruby dma ports
|
||||||
|
self.tsunami.ide.dma = self.physmem.dma_port
|
||||||
|
self.tsunami.ethernet.dma = self.physmem.dma_port
|
||||||
|
|
||||||
|
# connect the pio bus to rubymem
|
||||||
|
self.physmem.pio_port = self.piobus.port
|
||||||
|
|
||||||
|
self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(),
|
||||||
|
read_only = True))
|
||||||
|
self.intrctrl = IntrControl()
|
||||||
|
self.mem_mode = mem_mode
|
||||||
|
self.terminal = Terminal()
|
||||||
|
self.kernel = binary('vmlinux')
|
||||||
|
self.pal = binary('ts_osfpal')
|
||||||
|
self.console = binary('console')
|
||||||
|
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
def makeSparcSystem(mem_mode, mdesc = None):
|
def makeSparcSystem(mem_mode, mdesc = None):
|
||||||
class CowMmDisk(MmDisk):
|
class CowMmDisk(MmDisk):
|
||||||
image = CowDiskImage(child=RawDiskImage(read_only=True),
|
image = CowDiskImage(child=RawDiskImage(read_only=True),
|
||||||
|
|
|
@ -38,6 +38,7 @@ parser.add_option("--fastmem", action="store_true")
|
||||||
# Run duration options
|
# Run duration options
|
||||||
parser.add_option("-m", "--maxtick", type="int")
|
parser.add_option("-m", "--maxtick", type="int")
|
||||||
parser.add_option("--maxtime", type="float")
|
parser.add_option("--maxtime", type="float")
|
||||||
|
parser.add_option("--maxinsts", type="int")
|
||||||
parser.add_option("--prog_intvl", type="int")
|
parser.add_option("--prog_intvl", type="int")
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,6 +53,9 @@ parser.add_option("--checkpoint-dir", action="store", type="string",
|
||||||
help="Place all checkpoints in this absolute directory")
|
help="Place all checkpoints in this absolute directory")
|
||||||
parser.add_option("-r", "--checkpoint-restore", action="store", type="int",
|
parser.add_option("-r", "--checkpoint-restore", action="store", type="int",
|
||||||
help="restore from checkpoint <N>")
|
help="restore from checkpoint <N>")
|
||||||
|
parser.add_option("--checkpoint-at-end", action="store_true",
|
||||||
|
help="take a checkpoint at end of run")
|
||||||
|
|
||||||
|
|
||||||
# CPU Switching - default switch model goes from a checkpoint
|
# CPU Switching - default switch model goes from a checkpoint
|
||||||
# to a timing simple CPU with caches to warm up, then to detailed CPU for
|
# to a timing simple CPU with caches to warm up, then to detailed CPU for
|
||||||
|
@ -61,6 +65,7 @@ parser.add_option("-s", "--standard-switch", action="store_true",
|
||||||
parser.add_option("-w", "--warmup", action="store", type="int",
|
parser.add_option("-w", "--warmup", action="store", type="int",
|
||||||
help="if -s, then this is the warmup period. else, this is ignored",
|
help="if -s, then this is the warmup period. else, this is ignored",
|
||||||
default=5000000000)
|
default=5000000000)
|
||||||
|
parser.add_option("--profile", help="CPU profile interval")
|
||||||
|
|
||||||
# Fastforwarding and simpoint related materials
|
# Fastforwarding and simpoint related materials
|
||||||
parser.add_option("-W", "--warmup-insts", action="store", type="int",
|
parser.add_option("-W", "--warmup-insts", action="store", type="int",
|
||||||
|
|
|
@ -28,9 +28,13 @@
|
||||||
|
|
||||||
from os import getcwd
|
from os import getcwd
|
||||||
from os.path import join as joinpath
|
from os.path import join as joinpath
|
||||||
|
|
||||||
import m5
|
import m5
|
||||||
|
from m5.defines import buildEnv
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
m5.AddToPath('../common')
|
from m5.util import *
|
||||||
|
|
||||||
|
addToPath('../common')
|
||||||
|
|
||||||
def setCPUClass(options):
|
def setCPUClass(options):
|
||||||
|
|
||||||
|
@ -82,10 +86,10 @@ def run(options, root, testsys, cpu_class):
|
||||||
cptdir = getcwd()
|
cptdir = getcwd()
|
||||||
|
|
||||||
if options.fast_forward and options.checkpoint_restore != None:
|
if options.fast_forward and options.checkpoint_restore != None:
|
||||||
m5.fatal("Error: Can't specify both --fast-forward and --checkpoint-restore")
|
fatal("Can't specify both --fast-forward and --checkpoint-restore")
|
||||||
|
|
||||||
if options.standard_switch and not options.caches:
|
if options.standard_switch and not options.caches:
|
||||||
m5.fatal("Error: Must specify --caches when using --standard-switch")
|
fatal("Must specify --caches when using --standard-switch")
|
||||||
|
|
||||||
np = options.num_cpus
|
np = options.num_cpus
|
||||||
max_checkpoints = options.max_checkpoints
|
max_checkpoints = options.max_checkpoints
|
||||||
|
@ -95,6 +99,10 @@ def run(options, root, testsys, cpu_class):
|
||||||
for i in xrange(np):
|
for i in xrange(np):
|
||||||
testsys.cpu[i].progress_interval = options.prog_intvl
|
testsys.cpu[i].progress_interval = options.prog_intvl
|
||||||
|
|
||||||
|
if options.maxinsts:
|
||||||
|
for i in xrange(np):
|
||||||
|
testsys.cpu[i].max_insts_any_thread = options.maxinsts
|
||||||
|
|
||||||
if cpu_class:
|
if cpu_class:
|
||||||
switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
|
switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
|
||||||
for i in xrange(np)]
|
for i in xrange(np)]
|
||||||
|
@ -103,7 +111,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
if options.fast_forward:
|
if options.fast_forward:
|
||||||
testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
|
testsys.cpu[i].max_insts_any_thread = int(options.fast_forward)
|
||||||
switch_cpus[i].system = testsys
|
switch_cpus[i].system = testsys
|
||||||
if not m5.build_env['FULL_SYSTEM']:
|
if not buildEnv['FULL_SYSTEM']:
|
||||||
switch_cpus[i].workload = testsys.cpu[i].workload
|
switch_cpus[i].workload = testsys.cpu[i].workload
|
||||||
switch_cpus[i].clock = testsys.cpu[0].clock
|
switch_cpus[i].clock = testsys.cpu[0].clock
|
||||||
# simulation period
|
# simulation period
|
||||||
|
@ -122,7 +130,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
for i in xrange(np):
|
for i in xrange(np):
|
||||||
switch_cpus[i].system = testsys
|
switch_cpus[i].system = testsys
|
||||||
switch_cpus_1[i].system = testsys
|
switch_cpus_1[i].system = testsys
|
||||||
if not m5.build_env['FULL_SYSTEM']:
|
if not buildEnv['FULL_SYSTEM']:
|
||||||
switch_cpus[i].workload = testsys.cpu[i].workload
|
switch_cpus[i].workload = testsys.cpu[i].workload
|
||||||
switch_cpus_1[i].workload = testsys.cpu[i].workload
|
switch_cpus_1[i].workload = testsys.cpu[i].workload
|
||||||
switch_cpus[i].clock = testsys.cpu[0].clock
|
switch_cpus[i].clock = testsys.cpu[0].clock
|
||||||
|
@ -137,7 +145,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
# Fast forward to a simpoint (warning: time consuming)
|
# Fast forward to a simpoint (warning: time consuming)
|
||||||
elif options.simpoint:
|
elif options.simpoint:
|
||||||
if testsys.cpu[i].workload[0].simpoint == 0:
|
if testsys.cpu[i].workload[0].simpoint == 0:
|
||||||
m5.fatal('simpoint not found')
|
fatal('simpoint not found')
|
||||||
testsys.cpu[i].max_insts_any_thread = \
|
testsys.cpu[i].max_insts_any_thread = \
|
||||||
testsys.cpu[i].workload[0].simpoint
|
testsys.cpu[i].workload[0].simpoint
|
||||||
# No distance specified, just switch
|
# No distance specified, just switch
|
||||||
|
@ -170,7 +178,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
if options.simpoint:
|
if options.simpoint:
|
||||||
for i in xrange(np):
|
for i in xrange(np):
|
||||||
if testsys.cpu[i].workload[0].simpoint == 0:
|
if testsys.cpu[i].workload[0].simpoint == 0:
|
||||||
m5.fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
|
fatal('no simpoint for testsys.cpu[%d].workload[0]', i)
|
||||||
checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
|
checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset
|
||||||
testsys.cpu[i].max_insts_any_thread = checkpoint_inst
|
testsys.cpu[i].max_insts_any_thread = checkpoint_inst
|
||||||
# used for output below
|
# used for output below
|
||||||
|
@ -190,14 +198,13 @@ def run(options, root, testsys, cpu_class):
|
||||||
import re
|
import re
|
||||||
|
|
||||||
if not isdir(cptdir):
|
if not isdir(cptdir):
|
||||||
m5.fatal("checkpoint dir %s does not exist!", cptdir)
|
fatal("checkpoint dir %s does not exist!", cptdir)
|
||||||
|
|
||||||
if options.at_instruction:
|
if options.at_instruction:
|
||||||
checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % \
|
checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % \
|
||||||
(options.bench, options.checkpoint_restore))
|
(options.bench, options.checkpoint_restore))
|
||||||
if not exists(checkpoint_dir):
|
if not exists(checkpoint_dir):
|
||||||
m5.fatal("Unable to find checkpoint directory %s",
|
fatal("Unable to find checkpoint directory %s", checkpoint_dir)
|
||||||
checkpoint_dir)
|
|
||||||
|
|
||||||
print "Restoring checkpoint ..."
|
print "Restoring checkpoint ..."
|
||||||
m5.restoreCheckpoint(root, checkpoint_dir)
|
m5.restoreCheckpoint(root, checkpoint_dir)
|
||||||
|
@ -205,7 +212,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
elif options.simpoint:
|
elif options.simpoint:
|
||||||
# assume workload 0 has the simpoint
|
# assume workload 0 has the simpoint
|
||||||
if testsys.cpu[0].workload[0].simpoint == 0:
|
if testsys.cpu[0].workload[0].simpoint == 0:
|
||||||
m5.fatal('Unable to find simpoint')
|
fatal('Unable to find simpoint')
|
||||||
|
|
||||||
options.checkpoint_restore += \
|
options.checkpoint_restore += \
|
||||||
int(testsys.cpu[0].workload[0].simpoint)
|
int(testsys.cpu[0].workload[0].simpoint)
|
||||||
|
@ -213,8 +220,8 @@ def run(options, root, testsys, cpu_class):
|
||||||
checkpoint_dir = joinpath(cptdir, "cpt.%s.%d" % \
|
checkpoint_dir = joinpath(cptdir, "cpt.%s.%d" % \
|
||||||
(options.bench, options.checkpoint_restore))
|
(options.bench, options.checkpoint_restore))
|
||||||
if not exists(checkpoint_dir):
|
if not exists(checkpoint_dir):
|
||||||
m5.fatal("Unable to find checkpoint directory %s.%s",
|
fatal("Unable to find checkpoint directory %s.%s",
|
||||||
options.bench, options.checkpoint_restore)
|
options.bench, options.checkpoint_restore)
|
||||||
|
|
||||||
print "Restoring checkpoint ..."
|
print "Restoring checkpoint ..."
|
||||||
m5.restoreCheckpoint(root,checkpoint_dir)
|
m5.restoreCheckpoint(root,checkpoint_dir)
|
||||||
|
@ -233,7 +240,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
cpt_num = options.checkpoint_restore
|
cpt_num = options.checkpoint_restore
|
||||||
|
|
||||||
if cpt_num > len(cpts):
|
if cpt_num > len(cpts):
|
||||||
m5.fatal('Checkpoint %d not found', cpt_num)
|
fatal('Checkpoint %d not found', cpt_num)
|
||||||
|
|
||||||
## Adjust max tick based on our starting tick
|
## Adjust max tick based on our starting tick
|
||||||
maxtick = maxtick - int(cpts[cpt_num - 1])
|
maxtick = maxtick - int(cpts[cpt_num - 1])
|
||||||
|
@ -367,3 +374,6 @@ def run(options, root, testsys, cpu_class):
|
||||||
exit_cause = exit_event.getCause()
|
exit_cause = exit_event.getCause()
|
||||||
print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause)
|
print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause)
|
||||||
|
|
||||||
|
if options.checkpoint_at_end:
|
||||||
|
m5.checkpoint(root, joinpath(cptdir, "cpt.%d"))
|
||||||
|
|
||||||
|
|
|
@ -26,15 +26,20 @@
|
||||||
#
|
#
|
||||||
# Authors: Ali Saidi
|
# Authors: Ali Saidi
|
||||||
|
|
||||||
import optparse, os, sys
|
import optparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
import m5
|
import m5
|
||||||
|
from m5.defines import buildEnv
|
||||||
if not m5.build_env['FULL_SYSTEM']:
|
|
||||||
m5.fatal("This script requires full-system mode (*_FS).")
|
|
||||||
|
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
m5.AddToPath('../common')
|
from m5.util import addToPath, fatal
|
||||||
|
|
||||||
|
if not buildEnv['FULL_SYSTEM']:
|
||||||
|
fatal("This script requires full-system mode (*_FS).")
|
||||||
|
|
||||||
|
addToPath('../common')
|
||||||
|
|
||||||
from FSConfig import *
|
from FSConfig import *
|
||||||
from SysPaths import *
|
from SysPaths import *
|
||||||
from Benchmarks import *
|
from Benchmarks import *
|
||||||
|
@ -98,16 +103,16 @@ else:
|
||||||
|
|
||||||
np = options.num_cpus
|
np = options.num_cpus
|
||||||
|
|
||||||
if m5.build_env['TARGET_ISA'] == "alpha":
|
if buildEnv['TARGET_ISA'] == "alpha":
|
||||||
test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0])
|
test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0])
|
||||||
elif m5.build_env['TARGET_ISA'] == "mips":
|
elif buildEnv['TARGET_ISA'] == "mips":
|
||||||
test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0])
|
test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0])
|
||||||
elif m5.build_env['TARGET_ISA'] == "sparc":
|
elif buildEnv['TARGET_ISA'] == "sparc":
|
||||||
test_sys = makeSparcSystem(test_mem_mode, bm[0])
|
test_sys = makeSparcSystem(test_mem_mode, bm[0])
|
||||||
elif m5.build_env['TARGET_ISA'] == "x86":
|
elif buildEnv['TARGET_ISA'] == "x86":
|
||||||
test_sys = makeLinuxX86System(test_mem_mode, np, bm[0])
|
test_sys = makeLinuxX86System(test_mem_mode, np, bm[0])
|
||||||
else:
|
else:
|
||||||
m5.fatal("incapable of building non-alpha or non-sparc full system!")
|
fatal("incapable of building non-alpha or non-sparc full system!")
|
||||||
|
|
||||||
if options.kernel is not None:
|
if options.kernel is not None:
|
||||||
test_sys.kernel = binary(options.kernel)
|
test_sys.kernel = binary(options.kernel)
|
||||||
|
@ -123,7 +128,7 @@ if options.l2cache:
|
||||||
|
|
||||||
test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)]
|
test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)]
|
||||||
|
|
||||||
if options.caches:
|
if options.caches or options.l2cache:
|
||||||
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)]
|
test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)]
|
||||||
test_sys.bridge.filter_ranges_b=[AddrRange(0, size='8GB')]
|
test_sys.bridge.filter_ranges_b=[AddrRange(0, size='8GB')]
|
||||||
test_sys.iocache = IOCache(addr_range=AddrRange(0, size='8GB'))
|
test_sys.iocache = IOCache(addr_range=AddrRange(0, size='8GB'))
|
||||||
|
@ -142,17 +147,17 @@ for i in xrange(np):
|
||||||
if options.fastmem:
|
if options.fastmem:
|
||||||
test_sys.cpu[i].physmem_port = test_sys.physmem.port
|
test_sys.cpu[i].physmem_port = test_sys.physmem.port
|
||||||
|
|
||||||
if m5.build_env['TARGET_ISA'] == 'mips':
|
if buildEnv['TARGET_ISA'] == 'mips':
|
||||||
setMipsOptions(TestCPUClass)
|
setMipsOptions(TestCPUClass)
|
||||||
|
|
||||||
if len(bm) == 2:
|
if len(bm) == 2:
|
||||||
if m5.build_env['TARGET_ISA'] == 'alpha':
|
if buildEnv['TARGET_ISA'] == 'alpha':
|
||||||
drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1])
|
drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1])
|
||||||
elif m5.build_env['TARGET_ISA'] == 'mips':
|
elif buildEnv['TARGET_ISA'] == 'mips':
|
||||||
drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1])
|
drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1])
|
||||||
elif m5.build_env['TARGET_ISA'] == 'sparc':
|
elif buildEnv['TARGET_ISA'] == 'sparc':
|
||||||
drive_sys = makeSparcSystem(drive_mem_mode, bm[1])
|
drive_sys = makeSparcSystem(drive_mem_mode, bm[1])
|
||||||
elif m5.build.env['TARGET_ISA'] == 'x86':
|
elif buildEnv['TARGET_ISA'] == 'x86':
|
||||||
drive_sys = makeX86System(drive_mem_mode, np, bm[1])
|
drive_sys = makeX86System(drive_mem_mode, np, bm[1])
|
||||||
drive_sys.cpu = DriveCPUClass(cpu_id=0)
|
drive_sys.cpu = DriveCPUClass(cpu_id=0)
|
||||||
drive_sys.cpu.connectMemPorts(drive_sys.membus)
|
drive_sys.cpu.connectMemPorts(drive_sys.membus)
|
||||||
|
|
122
configs/example/memtest-ruby.py
Normal file
122
configs/example/memtest-ruby.py
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
# Copyright (c) 2006-2007 The Regents of The University of Michigan
|
||||||
|
# Copyright (c) 2009 Advanced Micro Devices, Inc.
|
||||||
|
# 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: Ron Dreslinski
|
||||||
|
# Brad Beckmann
|
||||||
|
|
||||||
|
import m5
|
||||||
|
from m5.objects import *
|
||||||
|
from m5.defines import buildEnv
|
||||||
|
from m5.util import addToPath
|
||||||
|
import os, optparse, sys
|
||||||
|
addToPath('../common')
|
||||||
|
addToPath('../../tests/configs/')
|
||||||
|
import ruby_config
|
||||||
|
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
|
||||||
|
parser.add_option("-a", "--atomic", action="store_true",
|
||||||
|
help="Use atomic (non-timing) mode")
|
||||||
|
parser.add_option("-b", "--blocking", action="store_true",
|
||||||
|
help="Use blocking caches")
|
||||||
|
parser.add_option("-l", "--maxloads", metavar="N", default=0,
|
||||||
|
help="Stop after N loads")
|
||||||
|
parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick,
|
||||||
|
metavar="T",
|
||||||
|
help="Stop after T ticks")
|
||||||
|
|
||||||
|
parser.add_option("-t", "--testers", type="int", metavar="N", default=1,
|
||||||
|
help="number of testers/cores")
|
||||||
|
|
||||||
|
parser.add_option("-f", "--functional", type="int", default=0,
|
||||||
|
metavar="PCT",
|
||||||
|
help="Target percentage of functional accesses "
|
||||||
|
"[default: %default]")
|
||||||
|
parser.add_option("-u", "--uncacheable", type="int", default=0,
|
||||||
|
metavar="PCT",
|
||||||
|
help="Target percentage of uncacheable accesses "
|
||||||
|
"[default: %default]")
|
||||||
|
|
||||||
|
parser.add_option("--progress", type="int", default=1000,
|
||||||
|
metavar="NLOADS",
|
||||||
|
help="Progress message interval "
|
||||||
|
"[default: %default]")
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
if args:
|
||||||
|
print "Error: script doesn't take any positional arguments"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
block_size = 64
|
||||||
|
|
||||||
|
if options.testers > block_size:
|
||||||
|
print "Error: Number of testers %d limited to %d because of false sharing" \
|
||||||
|
% (options.testers, block_size)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \
|
||||||
|
percent_functional=options.functional, \
|
||||||
|
percent_uncacheable=options.uncacheable, \
|
||||||
|
progress_interval=options.progress) \
|
||||||
|
for i in xrange(options.testers) ]
|
||||||
|
|
||||||
|
# create the desired simulated system
|
||||||
|
# ruby memory must be at least 16 MB to work with the mem tester
|
||||||
|
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb",
|
||||||
|
cores = options.testers,
|
||||||
|
memory_size = 16,
|
||||||
|
ports_per_cpu = 1)
|
||||||
|
|
||||||
|
system = System(cpu = cpus, funcmem = PhysicalMemory(),
|
||||||
|
physmem = ruby_memory)
|
||||||
|
|
||||||
|
for cpu in cpus:
|
||||||
|
cpu.test = system.physmem.port
|
||||||
|
cpu.functional = system.funcmem.port
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------
|
||||||
|
# run simulation
|
||||||
|
# -----------------------
|
||||||
|
|
||||||
|
root = Root( system = system )
|
||||||
|
if options.atomic:
|
||||||
|
root.system.mem_mode = 'atomic'
|
||||||
|
else:
|
||||||
|
root.system.mem_mode = 'timing'
|
||||||
|
|
||||||
|
# Not much point in this being higher than the L1 latency
|
||||||
|
m5.ticks.setGlobalFrequency('1ns')
|
||||||
|
|
||||||
|
# instantiate configuration
|
||||||
|
m5.instantiate(root)
|
||||||
|
|
||||||
|
# simulate until program terminates
|
||||||
|
exit_event = m5.simulate(options.maxtick)
|
||||||
|
|
||||||
|
print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()
|
|
@ -26,10 +26,11 @@
|
||||||
#
|
#
|
||||||
# Authors: Ron Dreslinski
|
# Authors: Ron Dreslinski
|
||||||
|
|
||||||
|
import optparse
|
||||||
|
import sys
|
||||||
|
|
||||||
import m5
|
import m5
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
import os, optparse, sys
|
|
||||||
m5.AddToPath('../common')
|
|
||||||
|
|
||||||
parser = optparse.OptionParser()
|
parser = optparse.OptionParser()
|
||||||
|
|
||||||
|
|
201
configs/example/ruby_fs.py
Normal file
201
configs/example/ruby_fs.py
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
# Copyright (c) 2009 Advanced Micro Devices, Inc.
|
||||||
|
# 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: Brad Beckmann
|
||||||
|
|
||||||
|
#
|
||||||
|
# Full system configuraiton for ruby
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import optparse
|
||||||
|
import sys
|
||||||
|
from os.path import join as joinpath
|
||||||
|
|
||||||
|
import m5
|
||||||
|
from m5.defines import buildEnv
|
||||||
|
from m5.objects import *
|
||||||
|
from m5.util import addToPath, panic
|
||||||
|
|
||||||
|
if not buildEnv['FULL_SYSTEM']:
|
||||||
|
panic("This script requires full-system mode (*_FS).")
|
||||||
|
|
||||||
|
addToPath('../../tests/configs/')
|
||||||
|
addToPath('../common')
|
||||||
|
|
||||||
|
import ruby_config
|
||||||
|
|
||||||
|
from FSConfig import *
|
||||||
|
from SysPaths import *
|
||||||
|
from Benchmarks import *
|
||||||
|
import Simulation
|
||||||
|
from Caches import *
|
||||||
|
|
||||||
|
# Get paths we might need. It's expected this file is in m5/configs/example.
|
||||||
|
config_path = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
config_root = os.path.dirname(config_path)
|
||||||
|
m5_root = os.path.dirname(config_root)
|
||||||
|
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
|
||||||
|
# Benchmark options
|
||||||
|
parser.add_option("-b", "--benchmark", action="store", type="string",
|
||||||
|
dest="benchmark",
|
||||||
|
help="Specify the benchmark to run. Available benchmarks: %s"\
|
||||||
|
% DefinedBenchmarks)
|
||||||
|
parser.add_option("-o", "--options", default="",
|
||||||
|
help='The options to pass to the binary, use " " around the entire string')
|
||||||
|
parser.add_option("-i", "--input", default="", help="Read stdin from a file.")
|
||||||
|
parser.add_option("--output", default="", help="Redirect stdout to a file.")
|
||||||
|
parser.add_option("--errout", default="", help="Redirect stderr to a file.")
|
||||||
|
|
||||||
|
# ruby options
|
||||||
|
parser.add_option("--ruby-debug", action="store_true")
|
||||||
|
parser.add_option("--ruby-debug-file", default="", help="Ruby debug out file (stdout if blank)")
|
||||||
|
parser.add_option("--protocol", default="", help="Ruby protocol compiled into binary")
|
||||||
|
|
||||||
|
|
||||||
|
# ruby host memory experimentation
|
||||||
|
parser.add_option("--cache_size", type="int")
|
||||||
|
parser.add_option("--cache_assoc", type="int")
|
||||||
|
parser.add_option("--map_levels", type="int")
|
||||||
|
|
||||||
|
execfile(os.path.join(config_root, "common", "Options.py"))
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
if args:
|
||||||
|
print "Error: script doesn't take any positional arguments"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if options.benchmark:
|
||||||
|
try:
|
||||||
|
bm = Benchmarks[options.benchmark]
|
||||||
|
except KeyError:
|
||||||
|
print "Error benchmark %s has not been defined." % options.benchmark
|
||||||
|
print "Valid benchmarks are: %s" % DefinedBenchmarks
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
bm = [SysConfig()]
|
||||||
|
|
||||||
|
#
|
||||||
|
# currently ruby fs only works in simple timing mode because ruby does not
|
||||||
|
# support atomic accesses by devices. Also ruby_fs currently assumes
|
||||||
|
# that is running a checkpoints that were created by ALPHA_FS under atomic
|
||||||
|
# mode. Since switch cpus are not defined in these checkpoints, we don't
|
||||||
|
# fast forward with the atomic cpu and instead set the FutureClass to None.
|
||||||
|
# Therefore the cpus resolve to the correct names and unserialize correctly.
|
||||||
|
#
|
||||||
|
assert(options.timing)
|
||||||
|
class CPUClass(TimingSimpleCPU): pass
|
||||||
|
test_mem_mode = 'timing'
|
||||||
|
FutureClass = None
|
||||||
|
|
||||||
|
CPUClass.clock = '1GHz'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Since we are running in timing mode, set the number of M5 ticks to ruby ticks
|
||||||
|
# to the cpu clock frequency
|
||||||
|
#
|
||||||
|
M5_to_ruby_tick = '1000t'
|
||||||
|
|
||||||
|
np = options.num_cpus
|
||||||
|
|
||||||
|
# check for max instruction count
|
||||||
|
if options.max_inst:
|
||||||
|
max_inst = options.max_inst
|
||||||
|
else:
|
||||||
|
max_inst = 0
|
||||||
|
|
||||||
|
# set cache size
|
||||||
|
if options.cache_size:
|
||||||
|
cache_size = options.cache_size
|
||||||
|
else:
|
||||||
|
cache_size = 32768 # 32 kB is default
|
||||||
|
|
||||||
|
# set cache assoc
|
||||||
|
if options.cache_assoc:
|
||||||
|
cache_assoc = options.cache_assoc
|
||||||
|
else:
|
||||||
|
cache_assoc = 8 # 8 is default
|
||||||
|
|
||||||
|
# set map levels
|
||||||
|
if options.map_levels:
|
||||||
|
map_levels = options.map_levels
|
||||||
|
else:
|
||||||
|
map_levels = 4 # 4 levels is the default
|
||||||
|
|
||||||
|
if options.protocol == "MOESI_hammer":
|
||||||
|
ruby_config_file = "MOESI_hammer-homogeneous.rb"
|
||||||
|
elif options.protocol == "MOESI_CMP_token":
|
||||||
|
ruby_config_file = "TwoLevel_SplitL1UnifiedL2.rb"
|
||||||
|
elif options.protocol == "MI_example":
|
||||||
|
ruby_config_file = "MI_example-homogeneous.rb"
|
||||||
|
else:
|
||||||
|
print "Error: unsupported ruby protocol"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Currently, since ruby configuraiton is separate from m5, we need to manually
|
||||||
|
# tell ruby that two dma ports are created by makeLinuxAlphaRubySystem().
|
||||||
|
# Eventually, this will be fix with a unified configuration system.
|
||||||
|
#
|
||||||
|
rubymem = ruby_config.generate(ruby_config_file,
|
||||||
|
np,
|
||||||
|
np,
|
||||||
|
128,
|
||||||
|
False,
|
||||||
|
cache_size,
|
||||||
|
cache_assoc,
|
||||||
|
map_levels,
|
||||||
|
2,
|
||||||
|
M5_to_ruby_tick)
|
||||||
|
|
||||||
|
if options.ruby_debug == True:
|
||||||
|
rubymem.debug = True
|
||||||
|
rubymem.debug_file = options.ruby_debug_file
|
||||||
|
|
||||||
|
system = makeLinuxAlphaRubySystem(test_mem_mode, rubymem, bm[0])
|
||||||
|
|
||||||
|
system.cpu = [CPUClass(cpu_id=i) for i in xrange(np)]
|
||||||
|
|
||||||
|
if options.l2cache:
|
||||||
|
print "Error: -l2cache incompatible with ruby, must configure it ruby-style"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if options.caches:
|
||||||
|
print "Error: -caches incompatible with ruby, must configure it ruby-style"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for i in xrange(np):
|
||||||
|
system.cpu[i].connectMemPorts(system.physmem)
|
||||||
|
|
||||||
|
if options.fastmem:
|
||||||
|
system.cpu[i].physmem_port = system.physmem.port
|
||||||
|
|
||||||
|
root = Root(system = system)
|
||||||
|
|
||||||
|
Simulation.run(options, root, system, FutureClass)
|
|
@ -30,17 +30,22 @@
|
||||||
#
|
#
|
||||||
# "m5 test.py"
|
# "m5 test.py"
|
||||||
|
|
||||||
import m5
|
import os
|
||||||
|
import optparse
|
||||||
if m5.build_env['FULL_SYSTEM']:
|
import sys
|
||||||
m5.panic("This script requires syscall emulation mode (*_SE).")
|
|
||||||
|
|
||||||
from m5.objects import *
|
|
||||||
import os, optparse, sys
|
|
||||||
from os.path import join as joinpath
|
from os.path import join as joinpath
|
||||||
m5.AddToPath('../common')
|
|
||||||
|
import m5
|
||||||
|
from m5.defines import buildEnv
|
||||||
|
from m5.objects import *
|
||||||
|
from m5.util import addToPath, panic
|
||||||
|
|
||||||
|
if buildEnv['FULL_SYSTEM']:
|
||||||
|
panic("This script requires syscall emulation mode (*_SE).")
|
||||||
|
|
||||||
|
addToPath('../common')
|
||||||
|
|
||||||
import Simulation
|
import Simulation
|
||||||
#from Caches import *
|
|
||||||
from cpu2000 import *
|
from cpu2000 import *
|
||||||
|
|
||||||
# Get paths we might need. It's expected this file is in m5/configs/example.
|
# Get paths we might need. It's expected this file is in m5/configs/example.
|
||||||
|
@ -72,7 +77,7 @@ if args:
|
||||||
|
|
||||||
if options.bench:
|
if options.bench:
|
||||||
try:
|
try:
|
||||||
if m5.build_env['TARGET_ISA'] != 'alpha':
|
if buildEnv['TARGET_ISA'] != 'alpha':
|
||||||
print >>sys.stderr, "Simpoints code only works for Alpha ISA at this time"
|
print >>sys.stderr, "Simpoints code only works for Alpha ISA at this time"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
exec("workload = %s('alpha', 'tru64', 'ref')" % options.bench)
|
exec("workload = %s('alpha', 'tru64', 'ref')" % options.bench)
|
||||||
|
@ -133,7 +138,6 @@ rubymem = RubyMemory(
|
||||||
range = AddrRange("512MB"),
|
range = AddrRange("512MB"),
|
||||||
clock = "1GHz",
|
clock = "1GHz",
|
||||||
num_cpus = np,
|
num_cpus = np,
|
||||||
libruby_file = "src/mem/ruby/amd64-linux/generated/MOESI_CMP_directory/bin/libruby.so",
|
|
||||||
config_file = "ruby.config",
|
config_file = "ruby.config",
|
||||||
stats_file = "m5out/ruby.stats"
|
stats_file = "m5out/ruby.stats"
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,15 +30,21 @@
|
||||||
#
|
#
|
||||||
# "m5 test.py"
|
# "m5 test.py"
|
||||||
|
|
||||||
import m5
|
import os
|
||||||
|
import optparse
|
||||||
if m5.build_env['FULL_SYSTEM']:
|
import sys
|
||||||
m5.fatal("This script requires syscall emulation mode (*_SE).")
|
|
||||||
|
|
||||||
from m5.objects import *
|
|
||||||
import os, optparse, sys
|
|
||||||
from os.path import join as joinpath
|
from os.path import join as joinpath
|
||||||
m5.AddToPath('../common')
|
|
||||||
|
import m5
|
||||||
|
from m5.defines import buildEnv
|
||||||
|
from m5.objects import *
|
||||||
|
from m5.util import addToPath, fatal
|
||||||
|
|
||||||
|
if buildEnv['FULL_SYSTEM']:
|
||||||
|
fatal("This script requires syscall emulation mode (*_SE).")
|
||||||
|
|
||||||
|
addToPath('../common')
|
||||||
|
|
||||||
import Simulation
|
import Simulation
|
||||||
from Caches import *
|
from Caches import *
|
||||||
from cpu2000 import *
|
from cpu2000 import *
|
||||||
|
@ -70,7 +76,7 @@ if args:
|
||||||
|
|
||||||
if options.bench:
|
if options.bench:
|
||||||
try:
|
try:
|
||||||
if m5.build_env['TARGET_ISA'] != 'alpha':
|
if buildEnv['TARGET_ISA'] != 'alpha':
|
||||||
print >>sys.stderr, "Simpoints code only works for Alpha ISA at this time"
|
print >>sys.stderr, "Simpoints code only works for Alpha ISA at this time"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
exec("workload = %s('alpha', 'tru64', 'ref')" % options.bench)
|
exec("workload = %s('alpha', 'tru64', 'ref')" % options.bench)
|
||||||
|
@ -94,8 +100,9 @@ if options.errout != "":
|
||||||
|
|
||||||
# By default, set workload to path of user-specified binary
|
# By default, set workload to path of user-specified binary
|
||||||
workloads = options.cmd
|
workloads = options.cmd
|
||||||
|
numThreads = 1
|
||||||
|
|
||||||
if options.detailed:
|
if options.detailed or options.inorder:
|
||||||
#check for SMT workload
|
#check for SMT workload
|
||||||
workloads = options.cmd.split(';')
|
workloads = options.cmd.split(';')
|
||||||
if len(workloads) > 1:
|
if len(workloads) > 1:
|
||||||
|
@ -124,11 +131,12 @@ if options.detailed:
|
||||||
smt_process.errout = errouts[smt_idx]
|
smt_process.errout = errouts[smt_idx]
|
||||||
process += [smt_process, ]
|
process += [smt_process, ]
|
||||||
smt_idx += 1
|
smt_idx += 1
|
||||||
|
numThreads = len(workloads)
|
||||||
|
|
||||||
(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
|
(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options)
|
||||||
|
|
||||||
CPUClass.clock = '2GHz'
|
CPUClass.clock = '2GHz'
|
||||||
CPUClass.numThreads = len(workloads)
|
CPUClass.numThreads = numThreads;
|
||||||
|
|
||||||
np = options.num_cpus
|
np = options.num_cpus
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,14 @@
|
||||||
#
|
#
|
||||||
# "m5 test.py"
|
# "m5 test.py"
|
||||||
|
|
||||||
|
import os
|
||||||
|
import optparse
|
||||||
|
import sys
|
||||||
|
|
||||||
import m5
|
import m5
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
import os, optparse, sys
|
|
||||||
m5.AddToPath('../common')
|
m5.util.addToPath('../common')
|
||||||
|
|
||||||
# --------------------
|
# --------------------
|
||||||
# Define Command Line Options
|
# Define Command Line Options
|
||||||
|
@ -266,10 +270,11 @@ elif options.benchmark == 'WaterNSquared':
|
||||||
elif options.benchmark == 'WaterSpatial':
|
elif options.benchmark == 'WaterSpatial':
|
||||||
root.workload = Water_spatial()
|
root.workload = Water_spatial()
|
||||||
else:
|
else:
|
||||||
panic("The --benchmark environment variable was set to something" \
|
m5.util.panic("""
|
||||||
+" improper.\nUse Cholesky, FFT, LUContig, LUNoncontig, Radix" \
|
The --benchmark environment variable was set to something improper.
|
||||||
+", Barnes, FMM, OceanContig,\nOceanNoncontig, Raytrace," \
|
Use Cholesky, FFT, LUContig, LUNoncontig, Radix, Barnes, FMM, OceanContig,
|
||||||
+" WaterNSquared, or WaterSpatial\n")
|
OceanNoncontig, Raytrace, WaterNSquared, or WaterSpatial
|
||||||
|
""")
|
||||||
|
|
||||||
# --------------------
|
# --------------------
|
||||||
# Assign the workload to the cpus
|
# Assign the workload to the cpus
|
||||||
|
|
|
@ -29,10 +29,14 @@
|
||||||
# Splash2 Run Script
|
# Splash2 Run Script
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import optparse
|
||||||
|
import sys
|
||||||
|
|
||||||
import m5
|
import m5
|
||||||
from m5.objects import *
|
from m5.objects import *
|
||||||
import os, optparse, sys
|
|
||||||
m5.AddToPath('../common')
|
m5.util.addToPath('../common')
|
||||||
|
|
||||||
# --------------------
|
# --------------------
|
||||||
# Define Command Line Options
|
# Define Command Line Options
|
||||||
|
|
100
src/SConscript
100
src/SConscript
|
@ -49,7 +49,7 @@ Import('*')
|
||||||
# Children need to see the environment
|
# Children need to see the environment
|
||||||
Export('env')
|
Export('env')
|
||||||
|
|
||||||
build_env = dict([(opt, env[opt]) for opt in export_vars])
|
build_env = [(opt, env[opt]) for opt in export_vars]
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Code for adding source files of various types
|
# Code for adding source files of various types
|
||||||
|
@ -132,15 +132,15 @@ class PySource(SourceFile):
|
||||||
modpath = '.'.join(modpath)
|
modpath = '.'.join(modpath)
|
||||||
|
|
||||||
arcpath = path + [ self.basename ]
|
arcpath = path + [ self.basename ]
|
||||||
debugname = self.snode.abspath
|
abspath = self.snode.abspath
|
||||||
if not exists(debugname):
|
if not exists(abspath):
|
||||||
debugname = self.tnode.abspath
|
abspath = self.tnode.abspath
|
||||||
|
|
||||||
self.package = package
|
self.package = package
|
||||||
self.modname = modname
|
self.modname = modname
|
||||||
self.modpath = modpath
|
self.modpath = modpath
|
||||||
self.arcname = joinpath(*arcpath)
|
self.arcname = joinpath(*arcpath)
|
||||||
self.debugname = debugname
|
self.abspath = abspath
|
||||||
self.compiled = File(self.filename + 'c')
|
self.compiled = File(self.filename + 'c')
|
||||||
self.assembly = File(self.filename + '.s')
|
self.assembly = File(self.filename + '.s')
|
||||||
self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath)
|
self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath)
|
||||||
|
@ -228,9 +228,6 @@ env.Append(CPPPATH=Dir('.'))
|
||||||
for extra_dir in extras_dir_list:
|
for extra_dir in extras_dir_list:
|
||||||
env.Append(CPPPATH=Dir(extra_dir))
|
env.Append(CPPPATH=Dir(extra_dir))
|
||||||
|
|
||||||
# Add a flag defining what THE_ISA should be for all compilation
|
|
||||||
env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
|
|
||||||
|
|
||||||
# Workaround for bug in SCons version > 0.97d20071212
|
# Workaround for bug in SCons version > 0.97d20071212
|
||||||
# Scons bug id: 2006 M5 Bug id: 308
|
# Scons bug id: 2006 M5 Bug id: 308
|
||||||
for root, dirs, files in os.walk(base_dir, topdown=True):
|
for root, dirs, files in os.walk(base_dir, topdown=True):
|
||||||
|
@ -261,11 +258,38 @@ for extra_dir in extras_dir_list:
|
||||||
for opt in export_vars:
|
for opt in export_vars:
|
||||||
env.ConfigFile(opt)
|
env.ConfigFile(opt)
|
||||||
|
|
||||||
|
def makeTheISA(source, target, env):
|
||||||
|
f = file(str(target[0]), 'w')
|
||||||
|
|
||||||
|
isas = [ src.get_contents() for src in source ]
|
||||||
|
target = env['TARGET_ISA']
|
||||||
|
def define(isa):
|
||||||
|
return isa.upper() + '_ISA'
|
||||||
|
|
||||||
|
def namespace(isa):
|
||||||
|
return isa[0].upper() + isa[1:].lower() + 'ISA'
|
||||||
|
|
||||||
|
|
||||||
|
print >>f, '#ifndef __CONFIG_THE_ISA_HH__'
|
||||||
|
print >>f, '#define __CONFIG_THE_ISA_HH__'
|
||||||
|
print >>f
|
||||||
|
for i,isa in enumerate(isas):
|
||||||
|
print >>f, '#define %s %d' % (define(isa), i + 1)
|
||||||
|
print >>f
|
||||||
|
print >>f, '#define THE_ISA %s' % (define(target))
|
||||||
|
print >>f, '#define TheISA %s' % (namespace(target))
|
||||||
|
print >>f
|
||||||
|
print >>f, '#endif // __CONFIG_THE_ISA_HH__'
|
||||||
|
|
||||||
|
env.Command('config/the_isa.hh', map(Value, all_isa_list), makeTheISA)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
#
|
#
|
||||||
# Prevent any SimObjects from being added after this point, they
|
# Prevent any SimObjects from being added after this point, they
|
||||||
# should all have been added in the SConscripts above
|
# should all have been added in the SConscripts above
|
||||||
#
|
#
|
||||||
|
SimObject.fixed = True
|
||||||
|
|
||||||
class DictImporter(object):
|
class DictImporter(object):
|
||||||
'''This importer takes a dictionary of arbitrary module names that
|
'''This importer takes a dictionary of arbitrary module names that
|
||||||
map to arbitrary filenames.'''
|
map to arbitrary filenames.'''
|
||||||
|
@ -283,7 +307,7 @@ class DictImporter(object):
|
||||||
self.installed = set()
|
self.installed = set()
|
||||||
|
|
||||||
def find_module(self, fullname, path):
|
def find_module(self, fullname, path):
|
||||||
if fullname == 'defines':
|
if fullname == 'm5.defines':
|
||||||
return self
|
return self
|
||||||
|
|
||||||
if fullname == 'm5.objects':
|
if fullname == 'm5.objects':
|
||||||
|
@ -293,7 +317,7 @@ class DictImporter(object):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
source = self.modules.get(fullname, None)
|
source = self.modules.get(fullname, None)
|
||||||
if source is not None and exists(source.snode.abspath):
|
if source is not None and fullname.startswith('m5.objects'):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -308,28 +332,31 @@ class DictImporter(object):
|
||||||
mod.__path__ = fullname.split('.')
|
mod.__path__ = fullname.split('.')
|
||||||
return mod
|
return mod
|
||||||
|
|
||||||
if fullname == 'defines':
|
if fullname == 'm5.defines':
|
||||||
mod.__dict__['buildEnv'] = build_env
|
mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env)
|
||||||
return mod
|
return mod
|
||||||
|
|
||||||
source = self.modules[fullname]
|
source = self.modules[fullname]
|
||||||
if source.modname == '__init__':
|
if source.modname == '__init__':
|
||||||
mod.__path__ = source.modpath
|
mod.__path__ = source.modpath
|
||||||
mod.__file__ = source.snode.abspath
|
mod.__file__ = source.abspath
|
||||||
|
|
||||||
exec file(source.snode.abspath, 'r') in mod.__dict__
|
exec file(source.abspath, 'r') in mod.__dict__
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
|
|
||||||
|
import m5.SimObject
|
||||||
|
import m5.params
|
||||||
|
|
||||||
|
m5.SimObject.clear()
|
||||||
|
m5.params.clear()
|
||||||
|
|
||||||
# install the python importer so we can grab stuff from the source
|
# install the python importer so we can grab stuff from the source
|
||||||
# tree itself. We can't have SimObjects added after this point or
|
# tree itself. We can't have SimObjects added after this point or
|
||||||
# else we won't know about them for the rest of the stuff.
|
# else we won't know about them for the rest of the stuff.
|
||||||
SimObject.fixed = True
|
|
||||||
importer = DictImporter(PySource.modules)
|
importer = DictImporter(PySource.modules)
|
||||||
sys.meta_path[0:0] = [ importer ]
|
sys.meta_path[0:0] = [ importer ]
|
||||||
|
|
||||||
import m5
|
|
||||||
|
|
||||||
# import all sim objects so we can populate the all_objects list
|
# import all sim objects so we can populate the all_objects list
|
||||||
# make sure that we're working with a list, then let's sort it
|
# make sure that we're working with a list, then let's sort it
|
||||||
for modname in SimObject.modnames:
|
for modname in SimObject.modnames:
|
||||||
|
@ -346,6 +373,12 @@ all_enums = m5.params.allEnums
|
||||||
all_params = {}
|
all_params = {}
|
||||||
for name,obj in sorted(sim_objects.iteritems()):
|
for name,obj in sorted(sim_objects.iteritems()):
|
||||||
for param in obj._params.local.values():
|
for param in obj._params.local.values():
|
||||||
|
# load the ptype attribute now because it depends on the
|
||||||
|
# current version of SimObject.allClasses, but when scons
|
||||||
|
# actually uses the value, all versions of
|
||||||
|
# SimObject.allClasses will have been loaded
|
||||||
|
param.ptype
|
||||||
|
|
||||||
if not hasattr(param, 'swig_decl'):
|
if not hasattr(param, 'swig_decl'):
|
||||||
continue
|
continue
|
||||||
pname = param.ptype_str
|
pname = param.ptype_str
|
||||||
|
@ -365,13 +398,27 @@ depends = [ PySource.modules[dep].tnode for dep in module_depends ]
|
||||||
#
|
#
|
||||||
|
|
||||||
# Generate Python file containing a dict specifying the current
|
# Generate Python file containing a dict specifying the current
|
||||||
# build_env flags.
|
# buildEnv flags.
|
||||||
def makeDefinesPyFile(target, source, env):
|
def makeDefinesPyFile(target, source, env):
|
||||||
f = file(str(target[0]), 'w')
|
|
||||||
build_env, hg_info = [ x.get_contents() for x in source ]
|
build_env, hg_info = [ x.get_contents() for x in source ]
|
||||||
print >>f, "buildEnv = %s" % build_env
|
|
||||||
print >>f, "hgRev = '%s'" % hg_info
|
code = m5.util.code_formatter()
|
||||||
f.close()
|
code("""
|
||||||
|
import m5.internal
|
||||||
|
import m5.util
|
||||||
|
|
||||||
|
buildEnv = m5.util.SmartDict($build_env)
|
||||||
|
hgRev = '$hg_info'
|
||||||
|
|
||||||
|
compileDate = m5.internal.core.compileDate
|
||||||
|
_globals = globals()
|
||||||
|
for key,val in m5.internal.core.__dict__.iteritems():
|
||||||
|
if key.startswith('flag_'):
|
||||||
|
flag = key[5:]
|
||||||
|
_globals[flag] = val
|
||||||
|
del _globals
|
||||||
|
""")
|
||||||
|
code.write(str(target[0]))
|
||||||
|
|
||||||
defines_info = [ Value(build_env), Value(env['HG_INFO']) ]
|
defines_info = [ Value(build_env), Value(env['HG_INFO']) ]
|
||||||
# Generate a file with all of the compile options in it
|
# Generate a file with all of the compile options in it
|
||||||
|
@ -467,12 +514,7 @@ for name,simobj in sorted(sim_objects.iteritems()):
|
||||||
# Generate any parameter header files needed
|
# Generate any parameter header files needed
|
||||||
params_i_files = []
|
params_i_files = []
|
||||||
for name,param in all_params.iteritems():
|
for name,param in all_params.iteritems():
|
||||||
if isinstance(param, m5.params.VectorParamDesc):
|
i_file = File('params/%s_%s.i' % (name, param.file_ext))
|
||||||
ext = 'vptype'
|
|
||||||
else:
|
|
||||||
ext = 'ptype'
|
|
||||||
|
|
||||||
i_file = File('params/%s_%s.i' % (name, ext))
|
|
||||||
params_i_files.append(i_file)
|
params_i_files.append(i_file)
|
||||||
env.Command(i_file, Value(name), createSwigParam)
|
env.Command(i_file, Value(name), createSwigParam)
|
||||||
env.Depends(i_file, depends)
|
env.Depends(i_file, depends)
|
||||||
|
@ -850,7 +892,7 @@ def objectifyPyFile(target, source, env):
|
||||||
dst = file(str(target[0]), 'w')
|
dst = file(str(target[0]), 'w')
|
||||||
|
|
||||||
pysource = PySource.tnodes[source[0]]
|
pysource = PySource.tnodes[source[0]]
|
||||||
compiled = compile(src, pysource.debugname, 'exec')
|
compiled = compile(src, pysource.abspath, 'exec')
|
||||||
marshalled = marshal.dumps(compiled)
|
marshalled = marshal.dumps(compiled)
|
||||||
compressed = zlib.compress(marshalled)
|
compressed = zlib.compress(marshalled)
|
||||||
data = compressed
|
data = compressed
|
||||||
|
|
|
@ -144,7 +144,7 @@ DtbFault::invoke(ThreadContext *tc)
|
||||||
// read, like the EV5). The EV6 approach is cleaner and seems to
|
// read, like the EV5). The EV6 approach is cleaner and seems to
|
||||||
// work with EV5 PAL code, but not the other way around.
|
// work with EV5 PAL code, but not the other way around.
|
||||||
if (!tc->misspeculating() &&
|
if (!tc->misspeculating() &&
|
||||||
reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) {
|
reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) {
|
||||||
// set VA register with faulting address
|
// set VA register with faulting address
|
||||||
tc->setMiscRegNoEffect(IPR_VA, vaddr);
|
tc->setMiscRegNoEffect(IPR_VA, vaddr);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace AlphaISA
|
||||||
{
|
{
|
||||||
|
|
||||||
void
|
void
|
||||||
ISA::serialize(std::ostream &os)
|
ISA::serialize(EventManager *em, std::ostream &os)
|
||||||
{
|
{
|
||||||
SERIALIZE_SCALAR(fpcr);
|
SERIALIZE_SCALAR(fpcr);
|
||||||
SERIALIZE_SCALAR(uniq);
|
SERIALIZE_SCALAR(uniq);
|
||||||
|
@ -46,7 +46,7 @@ ISA::serialize(std::ostream &os)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ISA::unserialize(Checkpoint *cp, const std::string §ion)
|
ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string §ion)
|
||||||
{
|
{
|
||||||
UNSERIALIZE_SCALAR(fpcr);
|
UNSERIALIZE_SCALAR(fpcr);
|
||||||
UNSERIALIZE_SCALAR(uniq);
|
UNSERIALIZE_SCALAR(uniq);
|
||||||
|
|
|
@ -83,8 +83,9 @@ namespace AlphaISA
|
||||||
intr_flag = 0;
|
intr_flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
void serialize(EventManager *em, std::ostream &os);
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
void unserialize(EventManager *em, Checkpoint *cp,
|
||||||
|
const std::string §ion);
|
||||||
|
|
||||||
void reset(std::string core_name, ThreadID num_threads,
|
void reset(std::string core_name, ThreadID num_threads,
|
||||||
unsigned num_vpes, BaseCPU *_cpu)
|
unsigned num_vpes, BaseCPU *_cpu)
|
||||||
|
|
|
@ -627,7 +627,7 @@ decode OPCODE default Unknown::unknown() {
|
||||||
format MiscPrefetch {
|
format MiscPrefetch {
|
||||||
0xf800: wh64({{ EA = Rb & ~ULL(63); }},
|
0xf800: wh64({{ EA = Rb & ~ULL(63); }},
|
||||||
{{ xc->writeHint(EA, 64, memAccessFlags); }},
|
{{ xc->writeHint(EA, 64, memAccessFlags); }},
|
||||||
mem_flags = NO_FAULT,
|
mem_flags = PREFETCH,
|
||||||
inst_flags = [IsMemRef, IsDataPrefetch,
|
inst_flags = [IsMemRef, IsDataPrefetch,
|
||||||
IsStore, MemWriteOp]);
|
IsStore, MemWriteOp]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,7 +548,7 @@ def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
||||||
pf_flags = makeList(pf_flags)
|
pf_flags = makeList(pf_flags)
|
||||||
inst_flags = makeList(inst_flags)
|
inst_flags = makeList(inst_flags)
|
||||||
|
|
||||||
pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
|
pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
|
||||||
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
|
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
|
||||||
'IsDataPrefetch', 'MemReadOp']
|
'IsDataPrefetch', 'MemReadOp']
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ class AlphaLinux : public Linux
|
||||||
static const unsigned TIOCISATTY_ = 0x2000745e;
|
static const unsigned TIOCISATTY_ = 0x2000745e;
|
||||||
static const unsigned TIOCGETS_ = 0x402c7413;
|
static const unsigned TIOCGETS_ = 0x402c7413;
|
||||||
static const unsigned TIOCGETA_ = 0x40127417;
|
static const unsigned TIOCGETA_ = 0x40127417;
|
||||||
|
static const unsigned TCSETAW_ = 0x80147419; // 2.6.15 kernel
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// For table().
|
/// For table().
|
||||||
|
@ -125,6 +126,21 @@ class AlphaLinux : public Linux
|
||||||
TGT_RLIMIT_MEMLOCK = 9,
|
TGT_RLIMIT_MEMLOCK = 9,
|
||||||
TGT_RLIMIT_LOCKS = 10
|
TGT_RLIMIT_LOCKS = 10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t uptime; /* Seconds since boot */
|
||||||
|
uint64_t loads[3]; /* 1, 5, and 15 minute load averages */
|
||||||
|
uint64_t totalram; /* Total usable main memory size */
|
||||||
|
uint64_t freeram; /* Available memory size */
|
||||||
|
uint64_t sharedram; /* Amount of shared memory */
|
||||||
|
uint64_t bufferram; /* Memory used by buffers */
|
||||||
|
uint64_t totalswap; /* Total swap space size */
|
||||||
|
uint64_t freeswap; /* swap space still available */
|
||||||
|
uint16_t procs; /* Number of current processes */
|
||||||
|
uint64_t totalhigh; /* Total high memory size */
|
||||||
|
uint64_t freehigh; /* Available high memory size */
|
||||||
|
uint64_t mem_unit; /* Memory unit size in bytes */
|
||||||
|
} tgt_sysinfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__
|
#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__
|
||||||
|
|
|
@ -48,7 +48,8 @@ static SyscallReturn
|
||||||
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
|
int index = 0;
|
||||||
|
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
|
||||||
|
|
||||||
strcpy(name->sysname, "Linux");
|
strcpy(name->sysname, "Linux");
|
||||||
strcpy(name->nodename, "m5.eecs.umich.edu");
|
strcpy(name->nodename, "m5.eecs.umich.edu");
|
||||||
|
@ -67,13 +68,15 @@ static SyscallReturn
|
||||||
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = process->getSyscallArg(tc, 0);
|
int index = 0;
|
||||||
|
unsigned op = process->getSyscallArg(tc, index);
|
||||||
|
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||||
// unsigned nbytes = process->getSyscallArg(tc, 2);
|
// unsigned nbytes = process->getSyscallArg(tc, 2);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
case 45: { // GSI_IEEE_FP_CONTROL
|
case 45: { // GSI_IEEE_FP_CONTROL
|
||||||
TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
*fpcr = 0;
|
*fpcr = 0;
|
||||||
fpcr.copyOut(tc->getMemPort());
|
fpcr.copyOut(tc->getMemPort());
|
||||||
|
@ -94,13 +97,15 @@ static SyscallReturn
|
||||||
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = process->getSyscallArg(tc, 0);
|
int index = 0;
|
||||||
|
unsigned op = process->getSyscallArg(tc, index);
|
||||||
|
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||||
// unsigned nbytes = process->getSyscallArg(tc, 2);
|
// unsigned nbytes = process->getSyscallArg(tc, 2);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
case 14: { // SSI_IEEE_FP_CONTROL
|
case 14: { // SSI_IEEE_FP_CONTROL
|
||||||
TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
fpcr.copyIn(tc->getMemPort());
|
fpcr.copyIn(tc->getMemPort());
|
||||||
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||||
|
@ -440,7 +445,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
|
||||||
/* 315 */ SyscallDesc("munlock", unimplementedFunc),
|
/* 315 */ SyscallDesc("munlock", unimplementedFunc),
|
||||||
/* 316 */ SyscallDesc("mlockall", unimplementedFunc),
|
/* 316 */ SyscallDesc("mlockall", unimplementedFunc),
|
||||||
/* 317 */ SyscallDesc("munlockall", unimplementedFunc),
|
/* 317 */ SyscallDesc("munlockall", unimplementedFunc),
|
||||||
/* 318 */ SyscallDesc("sysinfo", unimplementedFunc),
|
/* 318 */ SyscallDesc("sysinfo", sysinfoFunc<AlphaLinux>),
|
||||||
/* 319 */ SyscallDesc("_sysctl", unimplementedFunc),
|
/* 319 */ SyscallDesc("_sysctl", unimplementedFunc),
|
||||||
/* 320 */ SyscallDesc("was sys_idle", unimplementedFunc),
|
/* 320 */ SyscallDesc("was sys_idle", unimplementedFunc),
|
||||||
/* 321 */ SyscallDesc("oldumount", unimplementedFunc),
|
/* 321 */ SyscallDesc("oldumount", unimplementedFunc),
|
||||||
|
|
|
@ -193,10 +193,10 @@ AlphaLiveProcess::startup()
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaISA::IntReg
|
AlphaISA::IntReg
|
||||||
AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i)
|
AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
|
||||||
{
|
{
|
||||||
assert(i < 6);
|
assert(i < 6);
|
||||||
return tc->readIntReg(FirstArgumentReg + i);
|
return tc->readIntReg(FirstArgumentReg + i++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -44,7 +44,7 @@ class AlphaLiveProcess : public LiveProcess
|
||||||
void argsInit(int intSize, int pageSize);
|
void argsInit(int intSize, int pageSize);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i);
|
AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
||||||
void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val);
|
void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val);
|
||||||
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
|
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,8 @@ static SyscallReturn
|
||||||
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, 0));
|
int index = 0;
|
||||||
|
TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, index));
|
||||||
|
|
||||||
strcpy(name->sysname, "OSF1");
|
strcpy(name->sysname, "OSF1");
|
||||||
strcpy(name->nodename, "m5.eecs.umich.edu");
|
strcpy(name->nodename, "m5.eecs.umich.edu");
|
||||||
|
@ -62,35 +63,36 @@ static SyscallReturn
|
||||||
getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = process->getSyscallArg(tc, 0);
|
int index = 0;
|
||||||
unsigned nbytes = process->getSyscallArg(tc, 2);
|
unsigned op = process->getSyscallArg(tc, index);
|
||||||
|
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||||
|
unsigned nbytes = process->getSyscallArg(tc, index);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
case AlphaTru64::GSI_MAX_CPU: {
|
case AlphaTru64::GSI_MAX_CPU: {
|
||||||
TypedBufferArg<uint32_t> max_cpu(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint32_t> max_cpu(bufPtr);
|
||||||
*max_cpu = htog((uint32_t)process->numCpus());
|
*max_cpu = htog((uint32_t)process->numCpus());
|
||||||
max_cpu.copyOut(tc->getMemPort());
|
max_cpu.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
||||||
TypedBufferArg<uint32_t> cpus_in_box(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
|
||||||
*cpus_in_box = htog((uint32_t)process->numCpus());
|
*cpus_in_box = htog((uint32_t)process->numCpus());
|
||||||
cpus_in_box.copyOut(tc->getMemPort());
|
cpus_in_box.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PHYSMEM: {
|
case AlphaTru64::GSI_PHYSMEM: {
|
||||||
TypedBufferArg<uint64_t> physmem(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint64_t> physmem(bufPtr);
|
||||||
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
||||||
physmem.copyOut(tc->getMemPort());
|
physmem.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CPU_INFO: {
|
case AlphaTru64::GSI_CPU_INFO: {
|
||||||
TypedBufferArg<AlphaTru64::cpu_info>
|
TypedBufferArg<AlphaTru64::cpu_info> infop(bufPtr);
|
||||||
infop(process->getSyscallArg(tc, 1));
|
|
||||||
|
|
||||||
infop->current_cpu = htog(0);
|
infop->current_cpu = htog(0);
|
||||||
infop->cpus_in_box = htog(process->numCpus());
|
infop->cpus_in_box = htog(process->numCpus());
|
||||||
|
@ -107,14 +109,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PROC_TYPE: {
|
case AlphaTru64::GSI_PROC_TYPE: {
|
||||||
TypedBufferArg<uint64_t> proc_type(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint64_t> proc_type(bufPtr);
|
||||||
*proc_type = htog((uint64_t)11);
|
*proc_type = htog((uint64_t)11);
|
||||||
proc_type.copyOut(tc->getMemPort());
|
proc_type.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PLATFORM_NAME: {
|
case AlphaTru64::GSI_PLATFORM_NAME: {
|
||||||
BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes);
|
BufferArg bufArg(bufPtr, nbytes);
|
||||||
strncpy((char *)bufArg.bufferPtr(),
|
strncpy((char *)bufArg.bufferPtr(),
|
||||||
"COMPAQ Professional Workstation XP1000",
|
"COMPAQ Professional Workstation XP1000",
|
||||||
nbytes);
|
nbytes);
|
||||||
|
@ -123,7 +125,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CLK_TCK: {
|
case AlphaTru64::GSI_CLK_TCK: {
|
||||||
TypedBufferArg<uint64_t> clk_hz(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint64_t> clk_hz(bufPtr);
|
||||||
*clk_hz = htog((uint64_t)1024);
|
*clk_hz = htog((uint64_t)1024);
|
||||||
clk_hz.copyOut(tc->getMemPort());
|
clk_hz.copyOut(tc->getMemPort());
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -142,12 +144,13 @@ static SyscallReturn
|
||||||
setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = process->getSyscallArg(tc, 0);
|
int index = 0;
|
||||||
|
unsigned op = process->getSyscallArg(tc, index);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case AlphaTru64::SSI_IEEE_FP_CONTROL:
|
case AlphaTru64::SSI_IEEE_FP_CONTROL:
|
||||||
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
|
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
|
||||||
process->getSyscallArg(tc, 1));
|
process->getSyscallArg(tc, index));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -165,17 +168,19 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int id = process->getSyscallArg(tc, 0); // table ID
|
int argIndex = 0;
|
||||||
int index = process->getSyscallArg(tc, 1); // index into table
|
int id = process->getSyscallArg(tc, argIndex); // table ID
|
||||||
|
int index = process->getSyscallArg(tc, argIndex); // index into table
|
||||||
|
Addr bufPtr = process->getSyscallArg(tc, argIndex);
|
||||||
// arg 2 is buffer pointer; type depends on table ID
|
// arg 2 is buffer pointer; type depends on table ID
|
||||||
int nel = process->getSyscallArg(tc, 3); // number of elements
|
int nel = process->getSyscallArg(tc, argIndex); // number of elements
|
||||||
int lel = process->getSyscallArg(tc, 4); // expected element size
|
int lel = process->getSyscallArg(tc, argIndex); // expected element size
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case AlphaTru64::TBL_SYSINFO: {
|
case AlphaTru64::TBL_SYSINFO: {
|
||||||
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
|
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
TypedBufferArg<Tru64::tbl_sysinfo> elp(process->getSyscallArg(tc, 2));
|
TypedBufferArg<Tru64::tbl_sysinfo> elp(bufPtr);
|
||||||
|
|
||||||
const int clk_hz = one_million;
|
const int clk_hz = one_million;
|
||||||
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
|
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
|
||||||
|
|
|
@ -99,6 +99,7 @@ class AlphaTru64 : public Tru64
|
||||||
static const unsigned TIOCISATTY_ = 0x2000745e;
|
static const unsigned TIOCISATTY_ = 0x2000745e;
|
||||||
static const unsigned TIOCGETS_ = 0x402c7413;
|
static const unsigned TIOCGETS_ = 0x402c7413;
|
||||||
static const unsigned TIOCGETA_ = 0x40127417;
|
static const unsigned TIOCGETA_ = 0x40127417;
|
||||||
|
static const unsigned TCSETAW_ = 0x80147419;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
|
|
33
src/arch/arm/ArmInterrupts.py
Normal file
33
src/arch/arm/ArmInterrupts.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright (c) 2009 ARM Limited
|
||||||
|
# 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
|
||||||
|
|
||||||
|
from m5.SimObject import SimObject
|
||||||
|
|
||||||
|
class ArmInterrupts(SimObject):
|
||||||
|
type = 'ArmInterrupts'
|
||||||
|
cxx_class = 'ArmISA::Interrupts'
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2005 The Regents of The University of Michigan
|
# Copyright (c) 2009 ARM Limited
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -24,20 +24,12 @@
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
# Authors: Nathan Binkert
|
# Authors: Ali Saidi
|
||||||
# Steve Reinhardt
|
|
||||||
|
|
||||||
import os
|
from m5.params import *
|
||||||
|
|
||||||
# import the m5 compile options
|
from System import System
|
||||||
import defines
|
|
||||||
|
|
||||||
# make a SmartDict out of the build options for our local use
|
class ArmSystem(System):
|
||||||
import smartdict
|
type = 'ArmSystem'
|
||||||
build_env = smartdict.SmartDict()
|
|
||||||
build_env.update(defines.m5_build_env)
|
|
||||||
|
|
||||||
# make a SmartDict out of the OS environment too
|
|
||||||
env = smartdict.SmartDict()
|
|
||||||
env.update(os.environ)
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- mode:python -*-
|
# -*- mode:python -*-
|
||||||
|
|
||||||
# Copyright (c) 2007-2008 The Florida State University
|
# Copyright (c) 2007-2008 The Florida State University
|
||||||
|
# Copyright (c) 2009 ARM Limited
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
# Authors: Stephen Hines
|
# Authors: Stephen Hines
|
||||||
|
# Ali Saidi
|
||||||
|
|
||||||
Import('*')
|
Import('*')
|
||||||
|
|
||||||
|
@ -43,15 +45,20 @@ if env['TARGET_ISA'] == 'arm':
|
||||||
Source('pagetable.cc')
|
Source('pagetable.cc')
|
||||||
Source('tlb.cc')
|
Source('tlb.cc')
|
||||||
Source('vtophys.cc')
|
Source('vtophys.cc')
|
||||||
|
Source('utility.cc')
|
||||||
|
|
||||||
SimObject('ArmNativeTrace.py')
|
SimObject('ArmNativeTrace.py')
|
||||||
SimObject('ArmTLB.py')
|
SimObject('ArmTLB.py')
|
||||||
|
|
||||||
TraceFlag('Arm')
|
TraceFlag('Arm')
|
||||||
|
TraceFlag('Faults', "Trace Exceptions, interrupts, svc/swi")
|
||||||
if env['FULL_SYSTEM']:
|
if env['FULL_SYSTEM']:
|
||||||
#Insert Full-System Files Here
|
Source('interrupts.cc')
|
||||||
pass
|
Source('stacktrace.cc')
|
||||||
|
Source('system.cc')
|
||||||
|
|
||||||
|
SimObject('ArmInterrupts.py')
|
||||||
|
SimObject('ArmSystem.py')
|
||||||
else:
|
else:
|
||||||
Source('process.cc')
|
Source('process.cc')
|
||||||
Source('linux/linux.cc')
|
Source('linux/linux.cc')
|
||||||
|
|
|
@ -26,488 +26,114 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Authors: Gabe Black
|
* Authors: Ali Saidi
|
||||||
* Stephen Hines
|
* Gabe Black
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "arch/arm/faults.hh"
|
#include "arch/arm/faults.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#if !FULL_SYSTEM
|
|
||||||
#include "sim/process.hh"
|
|
||||||
#include "mem/page_table.hh"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ArmISA
|
namespace ArmISA
|
||||||
{
|
{
|
||||||
|
|
||||||
FaultName MachineCheckFault::_name = "Machine Check";
|
template<> ArmFaultBase::FaultVals ArmFault<Reset>::vals =
|
||||||
FaultVect MachineCheckFault::_vect = 0x0401;
|
{"reset", 0x00, MODE_SVC, 0, 0, true, true};
|
||||||
FaultStat MachineCheckFault::_count;
|
|
||||||
|
|
||||||
FaultName AlignmentFault::_name = "Alignment";
|
template<> ArmFaultBase::FaultVals ArmFault<UndefinedInstruction>::vals =
|
||||||
FaultVect AlignmentFault::_vect = 0x0301;
|
{"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ;
|
||||||
FaultStat AlignmentFault::_count;
|
|
||||||
|
|
||||||
FaultName ResetFault::_name = "Reset Fault";
|
template<> ArmFaultBase::FaultVals ArmFault<SupervisorCall>::vals =
|
||||||
#if FULL_SYSTEM
|
{"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false};
|
||||||
FaultVect ResetFault::_vect = 0xBFC00000;
|
|
||||||
#else
|
|
||||||
FaultVect ResetFault::_vect = 0x001;
|
|
||||||
#endif
|
|
||||||
FaultStat ResetFault::_count;
|
|
||||||
|
|
||||||
FaultName AddressErrorFault::_name = "Address Error";
|
template<> ArmFaultBase::FaultVals ArmFault<PrefetchAbort>::vals =
|
||||||
FaultVect AddressErrorFault::_vect = 0x0180;
|
{"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false};
|
||||||
FaultStat AddressErrorFault::_count;
|
|
||||||
|
|
||||||
FaultName StoreAddressErrorFault::_name = "Store Address Error";
|
template<> ArmFaultBase::FaultVals ArmFault<DataAbort>::vals =
|
||||||
FaultVect StoreAddressErrorFault::_vect = 0x0180;
|
{"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false};
|
||||||
FaultStat StoreAddressErrorFault::_count;
|
|
||||||
|
|
||||||
|
template<> ArmFaultBase::FaultVals ArmFault<Interrupt>::vals =
|
||||||
|
{"IRQ", 0x18, MODE_IRQ, 4, 4, true, false};
|
||||||
|
|
||||||
FaultName SystemCallFault::_name = "Syscall";
|
template<> ArmFaultBase::FaultVals ArmFault<FastInterrupt>::vals =
|
||||||
FaultVect SystemCallFault::_vect = 0x0180;
|
{"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true};
|
||||||
FaultStat SystemCallFault::_count;
|
|
||||||
|
|
||||||
FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault";
|
Addr
|
||||||
FaultVect CoprocessorUnusableFault::_vect = 0x180;
|
ArmFaultBase::getVector(ThreadContext *tc)
|
||||||
FaultStat CoprocessorUnusableFault::_count;
|
{
|
||||||
|
// ARM ARM B1-3
|
||||||
|
|
||||||
FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault";
|
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
|
||||||
FaultVect ReservedInstructionFault::_vect = 0x0180;
|
|
||||||
FaultStat ReservedInstructionFault::_count;
|
// panic if SCTLR.VE because I have no idea what to do with vectored
|
||||||
|
// interrupts
|
||||||
|
assert(!sctlr.ve);
|
||||||
|
|
||||||
|
if (!sctlr.v)
|
||||||
|
return offset();
|
||||||
|
return offset() + HighVecs;
|
||||||
|
|
||||||
FaultName ThreadFault::_name = "Thread Fault";
|
}
|
||||||
FaultVect ThreadFault::_vect = 0x00F1;
|
|
||||||
FaultStat ThreadFault::_count;
|
|
||||||
|
|
||||||
|
|
||||||
FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception";
|
|
||||||
FaultVect ArithmeticFault::_vect = 0x180;
|
|
||||||
FaultStat ArithmeticFault::_count;
|
|
||||||
|
|
||||||
FaultName UnimplementedOpcodeFault::_name = "opdec";
|
|
||||||
FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
|
|
||||||
FaultStat UnimplementedOpcodeFault::_count;
|
|
||||||
|
|
||||||
FaultName InterruptFault::_name = "interrupt";
|
|
||||||
FaultVect InterruptFault::_vect = 0x0180;
|
|
||||||
FaultStat InterruptFault::_count;
|
|
||||||
|
|
||||||
FaultName TrapFault::_name = "Trap";
|
|
||||||
FaultVect TrapFault::_vect = 0x0180;
|
|
||||||
FaultStat TrapFault::_count;
|
|
||||||
|
|
||||||
FaultName BreakpointFault::_name = "Breakpoint";
|
|
||||||
FaultVect BreakpointFault::_vect = 0x0180;
|
|
||||||
FaultStat BreakpointFault::_count;
|
|
||||||
|
|
||||||
|
|
||||||
FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)";
|
|
||||||
FaultVect ItbInvalidFault::_vect = 0x0180;
|
|
||||||
FaultStat ItbInvalidFault::_count;
|
|
||||||
|
|
||||||
FaultName ItbPageFault::_name = "itbmiss";
|
|
||||||
FaultVect ItbPageFault::_vect = 0x0181;
|
|
||||||
FaultStat ItbPageFault::_count;
|
|
||||||
|
|
||||||
FaultName ItbMissFault::_name = "itbmiss";
|
|
||||||
FaultVect ItbMissFault::_vect = 0x0181;
|
|
||||||
FaultStat ItbMissFault::_count;
|
|
||||||
|
|
||||||
FaultName ItbAcvFault::_name = "iaccvio";
|
|
||||||
FaultVect ItbAcvFault::_vect = 0x0081;
|
|
||||||
FaultStat ItbAcvFault::_count;
|
|
||||||
|
|
||||||
FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)";
|
|
||||||
FaultVect ItbRefillFault::_vect = 0x0180;
|
|
||||||
FaultStat ItbRefillFault::_count;
|
|
||||||
|
|
||||||
FaultName NDtbMissFault::_name = "dtb_miss_single";
|
|
||||||
FaultVect NDtbMissFault::_vect = 0x0201;
|
|
||||||
FaultStat NDtbMissFault::_count;
|
|
||||||
|
|
||||||
FaultName PDtbMissFault::_name = "dtb_miss_double";
|
|
||||||
FaultVect PDtbMissFault::_vect = 0x0281;
|
|
||||||
FaultStat PDtbMissFault::_count;
|
|
||||||
|
|
||||||
FaultName DtbPageFault::_name = "dfault";
|
|
||||||
FaultVect DtbPageFault::_vect = 0x0381;
|
|
||||||
FaultStat DtbPageFault::_count;
|
|
||||||
|
|
||||||
FaultName DtbAcvFault::_name = "dfault";
|
|
||||||
FaultVect DtbAcvFault::_vect = 0x0381;
|
|
||||||
FaultStat DtbAcvFault::_count;
|
|
||||||
|
|
||||||
FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)";
|
|
||||||
FaultVect DtbInvalidFault::_vect = 0x0180;
|
|
||||||
FaultStat DtbInvalidFault::_count;
|
|
||||||
|
|
||||||
FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)";
|
|
||||||
FaultVect DtbRefillFault::_vect = 0x0180;
|
|
||||||
FaultStat DtbRefillFault::_count;
|
|
||||||
|
|
||||||
FaultName TLBModifiedFault::_name = "TLB Modified Exception";
|
|
||||||
FaultVect TLBModifiedFault::_vect = 0x0180;
|
|
||||||
FaultStat TLBModifiedFault::_count;
|
|
||||||
|
|
||||||
FaultName FloatEnableFault::_name = "float_enable_fault";
|
|
||||||
FaultVect FloatEnableFault::_vect = 0x0581;
|
|
||||||
FaultStat FloatEnableFault::_count;
|
|
||||||
|
|
||||||
FaultName IntegerOverflowFault::_name = "Integer Overflow Fault";
|
|
||||||
FaultVect IntegerOverflowFault::_vect = 0x0501;
|
|
||||||
FaultStat IntegerOverflowFault::_count;
|
|
||||||
|
|
||||||
FaultName DspStateDisabledFault::_name = "DSP Disabled Fault";
|
|
||||||
FaultVect DspStateDisabledFault::_vect = 0x001a;
|
|
||||||
FaultStat DspStateDisabledFault::_count;
|
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
void ArmFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
|
|
||||||
|
void
|
||||||
|
ArmFaultBase::invoke(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
tc->setPC(HandlerBase);
|
// ARM ARM B1.6.3
|
||||||
tc->setNextPC(HandlerBase+sizeof(MachInst));
|
FaultBase::invoke(tc);
|
||||||
tc->setNextNPC(HandlerBase+2*sizeof(MachInst));
|
countStat()++;
|
||||||
|
|
||||||
|
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
|
||||||
|
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
|
||||||
|
CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) |
|
||||||
|
tc->readIntReg(INTREG_CONDCODES);
|
||||||
|
|
||||||
|
|
||||||
|
cpsr.mode = nextMode();
|
||||||
|
cpsr.it1 = cpsr.it2 = 0;
|
||||||
|
cpsr.j = 0;
|
||||||
|
|
||||||
|
if (sctlr.te)
|
||||||
|
cpsr.t = 1;
|
||||||
|
cpsr.a = cpsr.a | abortDisable();
|
||||||
|
cpsr.f = cpsr.f | fiqDisable();
|
||||||
|
cpsr.i = 1;
|
||||||
|
tc->setMiscReg(MISCREG_CPSR, cpsr);
|
||||||
|
tc->setIntReg(INTREG_LR, tc->readPC() +
|
||||||
|
(saved_cpsr.t ? thumbPcOffset() : armPcOffset()));
|
||||||
|
|
||||||
|
switch (nextMode()) {
|
||||||
|
case MODE_FIQ:
|
||||||
|
tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr);
|
||||||
|
break;
|
||||||
|
case MODE_IRQ:
|
||||||
|
tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr);
|
||||||
|
break;
|
||||||
|
case MODE_SVC:
|
||||||
|
tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr);
|
||||||
|
break;
|
||||||
|
case MODE_UNDEFINED:
|
||||||
|
tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr);
|
||||||
|
break;
|
||||||
|
case MODE_ABORT:
|
||||||
|
tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("unknown Mode\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(Faults, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n", name(), cpsr,
|
||||||
|
tc->readPC(), tc->readIntReg(INTREG_LR));
|
||||||
|
tc->setPC(getVector(tc));
|
||||||
|
tc->setNextPC(getVector(tc) + cpsr.t ? 2 : 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArmFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode)
|
|
||||||
{
|
|
||||||
// modify SRS Ctl - Save CSS, put ESS into CSS
|
|
||||||
MiscReg stat = tc->readMiscReg(ArmISA::Status);
|
|
||||||
if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1)
|
|
||||||
{
|
|
||||||
// SRS Ctl is modified only if Status_EXL and Status_BEV are not set
|
|
||||||
MiscReg srs = tc->readMiscReg(ArmISA::SRSCtl);
|
|
||||||
uint8_t CSS,ESS;
|
|
||||||
CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO);
|
|
||||||
ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO);
|
|
||||||
// Move CSS to PSS
|
|
||||||
replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS);
|
|
||||||
// Move ESS to CSS
|
|
||||||
replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::SRSCtl,srs);
|
|
||||||
//tc->setShadowSet(ESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set EXL bit (don't care if it is already set!)
|
|
||||||
replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::Status,stat);
|
|
||||||
|
|
||||||
// write EPC
|
|
||||||
// warn("Set EPC to %x\n",tc->readPC());
|
|
||||||
// CHECK ME or FIXME or FIX ME or POSSIBLE HACK
|
|
||||||
// Check to see if the exception occurred in the branch delay slot
|
|
||||||
DPRINTF(Arm,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC());
|
|
||||||
int C_BD=0;
|
|
||||||
if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()-sizeof(MachInst));
|
|
||||||
// In the branch delay slot? set CAUSE_31
|
|
||||||
C_BD = 1;
|
|
||||||
} else {
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC());
|
|
||||||
// In the branch delay slot? reset CAUSE_31
|
|
||||||
C_BD = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Cause_EXCCODE field
|
|
||||||
MiscReg cause = tc->readMiscReg(ArmISA::Cause);
|
|
||||||
replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode);
|
|
||||||
replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD);
|
|
||||||
replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::Cause,cause);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArithmeticFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0xC);
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
MiscReg stat = tc->readMiscReg(ArmISA::Status);
|
|
||||||
// Here, the handler is dependent on BEV, which is not modified by setExceptionState()
|
|
||||||
if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase);
|
|
||||||
}else{
|
|
||||||
HandlerBase = 0xBFC00200;
|
|
||||||
}
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
// warn("Exception Handler At: %x \n",HandlerBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StoreAddressErrorFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0x5);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
// warn("Exception Handler At: %x \n",HandlerBase);
|
|
||||||
// warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrapFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
// warn("%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0xD);
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
// warn("Exception Handler At: %x \n",HandlerBase);
|
|
||||||
// warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BreakpointFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
setExceptionState(tc,0x9);
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
// warn("Exception Handler At: %x \n",HandlerBase);
|
|
||||||
// warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void DtbInvalidFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
// warn("%s encountered.\n", name());
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
|
|
||||||
MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
|
|
||||||
replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
|
|
||||||
replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
|
|
||||||
replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
|
|
||||||
MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
|
|
||||||
replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
|
|
||||||
setExceptionState(tc,0x3);
|
|
||||||
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
// warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddressErrorFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0x4);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItbInvalidFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0x2);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
|
|
||||||
MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
|
|
||||||
replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
|
|
||||||
replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
|
|
||||||
replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
|
|
||||||
MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
|
|
||||||
replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
|
|
||||||
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
DPRINTF(Arm,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ItbRefillFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered (%x).\n", name(),BadVAddr);
|
|
||||||
Addr HandlerBase;
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
|
|
||||||
MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
|
|
||||||
replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
|
|
||||||
replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
|
|
||||||
replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
|
|
||||||
MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
|
|
||||||
replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
|
|
||||||
|
|
||||||
MiscReg stat = tc->readMiscReg(ArmISA::Status);
|
|
||||||
// Since handler depends on EXL bit, must check EXL bit before setting it!!
|
|
||||||
if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
}else{
|
|
||||||
HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000
|
|
||||||
}
|
|
||||||
|
|
||||||
setExceptionState(tc,0x2);
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DtbRefillFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
// Set new PC
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
Addr HandlerBase;
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
|
|
||||||
MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
|
|
||||||
replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
|
|
||||||
replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
|
|
||||||
replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
|
|
||||||
MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
|
|
||||||
replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
|
|
||||||
|
|
||||||
MiscReg stat = tc->readMiscReg(ArmISA::Status);
|
|
||||||
// Since handler depends on EXL bit, must check EXL bit before setting it!!
|
|
||||||
if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
}else{
|
|
||||||
HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setExceptionState(tc,0x3);
|
|
||||||
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TLBModifiedFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
|
|
||||||
MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
|
|
||||||
replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
|
|
||||||
replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
|
|
||||||
replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
|
|
||||||
MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
|
|
||||||
replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setExceptionState(tc,0x1);
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
// warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemCallFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0x8);
|
|
||||||
|
|
||||||
// Set new PC
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
// warn("Exception Handler At: %x \n",HandlerBase);
|
|
||||||
// warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0x0A);
|
|
||||||
Addr HandlerBase;
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t IV = bits(tc->readMiscRegNoEffect(ArmISA::Cause),Cause_IV);
|
|
||||||
if (IV)// Offset 200 for release 2
|
|
||||||
HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
|
|
||||||
else//Ofset at 180 for release 1
|
|
||||||
HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
|
|
||||||
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FULL_SYSTEM
|
#endif // FULL_SYSTEM
|
||||||
|
|
||||||
void ResetFault::invoke(ThreadContext *tc)
|
// return via SUBS pc, lr, xxx; rfe, movs, ldm
|
||||||
{
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
/* All reset activity must be invoked from here */
|
|
||||||
tc->setPC(vect());
|
|
||||||
tc->setNextPC(vect()+sizeof(MachInst));
|
|
||||||
tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst));
|
|
||||||
DPRINTF(Arm,"(%x) - ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set Coprocessor 1 (Floating Point) To Usable
|
|
||||||
//tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReservedInstructionFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0x0A);
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
#else
|
|
||||||
panic("%s encountered.\n", name());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
panic("%s encountered.\n", name());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DspStateDisabledFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
panic("%s encountered.\n", name());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoprocessorUnusableFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
DPRINTF(Arm,"%s encountered.\n", name());
|
|
||||||
setExceptionState(tc,0xb);
|
|
||||||
/* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */
|
|
||||||
MiscReg cause = tc->readMiscReg(ArmISA::Cause);
|
|
||||||
replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID);
|
|
||||||
tc->setMiscRegNoEffect(ArmISA::Cause,cause);
|
|
||||||
|
|
||||||
Addr HandlerBase;
|
|
||||||
HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
|
|
||||||
setHandlerPC(HandlerBase,tc);
|
|
||||||
|
|
||||||
// warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause));
|
|
||||||
#else
|
|
||||||
warn("%s (CP%d) encountered.\n", name(), coProcID);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ArmISA
|
} // namespace ArmISA
|
||||||
|
|
||||||
|
|
|
@ -26,548 +26,79 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Authors: Gabe Black
|
* Authors: Ali Saidi
|
||||||
* Stephen Hines
|
* Gabe Black
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ARM_FAULTS_HH__
|
#ifndef __ARM_FAULTS_HH__
|
||||||
#define __ARM_FAULTS_HH__
|
#define __ARM_FAULTS_HH__
|
||||||
|
|
||||||
|
#include "arch/arm/types.hh"
|
||||||
|
#include "config/full_system.hh"
|
||||||
#include "sim/faults.hh"
|
#include "sim/faults.hh"
|
||||||
|
|
||||||
// The design of the "name" and "vect" functions is in sim/faults.hh
|
// The design of the "name" and "vect" functions is in sim/faults.hh
|
||||||
|
|
||||||
namespace ArmISA
|
namespace ArmISA
|
||||||
{
|
{
|
||||||
typedef const Addr FaultVect;
|
typedef const Addr FaultOffset;
|
||||||
|
|
||||||
class ArmFault : public FaultBase
|
class ArmFaultBase : public FaultBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual bool skipFaultingInstruction() {return false;}
|
Addr getVector(ThreadContext *tc);
|
||||||
virtual bool setRestartAddress() {return true;}
|
|
||||||
public:
|
public:
|
||||||
Addr BadVAddr;
|
struct FaultVals
|
||||||
Addr EntryHi_Asid;
|
{
|
||||||
Addr EntryHi_VPN2;
|
const FaultName name;
|
||||||
Addr EntryHi_VPN2X;
|
const FaultOffset offset;
|
||||||
Addr Context_BadVPN2;
|
const OperatingMode nextMode;
|
||||||
|
const uint8_t armPcOffset;
|
||||||
|
const uint8_t thumbPcOffset;
|
||||||
|
const bool abortDisable;
|
||||||
|
const bool fiqDisable;
|
||||||
|
FaultStat count;
|
||||||
|
};
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
void invoke(ThreadContext * tc) {};
|
void invoke(ThreadContext *tc);
|
||||||
void setExceptionState(ThreadContext *,uint8_t);
|
|
||||||
void setHandlerPC(Addr,ThreadContext *);
|
|
||||||
#endif
|
#endif
|
||||||
virtual FaultVect vect() = 0;
|
virtual FaultStat& countStat() = 0;
|
||||||
virtual FaultStat & countStat() = 0;
|
virtual FaultOffset offset() = 0;
|
||||||
|
virtual OperatingMode nextMode() = 0;
|
||||||
|
virtual uint8_t armPcOffset() = 0;
|
||||||
|
virtual uint8_t thumbPcOffset() = 0;
|
||||||
|
virtual bool abortDisable() = 0;
|
||||||
|
virtual bool fiqDisable() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MachineCheckFault : public ArmFault
|
template<typename T>
|
||||||
{
|
class ArmFault : public ArmFaultBase
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
bool isMachineCheckFault() {return true;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class NonMaskableInterrupt : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
bool isNonMaskableInterrupt() {return true;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AlignmentFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
bool isAlignmentFault() {return true;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AddressErrorFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
class StoreAddressErrorFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
class UnimplementedOpcodeFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class TLBRefillIFetchFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Addr vaddr;
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
class TLBInvalidIFetchFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Addr vaddr;
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
class NDtbMissFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PDtbMissFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DtbPageFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DtbAcvFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CacheErrorFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Addr vaddr;
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline Fault genMachineCheckFault()
|
|
||||||
{
|
|
||||||
return new MachineCheckFault;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Fault genAlignmentFault()
|
|
||||||
{
|
|
||||||
return new AlignmentFault;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ResetFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
|
|
||||||
};
|
|
||||||
class SystemCallFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
class SoftResetFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
class DebugSingleStep : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
class DebugInterrupt : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
class CoprocessorUnusableFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
int coProcID;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
CoprocessorUnusableFault(int _procid){ coProcID = _procid;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ReservedInstructionFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ThreadFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ArithmeticFault : public ArmFault
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
bool skipFaultingInstruction() {return true;}
|
static FaultVals vals;
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
public:
|
||||||
FaultName name() const {return _name;}
|
FaultName name() const { return vals.name; }
|
||||||
FaultVect vect() {return _vect;}
|
FaultStat & countStat() {return vals.count;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultOffset offset() { return vals.offset; }
|
||||||
#if FULL_SYSTEM
|
OperatingMode nextMode() { return vals.nextMode; }
|
||||||
void invoke(ThreadContext * tc);
|
uint8_t armPcOffset() { return vals.armPcOffset; }
|
||||||
#endif
|
uint8_t thumbPcOffset() { return vals.thumbPcOffset; }
|
||||||
|
bool abortDisable() { return vals.abortDisable; }
|
||||||
|
bool fiqDisable() { return vals.fiqDisable; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterruptFault : public ArmFault
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
bool setRestartAddress() {return false;}
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
class Reset : public ArmFault<Reset> {};
|
||||||
void invoke(ThreadContext * tc);
|
class UndefinedInstruction : public ArmFault<UndefinedInstruction> {};
|
||||||
#endif
|
class SupervisorCall : public ArmFault<SupervisorCall> {};
|
||||||
|
class PrefetchAbort : public ArmFault<PrefetchAbort> {};
|
||||||
|
class DataAbort : public ArmFault<DataAbort> {};
|
||||||
|
class Interrupt : public ArmFault<Interrupt> {};
|
||||||
|
class FastInterrupt : public ArmFault<FastInterrupt> {};
|
||||||
|
|
||||||
//void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
class TrapFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class BreakpointFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class ItbRefillFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
class DtbRefillFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class ItbPageFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class ItbInvalidFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
class TLBModifiedFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class DtbInvalidFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class FloatEnableFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ItbMissFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ItbAcvFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IntegerOverflowFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DspStateDisabledFault : public ArmFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
FaultName name() const {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // ArmISA namespace
|
} // ArmISA namespace
|
||||||
|
|
||||||
|
|
|
@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp
|
||||||
*/
|
*/
|
||||||
class ArmMacroMemoryOp : public PredMacroOp
|
class ArmMacroMemoryOp : public PredMacroOp
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/// Memory request flags. See mem_req_base.hh.
|
/// Memory request flags. See mem_req_base.hh.
|
||||||
unsigned memAccessFlags;
|
unsigned memAccessFlags;
|
||||||
|
|
||||||
uint32_t reglist;
|
uint32_t reglist;
|
||||||
uint32_t ones;
|
uint32_t ones;
|
||||||
uint32_t puswl,
|
|
||||||
prepost,
|
|
||||||
up,
|
|
||||||
psruser,
|
|
||||||
writeback,
|
|
||||||
loadop;
|
|
||||||
|
|
||||||
ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst,
|
ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst,
|
||||||
OpClass __opClass)
|
OpClass __opClass)
|
||||||
: PredMacroOp(mnem, _machInst, __opClass),
|
: PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0),
|
||||||
memAccessFlags(0),
|
reglist(machInst.regList), ones(0)
|
||||||
reglist(machInst.regList), ones(0),
|
|
||||||
puswl(machInst.puswl),
|
|
||||||
prepost(machInst.puswl.prepost),
|
|
||||||
up(machInst.puswl.up),
|
|
||||||
psruser(machInst.puswl.psruser),
|
|
||||||
writeback(machInst.puswl.writeback),
|
|
||||||
loadop(machInst.puswl.loadOp)
|
|
||||||
{
|
{
|
||||||
ones = number_of_ones(reglist);
|
ones = number_of_ones(reglist);
|
||||||
numMicroops = ones + writeback + 1;
|
numMicroops = ones + machInst.puswl.writeback + 1;
|
||||||
// Remember that writeback adds a uop
|
// Remember that writeback adds a uop
|
||||||
microOps = new StaticInstPtr[numMicroops];
|
microOps = new StaticInstPtr[numMicroops];
|
||||||
}
|
}
|
||||||
|
@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp
|
||||||
*/
|
*/
|
||||||
class ArmMacroFPAOp : public PredMacroOp
|
class ArmMacroFPAOp : public PredMacroOp
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
uint32_t puswl,
|
uint32_t puswl,
|
||||||
prepost,
|
prepost,
|
||||||
up,
|
up,
|
||||||
|
@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp
|
||||||
*/
|
*/
|
||||||
class ArmMacroFMOp : public PredMacroOp
|
class ArmMacroFMOp : public PredMacroOp
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
uint32_t punwl,
|
uint32_t punwl,
|
||||||
prepost,
|
prepost,
|
||||||
up,
|
up,
|
||||||
|
|
|
@ -27,8 +27,10 @@
|
||||||
* Authors: Stephen Hines
|
* Authors: Stephen Hines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "arch/arm/faults.hh"
|
||||||
#include "arch/arm/insts/static_inst.hh"
|
#include "arch/arm/insts/static_inst.hh"
|
||||||
#include "base/condcodes.hh"
|
#include "base/condcodes.hh"
|
||||||
|
#include "base/cprintf.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
|
|
||||||
namespace ArmISA
|
namespace ArmISA
|
||||||
|
@ -62,7 +64,7 @@ ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
|
||||||
else
|
else
|
||||||
return (base << (32 - shamt)) | (base >> shamt);
|
return (base << (32 - shamt)) | (base >> shamt);
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unhandled shift type\n");
|
ccprintf(std::cerr, "Unhandled shift type\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +103,7 @@ ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
|
||||||
else
|
else
|
||||||
return (base << (32 - shamt)) | (base >> shamt);
|
return (base << (32 - shamt)) | (base >> shamt);
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unhandled shift type\n");
|
ccprintf(std::cerr, "Unhandled shift type\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +143,7 @@ ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
|
||||||
else
|
else
|
||||||
return (base >> (shamt - 1)) & 1;
|
return (base >> (shamt - 1)) & 1;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unhandled shift type\n");
|
ccprintf(std::cerr, "Unhandled shift type\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +184,7 @@ ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
|
||||||
shamt = 32;
|
shamt = 32;
|
||||||
return (base >> (shamt - 1)) & 1;
|
return (base >> (shamt - 1)) & 1;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unhandled shift type\n");
|
ccprintf(std::cerr, "Unhandled shift type\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,56 @@ class ArmStaticInst : public StaticInst
|
||||||
void printDataInst(std::ostream &os, bool withImm) const;
|
void printDataInst(std::ostream &os, bool withImm) const;
|
||||||
|
|
||||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
cpsrWriteByInstr(CPSR cpsr, uint32_t val,
|
||||||
|
uint8_t byteMask, bool affectState)
|
||||||
|
{
|
||||||
|
bool privileged = (cpsr.mode != MODE_USER);
|
||||||
|
|
||||||
|
uint32_t bitMask = 0;
|
||||||
|
|
||||||
|
if (bits(byteMask, 3)) {
|
||||||
|
unsigned lowIdx = affectState ? 24 : 27;
|
||||||
|
bitMask = bitMask | mask(31, lowIdx);
|
||||||
|
}
|
||||||
|
if (bits(byteMask, 2)) {
|
||||||
|
bitMask = bitMask | mask(19, 16);
|
||||||
|
}
|
||||||
|
if (bits(byteMask, 1)) {
|
||||||
|
unsigned highIdx = affectState ? 15 : 9;
|
||||||
|
unsigned lowIdx = privileged ? 8 : 9;
|
||||||
|
bitMask = bitMask | mask(highIdx, lowIdx);
|
||||||
|
}
|
||||||
|
if (bits(byteMask, 0)) {
|
||||||
|
if (privileged) {
|
||||||
|
bitMask = bitMask | mask(7, 6);
|
||||||
|
bitMask = bitMask | mask(5);
|
||||||
|
}
|
||||||
|
if (affectState)
|
||||||
|
bitMask = bitMask | (1 << 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((uint32_t)cpsr & ~bitMask) | (val & bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
spsrWriteByInstr(uint32_t spsr, uint32_t val,
|
||||||
|
uint8_t byteMask, bool affectState)
|
||||||
|
{
|
||||||
|
uint32_t bitMask = 0;
|
||||||
|
|
||||||
|
if (bits(byteMask, 3))
|
||||||
|
bitMask = bitMask | mask(31, 24);
|
||||||
|
if (bits(byteMask, 2))
|
||||||
|
bitMask = bitMask | mask(19, 16);
|
||||||
|
if (bits(byteMask, 1))
|
||||||
|
bitMask = bitMask | mask(15, 8);
|
||||||
|
if (bits(byteMask, 0))
|
||||||
|
bitMask = bitMask | mask(7, 0);
|
||||||
|
|
||||||
|
return ((spsr & ~bitMask) | (val & bitMask));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2009 ARM Limited
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,15 +24,14 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Ali Saidi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#include "arch/arm/interrupts.hh"
|
||||||
* AST.C
|
|
||||||
*
|
ArmISA::Interrupts *
|
||||||
* Description: See AST.hh
|
ArmInterruptsParams::create()
|
||||||
*
|
{
|
||||||
* $Id$
|
return new ArmISA::Interrupts(this);
|
||||||
*
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mem/slicc/ast/AST.hh"
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
|
* Copyright (c) 2009 ARM Limited
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,59 +25,97 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Ali Saidi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#ifndef __ARCH_ARM_INTERRUPT_HH__
|
||||||
* LiteralExprAST.hh
|
#define __ARCH_ARM_INTERRUPT_HH__
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
*
|
|
||||||
* $Id: LiteralExprAST.hh,v 3.1 2001/12/12 01:00:20 milo Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LITERALEXPRAST_H
|
#include "arch/arm/faults.hh"
|
||||||
#define LITERALEXPRAST_H
|
#include "arch/arm/isa_traits.hh"
|
||||||
|
#include "arch/arm/registers.hh"
|
||||||
|
#include "cpu/thread_context.hh"
|
||||||
|
#include "params/ArmInterrupts.hh"
|
||||||
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
#include "mem/slicc/slicc_global.hh"
|
namespace ArmISA
|
||||||
#include "mem/slicc/ast/ExprAST.hh"
|
|
||||||
|
|
||||||
|
|
||||||
class LiteralExprAST : public ExprAST {
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
LiteralExprAST(string* lit_ptr, string type) : ExprAST() { m_lit_ptr = lit_ptr; m_type = type; }
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
~LiteralExprAST() { delete m_lit_ptr; }
|
|
||||||
|
|
||||||
// Public Methods
|
|
||||||
Type* generate(string& code) const;
|
|
||||||
void print(ostream& out) const { out << "[Literal: " << *m_lit_ptr << "]"; }
|
|
||||||
private:
|
|
||||||
// Private Methods
|
|
||||||
|
|
||||||
// Private copy constructor and assignment operator
|
|
||||||
LiteralExprAST(const LiteralExprAST& obj);
|
|
||||||
LiteralExprAST& operator=(const LiteralExprAST& obj);
|
|
||||||
|
|
||||||
// Data Members (m_ prefix)
|
|
||||||
string* m_lit_ptr;
|
|
||||||
string m_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Output operator declaration
|
|
||||||
ostream& operator<<(ostream& out, const LiteralExprAST& obj);
|
|
||||||
|
|
||||||
// ******************* Definitions *******************
|
|
||||||
|
|
||||||
// Output operator definition
|
|
||||||
extern inline
|
|
||||||
ostream& operator<<(ostream& out, const LiteralExprAST& obj)
|
|
||||||
{
|
{
|
||||||
obj.print(out);
|
|
||||||
out << flush;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //LITERALEXPRAST_H
|
class Interrupts : public SimObject
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
BaseCPU * cpu;
|
||||||
|
|
||||||
|
uint64_t intStatus;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void
|
||||||
|
setCPU(BaseCPU * _cpu)
|
||||||
|
{
|
||||||
|
cpu = _cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef ArmInterruptsParams Params;
|
||||||
|
|
||||||
|
const Params *
|
||||||
|
params() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<const Params *>(_params);
|
||||||
|
}
|
||||||
|
|
||||||
|
Interrupts(Params * p) : SimObject(p), cpu(NULL)
|
||||||
|
{
|
||||||
|
clearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
post(int int_num, int index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clear(int int_num, int index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearAll()
|
||||||
|
{
|
||||||
|
intStatus = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
checkInterrupts(ThreadContext *tc) const
|
||||||
|
{
|
||||||
|
return intStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fault
|
||||||
|
getInterrupt(ThreadContext *tc)
|
||||||
|
{
|
||||||
|
warn_once("ARM Interrupts not handled\n");
|
||||||
|
return NoFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
updateIntrInfo(ThreadContext *tc)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
serialize(std::ostream &os)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace ARM_ISA
|
||||||
|
|
||||||
|
#endif // __ARCH_ARM_INTERRUPT_HH__
|
337
src/arch/arm/intregs.hh
Normal file
337
src/arch/arm/intregs.hh
Normal file
|
@ -0,0 +1,337 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifndef __ARCH_ARM_INTREGS_HH__
|
||||||
|
#define __ARCH_ARM_INTREGS_HH__
|
||||||
|
|
||||||
|
namespace ArmISA
|
||||||
|
{
|
||||||
|
|
||||||
|
enum IntRegIndex
|
||||||
|
{
|
||||||
|
/* All the unique register indices. */
|
||||||
|
INTREG_R0,
|
||||||
|
INTREG_R1,
|
||||||
|
INTREG_R2,
|
||||||
|
INTREG_R3,
|
||||||
|
INTREG_R4,
|
||||||
|
INTREG_R5,
|
||||||
|
INTREG_R6,
|
||||||
|
INTREG_R7,
|
||||||
|
INTREG_R8,
|
||||||
|
INTREG_R9,
|
||||||
|
INTREG_R10,
|
||||||
|
INTREG_R11,
|
||||||
|
INTREG_R12,
|
||||||
|
INTREG_R13,
|
||||||
|
INTREG_SP = INTREG_R13,
|
||||||
|
INTREG_R14,
|
||||||
|
INTREG_LR = INTREG_R14,
|
||||||
|
INTREG_R15,
|
||||||
|
INTREG_PC = INTREG_R15,
|
||||||
|
|
||||||
|
INTREG_R13_SVC,
|
||||||
|
INTREG_SP_SVC = INTREG_R13_SVC,
|
||||||
|
INTREG_R14_SVC,
|
||||||
|
INTREG_LR_SVC = INTREG_R14_SVC,
|
||||||
|
|
||||||
|
INTREG_R13_MON,
|
||||||
|
INTREG_SP_MON = INTREG_R13_MON,
|
||||||
|
INTREG_R14_MON,
|
||||||
|
INTREG_LR_MON = INTREG_R14_MON,
|
||||||
|
|
||||||
|
INTREG_R13_ABT,
|
||||||
|
INTREG_SP_ABT = INTREG_R13_ABT,
|
||||||
|
INTREG_R14_ABT,
|
||||||
|
INTREG_LR_ABT = INTREG_R14_ABT,
|
||||||
|
|
||||||
|
INTREG_R13_UND,
|
||||||
|
INTREG_SP_UND = INTREG_R13_UND,
|
||||||
|
INTREG_R14_UND,
|
||||||
|
INTREG_LR_UND = INTREG_R14_UND,
|
||||||
|
|
||||||
|
INTREG_R13_IRQ,
|
||||||
|
INTREG_SP_IRQ = INTREG_R13_IRQ,
|
||||||
|
INTREG_R14_IRQ,
|
||||||
|
INTREG_LR_IRQ = INTREG_R14_IRQ,
|
||||||
|
|
||||||
|
INTREG_R8_FIQ,
|
||||||
|
INTREG_R9_FIQ,
|
||||||
|
INTREG_R10_FIQ,
|
||||||
|
INTREG_R11_FIQ,
|
||||||
|
INTREG_R12_FIQ,
|
||||||
|
INTREG_R13_FIQ,
|
||||||
|
INTREG_SP_FIQ = INTREG_R13_FIQ,
|
||||||
|
INTREG_R14_FIQ,
|
||||||
|
INTREG_LR_FIQ = INTREG_R14_FIQ,
|
||||||
|
|
||||||
|
INTREG_ZERO, // Dummy zero reg since there has to be one.
|
||||||
|
INTREG_UREG0,
|
||||||
|
INTREG_RHI,
|
||||||
|
INTREG_RLO,
|
||||||
|
INTREG_CONDCODES,
|
||||||
|
|
||||||
|
NUM_INTREGS,
|
||||||
|
NUM_ARCH_INTREGS = INTREG_PC + 1,
|
||||||
|
|
||||||
|
/* All the aliased indexes. */
|
||||||
|
|
||||||
|
/* USR mode */
|
||||||
|
INTREG_R0_USR = INTREG_R0,
|
||||||
|
INTREG_R1_USR = INTREG_R1,
|
||||||
|
INTREG_R2_USR = INTREG_R2,
|
||||||
|
INTREG_R3_USR = INTREG_R3,
|
||||||
|
INTREG_R4_USR = INTREG_R4,
|
||||||
|
INTREG_R5_USR = INTREG_R5,
|
||||||
|
INTREG_R6_USR = INTREG_R6,
|
||||||
|
INTREG_R7_USR = INTREG_R7,
|
||||||
|
INTREG_R8_USR = INTREG_R8,
|
||||||
|
INTREG_R9_USR = INTREG_R9,
|
||||||
|
INTREG_R10_USR = INTREG_R10,
|
||||||
|
INTREG_R11_USR = INTREG_R11,
|
||||||
|
INTREG_R12_USR = INTREG_R12,
|
||||||
|
INTREG_R13_USR = INTREG_R13,
|
||||||
|
INTREG_SP_USR = INTREG_SP,
|
||||||
|
INTREG_R14_USR = INTREG_R14,
|
||||||
|
INTREG_LR_USR = INTREG_LR,
|
||||||
|
INTREG_R15_USR = INTREG_R15,
|
||||||
|
INTREG_PC_USR = INTREG_PC,
|
||||||
|
|
||||||
|
/* SVC mode */
|
||||||
|
INTREG_R0_SVC = INTREG_R0,
|
||||||
|
INTREG_R1_SVC = INTREG_R1,
|
||||||
|
INTREG_R2_SVC = INTREG_R2,
|
||||||
|
INTREG_R3_SVC = INTREG_R3,
|
||||||
|
INTREG_R4_SVC = INTREG_R4,
|
||||||
|
INTREG_R5_SVC = INTREG_R5,
|
||||||
|
INTREG_R6_SVC = INTREG_R6,
|
||||||
|
INTREG_R7_SVC = INTREG_R7,
|
||||||
|
INTREG_R8_SVC = INTREG_R8,
|
||||||
|
INTREG_R9_SVC = INTREG_R9,
|
||||||
|
INTREG_R10_SVC = INTREG_R10,
|
||||||
|
INTREG_R11_SVC = INTREG_R11,
|
||||||
|
INTREG_R12_SVC = INTREG_R12,
|
||||||
|
INTREG_PC_SVC = INTREG_PC,
|
||||||
|
INTREG_R15_SVC = INTREG_R15,
|
||||||
|
|
||||||
|
/* MON mode */
|
||||||
|
INTREG_R0_MON = INTREG_R0,
|
||||||
|
INTREG_R1_MON = INTREG_R1,
|
||||||
|
INTREG_R2_MON = INTREG_R2,
|
||||||
|
INTREG_R3_MON = INTREG_R3,
|
||||||
|
INTREG_R4_MON = INTREG_R4,
|
||||||
|
INTREG_R5_MON = INTREG_R5,
|
||||||
|
INTREG_R6_MON = INTREG_R6,
|
||||||
|
INTREG_R7_MON = INTREG_R7,
|
||||||
|
INTREG_R8_MON = INTREG_R8,
|
||||||
|
INTREG_R9_MON = INTREG_R9,
|
||||||
|
INTREG_R10_MON = INTREG_R10,
|
||||||
|
INTREG_R11_MON = INTREG_R11,
|
||||||
|
INTREG_R12_MON = INTREG_R12,
|
||||||
|
INTREG_PC_MON = INTREG_PC,
|
||||||
|
INTREG_R15_MON = INTREG_R15,
|
||||||
|
|
||||||
|
/* ABT mode */
|
||||||
|
INTREG_R0_ABT = INTREG_R0,
|
||||||
|
INTREG_R1_ABT = INTREG_R1,
|
||||||
|
INTREG_R2_ABT = INTREG_R2,
|
||||||
|
INTREG_R3_ABT = INTREG_R3,
|
||||||
|
INTREG_R4_ABT = INTREG_R4,
|
||||||
|
INTREG_R5_ABT = INTREG_R5,
|
||||||
|
INTREG_R6_ABT = INTREG_R6,
|
||||||
|
INTREG_R7_ABT = INTREG_R7,
|
||||||
|
INTREG_R8_ABT = INTREG_R8,
|
||||||
|
INTREG_R9_ABT = INTREG_R9,
|
||||||
|
INTREG_R10_ABT = INTREG_R10,
|
||||||
|
INTREG_R11_ABT = INTREG_R11,
|
||||||
|
INTREG_R12_ABT = INTREG_R12,
|
||||||
|
INTREG_PC_ABT = INTREG_PC,
|
||||||
|
INTREG_R15_ABT = INTREG_R15,
|
||||||
|
|
||||||
|
/* UND mode */
|
||||||
|
INTREG_R0_UND = INTREG_R0,
|
||||||
|
INTREG_R1_UND = INTREG_R1,
|
||||||
|
INTREG_R2_UND = INTREG_R2,
|
||||||
|
INTREG_R3_UND = INTREG_R3,
|
||||||
|
INTREG_R4_UND = INTREG_R4,
|
||||||
|
INTREG_R5_UND = INTREG_R5,
|
||||||
|
INTREG_R6_UND = INTREG_R6,
|
||||||
|
INTREG_R7_UND = INTREG_R7,
|
||||||
|
INTREG_R8_UND = INTREG_R8,
|
||||||
|
INTREG_R9_UND = INTREG_R9,
|
||||||
|
INTREG_R10_UND = INTREG_R10,
|
||||||
|
INTREG_R11_UND = INTREG_R11,
|
||||||
|
INTREG_R12_UND = INTREG_R12,
|
||||||
|
INTREG_PC_UND = INTREG_PC,
|
||||||
|
INTREG_R15_UND = INTREG_R15,
|
||||||
|
|
||||||
|
/* IRQ mode */
|
||||||
|
INTREG_R0_IRQ = INTREG_R0,
|
||||||
|
INTREG_R1_IRQ = INTREG_R1,
|
||||||
|
INTREG_R2_IRQ = INTREG_R2,
|
||||||
|
INTREG_R3_IRQ = INTREG_R3,
|
||||||
|
INTREG_R4_IRQ = INTREG_R4,
|
||||||
|
INTREG_R5_IRQ = INTREG_R5,
|
||||||
|
INTREG_R6_IRQ = INTREG_R6,
|
||||||
|
INTREG_R7_IRQ = INTREG_R7,
|
||||||
|
INTREG_R8_IRQ = INTREG_R8,
|
||||||
|
INTREG_R9_IRQ = INTREG_R9,
|
||||||
|
INTREG_R10_IRQ = INTREG_R10,
|
||||||
|
INTREG_R11_IRQ = INTREG_R11,
|
||||||
|
INTREG_R12_IRQ = INTREG_R12,
|
||||||
|
INTREG_PC_IRQ = INTREG_PC,
|
||||||
|
INTREG_R15_IRQ = INTREG_R15,
|
||||||
|
|
||||||
|
/* FIQ mode */
|
||||||
|
INTREG_R0_FIQ = INTREG_R0,
|
||||||
|
INTREG_R1_FIQ = INTREG_R1,
|
||||||
|
INTREG_R2_FIQ = INTREG_R2,
|
||||||
|
INTREG_R3_FIQ = INTREG_R3,
|
||||||
|
INTREG_R4_FIQ = INTREG_R4,
|
||||||
|
INTREG_R5_FIQ = INTREG_R5,
|
||||||
|
INTREG_R6_FIQ = INTREG_R6,
|
||||||
|
INTREG_R7_FIQ = INTREG_R7,
|
||||||
|
INTREG_PC_FIQ = INTREG_PC,
|
||||||
|
INTREG_R15_FIQ = INTREG_R15,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS];
|
||||||
|
|
||||||
|
const IntRegMap IntRegUsrMap = {
|
||||||
|
INTREG_R0_USR, INTREG_R1_USR, INTREG_R2_USR, INTREG_R3_USR,
|
||||||
|
INTREG_R4_USR, INTREG_R5_USR, INTREG_R6_USR, INTREG_R7_USR,
|
||||||
|
INTREG_R8_USR, INTREG_R9_USR, INTREG_R10_USR, INTREG_R11_USR,
|
||||||
|
INTREG_R12_USR, INTREG_R13_USR, INTREG_R14_USR, INTREG_R15_USR
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline IntRegIndex
|
||||||
|
INTREG_USR(unsigned index)
|
||||||
|
{
|
||||||
|
assert(index < NUM_ARCH_INTREGS);
|
||||||
|
return IntRegUsrMap[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const IntRegMap IntRegSvcMap = {
|
||||||
|
INTREG_R0_SVC, INTREG_R1_SVC, INTREG_R2_SVC, INTREG_R3_SVC,
|
||||||
|
INTREG_R4_SVC, INTREG_R5_SVC, INTREG_R6_SVC, INTREG_R7_SVC,
|
||||||
|
INTREG_R8_SVC, INTREG_R9_SVC, INTREG_R10_SVC, INTREG_R11_SVC,
|
||||||
|
INTREG_R12_SVC, INTREG_R13_SVC, INTREG_R14_SVC, INTREG_R15_SVC
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline IntRegIndex
|
||||||
|
INTREG_SVC(unsigned index)
|
||||||
|
{
|
||||||
|
assert(index < NUM_ARCH_INTREGS);
|
||||||
|
return IntRegSvcMap[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const IntRegMap IntRegMonMap = {
|
||||||
|
INTREG_R0_MON, INTREG_R1_MON, INTREG_R2_MON, INTREG_R3_MON,
|
||||||
|
INTREG_R4_MON, INTREG_R5_MON, INTREG_R6_MON, INTREG_R7_MON,
|
||||||
|
INTREG_R8_MON, INTREG_R9_MON, INTREG_R10_MON, INTREG_R11_MON,
|
||||||
|
INTREG_R12_MON, INTREG_R13_MON, INTREG_R14_MON, INTREG_R15_MON
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline IntRegIndex
|
||||||
|
INTREG_MON(unsigned index)
|
||||||
|
{
|
||||||
|
assert(index < NUM_ARCH_INTREGS);
|
||||||
|
return IntRegMonMap[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const IntRegMap IntRegAbtMap = {
|
||||||
|
INTREG_R0_ABT, INTREG_R1_ABT, INTREG_R2_ABT, INTREG_R3_ABT,
|
||||||
|
INTREG_R4_ABT, INTREG_R5_ABT, INTREG_R6_ABT, INTREG_R7_ABT,
|
||||||
|
INTREG_R8_ABT, INTREG_R9_ABT, INTREG_R10_ABT, INTREG_R11_ABT,
|
||||||
|
INTREG_R12_ABT, INTREG_R13_ABT, INTREG_R14_ABT, INTREG_R15_ABT
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline IntRegIndex
|
||||||
|
INTREG_ABT(unsigned index)
|
||||||
|
{
|
||||||
|
assert(index < NUM_ARCH_INTREGS);
|
||||||
|
return IntRegAbtMap[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const IntRegMap IntRegUndMap = {
|
||||||
|
INTREG_R0_UND, INTREG_R1_UND, INTREG_R2_UND, INTREG_R3_UND,
|
||||||
|
INTREG_R4_UND, INTREG_R5_UND, INTREG_R6_UND, INTREG_R7_UND,
|
||||||
|
INTREG_R8_UND, INTREG_R9_UND, INTREG_R10_UND, INTREG_R11_UND,
|
||||||
|
INTREG_R12_UND, INTREG_R13_UND, INTREG_R14_UND, INTREG_R15_UND
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline IntRegIndex
|
||||||
|
INTREG_UND(unsigned index)
|
||||||
|
{
|
||||||
|
assert(index < NUM_ARCH_INTREGS);
|
||||||
|
return IntRegUndMap[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const IntRegMap IntRegIrqMap = {
|
||||||
|
INTREG_R0_IRQ, INTREG_R1_IRQ, INTREG_R2_IRQ, INTREG_R3_IRQ,
|
||||||
|
INTREG_R4_IRQ, INTREG_R5_IRQ, INTREG_R6_IRQ, INTREG_R7_IRQ,
|
||||||
|
INTREG_R8_IRQ, INTREG_R9_IRQ, INTREG_R10_IRQ, INTREG_R11_IRQ,
|
||||||
|
INTREG_R12_IRQ, INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_R15_IRQ
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline IntRegIndex
|
||||||
|
INTREG_IRQ(unsigned index)
|
||||||
|
{
|
||||||
|
assert(index < NUM_ARCH_INTREGS);
|
||||||
|
return IntRegIrqMap[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const IntRegMap IntRegFiqMap = {
|
||||||
|
INTREG_R0_FIQ, INTREG_R1_FIQ, INTREG_R2_FIQ, INTREG_R3_FIQ,
|
||||||
|
INTREG_R4_FIQ, INTREG_R5_FIQ, INTREG_R6_FIQ, INTREG_R7_FIQ,
|
||||||
|
INTREG_R8_FIQ, INTREG_R9_FIQ, INTREG_R10_FIQ, INTREG_R11_FIQ,
|
||||||
|
INTREG_R12_FIQ, INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_R15_FIQ
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline IntRegIndex
|
||||||
|
INTREG_FIQ(unsigned index)
|
||||||
|
{
|
||||||
|
assert(index < NUM_ARCH_INTREGS);
|
||||||
|
return IntRegFiqMap[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline IntRegIndex
|
||||||
|
intRegForceUser(unsigned index)
|
||||||
|
{
|
||||||
|
assert(index < NUM_ARCH_INTREGS);
|
||||||
|
|
||||||
|
return index == 15 ? (IntRegIndex)15 : (IntRegIndex)(index + NUM_INTREGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -44,6 +44,38 @@ namespace ArmISA
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
MiscReg miscRegs[NumMiscRegs];
|
MiscReg miscRegs[NumMiscRegs];
|
||||||
|
const IntRegIndex *intRegMap;
|
||||||
|
|
||||||
|
void
|
||||||
|
updateRegMap(CPSR cpsr)
|
||||||
|
{
|
||||||
|
switch (cpsr.mode) {
|
||||||
|
case MODE_USER:
|
||||||
|
case MODE_SYSTEM:
|
||||||
|
intRegMap = IntRegUsrMap;
|
||||||
|
break;
|
||||||
|
case MODE_FIQ:
|
||||||
|
intRegMap = IntRegFiqMap;
|
||||||
|
break;
|
||||||
|
case MODE_IRQ:
|
||||||
|
intRegMap = IntRegIrqMap;
|
||||||
|
break;
|
||||||
|
case MODE_SVC:
|
||||||
|
intRegMap = IntRegSvcMap;
|
||||||
|
break;
|
||||||
|
case MODE_MON:
|
||||||
|
intRegMap = IntRegMonMap;
|
||||||
|
break;
|
||||||
|
case MODE_ABORT:
|
||||||
|
intRegMap = IntRegAbtMap;
|
||||||
|
break;
|
||||||
|
case MODE_UNDEFINED:
|
||||||
|
intRegMap = IntRegUndMap;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("Unrecognized mode setting in CPSR.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void clear()
|
void clear()
|
||||||
|
@ -52,6 +84,15 @@ namespace ArmISA
|
||||||
CPSR cpsr = 0;
|
CPSR cpsr = 0;
|
||||||
cpsr.mode = MODE_USER;
|
cpsr.mode = MODE_USER;
|
||||||
miscRegs[MISCREG_CPSR] = cpsr;
|
miscRegs[MISCREG_CPSR] = cpsr;
|
||||||
|
updateRegMap(cpsr);
|
||||||
|
|
||||||
|
SCTLR sctlr = 0;
|
||||||
|
sctlr.nmfi = 1;
|
||||||
|
sctlr.rao1 = 1;
|
||||||
|
sctlr.rao2 = 1;
|
||||||
|
sctlr.rao3 = 1;
|
||||||
|
sctlr.rao4 = 1;
|
||||||
|
|
||||||
//XXX We need to initialize the rest of the state.
|
//XXX We need to initialize the rest of the state.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,34 +100,94 @@ namespace ArmISA
|
||||||
readMiscRegNoEffect(int misc_reg)
|
readMiscRegNoEffect(int misc_reg)
|
||||||
{
|
{
|
||||||
assert(misc_reg < NumMiscRegs);
|
assert(misc_reg < NumMiscRegs);
|
||||||
|
if (misc_reg == MISCREG_SPSR) {
|
||||||
|
CPSR cpsr = miscRegs[MISCREG_CPSR];
|
||||||
|
switch (cpsr.mode) {
|
||||||
|
case MODE_USER:
|
||||||
|
return miscRegs[MISCREG_SPSR];
|
||||||
|
case MODE_FIQ:
|
||||||
|
return miscRegs[MISCREG_SPSR_FIQ];
|
||||||
|
case MODE_IRQ:
|
||||||
|
return miscRegs[MISCREG_SPSR_IRQ];
|
||||||
|
case MODE_SVC:
|
||||||
|
return miscRegs[MISCREG_SPSR_SVC];
|
||||||
|
case MODE_MON:
|
||||||
|
return miscRegs[MISCREG_SPSR_MON];
|
||||||
|
case MODE_ABORT:
|
||||||
|
return miscRegs[MISCREG_SPSR_ABT];
|
||||||
|
case MODE_UNDEFINED:
|
||||||
|
return miscRegs[MISCREG_SPSR_UND];
|
||||||
|
default:
|
||||||
|
return miscRegs[MISCREG_SPSR];
|
||||||
|
}
|
||||||
|
}
|
||||||
return miscRegs[misc_reg];
|
return miscRegs[misc_reg];
|
||||||
}
|
}
|
||||||
|
|
||||||
MiscReg
|
MiscReg
|
||||||
readMiscReg(int misc_reg, ThreadContext *tc)
|
readMiscReg(int misc_reg, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
assert(misc_reg < NumMiscRegs);
|
return readMiscRegNoEffect(misc_reg);
|
||||||
return miscRegs[misc_reg];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setMiscRegNoEffect(int misc_reg, const MiscReg &val)
|
setMiscRegNoEffect(int misc_reg, const MiscReg &val)
|
||||||
{
|
{
|
||||||
assert(misc_reg < NumMiscRegs);
|
assert(misc_reg < NumMiscRegs);
|
||||||
|
if (misc_reg == MISCREG_SPSR) {
|
||||||
|
CPSR cpsr = miscRegs[MISCREG_CPSR];
|
||||||
|
switch (cpsr.mode) {
|
||||||
|
case MODE_USER:
|
||||||
|
miscRegs[MISCREG_SPSR] = val;
|
||||||
|
return;
|
||||||
|
case MODE_FIQ:
|
||||||
|
miscRegs[MISCREG_SPSR_FIQ] = val;
|
||||||
|
return;
|
||||||
|
case MODE_IRQ:
|
||||||
|
miscRegs[MISCREG_SPSR_IRQ] = val;
|
||||||
|
return;
|
||||||
|
case MODE_SVC:
|
||||||
|
miscRegs[MISCREG_SPSR_SVC] = val;
|
||||||
|
return;
|
||||||
|
case MODE_MON:
|
||||||
|
miscRegs[MISCREG_SPSR_MON] = val;
|
||||||
|
return;
|
||||||
|
case MODE_ABORT:
|
||||||
|
miscRegs[MISCREG_SPSR_ABT] = val;
|
||||||
|
return;
|
||||||
|
case MODE_UNDEFINED:
|
||||||
|
miscRegs[MISCREG_SPSR_UND] = val;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
miscRegs[MISCREG_SPSR] = val;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
miscRegs[misc_reg] = val;
|
miscRegs[misc_reg] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
|
setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
assert(misc_reg < NumMiscRegs);
|
if (misc_reg == MISCREG_CPSR) {
|
||||||
miscRegs[misc_reg] = val;
|
updateRegMap(val);
|
||||||
|
}
|
||||||
|
return setMiscRegNoEffect(misc_reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
flattenIntIndex(int reg)
|
flattenIntIndex(int reg)
|
||||||
{
|
{
|
||||||
return reg;
|
assert(reg >= 0);
|
||||||
|
if (reg < NUM_ARCH_INTREGS) {
|
||||||
|
return intRegMap[reg];
|
||||||
|
} else if (reg < NUM_INTREGS) {
|
||||||
|
return reg;
|
||||||
|
} else {
|
||||||
|
reg -= NUM_INTREGS;
|
||||||
|
assert(reg < NUM_ARCH_INTREGS);
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -95,9 +196,10 @@ namespace ArmISA
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(std::ostream &os)
|
void serialize(EventManager *em, std::ostream &os)
|
||||||
{}
|
{}
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion)
|
void unserialize(EventManager *em, Checkpoint *cp,
|
||||||
|
const std::string §ion)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ISA()
|
ISA()
|
||||||
|
|
|
@ -38,14 +38,18 @@ def bitfield ENCODING encoding;
|
||||||
def bitfield OPCODE opcode;
|
def bitfield OPCODE opcode;
|
||||||
def bitfield MEDIA_OPCODE mediaOpcode;
|
def bitfield MEDIA_OPCODE mediaOpcode;
|
||||||
def bitfield MEDIA_OPCODE2 mediaOpcode2;
|
def bitfield MEDIA_OPCODE2 mediaOpcode2;
|
||||||
|
def bitfield USEIMM useImm;
|
||||||
def bitfield OPCODE_24 opcode24;
|
def bitfield OPCODE_24 opcode24;
|
||||||
def bitfield OPCODE_23_20 opcode23_20;
|
def bitfield OPCODE_23_20 opcode23_20;
|
||||||
def bitfield OPCODE_23_21 opcode23_21;
|
def bitfield OPCODE_23_21 opcode23_21;
|
||||||
def bitfield OPCODE_22 opcode22;
|
def bitfield OPCODE_22 opcode22;
|
||||||
|
def bitfield OPCODE_20 opcode20;
|
||||||
def bitfield OPCODE_19 opcode19;
|
def bitfield OPCODE_19 opcode19;
|
||||||
|
def bitfield OPCODE_18 opcode18;
|
||||||
def bitfield OPCODE_15_12 opcode15_12;
|
def bitfield OPCODE_15_12 opcode15_12;
|
||||||
def bitfield OPCODE_15 opcode15;
|
def bitfield OPCODE_15 opcode15;
|
||||||
def bitfield MISC_OPCODE miscOpcode;
|
def bitfield MISC_OPCODE miscOpcode;
|
||||||
|
def bitfield OPC2 opc2;
|
||||||
def bitfield OPCODE_7 opcode7;
|
def bitfield OPCODE_7 opcode7;
|
||||||
def bitfield OPCODE_4 opcode4;
|
def bitfield OPCODE_4 opcode4;
|
||||||
|
|
||||||
|
|
|
@ -51,20 +51,25 @@ format DataOp {
|
||||||
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
||||||
Rd = (uint32_t)(resTemp & 0xffffffff);
|
Rd = (uint32_t)(resTemp & 0xffffffff);
|
||||||
Rn = (uint32_t)(resTemp >> 32);
|
Rn = (uint32_t)(resTemp >> 32);
|
||||||
}});
|
}}, llbit);
|
||||||
0x5: WarnUnimpl::smlal();
|
0x5: smlal({{
|
||||||
|
resTemp = ((int64_t)Rm) * ((int64_t)Rs);
|
||||||
|
resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd);
|
||||||
|
Rd = (uint32_t)(resTemp & 0xffffffff);
|
||||||
|
Rn = (uint32_t)(resTemp >> 32);
|
||||||
|
}}, llbit);
|
||||||
0x6: smull({{
|
0x6: smull({{
|
||||||
resTemp = ((int64_t)(int32_t)Rm)*
|
resTemp = ((int64_t)(int32_t)Rm)*
|
||||||
((int64_t)(int32_t)Rs);
|
((int64_t)(int32_t)Rs);
|
||||||
Rd = (int32_t)(resTemp & 0xffffffff);
|
Rd = (int32_t)(resTemp & 0xffffffff);
|
||||||
Rn = (int32_t)(resTemp >> 32);
|
Rn = (int32_t)(resTemp >> 32);
|
||||||
}});
|
}}, llbit);
|
||||||
0x7: umlal({{
|
0x7: umlal({{
|
||||||
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
||||||
resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
|
resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
|
||||||
Rd = (uint32_t)(resTemp & 0xffffffff);
|
Rd = (uint32_t)(resTemp & 0xffffffff);
|
||||||
Rn = (uint32_t)(resTemp >> 32);
|
Rn = (uint32_t)(resTemp >> 32);
|
||||||
}});
|
}}, llbit);
|
||||||
}
|
}
|
||||||
1: decode PUBWL {
|
1: decode PUBWL {
|
||||||
0x10: WarnUnimpl::swp();
|
0x10: WarnUnimpl::swp();
|
||||||
|
@ -91,9 +96,9 @@ format DataOp {
|
||||||
0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub);
|
0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub);
|
||||||
0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb);
|
0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb);
|
||||||
0x4: add({{ Rd = resTemp = Rn + op2; }}, add);
|
0x4: add({{ Rd = resTemp = Rn + op2; }}, add);
|
||||||
0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add);
|
0x5: adc({{ Rd = resTemp = Rn + op2 + CondCodes<29:>; }}, add);
|
||||||
0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub);
|
0x6: sbc({{ Rd = resTemp = Rn - op2 - !CondCodes<29:>; }}, sub);
|
||||||
0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb);
|
0x7: rsc({{ Rd = resTemp = op2 - Rn - !CondCodes<29:>; }}, rsb);
|
||||||
0x8: tst({{ resTemp = Rn & op2; }});
|
0x8: tst({{ resTemp = Rn & op2; }});
|
||||||
0x9: teq({{ resTemp = Rn ^ op2; }});
|
0x9: teq({{ resTemp = Rn ^ op2; }});
|
||||||
0xa: cmp({{ resTemp = Rn - op2; }}, sub);
|
0xa: cmp({{ resTemp = Rn - op2; }}, sub);
|
||||||
|
@ -105,10 +110,37 @@ format DataOp {
|
||||||
}
|
}
|
||||||
1: decode MISC_OPCODE {
|
1: decode MISC_OPCODE {
|
||||||
0x0: decode OPCODE {
|
0x0: decode OPCODE {
|
||||||
0x8: WarnUnimpl::mrs_cpsr();
|
0x8: PredOp::mrs_cpsr({{
|
||||||
0x9: WarnUnimpl::msr_cpsr();
|
Rd = (Cpsr | CondCodes) & 0xF8FF03DF;
|
||||||
0xa: WarnUnimpl::mrs_spsr();
|
}});
|
||||||
0xb: WarnUnimpl::msr_spsr();
|
0x9: decode USEIMM {
|
||||||
|
// The mask field is the same as the RN index.
|
||||||
|
0: PredOp::msr_cpsr_reg({{
|
||||||
|
uint32_t newCpsr =
|
||||||
|
cpsrWriteByInstr(Cpsr | CondCodes,
|
||||||
|
Rm, RN, false);
|
||||||
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
|
CondCodes = CondCodesMask & newCpsr;
|
||||||
|
}});
|
||||||
|
1: PredImmOp::msr_cpsr_imm({{
|
||||||
|
uint32_t newCpsr =
|
||||||
|
cpsrWriteByInstr(Cpsr | CondCodes,
|
||||||
|
rotated_imm, RN, false);
|
||||||
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
|
CondCodes = CondCodesMask & newCpsr;
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
0xa: PredOp::mrs_spsr({{ Rd = Spsr; }});
|
||||||
|
0xb: decode USEIMM {
|
||||||
|
// The mask field is the same as the RN index.
|
||||||
|
0: PredOp::msr_spsr_reg({{
|
||||||
|
Spsr = spsrWriteByInstr(Spsr, Rm, RN, false);
|
||||||
|
}});
|
||||||
|
1: PredImmOp::msr_spsr_imm({{
|
||||||
|
Spsr = spsrWriteByInstr(Spsr, rotated_imm,
|
||||||
|
RN, false);
|
||||||
|
}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
0x1: decode OPCODE {
|
0x1: decode OPCODE {
|
||||||
0x9: BranchExchange::bx({{ }});
|
0x9: BranchExchange::bx({{ }});
|
||||||
|
@ -129,28 +161,32 @@ format DataOp {
|
||||||
0xb: WarnUnimpl::qdsub();
|
0xb: WarnUnimpl::qdsub();
|
||||||
}
|
}
|
||||||
0x8: decode OPCODE {
|
0x8: decode OPCODE {
|
||||||
0x8: WarnUnimpl::smlabb();
|
0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
|
||||||
0x9: WarnUnimpl::smlalbb();
|
0x9: WarnUnimpl::smlalbb();
|
||||||
0xa: WarnUnimpl::smlawb();
|
0xa: WarnUnimpl::smlawb();
|
||||||
0xb: WarnUnimpl::smulbb();
|
0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none);
|
||||||
}
|
}
|
||||||
0xa: decode OPCODE {
|
0xa: decode OPCODE {
|
||||||
0x8: WarnUnimpl::smlatb();
|
0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
|
||||||
0x9: WarnUnimpl::smulwb();
|
0x9: smulwb({{
|
||||||
|
Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16);
|
||||||
|
}}, none);
|
||||||
0xa: WarnUnimpl::smlaltb();
|
0xa: WarnUnimpl::smlaltb();
|
||||||
0xb: WarnUnimpl::smultb();
|
0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none);
|
||||||
}
|
}
|
||||||
0xc: decode OPCODE {
|
0xc: decode OPCODE {
|
||||||
0x8: WarnUnimpl::smlabt();
|
0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
|
||||||
0x9: WarnUnimpl::smlawt();
|
0x9: WarnUnimpl::smlawt();
|
||||||
0xa: WarnUnimpl::smlalbt();
|
0xa: WarnUnimpl::smlalbt();
|
||||||
0xb: WarnUnimpl::smulbt();
|
0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none);
|
||||||
}
|
}
|
||||||
0xe: decode OPCODE {
|
0xe: decode OPCODE {
|
||||||
0x8: WarnUnimpl::smlatt();
|
0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
|
||||||
0x9: WarnUnimpl::smulwt();
|
0x9: smulwt({{
|
||||||
|
Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16);
|
||||||
|
}}, none);
|
||||||
0xa: WarnUnimpl::smlaltt();
|
0xa: WarnUnimpl::smlaltt();
|
||||||
0xb: WarnUnimpl::smultt();
|
0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,9 +199,15 @@ format DataOp {
|
||||||
0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub);
|
0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub);
|
||||||
0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb);
|
0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb);
|
||||||
0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add);
|
0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add);
|
||||||
0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add);
|
0x5: adci({{
|
||||||
0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub);
|
Rd = resTemp = Rn + rotated_imm + CondCodes<29:>;
|
||||||
0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb);
|
}}, add);
|
||||||
|
0x6: sbci({{
|
||||||
|
Rd = resTemp = Rn -rotated_imm - !CondCodes<29:>;
|
||||||
|
}}, sub);
|
||||||
|
0x7: rsci({{
|
||||||
|
Rd = resTemp = rotated_imm - Rn - !CondCodes<29:>;
|
||||||
|
}}, rsb);
|
||||||
0x8: tsti({{ resTemp = Rn & rotated_imm; }});
|
0x8: tsti({{ resTemp = Rn & rotated_imm; }});
|
||||||
0x9: teqi({{ resTemp = Rn ^ rotated_imm; }});
|
0x9: teqi({{ resTemp = Rn ^ rotated_imm; }});
|
||||||
0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub);
|
0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub);
|
||||||
|
@ -178,11 +220,27 @@ format DataOp {
|
||||||
}
|
}
|
||||||
1: decode OPCODE {
|
1: decode OPCODE {
|
||||||
// The following two instructions aren't supposed to be defined
|
// The following two instructions aren't supposed to be defined
|
||||||
0x8: WarnUnimpl::undefined_instruction();
|
0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }});
|
||||||
0x9: WarnUnimpl::undefined_instruction();
|
0x9: decode RN {
|
||||||
|
0: decode IMM {
|
||||||
0xa: WarnUnimpl::mrs_i_cpsr();
|
0: PredImmOp::nop({{ ; }});
|
||||||
0xb: WarnUnimpl::mrs_i_spsr();
|
1: WarnUnimpl::yield();
|
||||||
|
2: WarnUnimpl::wfe();
|
||||||
|
3: WarnUnimpl::wfi();
|
||||||
|
4: WarnUnimpl::sev();
|
||||||
|
}
|
||||||
|
default: PredImmOp::msr_i_cpsr({{
|
||||||
|
uint32_t newCpsr =
|
||||||
|
cpsrWriteByInstr(Cpsr | CondCodes,
|
||||||
|
rotated_imm, RN, false);
|
||||||
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
|
CondCodes = CondCodesMask & newCpsr;
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }});
|
||||||
|
0xb: PredImmOp::msr_i_spsr({{
|
||||||
|
Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false);
|
||||||
|
}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x2: AddrMode2::addrMode2(Disp, disp);
|
0x2: AddrMode2::addrMode2(Disp, disp);
|
||||||
|
@ -324,77 +382,79 @@ format DataOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x7: decode OPCODE_24 {
|
0x7: decode OPCODE_24 {
|
||||||
0: decode CPNUM {
|
0: decode OPCODE_4 {
|
||||||
// Coprocessor Instructions
|
0: decode CPNUM {
|
||||||
0x1: decode OPCODE_4 {
|
|
||||||
format FloatOp {
|
format FloatOp {
|
||||||
// Basic FPA Instructions
|
0x1: decode OPCODE_23_20 {
|
||||||
0: decode OPCODE_23_20 {
|
0x0: decode OPCODE_15 {
|
||||||
0x0: decode OPCODE_15 {
|
0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
|
||||||
0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
|
1: mvf({{ Fd.sf = Fm.sf; }});
|
||||||
1: mvf({{ Fd.sf = Fm.sf; }});
|
}
|
||||||
}
|
0x1: decode OPCODE_15 {
|
||||||
0x1: decode OPCODE_15 {
|
0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
|
||||||
0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
|
1: mnf({{ Fd.sf = -Fm.sf; }});
|
||||||
1: mnf({{ Fd.sf = -Fm.sf; }});
|
}
|
||||||
}
|
0x2: decode OPCODE_15 {
|
||||||
0x2: decode OPCODE_15 {
|
0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
|
||||||
0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
|
1: abs({{ Fd.sf = fabs(Fm.sf); }});
|
||||||
1: abs({{ Fd.sf = fabs(Fm.sf); }});
|
}
|
||||||
}
|
0x3: decode OPCODE_15 {
|
||||||
0x3: decode OPCODE_15 {
|
0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
|
||||||
0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
|
1: rnd({{ Fd.sf = rint(Fm.sf); }});
|
||||||
1: rnd({{ Fd.sf = rint(Fm.sf); }});
|
}
|
||||||
}
|
0x4: decode OPCODE_15 {
|
||||||
0x4: decode OPCODE_15 {
|
0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
|
||||||
0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
|
1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
|
||||||
1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
|
}
|
||||||
}
|
0x5: decode OPCODE_15 {
|
||||||
0x5: decode OPCODE_15 {
|
0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
|
||||||
0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
|
1: log({{ Fd.sf = log10(Fm.sf); }});
|
||||||
1: log({{ Fd.sf = log10(Fm.sf); }});
|
}
|
||||||
}
|
0x6: decode OPCODE_15 {
|
||||||
0x6: decode OPCODE_15 {
|
0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
|
||||||
0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
|
1: lgn({{ Fd.sf = log(Fm.sf); }});
|
||||||
1: lgn({{ Fd.sf = log(Fm.sf); }});
|
}
|
||||||
}
|
0x7: decode OPCODE_15 {
|
||||||
0x7: decode OPCODE_15 {
|
0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
|
||||||
0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
|
1: exp({{ Fd.sf = exp(Fm.sf); }});
|
||||||
1: exp({{ Fd.sf = exp(Fm.sf); }});
|
}
|
||||||
}
|
0x8: decode OPCODE_15 {
|
||||||
0x8: decode OPCODE_15 {
|
0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
|
||||||
0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
|
1: sin({{ Fd.sf = sin(Fm.sf); }});
|
||||||
1: sin({{ Fd.sf = sin(Fm.sf); }});
|
}
|
||||||
}
|
0x9: decode OPCODE_15 {
|
||||||
0x9: decode OPCODE_15 {
|
0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
|
||||||
0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
|
1: cos({{ Fd.sf = cos(Fm.sf); }});
|
||||||
1: cos({{ Fd.sf = cos(Fm.sf); }});
|
}
|
||||||
}
|
0xa: decode OPCODE_15 {
|
||||||
0xa: decode OPCODE_15 {
|
0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
|
||||||
0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
|
1: tan({{ Fd.sf = tan(Fm.sf); }});
|
||||||
1: tan({{ Fd.sf = tan(Fm.sf); }});
|
}
|
||||||
}
|
0xb: decode OPCODE_15 {
|
||||||
0xb: decode OPCODE_15 {
|
0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
|
||||||
0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
|
1: asn({{ Fd.sf = asin(Fm.sf); }});
|
||||||
1: asn({{ Fd.sf = asin(Fm.sf); }});
|
}
|
||||||
}
|
0xc: decode OPCODE_15 {
|
||||||
0xc: decode OPCODE_15 {
|
0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
|
||||||
0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
|
1: acs({{ Fd.sf = acos(Fm.sf); }});
|
||||||
1: acs({{ Fd.sf = acos(Fm.sf); }});
|
}
|
||||||
}
|
0xd: decode OPCODE_15 {
|
||||||
0xd: decode OPCODE_15 {
|
1: atn({{ Fd.sf = atan(Fm.sf); }});
|
||||||
1: atn({{ Fd.sf = atan(Fm.sf); }});
|
}
|
||||||
}
|
0xe: decode OPCODE_15 {
|
||||||
0xe: decode OPCODE_15 {
|
// Unnormalised Round
|
||||||
// Unnormalised Round
|
1: FailUnimpl::urd();
|
||||||
1: FailUnimpl::urd();
|
}
|
||||||
}
|
0xf: decode OPCODE_15 {
|
||||||
0xf: decode OPCODE_15 {
|
// Normalise
|
||||||
// Normalise
|
1: FailUnimpl::nrm();
|
||||||
1: FailUnimpl::nrm();
|
}
|
||||||
}
|
} // OPCODE_23_20
|
||||||
}
|
} // format FloatOp
|
||||||
1: decode OPCODE_15_12 {
|
} // CPNUM
|
||||||
|
1: decode CPNUM { // 27-24=1110,4 ==1
|
||||||
|
1: decode OPCODE_15_12 {
|
||||||
|
format FloatOp {
|
||||||
0xf: decode OPCODE_23_21 {
|
0xf: decode OPCODE_23_21 {
|
||||||
format FloatCmp {
|
format FloatCmp {
|
||||||
0x4: cmf({{ Fn.df }}, {{ Fm.df }});
|
0x4: cmf({{ Fn.df }}, {{ Fm.df }});
|
||||||
|
@ -417,36 +477,86 @@ format DataOp {
|
||||||
0x4: FailUnimpl::wfc();
|
0x4: FailUnimpl::wfc();
|
||||||
0x5: FailUnimpl::rfc();
|
0x5: FailUnimpl::rfc();
|
||||||
}
|
}
|
||||||
}
|
} // format FloatOp
|
||||||
}
|
}
|
||||||
}
|
0xa: decode MISC_OPCODE {
|
||||||
0xa: decode MISC_OPCODE {
|
0x1: decode MEDIA_OPCODE {
|
||||||
0x1: decode MEDIA_OPCODE {
|
0xf: decode RN {
|
||||||
0xf: decode RN {
|
0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
|
||||||
0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
|
0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
|
||||||
0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
|
0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
|
||||||
0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
|
}
|
||||||
|
0xe: decode RN {
|
||||||
|
0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
|
||||||
|
0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
|
||||||
|
0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
|
||||||
|
}
|
||||||
|
} // MEDIA_OPCODE (MISC_OPCODE 0x1)
|
||||||
|
} // MISC_OPCODE (CPNUM 0xA)
|
||||||
|
0xf: decode RN {
|
||||||
|
// Barrriers, Cache Maintence, NOPS
|
||||||
|
7: decode OPCODE_23_21 {
|
||||||
|
0: decode RM {
|
||||||
|
0: decode OPC2 {
|
||||||
|
4: decode OPCODE_20 {
|
||||||
|
0: PredOp::mcr_cp15_nop1({{ }}); // was wfi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1: WarnUnimpl::cp15_cache_maint();
|
||||||
|
4: WarnUnimpl::cp15_par();
|
||||||
|
5: decode OPC2 {
|
||||||
|
0,1: WarnUnimpl::cp15_cache_maint2();
|
||||||
|
4: PredOp::cp15_isb({{ ; }}, IsMemBarrier, IsSerializeBefore);
|
||||||
|
6,7: WarnUnimpl::cp15_bp_maint();
|
||||||
|
}
|
||||||
|
6: WarnUnimpl::cp15_cache_maint3();
|
||||||
|
8: WarnUnimpl::cp15_va_to_pa();
|
||||||
|
10: decode OPC2 {
|
||||||
|
1,2: WarnUnimpl::cp15_cache_maint3();
|
||||||
|
4: PredOp::cp15_dsb({{ ; }}, IsMemBarrier, IsSerializeBefore);
|
||||||
|
5: PredOp::cp15_dmb({{ ; }}, IsMemBarrier, IsSerializeBefore);
|
||||||
|
}
|
||||||
|
11: WarnUnimpl::cp15_cache_maint4();
|
||||||
|
13: decode OPC2 {
|
||||||
|
1: decode OPCODE_20 {
|
||||||
|
0: PredOp::mcr_cp15_nop2({{ }}); // was prefetch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
14: WarnUnimpl::cp15_cache_maint5();
|
||||||
|
} // RM
|
||||||
|
} // OPCODE_23_21 CR
|
||||||
|
|
||||||
|
// Thread ID and context ID registers
|
||||||
|
// Thread ID register needs cheaper access than miscreg
|
||||||
|
13: WarnUnimpl::mcr_mrc_cp15_c7();
|
||||||
|
|
||||||
|
// All the rest
|
||||||
|
default: decode OPCODE_20 {
|
||||||
|
0: PredOp::mcr_cp15({{
|
||||||
|
fault = setCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2);
|
||||||
|
}});
|
||||||
|
1: PredOp::mrc_cp15({{
|
||||||
|
fault = readCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2);
|
||||||
|
}});
|
||||||
}
|
}
|
||||||
0xe: decode RN {
|
} // RN
|
||||||
0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
|
} // CPNUM (OP4 == 1)
|
||||||
0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
|
} //OPCODE_4
|
||||||
0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
|
|
||||||
}
|
#if FULL_SYSTEM
|
||||||
}
|
1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
|
||||||
|
#else
|
||||||
|
1: PredOp::swi({{ if (testPredicate(CondCodes, condCode))
|
||||||
|
{
|
||||||
|
if (IMMED_23_0)
|
||||||
|
xc->syscall(IMMED_23_0);
|
||||||
|
else
|
||||||
|
xc->syscall(R7);
|
||||||
}
|
}
|
||||||
}
|
}});
|
||||||
format PredOp {
|
#endif // FULL_SYSTEM
|
||||||
// ARM System Call (SoftWare Interrupt)
|
} // OPCODE_24
|
||||||
1: swi({{ if (testPredicate(Cpsr, condCode))
|
|
||||||
{
|
|
||||||
if (IMMED_23_0)
|
|
||||||
xc->syscall(IMMED_23_0);
|
|
||||||
else
|
|
||||||
xc->syscall(R7);
|
|
||||||
}
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ def format Branch(code,*opt_flags) {{
|
||||||
else:
|
else:
|
||||||
inst_flags += ('IsCondControl', )
|
inst_flags += ('IsCondControl', )
|
||||||
|
|
||||||
icode = 'if (testPredicate(Cpsr, condCode)) {\n'
|
icode = 'if (testPredicate(CondCodes, condCode)) {\n'
|
||||||
icode += code
|
icode += code
|
||||||
icode += ' NPC = NPC + 4 + disp;\n'
|
icode += ' NPC = NPC + 4 + disp;\n'
|
||||||
icode += '} else {\n'
|
icode += '} else {\n'
|
||||||
|
@ -90,7 +90,7 @@ def format BranchExchange(code,*opt_flags) {{
|
||||||
|
|
||||||
#Condition code
|
#Condition code
|
||||||
|
|
||||||
icode = 'if (testPredicate(Cpsr, condCode)) {\n'
|
icode = 'if (testPredicate(CondCodes, condCode)) {\n'
|
||||||
icode += code
|
icode += code
|
||||||
icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
|
icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
|
||||||
icode += '} else {\n'
|
icode += '} else {\n'
|
||||||
|
|
|
@ -119,8 +119,8 @@ let {{
|
||||||
_ic = %(fReg1)s >= %(fReg2)s;
|
_ic = %(fReg1)s >= %(fReg2)s;
|
||||||
_iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
|
_iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
|
||||||
|
|
||||||
Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
||||||
(Cpsr & 0x0FFFFFFF);
|
(CondCodes & 0x0FFFFFFF);
|
||||||
'''
|
'''
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,18 @@ let {{
|
||||||
'predicate_test': predicateTest},
|
'predicate_test': predicateTest},
|
||||||
['IsMicroop'])
|
['IsMicroop'])
|
||||||
|
|
||||||
|
microLdrRetUopCode = '''
|
||||||
|
Ra = Mem;
|
||||||
|
Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true);
|
||||||
|
'''
|
||||||
|
microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
|
||||||
|
'MicroMemOp',
|
||||||
|
{'memacc_code': microLdrRetUopCode,
|
||||||
|
'ea_code':
|
||||||
|
'EA = Rb + (UP ? imm : -imm);',
|
||||||
|
'predicate_test': predicateTest},
|
||||||
|
['IsMicroop'])
|
||||||
|
|
||||||
microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
|
microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
|
||||||
'MicroMemOp',
|
'MicroMemOp',
|
||||||
{'memacc_code': 'Mem = Ra;',
|
{'memacc_code': 'Mem = Ra;',
|
||||||
|
@ -80,14 +92,19 @@ let {{
|
||||||
['IsMicroop'])
|
['IsMicroop'])
|
||||||
|
|
||||||
header_output = MicroMemDeclare.subst(microLdrUopIop) + \
|
header_output = MicroMemDeclare.subst(microLdrUopIop) + \
|
||||||
|
MicroMemDeclare.subst(microLdrRetUopIop) + \
|
||||||
MicroMemDeclare.subst(microStrUopIop)
|
MicroMemDeclare.subst(microStrUopIop)
|
||||||
decoder_output = MicroConstructor.subst(microLdrUopIop) + \
|
decoder_output = MicroConstructor.subst(microLdrUopIop) + \
|
||||||
|
MicroConstructor.subst(microLdrRetUopIop) + \
|
||||||
MicroConstructor.subst(microStrUopIop)
|
MicroConstructor.subst(microStrUopIop)
|
||||||
exec_output = LoadExecute.subst(microLdrUopIop) + \
|
exec_output = LoadExecute.subst(microLdrUopIop) + \
|
||||||
|
LoadExecute.subst(microLdrRetUopIop) + \
|
||||||
StoreExecute.subst(microStrUopIop) + \
|
StoreExecute.subst(microStrUopIop) + \
|
||||||
LoadInitiateAcc.subst(microLdrUopIop) + \
|
LoadInitiateAcc.subst(microLdrUopIop) + \
|
||||||
|
LoadInitiateAcc.subst(microLdrRetUopIop) + \
|
||||||
StoreInitiateAcc.subst(microStrUopIop) + \
|
StoreInitiateAcc.subst(microStrUopIop) + \
|
||||||
LoadCompleteAcc.subst(microLdrUopIop) + \
|
LoadCompleteAcc.subst(microLdrUopIop) + \
|
||||||
|
LoadCompleteAcc.subst(microLdrRetUopIop) + \
|
||||||
StoreCompleteAcc.subst(microStrUopIop)
|
StoreCompleteAcc.subst(microStrUopIop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -178,73 +195,64 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
|
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
|
||||||
{
|
{
|
||||||
%(constructor)s;
|
%(constructor)s;
|
||||||
uint32_t regs_to_handle = reglist;
|
uint32_t regs = reglist;
|
||||||
uint32_t start_addr = 0;
|
uint32_t addr = 0;
|
||||||
|
bool up = machInst.puswl.up;
|
||||||
|
|
||||||
switch (puswl)
|
if (!up)
|
||||||
{
|
addr = (ones << 2) - 4;
|
||||||
case 0x00: // stmda
|
|
||||||
case 0x01: // L ldmda_l
|
|
||||||
case 0x02: // W stmda_w
|
|
||||||
case 0x03: // WL ldmda_wl
|
|
||||||
start_addr = (ones << 2) - 4;
|
|
||||||
break;
|
|
||||||
case 0x08: // U stmia_u
|
|
||||||
case 0x09: // U L ldmia_ul
|
|
||||||
case 0x0a: // U W stmia
|
|
||||||
case 0x0b: // U WL ldmia
|
|
||||||
start_addr = 0;
|
|
||||||
break;
|
|
||||||
case 0x10: // P stmdb
|
|
||||||
case 0x11: // P L ldmdb
|
|
||||||
case 0x12: // P W stmdb
|
|
||||||
case 0x13: // P WL ldmdb
|
|
||||||
start_addr = (ones << 2); // U-bit is already 0 for subtract
|
|
||||||
break;
|
|
||||||
case 0x18: // PU stmib
|
|
||||||
case 0x19: // PU L ldmib
|
|
||||||
case 0x1a: // PU W stmib
|
|
||||||
case 0x1b: // PU WL ldmib
|
|
||||||
start_addr = 4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
panic("Unhandled Load/Store Multiple Instruction, "
|
|
||||||
"puswl = 0x%x", (unsigned) puswl);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add 0 to Rn and stick it in Raddr (register 17).
|
if (machInst.puswl.prepost)
|
||||||
|
addr += 4;
|
||||||
|
|
||||||
|
// Add 0 to Rn and stick it in ureg0.
|
||||||
// This is equivalent to a move.
|
// This is equivalent to a move.
|
||||||
microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
|
microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
|
||||||
|
|
||||||
unsigned j = 0;
|
unsigned reg = 0;
|
||||||
for (int i = 1; i < ones+1; i++) {
|
bool force_user = machInst.puswl.psruser & !OPCODE_15;
|
||||||
// Get next available bit for transfer
|
bool exception_ret = machInst.puswl.psruser & OPCODE_15;
|
||||||
while (! ( regs_to_handle & (1<<j)))
|
|
||||||
j++;
|
|
||||||
regs_to_handle &= ~(1<<j);
|
|
||||||
|
|
||||||
if (loadop)
|
for (int i = 1; i < ones + 1; i++) {
|
||||||
microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr);
|
// Find the next register.
|
||||||
else
|
while (!bits(regs, reg))
|
||||||
microOps[i] = new MicroStrUop(machInst, j, 17, start_addr);
|
reg++;
|
||||||
|
replaceBits(regs, reg, 0);
|
||||||
|
|
||||||
|
unsigned regIdx = reg;
|
||||||
|
if (force_user) {
|
||||||
|
regIdx = intRegForceUser(regIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (machInst.puswl.loadOp) {
|
||||||
|
if (reg == INTREG_PC && exception_ret) {
|
||||||
|
// This must be the exception return form of ldm.
|
||||||
|
microOps[i] =
|
||||||
|
new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
|
||||||
|
} else {
|
||||||
|
microOps[i] =
|
||||||
|
new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
microOps[i] =
|
||||||
|
new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
|
||||||
|
}
|
||||||
|
|
||||||
if (up)
|
if (up)
|
||||||
start_addr += 4;
|
addr += 4;
|
||||||
else
|
else
|
||||||
start_addr -= 4;
|
addr -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeback) {
|
StaticInstPtr &lastUop = microOps[numMicroops - 1];
|
||||||
|
if (machInst.puswl.writeback) {
|
||||||
if (up) {
|
if (up) {
|
||||||
microOps[numMicroops-1] =
|
lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
|
||||||
new MicroAddiUop(machInst, RN, RN, ones * 4);
|
|
||||||
} else {
|
} else {
|
||||||
microOps[numMicroops-1] =
|
lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
|
||||||
new MicroSubiUop(machInst, RN, RN, ones * 4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
microOps[numMicroops-1]->setLastMicroop();
|
lastUop->setLastMicroop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
@ -285,14 +293,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
if (writeback)
|
if (writeback)
|
||||||
{
|
{
|
||||||
if (up) {
|
if (up) {
|
||||||
microOps[numMicroops-1] =
|
microOps[numMicroops - 1] =
|
||||||
new MicroAddiUop(machInst, RN, RN, disp8);
|
new MicroAddiUop(machInst, RN, RN, disp8);
|
||||||
} else {
|
} else {
|
||||||
microOps[numMicroops-1] =
|
microOps[numMicroops - 1] =
|
||||||
new MicroSubiUop(machInst, RN, RN, disp8);
|
new MicroSubiUop(machInst, RN, RN, disp8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
microOps[numMicroops-1]->setLastMicroop();
|
microOps[numMicroops - 1]->setLastMicroop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
@ -316,14 +324,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
|
|
||||||
if (writeback) {
|
if (writeback) {
|
||||||
if (up) {
|
if (up) {
|
||||||
microOps[numMicroops-1] =
|
microOps[numMicroops - 1] =
|
||||||
new MicroAddiUop(machInst, RN, RN, disp8);
|
new MicroAddiUop(machInst, RN, RN, disp8);
|
||||||
} else {
|
} else {
|
||||||
microOps[numMicroops-1] =
|
microOps[numMicroops - 1] =
|
||||||
new MicroSubiUop(machInst, RN, RN, disp8);
|
new MicroSubiUop(machInst, RN, RN, disp8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
microOps[numMicroops-1]->setLastMicroop();
|
microOps[numMicroops - 1]->setLastMicroop();
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
let {{
|
let {{
|
||||||
predicateTest = 'testPredicate(Cpsr, condCode)'
|
predicateTest = 'testPredicate(CondCodes, condCode)'
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def template PredOpExecute {{
|
def template PredOpExecute {{
|
||||||
|
@ -81,32 +81,45 @@ def template DataImmDecode {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
let {{
|
let {{
|
||||||
|
|
||||||
|
calcCcCode = '''
|
||||||
|
if (%(canOverflow)s){
|
||||||
|
cprintf("canOverflow: %%d\\n", Rd < resTemp);
|
||||||
|
replaceBits(CondCodes, 27, Rd < resTemp);
|
||||||
|
} else {
|
||||||
|
uint16_t _ic, _iv, _iz, _in;
|
||||||
|
_in = (resTemp >> %(negBit)d) & 1;
|
||||||
|
_iz = (resTemp == 0);
|
||||||
|
_iv = %(ivValue)s & 1;
|
||||||
|
_ic = %(icValue)s & 1;
|
||||||
|
|
||||||
|
CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
||||||
|
(CondCodes & 0x0FFFFFFF);
|
||||||
|
|
||||||
calcCcCode = '''
|
DPRINTF(Arm, "in = %%d\\n", _in);
|
||||||
uint16_t _ic, _iv, _iz, _in;
|
DPRINTF(Arm, "iz = %%d\\n", _iz);
|
||||||
|
DPRINTF(Arm, "ic = %%d\\n", _ic);
|
||||||
_in = (resTemp >> 31) & 1;
|
DPRINTF(Arm, "iv = %%d\\n", _iv);
|
||||||
_iz = (resTemp == 0);
|
}
|
||||||
_iv = %(ivValue)s & 1;
|
|
||||||
_ic = %(icValue)s & 1;
|
|
||||||
|
|
||||||
Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
|
||||||
(Cpsr & 0x0FFFFFFF);
|
|
||||||
|
|
||||||
DPRINTF(Arm, "in = %%d\\n", _in);
|
|
||||||
DPRINTF(Arm, "iz = %%d\\n", _iz);
|
|
||||||
DPRINTF(Arm, "ic = %%d\\n", _ic);
|
|
||||||
DPRINTF(Arm, "iv = %%d\\n", _iv);
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
let {{
|
let {{
|
||||||
def getCcCode(flagtype):
|
def getCcCode(flagtype):
|
||||||
icReg = icImm = iv = ''
|
icReg = icImm = iv = ''
|
||||||
|
negBit = 31
|
||||||
|
canOverflow = 'false'
|
||||||
|
|
||||||
if flagtype == "none":
|
if flagtype == "none":
|
||||||
icReg = icImm = 'Cpsr<29:>'
|
icReg = icImm = 'CondCodes<29:>'
|
||||||
iv = 'Cpsr<28:>'
|
iv = 'CondCodes<28:>'
|
||||||
|
elif flagtype == "llbit":
|
||||||
|
icReg = icImm = 'CondCodes<29:>'
|
||||||
|
iv = 'CondCodes<28:>'
|
||||||
|
negBit = 63
|
||||||
|
elif flagtype == "overflow":
|
||||||
|
canOverflow = "true"
|
||||||
|
icReg = icImm = iv = '0'
|
||||||
elif flagtype == "add":
|
elif flagtype == "add":
|
||||||
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
|
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
|
||||||
iv = 'findOverflow(32, resTemp, Rn, op2)'
|
iv = 'findOverflow(32, resTemp, Rn, op2)'
|
||||||
|
@ -117,17 +130,32 @@ let {{
|
||||||
icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
|
icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
|
||||||
iv = 'findOverflow(32, resTemp, op2, ~Rn)'
|
iv = 'findOverflow(32, resTemp, op2, ~Rn)'
|
||||||
else:
|
else:
|
||||||
icReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)'
|
icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)'
|
||||||
icImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)'
|
icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
|
||||||
iv = 'Cpsr<28:>'
|
iv = 'CondCodes<28:>'
|
||||||
return (calcCcCode % {"icValue" : icReg, "ivValue" : iv},
|
return (calcCcCode % {"icValue" : icReg,
|
||||||
calcCcCode % {"icValue" : icImm, "ivValue" : iv})
|
"ivValue" : iv,
|
||||||
|
"negBit" : negBit,
|
||||||
|
"canOverflow" : canOverflow },
|
||||||
|
calcCcCode % {"icValue" : icImm,
|
||||||
|
"ivValue" : iv,
|
||||||
|
"negBit" : negBit,
|
||||||
|
"canOverflow" : canOverflow })
|
||||||
|
|
||||||
def getImmCcCode(flagtype):
|
def getImmCcCode(flagtype):
|
||||||
ivValue = icValue = ''
|
ivValue = icValue = ''
|
||||||
|
negBit = 31
|
||||||
|
canOverflow = 'false'
|
||||||
if flagtype == "none":
|
if flagtype == "none":
|
||||||
icValue = 'Cpsr<29:>'
|
icValue = 'CondCodes<29:>'
|
||||||
ivValue = 'Cpsr<28:>'
|
ivValue = 'CondCodes<28:>'
|
||||||
|
elif flagtype == "llbit":
|
||||||
|
icValue = 'CondCodes<29:>'
|
||||||
|
ivValue = 'CondCodes<28:>'
|
||||||
|
negBit = 63
|
||||||
|
elif flagtype == "overflow":
|
||||||
|
icVaule = ivValue = '0'
|
||||||
|
canOverflow = "true"
|
||||||
elif flagtype == "add":
|
elif flagtype == "add":
|
||||||
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
|
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
|
||||||
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
|
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
|
||||||
|
@ -138,18 +166,18 @@ let {{
|
||||||
icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)'
|
icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)'
|
||||||
ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
|
ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
|
||||||
else:
|
else:
|
||||||
icValue = '(rotate ? rotated_carry:Cpsr<29:>)'
|
icValue = '(rotate ? rotated_carry:CondCodes<29:>)'
|
||||||
ivValue = 'Cpsr<28:>'
|
ivValue = 'CondCodes<28:>'
|
||||||
return calcCcCode % vars()
|
return calcCcCode % vars()
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format DataOp(code, flagtype = logic) {{
|
def format DataOp(code, flagtype = logic) {{
|
||||||
(regCcCode, immCcCode) = getCcCode(flagtype)
|
(regCcCode, immCcCode) = getCcCode(flagtype)
|
||||||
regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
|
regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>,
|
||||||
shift, Cpsr<29:0>);
|
shift, CondCodes<29:>);
|
||||||
op2 = op2;''' + code
|
op2 = op2;''' + code
|
||||||
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
|
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
|
||||||
shift, Cpsr<29:0>);
|
shift, CondCodes<29:>);
|
||||||
op2 = op2;''' + code
|
op2 = op2;''' + code
|
||||||
regIop = InstObjParams(name, Name, 'PredIntOp',
|
regIop = InstObjParams(name, Name, 'PredIntOp',
|
||||||
{"code": regCode,
|
{"code": regCode,
|
||||||
|
|
|
@ -115,7 +115,7 @@ output exec {{
|
||||||
panic("attempt to execute unimplemented instruction '%s' "
|
panic("attempt to execute unimplemented instruction '%s' "
|
||||||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||||||
inst2string(machInst));
|
inst2string(machInst));
|
||||||
return new UnimplementedOpcodeFault;
|
return new UnimpFault("Unimplemented Instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
|
|
|
@ -74,7 +74,7 @@ output exec {{
|
||||||
{
|
{
|
||||||
panic("attempt to execute unknown instruction "
|
panic("attempt to execute unknown instruction "
|
||||||
"(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
|
"(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
|
||||||
return new UnimplementedOpcodeFault;
|
return new UnimpFault("Unimplemented Instruction");
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,10 @@ let {{
|
||||||
# Generic substitutions for Arm instructions
|
# Generic substitutions for Arm instructions
|
||||||
def ArmGenericCodeSubs(code):
|
def ArmGenericCodeSubs(code):
|
||||||
# Substitute in the shifted portion of operations
|
# Substitute in the shifted portion of operations
|
||||||
new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code)
|
new_code = re.sub(r'Rm_Imm',
|
||||||
new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code)
|
'shift_rm_imm(Rm, shift_size, shift, CondCodes<29:>)', code)
|
||||||
|
new_code = re.sub(r'Rm_Rs',
|
||||||
|
'shift_rm_rs(Rm, Rs, shift, CondCodes<29:>)', new_code)
|
||||||
return new_code
|
return new_code
|
||||||
|
|
||||||
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||||
|
|
|
@ -58,15 +58,16 @@ def operands {{
|
||||||
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
|
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
|
||||||
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
||||||
'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
|
'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
|
||||||
|
'R0': ('IntReg', 'uw', '0', 'IsInteger', 0),
|
||||||
|
|
||||||
#Destination register for load/store double instructions
|
#Destination register for load/store double instructions
|
||||||
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
||||||
'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite),
|
'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite),
|
||||||
|
|
||||||
'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6),
|
'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7),
|
||||||
'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7),
|
'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8),
|
||||||
'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8),
|
'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9),
|
||||||
'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
|
'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', 'IsInteger', 10),
|
||||||
|
|
||||||
#Register fields for microops
|
#Register fields for microops
|
||||||
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite),
|
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite),
|
||||||
|
@ -80,12 +81,13 @@ def operands {{
|
||||||
#Memory Operand
|
#Memory Operand
|
||||||
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30),
|
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30),
|
||||||
|
|
||||||
'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40),
|
'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', (None, None, 'IsControl'), 40),
|
||||||
'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41),
|
'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', (None, None, 'IsControl'), 41),
|
||||||
'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42),
|
'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', (None, None, 'IsControl'), 42),
|
||||||
'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43),
|
'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', (None, None, 'IsControl'), 43),
|
||||||
'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44),
|
'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', (None, None, 'IsControl'), 44),
|
||||||
'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45),
|
'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', (None, None, 'IsControl'), 45),
|
||||||
'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46)
|
'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50),
|
||||||
|
'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51)
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -104,6 +104,8 @@ namespace ArmISA
|
||||||
const int WordBytes = 4;
|
const int WordBytes = 4;
|
||||||
const int HalfwordBytes = 2;
|
const int HalfwordBytes = 2;
|
||||||
const int ByteBytes = 1;
|
const int ByteBytes = 1;
|
||||||
|
|
||||||
|
const uint32_t HighVecs = 0xFFFF0000;
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace ArmISA;
|
using namespace ArmISA;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,43 +24,34 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Gabe Black
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#ifndef __ARCH_ARM_KERNEL_STATS_HH__
|
||||||
* TypeAST.C
|
#define __ARCH_ARM_KERNEL_STATS_HH__
|
||||||
*
|
|
||||||
* Description: See TypeAST.hh
|
|
||||||
*
|
|
||||||
* $Id: TypeAST.C,v 3.1 2003/03/22 15:15:16 xu Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mem/slicc/ast/TypeAST.hh"
|
#include <map>
|
||||||
|
#include <stack>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
TypeAST::TypeAST(string* ident_ptr)
|
#include "kern/kernel_stats.hh"
|
||||||
: AST()
|
|
||||||
|
namespace ArmISA {
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num };
|
||||||
|
extern const char *modestr[];
|
||||||
|
|
||||||
|
class Statistics : public ::Kernel::Statistics
|
||||||
{
|
{
|
||||||
m_ident_ptr = ident_ptr;
|
public:
|
||||||
}
|
Statistics(System *system) : ::Kernel::Statistics(system)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
TypeAST::~TypeAST()
|
} /* end namespace ArmISA::Kernel */
|
||||||
{
|
} /* end namespace ArmISA */
|
||||||
delete m_ident_ptr;
|
|
||||||
|
|
||||||
}
|
#endif // __ARCH_ARM_KERNEL_STATS_HH__
|
||||||
|
|
||||||
string TypeAST::toString() const
|
|
||||||
{
|
|
||||||
return *m_ident_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type* TypeAST::lookupType() const
|
|
||||||
{
|
|
||||||
Type* type_ptr = g_sym_table.getType(*m_ident_ptr);
|
|
||||||
if (type_ptr != NULL) {
|
|
||||||
return type_ptr;
|
|
||||||
} else {
|
|
||||||
error("Type '" + *m_ident_ptr + "' not declared.");
|
|
||||||
}
|
|
||||||
return NULL; // Not reached
|
|
||||||
}
|
|
|
@ -86,6 +86,7 @@ class ArmLinux : public Linux
|
||||||
static const unsigned TIOCISATTY_ = 0x2000745e;
|
static const unsigned TIOCISATTY_ = 0x2000745e;
|
||||||
static const unsigned TIOCGETS_ = 0x402c7413;
|
static const unsigned TIOCGETS_ = 0x402c7413;
|
||||||
static const unsigned TIOCGETA_ = 0x40127417;
|
static const unsigned TIOCGETA_ = 0x40127417;
|
||||||
|
static const unsigned TCSETAW_ = 0x5407; // 2.6.15 kernel
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// For table().
|
/// For table().
|
||||||
|
@ -147,6 +148,21 @@ class ArmLinux : public Linux
|
||||||
uint64_t st_ino;
|
uint64_t st_ino;
|
||||||
} tgt_stat64;
|
} tgt_stat64;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t uptime; /* Seconds since boot */
|
||||||
|
uint32_t loads[3]; /* 1, 5, and 15 minute load averages */
|
||||||
|
uint32_t totalram; /* Total usable main memory size */
|
||||||
|
uint32_t freeram; /* Available memory size */
|
||||||
|
uint32_t sharedram; /* Amount of shared memory */
|
||||||
|
uint32_t bufferram; /* Memory used by buffers */
|
||||||
|
uint32_t totalswap; /* Total swap space size */
|
||||||
|
uint32_t freeswap; /* swap space still available */
|
||||||
|
uint16_t procs; /* Number of current processes */
|
||||||
|
uint32_t totalhigh; /* Total high memory size */
|
||||||
|
uint32_t freehigh; /* Available high memory size */
|
||||||
|
uint32_t mem_unit; /* Memory unit size in bytes */
|
||||||
|
} tgt_sysinfo;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,8 @@ static SyscallReturn
|
||||||
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
|
int index = 0;
|
||||||
|
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
|
||||||
|
|
||||||
strcpy(name->sysname, "Linux");
|
strcpy(name->sysname, "Linux");
|
||||||
strcpy(name->nodename, "m5.eecs.umich.edu");
|
strcpy(name->nodename, "m5.eecs.umich.edu");
|
||||||
|
@ -179,7 +180,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
|
||||||
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
|
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
|
||||||
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
|
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
|
||||||
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
|
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
|
||||||
/* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
|
/* 116 */ SyscallDesc("sysinfo", sysinfoFunc<ArmLinux>),
|
||||||
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
|
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
|
||||||
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
|
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
|
||||||
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
|
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
|
||||||
|
@ -417,7 +418,8 @@ static SyscallReturn
|
||||||
setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
uint32_t tlsPtr = process->getSyscallArg(tc, 0);
|
int index = 0;
|
||||||
|
uint32_t tlsPtr = process->getSyscallArg(tc, index);
|
||||||
|
|
||||||
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
||||||
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
|
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
|
||||||
|
@ -511,12 +513,12 @@ ArmLinuxProcess::startup()
|
||||||
}
|
}
|
||||||
|
|
||||||
ArmISA::IntReg
|
ArmISA::IntReg
|
||||||
ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int i)
|
ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int &i)
|
||||||
{
|
{
|
||||||
// Linux apparently allows more parameter than the ABI says it should.
|
// Linux apparently allows more parameter than the ABI says it should.
|
||||||
// This limit may need to be increased even further.
|
// This limit may need to be increased even further.
|
||||||
assert(i < 6);
|
assert(i < 6);
|
||||||
return tc->readIntReg(ArgumentReg0 + i);
|
return tc->readIntReg(ArgumentReg0 + i++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -44,7 +44,7 @@ class ArmLinuxProcess : public ArmLiveProcess
|
||||||
|
|
||||||
void startup();
|
void startup();
|
||||||
|
|
||||||
ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i);
|
ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
||||||
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
|
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
|
||||||
|
|
||||||
/// The target system's hostname.
|
/// The target system's hostname.
|
||||||
|
|
|
@ -55,23 +55,24 @@ namespace ArmISA
|
||||||
|
|
||||||
enum MiscRegIndex {
|
enum MiscRegIndex {
|
||||||
MISCREG_CPSR = 0,
|
MISCREG_CPSR = 0,
|
||||||
MISCREG_SPSR,
|
MISCREG_SPSR,
|
||||||
MISCREG_SPSR_FIQ,
|
MISCREG_SPSR_FIQ,
|
||||||
MISCREG_SPSR_IRQ,
|
MISCREG_SPSR_IRQ,
|
||||||
MISCREG_SPSR_SVC,
|
MISCREG_SPSR_SVC,
|
||||||
|
MISCREG_SPSR_MON,
|
||||||
MISCREG_SPSR_UND,
|
MISCREG_SPSR_UND,
|
||||||
MISCREG_SPSR_ABT,
|
MISCREG_SPSR_ABT,
|
||||||
MISCREG_FPSR,
|
MISCREG_FPSR,
|
||||||
MISCREG_FPSID,
|
MISCREG_FPSID,
|
||||||
MISCREG_FPSCR,
|
MISCREG_FPSCR,
|
||||||
MISCREG_FPEXC,
|
MISCREG_FPEXC,
|
||||||
NUM_MISCREGS
|
MISCREG_SCTLR,
|
||||||
|
NUM_MISCREGS
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * const miscRegName[NUM_MISCREGS] = {
|
const char * const miscRegName[NUM_MISCREGS] = {
|
||||||
"cpsr",
|
"cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und",
|
||||||
"spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", "spsr_abt",
|
"spsr_abt", "fpsr", "fpsid", "fpscr", "fpexc", "sctlr"
|
||||||
"fpsr"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BitUnion32(CPSR)
|
BitUnion32(CPSR)
|
||||||
|
@ -80,8 +81,10 @@ namespace ArmISA
|
||||||
Bitfield<29> c;
|
Bitfield<29> c;
|
||||||
Bitfield<28> v;
|
Bitfield<28> v;
|
||||||
Bitfield<27> q;
|
Bitfield<27> q;
|
||||||
|
Bitfield<26,25> it1;
|
||||||
Bitfield<24> j;
|
Bitfield<24> j;
|
||||||
Bitfield<19, 16> ge;
|
Bitfield<19, 16> ge;
|
||||||
|
Bitfield<15,10> it2;
|
||||||
Bitfield<9> e;
|
Bitfield<9> e;
|
||||||
Bitfield<8> a;
|
Bitfield<8> a;
|
||||||
Bitfield<7> i;
|
Bitfield<7> i;
|
||||||
|
@ -89,6 +92,35 @@ namespace ArmISA
|
||||||
Bitfield<5> t;
|
Bitfield<5> t;
|
||||||
Bitfield<4, 0> mode;
|
Bitfield<4, 0> mode;
|
||||||
EndBitUnion(CPSR)
|
EndBitUnion(CPSR)
|
||||||
|
|
||||||
|
// This mask selects bits of the CPSR that actually go in the CondCodes
|
||||||
|
// integer register to allow renaming.
|
||||||
|
static const uint32_t CondCodesMask = 0xF80F0000;
|
||||||
|
|
||||||
|
BitUnion32(SCTLR)
|
||||||
|
Bitfield<30> te; // Thumb Exception Enable
|
||||||
|
Bitfield<29> afe; // Access flag enable
|
||||||
|
Bitfield<28> tre; // TEX Remap bit
|
||||||
|
Bitfield<27> nmfi;// Non-maskable fast interrupts enable
|
||||||
|
Bitfield<25> ee; // Exception Endianness bit
|
||||||
|
Bitfield<24> ve; // Interrupt vectors enable
|
||||||
|
Bitfield<23> rao1;// Read as one
|
||||||
|
Bitfield<22> u; // Alignment (now unused)
|
||||||
|
Bitfield<21> fi; // Fast interrupts configuration enable
|
||||||
|
Bitfield<18> rao2;// Read as one
|
||||||
|
Bitfield<17> ha; // Hardware access flag enable
|
||||||
|
Bitfield<16> rao3;// Read as one
|
||||||
|
Bitfield<14> rr; // Round robin cache replacement
|
||||||
|
Bitfield<13> v; // Base address for exception vectors
|
||||||
|
Bitfield<12> i; // instruction cache enable
|
||||||
|
Bitfield<11> z; // branch prediction enable bit
|
||||||
|
Bitfield<10> sw; // Enable swp/swpb
|
||||||
|
Bitfield<6,3> rao4;// Read as one
|
||||||
|
Bitfield<7> b; // Endianness support (unused)
|
||||||
|
Bitfield<2> c; // Cache enable bit
|
||||||
|
Bitfield<1> a; // Alignment fault checking
|
||||||
|
Bitfield<0> m; // MMU enable bit
|
||||||
|
EndBitUnion(SCTLR)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ARCH_ARM_MISCREGS_HH__
|
#endif // __ARCH_ARM_MISCREGS_HH__
|
||||||
|
|
|
@ -97,7 +97,8 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
|
||||||
changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
|
changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
|
||||||
|
|
||||||
//CPSR
|
//CPSR
|
||||||
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR);
|
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
|
||||||
|
tc->readIntReg(INTREG_CONDCODES);
|
||||||
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
|
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -324,10 +324,10 @@ ArmLiveProcess::argsInit(int intSize, int pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
ArmISA::IntReg
|
ArmISA::IntReg
|
||||||
ArmLiveProcess::getSyscallArg(ThreadContext *tc, int i)
|
ArmLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
|
||||||
{
|
{
|
||||||
assert(i < 4);
|
assert(i < 4);
|
||||||
return tc->readIntReg(ArgumentReg0 + i);
|
return tc->readIntReg(ArgumentReg0 + i++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -53,7 +53,7 @@ class ArmLiveProcess : public LiveProcess
|
||||||
public:
|
public:
|
||||||
void argsInit(int intSize, int pageSize);
|
void argsInit(int intSize, int pageSize);
|
||||||
|
|
||||||
ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i);
|
ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
||||||
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
|
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
|
||||||
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
|
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define __ARCH_ARM_REGISTERS_HH__
|
#define __ARCH_ARM_REGISTERS_HH__
|
||||||
|
|
||||||
#include "arch/arm/max_inst_regs.hh"
|
#include "arch/arm/max_inst_regs.hh"
|
||||||
|
#include "arch/arm/intregs.hh"
|
||||||
#include "arch/arm/miscregs.hh"
|
#include "arch/arm/miscregs.hh"
|
||||||
|
|
||||||
namespace ArmISA {
|
namespace ArmISA {
|
||||||
|
@ -51,13 +52,11 @@ typedef float FloatReg;
|
||||||
typedef uint64_t MiscReg;
|
typedef uint64_t MiscReg;
|
||||||
|
|
||||||
// Constants Related to the number of registers
|
// Constants Related to the number of registers
|
||||||
const int NumIntArchRegs = 16;
|
const int NumIntArchRegs = NUM_ARCH_INTREGS;
|
||||||
const int NumIntSpecialRegs = 19;
|
|
||||||
const int NumFloatArchRegs = 16;
|
const int NumFloatArchRegs = 16;
|
||||||
const int NumFloatSpecialRegs = 5;
|
const int NumFloatSpecialRegs = 5;
|
||||||
const int NumInternalProcRegs = 0;
|
|
||||||
|
|
||||||
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
|
const int NumIntRegs = NUM_INTREGS;
|
||||||
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
|
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
|
||||||
|
|
||||||
const int NumMiscRegs = NUM_MISCREGS;
|
const int NumMiscRegs = NUM_MISCREGS;
|
||||||
|
@ -72,12 +71,11 @@ const int ArgumentReg1 = 1;
|
||||||
const int ArgumentReg2 = 2;
|
const int ArgumentReg2 = 2;
|
||||||
const int ArgumentReg3 = 3;
|
const int ArgumentReg3 = 3;
|
||||||
const int FramePointerReg = 11;
|
const int FramePointerReg = 11;
|
||||||
const int StackPointerReg = 13;
|
const int StackPointerReg = INTREG_SP;
|
||||||
const int ReturnAddressReg = 14;
|
const int ReturnAddressReg = INTREG_LR;
|
||||||
const int PCReg = 15;
|
const int PCReg = INTREG_PC;
|
||||||
|
|
||||||
const int ZeroReg = NumIntArchRegs;
|
const int ZeroReg = INTREG_ZERO;
|
||||||
const int AddrReg = ZeroReg + 1; // Used to generate address for uops
|
|
||||||
|
|
||||||
const int SyscallNumReg = ReturnValueReg;
|
const int SyscallNumReg = ReturnValueReg;
|
||||||
const int SyscallPseudoReturnReg = ReturnValueReg;
|
const int SyscallPseudoReturnReg = ReturnValueReg;
|
||||||
|
@ -116,35 +114,6 @@ enum FCSRFields {
|
||||||
Cause_Field = 11
|
Cause_Field = 11
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MiscIntRegNums {
|
|
||||||
zero_reg = NumIntArchRegs,
|
|
||||||
addr_reg,
|
|
||||||
|
|
||||||
rhi,
|
|
||||||
rlo,
|
|
||||||
|
|
||||||
r8_fiq, /* FIQ mode register bank */
|
|
||||||
r9_fiq,
|
|
||||||
r10_fiq,
|
|
||||||
r11_fiq,
|
|
||||||
r12_fiq,
|
|
||||||
|
|
||||||
r13_fiq, /* FIQ mode SP and LR */
|
|
||||||
r14_fiq,
|
|
||||||
|
|
||||||
r13_irq, /* IRQ mode SP and LR */
|
|
||||||
r14_irq,
|
|
||||||
|
|
||||||
r13_svc, /* SVC mode SP and LR */
|
|
||||||
r14_svc,
|
|
||||||
|
|
||||||
r13_undef, /* UNDEF mode SP and LR */
|
|
||||||
r14_undef,
|
|
||||||
|
|
||||||
r13_abt, /* ABT mode SP and LR */
|
|
||||||
r14_abt
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ArmISA
|
} // namespace ArmISA
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
151
src/arch/arm/stacktrace.cc
Normal file
151
src/arch/arm/stacktrace.cc
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "arch/arm/isa_traits.hh"
|
||||||
|
#include "arch/arm/stacktrace.hh"
|
||||||
|
#include "arch/arm/vtophys.hh"
|
||||||
|
#include "base/bitfield.hh"
|
||||||
|
#include "base/trace.hh"
|
||||||
|
#include "cpu/base.hh"
|
||||||
|
#include "cpu/thread_context.hh"
|
||||||
|
#include "sim/system.hh"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
namespace ArmISA
|
||||||
|
{
|
||||||
|
ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
||||||
|
: tc(_tc)
|
||||||
|
{
|
||||||
|
Addr addr = 0;
|
||||||
|
|
||||||
|
VirtualPort *vp;
|
||||||
|
|
||||||
|
vp = tc->getVirtPort();
|
||||||
|
|
||||||
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||||
|
panic("thread info not compiled into kernel\n");
|
||||||
|
thread_info_size = vp->readGtoH<int32_t>(addr);
|
||||||
|
|
||||||
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
|
||||||
|
panic("thread info not compiled into kernel\n");
|
||||||
|
task_struct_size = vp->readGtoH<int32_t>(addr);
|
||||||
|
|
||||||
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
|
||||||
|
panic("thread info not compiled into kernel\n");
|
||||||
|
task_off = vp->readGtoH<int32_t>(addr);
|
||||||
|
|
||||||
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
|
||||||
|
panic("thread info not compiled into kernel\n");
|
||||||
|
pid_off = vp->readGtoH<int32_t>(addr);
|
||||||
|
|
||||||
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
|
||||||
|
panic("thread info not compiled into kernel\n");
|
||||||
|
name_off = vp->readGtoH<int32_t>(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr
|
||||||
|
ProcessInfo::task(Addr ksp) const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ProcessInfo::pid(Addr ksp) const
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
ProcessInfo::name(Addr ksp) const
|
||||||
|
{
|
||||||
|
return "Implement me";
|
||||||
|
}
|
||||||
|
|
||||||
|
StackTrace::StackTrace()
|
||||||
|
: tc(0), stack(64)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
|
||||||
|
: tc(0), stack(64)
|
||||||
|
{
|
||||||
|
trace(_tc, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
StackTrace::~StackTrace()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StackTrace::trace(ThreadContext *_tc, bool is_call)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StackTrace::isEntry(Addr addr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StackTrace::decodeStack(MachInst inst, int &disp)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StackTrace::decodeSave(MachInst inst, int ®, int &disp)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode the function prologue for the function we're in, and note
|
||||||
|
* which registers are stored where, and how large the stack frame is.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
|
||||||
|
int &size, Addr &ra)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TRACING_ON
|
||||||
|
void
|
||||||
|
StackTrace::dump()
|
||||||
|
{
|
||||||
|
DPRINTFN("------ Stack ------\n");
|
||||||
|
|
||||||
|
DPRINTFN(" Not implemented\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005 The Regents of The University of Michigan
|
* Copyright (c) 2005 The Regents of The University of Michigan
|
||||||
* Copyright (c) 2007-2008 The Florida State University
|
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -26,8 +25,7 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Authors: Ali Saidi
|
* Authors: Nathan Binkert
|
||||||
* Stephen Hines
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ARCH_ARM_STACKTRACE_HH__
|
#ifndef __ARCH_ARM_STACKTRACE_HH__
|
||||||
|
@ -37,11 +35,11 @@
|
||||||
#include "cpu/static_inst.hh"
|
#include "cpu/static_inst.hh"
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
class StackTrace;
|
|
||||||
|
|
||||||
namespace ArmISA
|
namespace ArmISA
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class StackTrace;
|
||||||
|
|
||||||
class ProcessInfo
|
class ProcessInfo
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -64,7 +62,7 @@ class ProcessInfo
|
||||||
class StackTrace
|
class StackTrace
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
typedef TheISA::MachInst MachInst;
|
typedef ArmISA::MachInst MachInst;
|
||||||
private:
|
private:
|
||||||
ThreadContext *tc;
|
ThreadContext *tc;
|
||||||
std::vector<Addr> stack;
|
std::vector<Addr> stack;
|
||||||
|
@ -94,10 +92,6 @@ class StackTrace
|
||||||
public:
|
public:
|
||||||
const std::vector<Addr> &getstack() const { return stack; }
|
const std::vector<Addr> &getstack() const { return stack; }
|
||||||
|
|
||||||
static const int user = 1;
|
|
||||||
static const int console = 2;
|
|
||||||
static const int unknown = 3;
|
|
||||||
|
|
||||||
#if TRACING_ON
|
#if TRACING_ON
|
||||||
private:
|
private:
|
||||||
void dump();
|
void dump();
|
||||||
|
@ -123,6 +117,6 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // Namespace ArmISA
|
||||||
|
|
||||||
#endif // __ARCH_ARM_STACKTRACE_HH__
|
#endif // __ARCH_ARM_STACKTRACE_HH__
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2002-2006 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,20 +24,28 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Ali Saidi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#include "arch/arm/system.hh"
|
||||||
* TypeFieldAST.C
|
|
||||||
*
|
|
||||||
* Description: See TypeFieldAST.hh
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mem/slicc/ast/TypeFieldAST.hh"
|
|
||||||
|
|
||||||
TypeFieldAST::TypeFieldAST(PairListAST* pairs_ptr)
|
using namespace LittleEndianGuest;
|
||||||
: AST(pairs_ptr->getPairs()) {
|
|
||||||
|
ArmSystem::ArmSystem(Params *p)
|
||||||
|
: System(p)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArmSystem::~ArmSystem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ArmSystem *
|
||||||
|
ArmSystemParams::create()
|
||||||
|
{
|
||||||
|
return new ArmSystem(this);
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,36 +24,33 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Ali Saidi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#ifndef __ARCH_ARM_SYSTEM_HH__
|
||||||
* StatementAST.C
|
#define __ARCH_ARM_SYSTEM_HH__
|
||||||
*
|
|
||||||
* Description: See StatementAST.hh
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mem/slicc/ast/StatementAST.hh"
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
static int indentation_depth = 1;
|
#include "params/ArmSystem.hh"
|
||||||
|
#include "sim/sim_object.hh"
|
||||||
|
#include "sim/system.hh"
|
||||||
|
|
||||||
void inc_indent()
|
class ArmSystem : public System
|
||||||
{
|
{
|
||||||
indentation_depth++;
|
public:
|
||||||
}
|
typedef ArmSystemParams Params;
|
||||||
|
ArmSystem(Params *p);
|
||||||
|
~ArmSystem();
|
||||||
|
|
||||||
|
virtual Addr fixFuncEventAddr(Addr addr)
|
||||||
|
{
|
||||||
|
//XXX This may eventually have to do something useful.
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void dec_indent()
|
#endif
|
||||||
{
|
|
||||||
indentation_depth--;
|
|
||||||
}
|
|
||||||
|
|
||||||
string indent_str()
|
|
||||||
{
|
|
||||||
string temp;
|
|
||||||
for(int i=0; i<indentation_depth; i++) {
|
|
||||||
temp += " ";
|
|
||||||
}
|
|
||||||
return temp;
|
|
||||||
}
|
|
|
@ -287,7 +287,15 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
|
||||||
|
|
||||||
return NoFault;
|
return NoFault;
|
||||||
#else
|
#else
|
||||||
fatal("translate atomic not yet implemented\n");
|
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
|
||||||
|
if (!sctlr.m) {
|
||||||
|
req->setPaddr(req->getVaddr());
|
||||||
|
return NoFault;
|
||||||
|
}
|
||||||
|
panic("MMU translation not implemented\n");
|
||||||
|
return NoFault;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,16 +45,20 @@ namespace ArmISA
|
||||||
|
|
||||||
// All the different types of opcode fields.
|
// All the different types of opcode fields.
|
||||||
Bitfield<27, 25> encoding;
|
Bitfield<27, 25> encoding;
|
||||||
|
Bitfield<25> useImm;
|
||||||
Bitfield<24, 21> opcode;
|
Bitfield<24, 21> opcode;
|
||||||
Bitfield<24, 20> mediaOpcode;
|
Bitfield<24, 20> mediaOpcode;
|
||||||
Bitfield<24> opcode24;
|
Bitfield<24> opcode24;
|
||||||
Bitfield<23, 20> opcode23_20;
|
Bitfield<23, 20> opcode23_20;
|
||||||
Bitfield<23, 21> opcode23_21;
|
Bitfield<23, 21> opcode23_21;
|
||||||
|
Bitfield<20> opcode20;
|
||||||
Bitfield<22> opcode22;
|
Bitfield<22> opcode22;
|
||||||
Bitfield<19> opcode19;
|
Bitfield<19> opcode19;
|
||||||
|
Bitfield<18> opcode18;
|
||||||
Bitfield<15, 12> opcode15_12;
|
Bitfield<15, 12> opcode15_12;
|
||||||
Bitfield<15> opcode15;
|
Bitfield<15> opcode15;
|
||||||
Bitfield<7, 4> miscOpcode;
|
Bitfield<7, 4> miscOpcode;
|
||||||
|
Bitfield<7,5> opc2;
|
||||||
Bitfield<7> opcode7;
|
Bitfield<7> opcode7;
|
||||||
Bitfield<4> opcode4;
|
Bitfield<4> opcode4;
|
||||||
|
|
||||||
|
@ -156,6 +160,7 @@ namespace ArmISA
|
||||||
MODE_FIQ = 17,
|
MODE_FIQ = 17,
|
||||||
MODE_IRQ = 18,
|
MODE_IRQ = 18,
|
||||||
MODE_SVC = 19,
|
MODE_SVC = 19,
|
||||||
|
MODE_MON = 22,
|
||||||
MODE_ABORT = 23,
|
MODE_ABORT = 23,
|
||||||
MODE_UNDEFINED = 27,
|
MODE_UNDEFINED = 27,
|
||||||
MODE_SYSTEM = 31
|
MODE_SYSTEM = 31
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2009 ARM Limited
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,49 +24,53 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Ali Saidi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* ExprStatementAST.C
|
|
||||||
*
|
|
||||||
* Description: See ExprStatementAST.hh
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mem/slicc/ast/ExprStatementAST.hh"
|
#include "arch/arm/faults.hh"
|
||||||
|
#include "arch/arm/utility.hh"
|
||||||
|
#include "cpu/thread_context.hh"
|
||||||
|
|
||||||
ExprStatementAST::ExprStatementAST(ExprAST* expr_ptr)
|
|
||||||
: StatementAST()
|
namespace ArmISA {
|
||||||
|
|
||||||
|
void
|
||||||
|
initCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
m_expr_ptr = expr_ptr;
|
// Reset CP15?? What does that mean -- ali
|
||||||
|
|
||||||
|
// FPEXC.EN = 0
|
||||||
|
|
||||||
|
static Fault reset = new Reset;
|
||||||
|
if (cpuId == 0)
|
||||||
|
reset->invoke(tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprStatementAST::~ExprStatementAST()
|
uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
|
||||||
{
|
#if FULL_SYSTEM
|
||||||
delete m_expr_ptr;
|
panic("getArgument() not implemented for ARM!\n");
|
||||||
|
#else
|
||||||
|
panic("getArgument() only implemented for FULL_SYSTEM\n");
|
||||||
|
M5_DUMMY_RETURN
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprStatementAST::generate(string& code, Type* return_type_ptr) const
|
Fault
|
||||||
|
setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2)
|
||||||
{
|
{
|
||||||
code += indent_str();
|
return new UnimpFault(csprintf("MCR CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n",
|
||||||
Type* actual_type_ptr = m_expr_ptr->generate(code);
|
CRn, opc1, CRm, opc2));
|
||||||
code += ";\n";
|
|
||||||
|
|
||||||
// The return type must be void
|
|
||||||
Type* expected_type_ptr = g_sym_table.getType("void");
|
|
||||||
if (expected_type_ptr != actual_type_ptr) {
|
|
||||||
m_expr_ptr->error("Non-void return must not be ignored, return type is '" + actual_type_ptr->toString() + "'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprStatementAST::findResources(Map<Var*, string>& resource_list) const
|
Fault
|
||||||
|
readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2)
|
||||||
{
|
{
|
||||||
m_expr_ptr->findResources(resource_list);
|
return new UnimpFault(csprintf("MRC CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n",
|
||||||
|
CRn, opc1, CRm, opc2));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprStatementAST::print(ostream& out) const
|
|
||||||
{
|
|
||||||
out << "[ExprStatementAST: " << *m_expr_ptr << "]";
|
|
||||||
}
|
}
|
|
@ -125,6 +125,20 @@ namespace ArmISA {
|
||||||
{
|
{
|
||||||
panic("Copy Misc. Regs Not Implemented Yet\n");
|
panic("Copy Misc. Regs Not Implemented Yet\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initCPU(ThreadContext *tc, int cpuId);
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
inUserMode(ThreadContext *tc)
|
||||||
|
{
|
||||||
|
return (tc->readMiscRegNoEffect(MISCREG_CPSR) & 0x1f) == MODE_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getArgument(ThreadContext *tc, int number, bool fp);
|
||||||
|
|
||||||
|
Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);
|
||||||
|
Fault readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -34,10 +34,6 @@ import traceback
|
||||||
# get type names
|
# get type names
|
||||||
from types import *
|
from types import *
|
||||||
|
|
||||||
# Prepend the directory where the PLY lex & yacc modules are found
|
|
||||||
# to the search path.
|
|
||||||
sys.path[0:0] = [os.environ['M5_PLY']]
|
|
||||||
|
|
||||||
from ply import lex
|
from ply import lex
|
||||||
from ply import yacc
|
from ply import yacc
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,11 @@
|
||||||
#
|
#
|
||||||
# Authors: Jaidev Patwardhan
|
# Authors: Jaidev Patwardhan
|
||||||
|
|
||||||
from m5 import build_env
|
from m5.defines import buildEnv
|
||||||
|
|
||||||
from System import *
|
from System import *
|
||||||
|
|
||||||
if build_env['FULL_SYSTEM']:
|
if buildEnv['FULL_SYSTEM']:
|
||||||
class BareIronMipsSystem(MipsSystem):
|
class BareIronMipsSystem(MipsSystem):
|
||||||
type = 'BareIronMipsSystem'
|
type = 'BareIronMipsSystem'
|
||||||
system_type = 34
|
system_type = 34
|
||||||
|
|
|
@ -29,12 +29,13 @@
|
||||||
# Authors: Jaidev Patwardhan
|
# Authors: Jaidev Patwardhan
|
||||||
# Korey Sewell
|
# Korey Sewell
|
||||||
|
|
||||||
from m5.SimObject import SimObject
|
from m5.defines import buildEnv
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
|
|
||||||
from BaseCPU import BaseCPU
|
from BaseCPU import BaseCPU
|
||||||
|
|
||||||
class BaseMipsCPU(BaseCPU)
|
class BaseMipsCPU(BaseCPU)
|
||||||
if build_env['TARGET_ISA'] == 'mips':
|
if buildEnv['TARGET_ISA'] == 'mips':
|
||||||
CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description")
|
CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description")
|
||||||
CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description")
|
CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description")
|
||||||
CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description")
|
CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description")
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
#
|
#
|
||||||
# Authors: Jaidev Patwardhan
|
# Authors: Jaidev Patwardhan
|
||||||
|
|
||||||
from m5.SimObject import SimObject
|
from m5.defines import buildEnv
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
from m5.proxy import *
|
from m5.proxy import *
|
||||||
from m5 import build_env
|
|
||||||
from System import System
|
from System import System
|
||||||
|
|
||||||
class MipsSystem(System):
|
class MipsSystem(System):
|
||||||
|
@ -42,7 +42,7 @@ class MipsSystem(System):
|
||||||
system_type = Param.UInt64("Type of system we are emulating")
|
system_type = Param.UInt64("Type of system we are emulating")
|
||||||
system_rev = Param.UInt64("Revision of system we are emulating")
|
system_rev = Param.UInt64("Revision of system we are emulating")
|
||||||
|
|
||||||
if build_env['FULL_SYSTEM']:
|
if buildEnv['FULL_SYSTEM']:
|
||||||
class LinuxMipsSystem(MipsSystem):
|
class LinuxMipsSystem(MipsSystem):
|
||||||
type = 'LinuxMipsSystem'
|
type = 'LinuxMipsSystem'
|
||||||
system_type = 34
|
system_type = 34
|
||||||
|
|
|
@ -463,6 +463,8 @@ MipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl)
|
||||||
uint64_t b_values[SIMD_MAX_VALS];
|
uint64_t b_values[SIMD_MAX_VALS];
|
||||||
uint64_t c_values[SIMD_MAX_VALS];
|
uint64_t c_values[SIMD_MAX_VALS];
|
||||||
|
|
||||||
|
memset(c_values, 0, sizeof(c_values));
|
||||||
|
|
||||||
simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
|
simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
|
||||||
simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
|
simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
|
||||||
|
|
||||||
|
@ -743,7 +745,7 @@ MipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
|
||||||
int nvals = SIMD_NVALS[fmt];
|
int nvals = SIMD_NVALS[fmt];
|
||||||
uint64_t a_values[SIMD_MAX_VALS];
|
uint64_t a_values[SIMD_MAX_VALS];
|
||||||
uint64_t b_values[SIMD_MAX_VALS];
|
uint64_t b_values[SIMD_MAX_VALS];
|
||||||
int64_t temp[2];
|
int64_t temp[2] = {0, 0};
|
||||||
uint32_t ouflag = 0;
|
uint32_t ouflag = 0;
|
||||||
|
|
||||||
simdUnpack(a, a_values, fmt, SIGNED);
|
simdUnpack(a, a_values, fmt, SIGNED);
|
||||||
|
|
|
@ -172,8 +172,11 @@ namespace MipsISA
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
void serialize(EventManager *em, std::ostream &os)
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
{}
|
||||||
|
void unserialize(EventManager *em, Checkpoint *cp,
|
||||||
|
const std::string §ion)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -619,7 +619,7 @@ def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
|
||||||
|
|
||||||
def format Prefetch(ea_code = {{ EA = Rs + disp; }},
|
def format Prefetch(ea_code = {{ EA = Rs + disp; }},
|
||||||
mem_flags = [], pf_flags = [], inst_flags = []) {{
|
mem_flags = [], pf_flags = [], inst_flags = []) {{
|
||||||
pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
|
pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
|
||||||
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
|
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
|
||||||
'IsDataPrefetch', 'MemReadOp']
|
'IsDataPrefetch', 'MemReadOp']
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ class MipsLinux : public Linux
|
||||||
static const unsigned TIOCISATTY_ = 0x5480;
|
static const unsigned TIOCISATTY_ = 0x5480;
|
||||||
static const unsigned TIOCGETS_ = 0x540d;
|
static const unsigned TIOCGETS_ = 0x540d;
|
||||||
static const unsigned TIOCGETA_ = 0x7417;
|
static const unsigned TIOCGETA_ = 0x7417;
|
||||||
|
static const unsigned TCSETAW_ = 0x5403; // 2.6.15 kernel
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// For table().
|
/// For table().
|
||||||
|
@ -126,6 +127,22 @@ class MipsLinux : public Linux
|
||||||
/// assign themselves to process IDs reserved for
|
/// assign themselves to process IDs reserved for
|
||||||
/// the root users.
|
/// the root users.
|
||||||
static const int NUM_ROOT_PROCS = 2;
|
static const int NUM_ROOT_PROCS = 2;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t uptime; /* Seconds since boot */
|
||||||
|
uint32_t loads[3]; /* 1, 5, and 15 minute load averages */
|
||||||
|
uint32_t totalram; /* Total usable main memory size */
|
||||||
|
uint32_t freeram; /* Available memory size */
|
||||||
|
uint32_t sharedram; /* Amount of shared memory */
|
||||||
|
uint32_t bufferram; /* Memory used by buffers */
|
||||||
|
uint32_t totalswap; /* Total swap space size */
|
||||||
|
uint32_t freeswap; /* swap space still available */
|
||||||
|
uint16_t procs; /* Number of current processes */
|
||||||
|
uint32_t totalhigh; /* Total high memory size */
|
||||||
|
uint32_t freehigh; /* Available high memory size */
|
||||||
|
uint32_t mem_unit; /* Memory unit size in bytes */
|
||||||
|
} tgt_sysinfo;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,7 +51,8 @@ static SyscallReturn
|
||||||
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
|
int index = 0;
|
||||||
|
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
|
||||||
|
|
||||||
strcpy(name->sysname, "Linux");
|
strcpy(name->sysname, "Linux");
|
||||||
strcpy(name->nodename,"m5.eecs.umich.edu");
|
strcpy(name->nodename,"m5.eecs.umich.edu");
|
||||||
|
@ -70,14 +71,16 @@ static SyscallReturn
|
||||||
sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = process->getSyscallArg(tc, 0);
|
int index = 0;
|
||||||
// unsigned nbytes = process->getSyscallArg(tc, 2);
|
unsigned op = process->getSyscallArg(tc, index);
|
||||||
|
unsigned bufPtr = process->getSyscallArg(tc, index);
|
||||||
|
// unsigned nbytes = process->getSyscallArg(tc, index);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 45:
|
case 45:
|
||||||
{
|
{
|
||||||
// GSI_IEEE_FP_CONTROL
|
// GSI_IEEE_FP_CONTROL
|
||||||
TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
*fpcr = 0;
|
*fpcr = 0;
|
||||||
fpcr.copyOut(tc->getMemPort());
|
fpcr.copyOut(tc->getMemPort());
|
||||||
|
@ -97,15 +100,17 @@ static SyscallReturn
|
||||||
sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
unsigned op = process->getSyscallArg(tc, 0);
|
int index = 0;
|
||||||
// unsigned nbytes = process->getSyscallArg(tc, 2);
|
unsigned op = process->getSyscallArg(tc, index);
|
||||||
|
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||||
|
// unsigned nbytes = process->getSyscallArg(tc, index);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
case 14:
|
case 14:
|
||||||
{
|
{
|
||||||
// SSI_IEEE_FP_CONTROL
|
// SSI_IEEE_FP_CONTROL
|
||||||
TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
fpcr.copyIn(tc->getMemPort());
|
fpcr.copyIn(tc->getMemPort());
|
||||||
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||||
|
@ -238,7 +243,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
|
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
|
||||||
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
|
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
|
||||||
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
|
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
|
||||||
/* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
|
/* 116 */ SyscallDesc("sysinfo", sysinfoFunc<MipsLinux>),
|
||||||
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
|
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
|
||||||
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
|
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
|
||||||
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
|
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
|
||||||
|
@ -413,12 +418,6 @@ MipsLinuxProcess::MipsLinuxProcess(LiveProcessParams * params,
|
||||||
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
|
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void
|
|
||||||
MipsLinuxProcess::startup()
|
|
||||||
{
|
|
||||||
MipsLiveProcess::argsInit(MachineBytes, VMPageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
SyscallDesc*
|
SyscallDesc*
|
||||||
MipsLinuxProcess::getDesc(int callnum)
|
MipsLinuxProcess::getDesc(int callnum)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,8 +43,6 @@ class MipsLinuxProcess : public MipsLiveProcess
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
MipsLinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
|
MipsLinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
|
||||||
|
|
||||||
void startup();
|
|
||||||
|
|
||||||
virtual SyscallDesc* getDesc(int callnum);
|
virtual SyscallDesc* getDesc(int callnum);
|
||||||
|
|
||||||
/// The target system's hostname.
|
/// The target system's hostname.
|
||||||
|
|
|
@ -32,9 +32,15 @@
|
||||||
|
|
||||||
#include "arch/mips/isa_traits.hh"
|
#include "arch/mips/isa_traits.hh"
|
||||||
#include "arch/mips/process.hh"
|
#include "arch/mips/process.hh"
|
||||||
|
|
||||||
#include "base/loader/object_file.hh"
|
#include "base/loader/object_file.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
|
||||||
|
#include "mem/page_table.hh"
|
||||||
|
|
||||||
|
#include "sim/process.hh"
|
||||||
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -62,14 +68,89 @@ MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params,
|
||||||
void
|
void
|
||||||
MipsLiveProcess::startup()
|
MipsLiveProcess::startup()
|
||||||
{
|
{
|
||||||
|
Process::startup();
|
||||||
|
|
||||||
argsInit(MachineBytes, VMPageSize);
|
argsInit(MachineBytes, VMPageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MipsLiveProcess::argsInit(int intSize, int pageSize)
|
||||||
|
{
|
||||||
|
// load object file into target memory
|
||||||
|
objFile->loadSections(initVirtMem);
|
||||||
|
|
||||||
|
// Calculate how much space we need for arg & env arrays.
|
||||||
|
int argv_array_size = intSize * (argv.size() + 1);
|
||||||
|
int envp_array_size = intSize * (envp.size() + 1);
|
||||||
|
int arg_data_size = 0;
|
||||||
|
for (vector<string>::size_type i = 0; i < argv.size(); ++i) {
|
||||||
|
arg_data_size += argv[i].size() + 1;
|
||||||
|
}
|
||||||
|
int env_data_size = 0;
|
||||||
|
for (vector<string>::size_type i = 0; i < envp.size(); ++i) {
|
||||||
|
env_data_size += envp[i].size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int space_needed =
|
||||||
|
argv_array_size + envp_array_size + arg_data_size + env_data_size;
|
||||||
|
if (space_needed < 32*1024)
|
||||||
|
space_needed = 32*1024;
|
||||||
|
|
||||||
|
// set bottom of stack
|
||||||
|
stack_min = stack_base - space_needed;
|
||||||
|
// align it
|
||||||
|
stack_min = roundDown(stack_min, pageSize);
|
||||||
|
stack_size = stack_base - stack_min;
|
||||||
|
// map memory
|
||||||
|
pTable->allocate(stack_min, roundUp(stack_size, pageSize));
|
||||||
|
|
||||||
|
// map out initial stack contents
|
||||||
|
// ========
|
||||||
|
// NOTE: Using uint32_t hardcodes MIPS32 and not MIPS64
|
||||||
|
// even if MIPS64 was intended. This is because the
|
||||||
|
// copyStringArray function templates on the parameters.
|
||||||
|
// Elegant way to check intSize and vary between 32/64?
|
||||||
|
// ========
|
||||||
|
uint32_t argv_array_base = stack_min + intSize; // room for argc
|
||||||
|
uint32_t envp_array_base = argv_array_base + argv_array_size;
|
||||||
|
uint32_t arg_data_base = envp_array_base + envp_array_size;
|
||||||
|
uint32_t env_data_base = arg_data_base + arg_data_size;
|
||||||
|
|
||||||
|
// write contents to stack
|
||||||
|
uint32_t argc = argv.size();
|
||||||
|
|
||||||
|
if (intSize == 8)
|
||||||
|
argc = htog((uint64_t)argc);
|
||||||
|
else if (intSize == 4)
|
||||||
|
argc = htog((uint32_t)argc);
|
||||||
|
else
|
||||||
|
panic("Unknown int size");
|
||||||
|
|
||||||
|
|
||||||
|
initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
|
||||||
|
|
||||||
|
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
|
||||||
|
|
||||||
|
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
|
||||||
|
|
||||||
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
|
|
||||||
|
setSyscallArg(tc, 0, argc);
|
||||||
|
setSyscallArg(tc, 1, argv_array_base);
|
||||||
|
tc->setIntReg(StackPointerReg, stack_min);
|
||||||
|
|
||||||
|
Addr prog_entry = objFile->entryPoint();
|
||||||
|
tc->setPC(prog_entry);
|
||||||
|
tc->setNextPC(prog_entry + sizeof(MachInst));
|
||||||
|
tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MipsISA::IntReg
|
MipsISA::IntReg
|
||||||
MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i)
|
MipsLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
|
||||||
{
|
{
|
||||||
assert(i < 6);
|
assert(i < 6);
|
||||||
return tc->readIntReg(FirstArgumentReg + i);
|
return tc->readIntReg(FirstArgumentReg + i++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -45,10 +45,12 @@ class MipsLiveProcess : public LiveProcess
|
||||||
protected:
|
protected:
|
||||||
MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
|
MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
|
||||||
|
|
||||||
virtual void startup();
|
void startup();
|
||||||
|
|
||||||
|
void argsInit(int intSize, int pageSize);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i);
|
MipsISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
||||||
void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val);
|
void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val);
|
||||||
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
|
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
|
||||||
};
|
};
|
||||||
|
|
37
src/arch/power/PowerTLB.py
Normal file
37
src/arch/power/PowerTLB.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# -*- mode:python -*-
|
||||||
|
|
||||||
|
# Copyright (c) 2009 The University of Edinburgh
|
||||||
|
# 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: Timothy M. Jones
|
||||||
|
|
||||||
|
from m5.SimObject import SimObject
|
||||||
|
from m5.params import *
|
||||||
|
|
||||||
|
class PowerTLB(SimObject):
|
||||||
|
type = 'PowerTLB'
|
||||||
|
cxx_class = 'PowerISA::TLB'
|
||||||
|
size = Param.Int(64, "TLB size")
|
61
src/arch/power/SConscript
Normal file
61
src/arch/power/SConscript
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# -*- mode:python -*-
|
||||||
|
|
||||||
|
# Copyright (c) 2009 The University of Edinburgh
|
||||||
|
# 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: Timothy M. Jones
|
||||||
|
|
||||||
|
Import('*')
|
||||||
|
|
||||||
|
if env['TARGET_ISA'] == 'power':
|
||||||
|
# Workaround for bug in SCons version > 0.97d20071212
|
||||||
|
# Scons bug id: 2006 M5 Bug id: 308
|
||||||
|
Dir('isa/formats')
|
||||||
|
Source('insts/branch.cc')
|
||||||
|
Source('insts/mem.cc')
|
||||||
|
Source('insts/integer.cc')
|
||||||
|
Source('insts/floating.cc')
|
||||||
|
Source('insts/condition.cc')
|
||||||
|
Source('insts/static_inst.cc')
|
||||||
|
Source('pagetable.cc')
|
||||||
|
Source('tlb.cc')
|
||||||
|
|
||||||
|
SimObject('PowerTLB.py')
|
||||||
|
TraceFlag('Power')
|
||||||
|
|
||||||
|
if not env['FULL_SYSTEM']:
|
||||||
|
Source('process.cc')
|
||||||
|
Source('linux/linux.cc')
|
||||||
|
Source('linux/process.cc')
|
||||||
|
|
||||||
|
# Add in files generated by the ISA description.
|
||||||
|
isa_desc_files = env.ISADesc('isa/main.isa')
|
||||||
|
|
||||||
|
# Only non-header files need to be compiled.
|
||||||
|
for f in isa_desc_files:
|
||||||
|
if not f.path.endswith('.hh'):
|
||||||
|
Source(f)
|
||||||
|
|
33
src/arch/power/SConsopts
Normal file
33
src/arch/power/SConsopts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# -*- mode:python -*-
|
||||||
|
|
||||||
|
# Copyright (c) 2009 The University of Edinburgh
|
||||||
|
# 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: Timothy M. Jones
|
||||||
|
|
||||||
|
Import('*')
|
||||||
|
|
||||||
|
all_isa_list.append('power')
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,48 +25,63 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*
|
*
|
||||||
|
* Authors: Gabe Black
|
||||||
|
* Timothy M. Jones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mem/slicc/symbols/Symbol.hh"
|
#ifndef __ARCH_POWER_FAULTS_HH__
|
||||||
|
#define __ARCH_POWER_FAULTS_HH__
|
||||||
|
|
||||||
Symbol::Symbol(string id, const Location& location, const Map<string, string>& pairs)
|
#include "sim/faults.hh"
|
||||||
|
|
||||||
|
namespace PowerISA
|
||||||
{
|
{
|
||||||
m_id = id;
|
|
||||||
m_location = location;
|
class PowerFault : public FaultBase
|
||||||
m_pairs = pairs;
|
{
|
||||||
if (!existPair("short")) {
|
protected:
|
||||||
addPair("short", m_id);
|
FaultName _name;
|
||||||
}
|
|
||||||
m_used = false;
|
PowerFault(FaultName name)
|
||||||
|
: _name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FaultName
|
||||||
|
name() const
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class UnimplementedOpcodeFault : public PowerFault
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnimplementedOpcodeFault()
|
||||||
|
: PowerFault("Unimplemented Opcode")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class MachineCheckFault : public PowerFault
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MachineCheckFault()
|
||||||
|
: PowerFault("Machine Check")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static inline Fault
|
||||||
|
genMachineCheckFault()
|
||||||
|
{
|
||||||
|
return new MachineCheckFault();
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol::Symbol(string id, const Location& location)
|
} // PowerISA namespace
|
||||||
{
|
|
||||||
m_id = id;
|
|
||||||
m_location = location;
|
|
||||||
if (!existPair("short")) {
|
|
||||||
addPair("short", m_id);
|
|
||||||
}
|
|
||||||
m_used = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const string& Symbol::lookupPair(const string& key) const
|
#endif // __ARCH_POWER_FAULTS_HH__
|
||||||
{
|
|
||||||
if (!existPair(key)) {
|
|
||||||
error("Value for pair '" + key + "' missing.");
|
|
||||||
}
|
|
||||||
return m_pairs.lookup(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Symbol::addPair(const string& key, const string& value)
|
|
||||||
{
|
|
||||||
if (existPair(key)) {
|
|
||||||
warning("Pair key '" + key + "' re-defined. new: '" + value + "' old: '" + lookupPair(key) + "'");
|
|
||||||
}
|
|
||||||
m_pairs.add(key, value);
|
|
||||||
}
|
|
169
src/arch/power/insts/branch.cc
Normal file
169
src/arch/power/insts/branch.cc
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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: Timothy M. Jones
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/power/insts/branch.hh"
|
||||||
|
#include "base/loader/symtab.hh"
|
||||||
|
|
||||||
|
using namespace PowerISA;
|
||||||
|
|
||||||
|
const std::string &
|
||||||
|
PCDependentDisassembly::disassemble(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
if (!cachedDisassembly ||
|
||||||
|
pc != cachedPC || symtab != cachedSymtab)
|
||||||
|
{
|
||||||
|
if (cachedDisassembly)
|
||||||
|
delete cachedDisassembly;
|
||||||
|
|
||||||
|
cachedDisassembly =
|
||||||
|
new std::string(generateDisassembly(pc, symtab));
|
||||||
|
cachedPC = pc;
|
||||||
|
cachedSymtab = symtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *cachedDisassembly;
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr
|
||||||
|
BranchPCRel::branchTarget(Addr pc) const
|
||||||
|
{
|
||||||
|
return (uint32_t)(pc + disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
BranchPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
Addr target = pc + disp;
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
if (symtab && symtab->findSymbol(target, str))
|
||||||
|
ss << str;
|
||||||
|
else
|
||||||
|
ccprintf(ss, "0x%x", target);
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr
|
||||||
|
BranchNonPCRel::branchTarget(Addr pc) const
|
||||||
|
{
|
||||||
|
return targetAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
BranchNonPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
if (symtab && symtab->findSymbol(targetAddr, str))
|
||||||
|
ss << str;
|
||||||
|
else
|
||||||
|
ccprintf(ss, "0x%x", targetAddr);
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr
|
||||||
|
BranchPCRelCond::branchTarget(Addr pc) const
|
||||||
|
{
|
||||||
|
return (uint32_t)(pc + disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
BranchPCRelCond::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
ss << bo << ", " << bi << ", ";
|
||||||
|
|
||||||
|
Addr target = pc + disp;
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
if (symtab && symtab->findSymbol(target, str))
|
||||||
|
ss << str;
|
||||||
|
else
|
||||||
|
ccprintf(ss, "0x%x", target);
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr
|
||||||
|
BranchNonPCRelCond::branchTarget(Addr pc) const
|
||||||
|
{
|
||||||
|
return targetAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
BranchNonPCRelCond::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
ss << bo << ", " << bi << ", ";
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
if (symtab && symtab->findSymbol(targetAddr, str))
|
||||||
|
ss << str;
|
||||||
|
else
|
||||||
|
ccprintf(ss, "0x%x", targetAddr);
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr
|
||||||
|
BranchRegCond::branchTarget(ThreadContext *tc) const
|
||||||
|
{
|
||||||
|
uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1]);
|
||||||
|
return (regVal & 0xfffffffc);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
BranchRegCond::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
ss << bo << ", " << bi << ", ";
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
241
src/arch/power/insts/branch.hh
Normal file
241
src/arch/power/insts/branch.hh
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
/* Copyright (c) 2007-2008 The Florida State University
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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: Timothy M. Jones
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ARCH_POWER_INSTS_BRANCH_HH__
|
||||||
|
#define __ARCH_POWER_INSTS_BRANCH_HH__
|
||||||
|
|
||||||
|
#include "arch/power/insts/static_inst.hh"
|
||||||
|
|
||||||
|
namespace PowerISA
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for instructions whose disassembly is not purely a
|
||||||
|
* function of the machine instruction (i.e., it depends on the
|
||||||
|
* PC). This class overrides the disassemble() method to check
|
||||||
|
* the PC and symbol table values before re-using a cached
|
||||||
|
* disassembly string. This is necessary for branches and jumps,
|
||||||
|
* where the disassembly string includes the target address (which
|
||||||
|
* may depend on the PC and/or symbol table).
|
||||||
|
*/
|
||||||
|
class PCDependentDisassembly : public PowerStaticInst
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/// Cached program counter from last disassembly
|
||||||
|
mutable Addr cachedPC;
|
||||||
|
/// Cached symbol table pointer from last disassembly
|
||||||
|
mutable const SymbolTable *cachedSymtab;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
PCDependentDisassembly(const char *mnem, ExtMachInst _machInst,
|
||||||
|
OpClass __opClass)
|
||||||
|
: PowerStaticInst(mnem, _machInst, __opClass),
|
||||||
|
cachedPC(0), cachedSymtab(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &
|
||||||
|
disassemble(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for unconditional, PC-relative branches.
|
||||||
|
*/
|
||||||
|
class BranchPCRel : public PCDependentDisassembly
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// Displacement
|
||||||
|
uint32_t disp;
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||||
|
disp(machInst.li << 2)
|
||||||
|
{
|
||||||
|
// If bit 26 is 1 then sign extend
|
||||||
|
if (disp & 0x2000000) {
|
||||||
|
disp |= 0xfc000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr branchTarget(Addr pc) const;
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for unconditional, non PC-relative branches.
|
||||||
|
*/
|
||||||
|
class BranchNonPCRel : public PCDependentDisassembly
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// Target address
|
||||||
|
uint32_t targetAddr;
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||||
|
targetAddr(machInst.li << 2)
|
||||||
|
{
|
||||||
|
// If bit 26 is 1 then sign extend
|
||||||
|
if (targetAddr & 0x2000000) {
|
||||||
|
targetAddr |= 0xfc000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr branchTarget(Addr pc) const;
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for conditional branches.
|
||||||
|
*/
|
||||||
|
class BranchCond : public PCDependentDisassembly
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// Fields needed for conditions
|
||||||
|
uint32_t bo;
|
||||||
|
uint32_t bi;
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||||
|
bo(machInst.bo),
|
||||||
|
bi(machInst.bi)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
ctrOk(uint32_t& ctr) const
|
||||||
|
{
|
||||||
|
bool ctr_ok;
|
||||||
|
if (bo & 4) {
|
||||||
|
ctr_ok = true;
|
||||||
|
} else {
|
||||||
|
ctr--;
|
||||||
|
if (ctr != 0) {
|
||||||
|
ctr_ok = ((bo & 2) == 0);
|
||||||
|
} else {
|
||||||
|
ctr_ok = ((bo & 2) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctr_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
condOk(uint32_t cr) const
|
||||||
|
{
|
||||||
|
bool cond_ok;
|
||||||
|
if (bo & 16) {
|
||||||
|
cond_ok = true;
|
||||||
|
} else {
|
||||||
|
cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1));
|
||||||
|
}
|
||||||
|
return cond_ok;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for conditional, PC-relative branches.
|
||||||
|
*/
|
||||||
|
class BranchPCRelCond : public BranchCond
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// Displacement
|
||||||
|
uint32_t disp;
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: BranchCond(mnem, _machInst, __opClass),
|
||||||
|
disp(machInst.bd << 2)
|
||||||
|
{
|
||||||
|
// If bit 16 is 1 then sign extend
|
||||||
|
if (disp & 0x8000) {
|
||||||
|
disp |= 0xffff0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr branchTarget(Addr pc) const;
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for conditional, non PC-relative branches.
|
||||||
|
*/
|
||||||
|
class BranchNonPCRelCond : public BranchCond
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// Target address
|
||||||
|
uint32_t targetAddr;
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: BranchCond(mnem, _machInst, __opClass),
|
||||||
|
targetAddr(machInst.bd << 2)
|
||||||
|
{
|
||||||
|
// If bit 16 is 1 then sign extend
|
||||||
|
if (targetAddr & 0x8000) {
|
||||||
|
targetAddr |= 0xffff0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr branchTarget(Addr pc) const;
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for conditional, register-based branches
|
||||||
|
*/
|
||||||
|
class BranchRegCond : public BranchCond
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: BranchCond(mnem, _machInst, __opClass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Addr branchTarget(ThreadContext *tc) const;
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // PowerISA namespace
|
||||||
|
|
||||||
|
#endif //__ARCH_POWER_INSTS_BRANCH_HH__
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,33 +24,36 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Timothy M. Jones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#include "arch/power/insts/condition.hh"
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
|
|
||||||
#include "mem/slicc/symbols/Var.hh"
|
using namespace PowerISA;
|
||||||
#include "mem/slicc/symbols/StateMachine.hh"
|
|
||||||
|
|
||||||
Var::Var(string id, const Location& location,
|
std::string
|
||||||
Type* type_ptr, string code,
|
CondLogicOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
const Map<string, string>& pairs,
|
|
||||||
StateMachine* machine_ptr) : Symbol(id, location, pairs)
|
|
||||||
{
|
{
|
||||||
if (machine_ptr == NULL) {
|
std::stringstream ss;
|
||||||
m_c_id = id;
|
|
||||||
} else {
|
|
||||||
m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name
|
|
||||||
}
|
|
||||||
|
|
||||||
m_machine_ptr = machine_ptr;
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
m_type_ptr = type_ptr;
|
|
||||||
m_code = code;
|
// Format is <mnemonic> bt, ba, bb
|
||||||
|
ss << bt << ", " << ba << ", " << bb;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Var::print(ostream& out) const
|
std::string
|
||||||
|
CondMoveOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
out << "[Var id: " << m_c_id << "]" << endl;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
// Format is <mnemonic> bf, bfa
|
||||||
|
ss << bf << ", " << bfa;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,61 +24,63 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Timothy M. Jones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#ifndef __ARCH_POWER_INSTS_CONDITION_HH__
|
||||||
* DeclAST.hh
|
#define __ARCH_POWER_INSTS_CONDITION_HH__
|
||||||
*
|
|
||||||
* Description:
|
#include "arch/power/insts/static_inst.hh"
|
||||||
*
|
#include "base/cprintf.hh"
|
||||||
* $Id$
|
|
||||||
*
|
namespace PowerISA
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for condition register logical operations.
|
||||||
*/
|
*/
|
||||||
|
class CondLogicOp : public PowerStaticInst
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
#ifndef DECLAST_H
|
uint32_t ba;
|
||||||
#define DECLAST_H
|
uint32_t bb;
|
||||||
|
uint32_t bt;
|
||||||
|
|
||||||
#include "mem/slicc/slicc_global.hh"
|
/// Constructor
|
||||||
#include "mem/slicc/ast/AST.hh"
|
CondLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
#include "mem/slicc/ast/PairListAST.hh"
|
: PowerStaticInst(mnem, _machInst, __opClass),
|
||||||
#include "mem/slicc/symbols/StateMachine.hh"
|
ba(machInst.ba),
|
||||||
#include "mem/slicc/ast/TypeAST.hh"
|
bb(machInst.bb),
|
||||||
|
bt(machInst.bt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
class DeclAST : public AST {
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
DeclAST(PairListAST* pairs_ptr) : AST(pairs_ptr->getPairs()) {}
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
virtual ~DeclAST() {}
|
|
||||||
|
|
||||||
// Public Methods
|
|
||||||
virtual void generate() = 0;
|
|
||||||
virtual void findMachines() {};
|
|
||||||
|
|
||||||
// void print(ostream& out) const;
|
|
||||||
private:
|
|
||||||
// Private Methods
|
|
||||||
|
|
||||||
// Private copy constructor and assignment operator
|
|
||||||
// DeclAST(const DeclAST& obj);
|
|
||||||
// DeclAST& operator=(const DeclAST& obj);
|
|
||||||
|
|
||||||
// Data Members (m_ prefix)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Output operator declaration
|
/**
|
||||||
ostream& operator<<(ostream& out, const DeclAST& obj);
|
* Class for condition register move operations.
|
||||||
|
*/
|
||||||
// ******************* Definitions *******************
|
class CondMoveOp : public PowerStaticInst
|
||||||
|
|
||||||
// Output operator definition
|
|
||||||
extern inline
|
|
||||||
ostream& operator<<(ostream& out, const DeclAST& obj)
|
|
||||||
{
|
{
|
||||||
obj.print(out);
|
protected:
|
||||||
out << flush;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //DECLAST_H
|
uint32_t bf;
|
||||||
|
uint32_t bfa;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
CondMoveOp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: PowerStaticInst(mnem, _machInst, __opClass),
|
||||||
|
bf(machInst.bf),
|
||||||
|
bfa(machInst.bfa)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // PowerISA namespace
|
||||||
|
|
||||||
|
#endif //__ARCH_POWER_INSTS_CONDITION_HH__
|
60
src/arch/power/insts/floating.cc
Normal file
60
src/arch/power/insts/floating.cc
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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: Timothy M. Jones
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/power/insts/floating.hh"
|
||||||
|
|
||||||
|
using namespace PowerISA;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
FloatOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
// Print the first destination only
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
printReg(ss, _destRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the (possibly) two source registers
|
||||||
|
if (_numSrcRegs > 0) {
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
printReg(ss, _srcRegIdx[0]);
|
||||||
|
if (_numSrcRegs > 1) {
|
||||||
|
ss << ", ";
|
||||||
|
printReg(ss, _srcRegIdx[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
153
src/arch/power/insts/floating.hh
Normal file
153
src/arch/power/insts/floating.hh
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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: Timothy M. Jones
|
||||||
|
* Korey Sewell
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ARCH_POWER_INSTS_FLOATING_HH__
|
||||||
|
#define __ARCH_POWER_INSTS_FLOATING_HH__
|
||||||
|
|
||||||
|
#include "arch/power/insts/static_inst.hh"
|
||||||
|
#include "base/cprintf.hh"
|
||||||
|
#include "base/bitfield.hh"
|
||||||
|
|
||||||
|
namespace PowerISA
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for floating point operations.
|
||||||
|
*/
|
||||||
|
class FloatOp : public PowerStaticInst
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool rcSet;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
FloatOp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: PowerStaticInst(mnem, _machInst, __opClass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for NaN (maximum biased exponent & non-zero fraction)
|
||||||
|
inline bool
|
||||||
|
isNan(uint32_t val_bits) const
|
||||||
|
{
|
||||||
|
return ((bits(val_bits, 30, 23) == 0xFF) && bits(val_bits, 22, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
isNan(uint64_t val_bits) const
|
||||||
|
{
|
||||||
|
return ((bits(val_bits, 62, 52) == 0x7FF) && bits(val_bits, 51, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
isNan(float val) const
|
||||||
|
{
|
||||||
|
void *val_ptr = &val;
|
||||||
|
uint32_t val_bits = *(uint32_t *) val_ptr;
|
||||||
|
return isNan(val_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
isNan(double val) const
|
||||||
|
{
|
||||||
|
void *val_ptr = &val;
|
||||||
|
uint64_t val_bits = *(uint64_t *) val_ptr;
|
||||||
|
return isNan(val_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for SNaN (NaN with high order bit of fraction set to 0)
|
||||||
|
inline bool
|
||||||
|
isSnan(uint32_t val_bits) const
|
||||||
|
{
|
||||||
|
return ((bits(val_bits, 30, 22) == 0x1FE) && bits(val_bits, 22, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for QNaN (NaN with high order bit of fraction set to 1)
|
||||||
|
inline bool
|
||||||
|
isQnan(uint32_t val_bits) const
|
||||||
|
{
|
||||||
|
return (bits(val_bits, 30, 22) == 0x1FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for infinity (maximum biased exponent and zero fraction)
|
||||||
|
inline bool
|
||||||
|
isInfinity(uint32_t val_bits) const
|
||||||
|
{
|
||||||
|
return ((bits(val_bits, 30, 23) == 0xFF) && !bits(val_bits, 22, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for normalized numbers (biased exponent in the range 1 to 254)
|
||||||
|
inline bool
|
||||||
|
isNormalized(uint32_t val_bits) const
|
||||||
|
{
|
||||||
|
return ((bits(val_bits, 30, 23) != 0xFF) && bits(val_bits, 22, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for denormalized numbers (biased exponent of zero and
|
||||||
|
// non-zero fraction)
|
||||||
|
inline bool
|
||||||
|
isDenormalized(uint32_t val_bits) const
|
||||||
|
{
|
||||||
|
return (!bits(val_bits, 30, 23) && bits(val_bits, 22, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for zero (biased exponent of zero and fraction of zero)
|
||||||
|
inline bool
|
||||||
|
isZero(uint32_t val_bits) const
|
||||||
|
{
|
||||||
|
return (!bits(val_bits, 30, 23) && !bits(val_bits, 22, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for negative
|
||||||
|
inline bool
|
||||||
|
isNegative(uint32_t val_bits) const
|
||||||
|
{
|
||||||
|
return (bits(val_bits, 31));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the CR field
|
||||||
|
inline uint32_t
|
||||||
|
makeCRField(double a, double b) const
|
||||||
|
{
|
||||||
|
uint32_t c = 0;
|
||||||
|
if (isNan(a) || isNan(b)) { c = 0x1; }
|
||||||
|
else if (a < b) { c = 0x8; }
|
||||||
|
else if (a > b) { c = 0x4; }
|
||||||
|
else { c = 0x2; }
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // PowerISA namespace
|
||||||
|
|
||||||
|
#endif //__ARCH_POWER_INSTS_FLOATING_HH__
|
170
src/arch/power/insts/integer.cc
Normal file
170
src/arch/power/insts/integer.cc
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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: Timothy M. Jones
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/power/insts/integer.hh"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace PowerISA;
|
||||||
|
|
||||||
|
string
|
||||||
|
IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
bool printDest = true;
|
||||||
|
bool printSrcs = true;
|
||||||
|
bool printSecondSrc = true;
|
||||||
|
|
||||||
|
// Generate the correct mnemonic
|
||||||
|
string myMnemonic(mnemonic);
|
||||||
|
|
||||||
|
// Special cases
|
||||||
|
if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) {
|
||||||
|
myMnemonic = "mr";
|
||||||
|
printSecondSrc = false;
|
||||||
|
} else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) {
|
||||||
|
printDest = false;
|
||||||
|
} else if (!myMnemonic.compare("mflr")) {
|
||||||
|
printSrcs = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Additional characters depending on isa bits being set
|
||||||
|
if (oeSet) myMnemonic = myMnemonic + "o";
|
||||||
|
if (rcSet) myMnemonic = myMnemonic + ".";
|
||||||
|
ccprintf(ss, "%-10s ", myMnemonic);
|
||||||
|
|
||||||
|
// Print the first destination only
|
||||||
|
if (_numDestRegs > 0 && printDest) {
|
||||||
|
printReg(ss, _destRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the (possibly) two source registers
|
||||||
|
if (_numSrcRegs > 0 && printSrcs) {
|
||||||
|
if (_numDestRegs > 0 && printDest) {
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
printReg(ss, _srcRegIdx[0]);
|
||||||
|
if (_numSrcRegs > 1 && printSecondSrc) {
|
||||||
|
ss << ", ";
|
||||||
|
printReg(ss, _srcRegIdx[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string
|
||||||
|
IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
// Generate the correct mnemonic
|
||||||
|
string myMnemonic(mnemonic);
|
||||||
|
|
||||||
|
// Special cases
|
||||||
|
if (!myMnemonic.compare("addi") && _numSrcRegs == 0) {
|
||||||
|
myMnemonic = "li";
|
||||||
|
} else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) {
|
||||||
|
myMnemonic = "lis";
|
||||||
|
}
|
||||||
|
ccprintf(ss, "%-10s ", myMnemonic);
|
||||||
|
|
||||||
|
// Print the first destination only
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
printReg(ss, _destRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the source register
|
||||||
|
if (_numSrcRegs > 0) {
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
printReg(ss, _srcRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the immediate value last
|
||||||
|
ss << ", " << (int32_t)imm;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string
|
||||||
|
IntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
// Print the first destination only
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
printReg(ss, _destRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the first source register
|
||||||
|
if (_numSrcRegs > 0) {
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
printReg(ss, _srcRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the shift
|
||||||
|
ss << ", " << sh;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string
|
||||||
|
IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
// Print the first destination only
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
printReg(ss, _destRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the first source register
|
||||||
|
if (_numSrcRegs > 0) {
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
printReg(ss, _srcRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the shift, mask begin and mask end
|
||||||
|
ss << ", " << sh << ", " << mb << ", " << me;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
176
src/arch/power/insts/integer.hh
Normal file
176
src/arch/power/insts/integer.hh
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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: Timothy M. Jones
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ARCH_POWER_INSTS_INTEGER_HH__
|
||||||
|
#define __ARCH_POWER_INSTS_INTEGER_HH__
|
||||||
|
|
||||||
|
#include "arch/power/insts/static_inst.hh"
|
||||||
|
#include "base/cprintf.hh"
|
||||||
|
#include "base/bitfield.hh"
|
||||||
|
|
||||||
|
namespace PowerISA
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We provide a base class for integer operations and then inherit for
|
||||||
|
* several other classes. These specialise for instructions using immediate
|
||||||
|
* values and also rotate instructions. We also need to have versions that
|
||||||
|
* consider the Rc and OE bits.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for integer operations.
|
||||||
|
*/
|
||||||
|
class IntOp : public PowerStaticInst
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool rcSet;
|
||||||
|
bool oeSet;
|
||||||
|
|
||||||
|
// Needed for srawi only
|
||||||
|
uint32_t sh;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
IntOp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: PowerStaticInst(mnem, _machInst, __opClass),
|
||||||
|
rcSet(false), oeSet(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the CR (condition register) field using signed comparison */
|
||||||
|
inline uint32_t
|
||||||
|
makeCRField(int32_t a, int32_t b, uint32_t xerSO) const
|
||||||
|
{
|
||||||
|
uint32_t c = xerSO;
|
||||||
|
|
||||||
|
/* We've pre-shifted the immediate values here */
|
||||||
|
if (a < b) { c += 0x8; }
|
||||||
|
else if (a > b) { c += 0x4; }
|
||||||
|
else { c += 0x2; }
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the CR (condition register) field using unsigned comparison */
|
||||||
|
inline uint32_t
|
||||||
|
makeCRField(uint32_t a, uint32_t b, uint32_t xerSO) const
|
||||||
|
{
|
||||||
|
uint32_t c = xerSO;
|
||||||
|
|
||||||
|
/* We've pre-shifted the immediate values here */
|
||||||
|
if (a < b) { c += 0x8; }
|
||||||
|
else if (a > b) { c += 0x4; }
|
||||||
|
else { c += 0x2; }
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for integer immediate (signed and unsigned) operations.
|
||||||
|
*/
|
||||||
|
class IntImmOp : public IntOp
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int32_t imm;
|
||||||
|
uint32_t uimm;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: IntOp(mnem, _machInst, __opClass),
|
||||||
|
imm(sext<16>(machInst.si)),
|
||||||
|
uimm(machInst.si)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for integer operations with a shift.
|
||||||
|
*/
|
||||||
|
class IntShiftOp : public IntOp
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
uint32_t sh;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: IntOp(mnem, _machInst, __opClass),
|
||||||
|
sh(machInst.sh)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for integer rotate operations.
|
||||||
|
*/
|
||||||
|
class IntRotateOp : public IntShiftOp
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
uint32_t mb;
|
||||||
|
uint32_t me;
|
||||||
|
uint32_t fullMask;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: IntShiftOp(mnem, _machInst, __opClass),
|
||||||
|
mb(machInst.mb),
|
||||||
|
me(machInst.me)
|
||||||
|
{
|
||||||
|
if (me >= mb) {
|
||||||
|
fullMask = mask(31 - mb, 31 - me);
|
||||||
|
} else {
|
||||||
|
fullMask = ~mask(31 - (me + 1), 31 - (mb - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
rotateValue(uint32_t rs, uint32_t shift) const
|
||||||
|
{
|
||||||
|
uint32_t n = shift & 31;
|
||||||
|
return (rs << n) | (rs >> (32 - n));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // PowerISA namespace
|
||||||
|
|
||||||
|
#endif //__ARCH_POWER_INSTS_INTEGER_HH__
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,62 +24,51 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Timothy M. Jones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#include "arch/power/insts/mem.hh"
|
||||||
* DeclListAST.C
|
#include "base/loader/symtab.hh"
|
||||||
*
|
|
||||||
* Description: See DeclListAST.hh
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mem/slicc/ast/DeclListAST.hh"
|
using namespace PowerISA;
|
||||||
|
|
||||||
DeclListAST::DeclListAST(Vector<DeclAST*>* vec_ptr)
|
std::string
|
||||||
: AST()
|
MemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
assert(vec_ptr != NULL);
|
return csprintf("%-10s", mnemonic);
|
||||||
m_vec_ptr = vec_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton constructor.
|
std::string
|
||||||
DeclListAST::DeclListAST(DeclAST* Decl_ptr)
|
MemDispOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
: AST()
|
|
||||||
{
|
{
|
||||||
assert(Decl_ptr != NULL);
|
std::stringstream ss;
|
||||||
m_vec_ptr = new Vector<DeclAST*>;
|
|
||||||
m_vec_ptr->insertAtTop(Decl_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
DeclListAST::~DeclListAST()
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
{
|
|
||||||
int size = m_vec_ptr->size();
|
|
||||||
for(int i=0; i<size; i++) {
|
|
||||||
delete (*m_vec_ptr)[i];
|
|
||||||
}
|
|
||||||
delete m_vec_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeclListAST::generate() const
|
// Print the destination only for a load
|
||||||
{
|
if (!flags[IsStore]) {
|
||||||
int size = m_vec_ptr->size();
|
if (_numDestRegs > 0) {
|
||||||
for(int i=0; i<size; i++) {
|
|
||||||
(*m_vec_ptr)[i]->generate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeclListAST::findMachines() const
|
// If the instruction updates the source register with the
|
||||||
{
|
// EA, then this source register is placed in position 0,
|
||||||
int size = m_vec_ptr->size();
|
// therefore we print the last destination register.
|
||||||
for(int i=0; i<size; i++) {
|
printReg(ss, _destRegIdx[_numDestRegs-1]);
|
||||||
(*m_vec_ptr)[i]->findMachines();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DeclListAST::print(ostream& out) const
|
// Print the data register for a store
|
||||||
{
|
else {
|
||||||
assert(m_vec_ptr != NULL);
|
printReg(ss, _srcRegIdx[1]);
|
||||||
out << "[DeclListAST: " << *m_vec_ptr << "]";
|
}
|
||||||
|
|
||||||
|
// Print the displacement
|
||||||
|
ss << ", " << (int32_t)disp;
|
||||||
|
|
||||||
|
// Print the address register
|
||||||
|
ss << "(";
|
||||||
|
printReg(ss, _srcRegIdx[0]);
|
||||||
|
ss << ")";
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,62 +24,68 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Timothy M. Jones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#ifndef __ARCH_POWER_MEM_HH__
|
||||||
* TypeDeclAST.C
|
#define __ARCH_POWER_MEM_HH__
|
||||||
*
|
|
||||||
* Description: See TypeDeclAST.hh
|
#include "arch/power/insts/static_inst.hh"
|
||||||
*
|
|
||||||
* $Id: TypeDeclAST.C,v 3.1 2003/03/22 15:15:17 xu Exp $
|
namespace PowerISA
|
||||||
*
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for memory operations.
|
||||||
*/
|
*/
|
||||||
|
class MemOp : public PowerStaticInst
|
||||||
#include "mem/slicc/ast/TypeDeclAST.hh"
|
|
||||||
#include "mem/slicc/main.hh"
|
|
||||||
#include "mem/slicc/symbols/SymbolTable.hh"
|
|
||||||
|
|
||||||
TypeDeclAST::TypeDeclAST(TypeAST* type_ast_ptr,
|
|
||||||
PairListAST* pairs_ptr,
|
|
||||||
Vector<TypeFieldAST*>* field_vec_ptr)
|
|
||||||
: DeclAST(pairs_ptr)
|
|
||||||
{
|
{
|
||||||
m_type_ast_ptr = type_ast_ptr;
|
protected:
|
||||||
m_field_vec_ptr = field_vec_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeDeclAST::~TypeDeclAST()
|
/// Memory request flags. See mem_req_base.hh.
|
||||||
{
|
unsigned memAccessFlags;
|
||||||
delete m_type_ast_ptr;
|
/// Pointer to EAComp object.
|
||||||
if (m_field_vec_ptr != NULL) {
|
const StaticInstPtr eaCompPtr;
|
||||||
int size = m_field_vec_ptr->size();
|
/// Pointer to MemAcc object.
|
||||||
for(int i=0; i<size; i++) {
|
const StaticInstPtr memAccPtr;
|
||||||
delete (*m_field_vec_ptr)[i];
|
|
||||||
|
/// Constructor
|
||||||
|
MemOp(const char *mnem, MachInst _machInst, OpClass __opClass,
|
||||||
|
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
||||||
|
StaticInstPtr _memAccPtr = nullStaticInstPtr)
|
||||||
|
: PowerStaticInst(mnem, _machInst, __opClass),
|
||||||
|
memAccessFlags(0),
|
||||||
|
eaCompPtr(_eaCompPtr),
|
||||||
|
memAccPtr(_memAccPtr)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
delete m_field_vec_ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TypeDeclAST::generate()
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for memory operations with displacement.
|
||||||
|
*/
|
||||||
|
class MemDispOp : public MemOp
|
||||||
{
|
{
|
||||||
string machine_name;
|
protected:
|
||||||
string id = m_type_ast_ptr->toString();
|
|
||||||
|
|
||||||
// Make the new type
|
int16_t disp;
|
||||||
Type* new_type_ptr = new Type(id, getLocation(), getPairs(),
|
|
||||||
g_sym_table.getStateMachine());
|
|
||||||
g_sym_table.newSym(new_type_ptr);
|
|
||||||
|
|
||||||
// Add all of the fields of the type to it
|
/// Constructor
|
||||||
if (m_field_vec_ptr != NULL) {
|
MemDispOp(const char *mnem, MachInst _machInst, OpClass __opClass,
|
||||||
int size = m_field_vec_ptr->size();
|
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
|
||||||
for(int i=0; i<size; i++) {
|
StaticInstPtr _memAccPtr = nullStaticInstPtr)
|
||||||
(*m_field_vec_ptr)[i]->generate(new_type_ptr);
|
: MemOp(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
|
||||||
|
disp(machInst.d)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TypeDeclAST::print(ostream& out) const
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
{
|
};
|
||||||
out << "[TypeDecl: " << m_type_ast_ptr->toString() << "]";
|
|
||||||
}
|
} // PowerISA namespace
|
||||||
|
|
||||||
|
#endif //__ARCH_POWER_INSTS_MEM_HH__
|
60
src/arch/power/insts/misc.cc
Normal file
60
src/arch/power/insts/misc.cc
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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: Timothy M. Jones
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/power/insts/misc.hh"
|
||||||
|
|
||||||
|
using namespace PowerISA;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
MiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
// Print the first destination only
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
printReg(ss, _destRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the (possibly) two source registers
|
||||||
|
if (_numSrcRegs > 0) {
|
||||||
|
if (_numDestRegs > 0) {
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
printReg(ss, _srcRegIdx[0]);
|
||||||
|
if (_numSrcRegs > 1) {
|
||||||
|
ss << ", ";
|
||||||
|
printReg(ss, _srcRegIdx[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,31 +24,34 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Timothy M. Jones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#ifndef __ARCH_POWER_INSTS_MISC_HH__
|
||||||
* LiteralExprAST.C
|
#define __ARCH_POWER_INSTS_MISC_HH__
|
||||||
*
|
|
||||||
* Description: See LiteralExprAST.hh
|
|
||||||
*
|
|
||||||
* $Id: LiteralExprAST.C,v 3.1 2002/10/22 21:27:52 milo Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mem/slicc/ast/LiteralExprAST.hh"
|
#include "arch/power/insts/static_inst.hh"
|
||||||
|
|
||||||
Type* LiteralExprAST::generate(string& code) const
|
namespace PowerISA
|
||||||
{
|
{
|
||||||
if (m_type == "string") {
|
|
||||||
code += "(\"" + *m_lit_ptr + "\")";
|
|
||||||
} else {
|
|
||||||
code += "(" + *m_lit_ptr + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
Type* type_ptr = g_sym_table.getType(m_type);
|
/**
|
||||||
if (type_ptr == NULL) {
|
* Class for misc operations.
|
||||||
// Can't find the type
|
*/
|
||||||
error("Internal: can't primitive type '" + m_type + "'");
|
class MiscOp : public PowerStaticInst
|
||||||
}
|
{
|
||||||
return type_ptr;
|
protected:
|
||||||
}
|
|
||||||
|
/// Constructor
|
||||||
|
MiscOp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
|
: PowerStaticInst(mnem, _machInst, __opClass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // PowerISA namespace
|
||||||
|
|
||||||
|
#endif //__ARCH_POWER_INSTS_MISC_HH__
|
62
src/arch/power/insts/static_inst.cc
Normal file
62
src/arch/power/insts/static_inst.cc
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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: Timothy M. Jones
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/power/insts/static_inst.hh"
|
||||||
|
|
||||||
|
using namespace PowerISA;
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStaticInst::printReg(std::ostream &os, int reg) const
|
||||||
|
{
|
||||||
|
if (reg < FP_Base_DepTag) {
|
||||||
|
ccprintf(os, "r%d", reg);
|
||||||
|
} else if (reg < Ctrl_Base_DepTag) {
|
||||||
|
ccprintf(os, "f%d", reg - FP_Base_DepTag);
|
||||||
|
} else {
|
||||||
|
switch (reg - Ctrl_Base_DepTag) {
|
||||||
|
case 0: ccprintf(os, "cr"); break;
|
||||||
|
case 1: ccprintf(os, "xer"); break;
|
||||||
|
case 2: ccprintf(os, "lr"); break;
|
||||||
|
case 3: ccprintf(os, "ctr"); break;
|
||||||
|
default: ccprintf(os, "unknown_reg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
PowerStaticInst::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ccprintf(ss, "%-10s ", mnemonic);
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -25,58 +24,47 @@
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Timothy M. Jones
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#ifndef __ARCH_POWER_INSTS_STATICINST_HH__
|
||||||
* PairListAST.hh
|
#define __ARCH_POWER_INSTS_STATICINST_HH__
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PairListAST_H
|
#include "base/trace.hh"
|
||||||
#define PairListAST_H
|
#include "cpu/static_inst.hh"
|
||||||
|
|
||||||
#include "mem/slicc/slicc_global.hh"
|
namespace PowerISA
|
||||||
#include "mem/slicc/ast/AST.hh"
|
{
|
||||||
#include "mem/slicc/ast/PairAST.hh"
|
|
||||||
|
|
||||||
|
class PowerStaticInst : public StaticInst
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
class PairListAST : public AST {
|
// Constructor
|
||||||
public:
|
PowerStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||||
// Constructors
|
: StaticInst(mnem, _machInst, __opClass)
|
||||||
PairListAST() : AST() {}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Destructor
|
// Insert a condition value into a CR (condition register) field
|
||||||
//~PairListAST();
|
inline uint32_t
|
||||||
|
insertCRField(uint32_t cr, uint32_t bf, uint32_t value) const
|
||||||
|
{
|
||||||
|
uint32_t bits = value << ((7 - bf) * 4);
|
||||||
|
uint32_t mask = ~(0xf << ((7 - bf) * 4));
|
||||||
|
return (cr & mask) | bits;
|
||||||
|
}
|
||||||
|
|
||||||
// Public Methods
|
/// Print a register name for disassembly given the unique
|
||||||
void addPair(PairAST* pair_ptr);
|
/// dependence tag number (FP or int).
|
||||||
void print(ostream& out) const;
|
void
|
||||||
private:
|
printReg(std::ostream &os, int reg) const;
|
||||||
// Private Methods
|
|
||||||
|
|
||||||
// Private copy constructor and assignment operator
|
std::string
|
||||||
PairListAST(const PairListAST& obj);
|
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
PairListAST& operator=(const PairListAST& obj);
|
|
||||||
|
|
||||||
// Data Members (m_ prefix)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Output operator declaration
|
} // PowerISA namespace
|
||||||
ostream& operator<<(ostream& out, const PairListAST& obj);
|
|
||||||
|
|
||||||
// ******************* Definitions *******************
|
#endif //__ARCH_POWER_INSTS_STATICINST_HH__
|
||||||
|
|
||||||
// Output operator definition
|
|
||||||
extern inline
|
|
||||||
ostream& operator<<(ostream& out, const PairListAST& obj)
|
|
||||||
{
|
|
||||||
obj.print(out);
|
|
||||||
out << flush;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //PairListAST_H
|
|
115
src/arch/power/isa.hh
Normal file
115
src/arch/power/isa.hh
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 The Regents of The University of Michigan
|
||||||
|
* Copyright (c) 2009 The University of Edinburgh
|
||||||
|
* 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
|
||||||
|
* Timothy M. Jones
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ARCH_POWER_ISA_HH__
|
||||||
|
#define __ARCH_POWER_ISA_HH__
|
||||||
|
|
||||||
|
#include "arch/power/registers.hh"
|
||||||
|
#include "arch/power/types.hh"
|
||||||
|
#include "base/misc.hh"
|
||||||
|
|
||||||
|
class ThreadContext;
|
||||||
|
class Checkpoint;
|
||||||
|
class EventManager;
|
||||||
|
|
||||||
|
namespace PowerISA
|
||||||
|
{
|
||||||
|
|
||||||
|
class ISA
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
MiscReg dummy;
|
||||||
|
MiscReg miscRegs[NumMiscRegs];
|
||||||
|
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
clear()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MiscReg
|
||||||
|
readMiscRegNoEffect(int misc_reg)
|
||||||
|
{
|
||||||
|
fatal("Power does not currently have any misc regs defined\n");
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
MiscReg
|
||||||
|
readMiscReg(int misc_reg, ThreadContext *tc)
|
||||||
|
{
|
||||||
|
fatal("Power does not currently have any misc regs defined\n");
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setMiscRegNoEffect(int misc_reg, const MiscReg &val)
|
||||||
|
{
|
||||||
|
fatal("Power does not currently have any misc regs defined\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
|
||||||
|
{
|
||||||
|
fatal("Power does not currently have any misc regs defined\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
flattenIntIndex(int reg)
|
||||||
|
{
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
flattenFloatIndex(int reg)
|
||||||
|
{
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
serialize(EventManager *em, std::ostream &os)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unserialize(EventManager *em, Checkpoint *cp, const std::string §ion)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ISA()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // PowerISA namespace
|
||||||
|
|
||||||
|
#endif // __ARCH_POWER_ISA_HH__
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue