[gem5-dev] Change in gem5/gem5[develop]: configs: Make GPU_VIPER config python3 friendly

2020-10-09 Thread Matthew Poremba (Gerrit) via gem5-dev
Matthew Poremba has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35855 )



Change subject: configs: Make GPU_VIPER config python3 friendly
..

configs: Make GPU_VIPER config python3 friendly

There is no xrange in python3. This will be required when eventually
20.2 is released.

Change-Id: I3a0da6353b70e6e17ce1f77d6177d48059e32487
---
M configs/ruby/GPU_VIPER.py
1 file changed, 2 insertions(+), 2 deletions(-)



diff --git a/configs/ruby/GPU_VIPER.py b/configs/ruby/GPU_VIPER.py
index 6a6dec5..6a5e416 100644
--- a/configs/ruby/GPU_VIPER.py
+++ b/configs/ruby/GPU_VIPER.py
@@ -661,7 +661,7 @@
 # SQC also in GPU cluster
 gpuCluster.add(sqc_cntrl)

-for i in xrange(options.num_scalar_cache):
+for i in range(options.num_scalar_cache):
 scalar_cntrl = SQCCntrl(TCC_select_num_bits = TCC_bits)
 scalar_cntrl.create(options, ruby_system, system)

@@ -683,7 +683,7 @@

 gpuCluster.add(scalar_cntrl)

-for i in xrange(options.num_cp):
+for i in range(options.num_cp):

 tcp_ID = options.num_compute_units + i
 sqc_ID = options.num_sqc + i

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/35855
To unsubscribe, or for help writing mail filters, visit  
https://gem5-review.googlesource.com/settings


Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I3a0da6353b70e6e17ce1f77d6177d48059e32487
Gerrit-Change-Number: 35855
Gerrit-PatchSet: 1
Gerrit-Owner: Matthew Poremba 
Gerrit-MessageType: newchange
___
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

[gem5-dev] Change in gem5/gem5[develop]: arch: Put isa_parser operands into families.

2020-10-09 Thread Gabe Black (Gerrit) via gem5-dev
Gabe Black has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35819 )



Change subject: arch: Put isa_parser operands into families.
..

arch: Put isa_parser operands into families.

When creating a new operand class, it will be associated with a family
to keep, for instance, the operands for different ISAs separate from one
another. To create a new IntReg operand for ARM for instance, you might
one day declare one like this:

arm_operands = isa_parser.operands.families['ARM']

class ArmIntReg(arm_operands.IntReg):
abstract = True
dflt_ext = 'uw'

class Rd(ArmIntReg):
reg_spec = 'RD'

Then when you define an ARM instruction, you would tell it to use
operand family "ARM". Also, that operand family will automatically end
up with classes attached to it with the names ArmIntReg and Rd which can
be further subclassed, or referred to in a different body of code.

Change-Id: Idef457a917ccaafd299e3b8621544ee104d44c35
---
M src/arch/arm/isa/operands.isa
M src/arch/isa_parser/isa_parser.py
M src/arch/isa_parser/operand_list.py
R src/arch/isa_parser/operands.py
M src/arch/mips/isa/operands.isa
M src/arch/power/isa/operands.isa
M src/arch/riscv/isa/operands.isa
M src/arch/sparc/isa/operands.isa
M src/arch/x86/isa/operands.isa
9 files changed, 204 insertions(+), 128 deletions(-)



diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index 134c51f..961008b 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -681,7 +681,7 @@
 'XURc' : intRegX64('urc'),

 #Memory Operand
-'Mem': ('Mem', 'uw', None, (None, 'IsLoad', 'IsStore'), srtNormal),
+'Mem': ('Memory', 'uw', None, (None, 'IsLoad', 'IsStore'), srtNormal),

 #PCState fields
 'RawPC': pcStateReg('pc', srtPC),
diff --git a/src/arch/isa_parser/isa_parser.py  
b/src/arch/isa_parser/isa_parser.py

index 999d92f..80d50b7 100755
--- a/src/arch/isa_parser/isa_parser.py
+++ b/src/arch/isa_parser/isa_parser.py
@@ -44,9 +44,10 @@
 # get type names
 from types import *

+from . import operands
+
 from m5.util.grammar import Grammar
 from .operand_list import *
-from .operand_types import *
 from .util import *

 debug=False
@@ -466,16 +467,13 @@
 # variable to hold templates
 self.templateMap = {}

-# variable to hold operands
-self.operandNameMap = {}
-
-# Regular expressions for working with operands
-self._operandsRE = None
-self._operandsWithExtRE = None
-
 # This dictionary maps format name strings to Format objects.
 self.formatMap = {}

+# The operand family of this ISA. This should be named after the  
ISA,

+# but for now just call it 'main'.
+self.operandFamily = operands.Family('main')
+
 # Track open files and, if applicable, how many chunks it has been
 # split into so far.
 self.files = {}
@@ -505,16 +503,6 @@
 self.maxInstDestRegs = 0
 self.maxMiscDestRegs = 0

-def operandsRE(self):
-if not self._operandsRE:
-self.buildOperandREs()
-return self._operandsRE
-
-def operandsWithExtRE(self):
-if not self._operandsWithExtRE:
-self.buildOperandREs()
-return self._operandsWithExtRE
-
 def __getitem__(self, i):# Allow object (self) to be
 return getattr(self, i)  # passed to %-substitutions

@@ -977,11 +965,11 @@
 decode_block=self.exportContext["decode_block"]).emit()

 # Define the mapping from operand type extensions to C++ types and
-# bit widths (stored in operandTypeMap).
+# bit widths (stored in operandFamily.suffixes).
 def p_def_operand_types(self, t):
 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI'
 try:
-self.operandTypeMap = eval('{' + t[3] + '}')
+self.operandFamily.addSuffixes(eval('{' + t[3] + '}'))
 except Exception as exc:
 if debug:
 raise
@@ -989,10 +977,10 @@
   'In def operand_types: %s' % exc)

 # Define the mapping from operand names to operand classes and
-# other traits.  Stored in operandNameMap.
+# other traits.  Stored in operandFamily.
 def p_def_operands(self, t):
 'def_operands : DEF OPERANDS CODELIT SEMI'
-if not hasattr(self, 'operandTypeMap'):
+if not self.operandFamily.suffixes:
 error(t.lineno(1),
   'error: operand types must be defined before operands')
 try:
@@ -1429,7 +1417,6 @@
 self.formatMap[id] = Format(id, params, code)

 def buildOperandNameMap(self, user_dict, lineno):
-operand_name = {}
 for op_name, val in user_dict.items():

 # Check if extra attributes have been specified.
@@ -1469,7 +1456,7 @@
 'read_code', 'write_code',
 

[gem5-dev] Change in gem5/gem5[develop]: WIP dynamic index arrays

2020-10-09 Thread Gabe Black (Gerrit) via gem5-dev
Gabe Black has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35821 )


Change subject: WIP dynamic index arrays
..

WIP dynamic index arrays

Change-Id: I1f9d85c4ddc6fd46084f409592fb5f5bce480ce9
---
M src/arch/SConscript
M src/arch/arm/registers.hh
M src/arch/isa_parser/isa_parser.py
M src/arch/isa_parser/operands.py
M src/arch/mips/isa/base.isa
M src/arch/mips/isa/formats/branch.isa
M src/arch/mips/isa/formats/dsp.isa
M src/arch/mips/isa/formats/fp.isa
M src/arch/mips/isa/formats/int.isa
M src/arch/mips/registers.hh
M src/arch/power/registers.hh
M src/arch/riscv/registers.hh
M src/arch/sparc/insts/branch.cc
M src/arch/sparc/insts/integer.cc
M src/arch/sparc/insts/static_inst.cc
M src/arch/sparc/insts/static_inst.hh
M src/arch/sparc/registers.hh
M src/arch/x86/registers.hh
M src/cpu/base_dyn_inst.hh
M src/cpu/base_dyn_inst_impl.hh
M src/cpu/minor/dyn_inst.hh
M src/cpu/minor/scoreboard.cc
M src/cpu/o3/dyn_inst.hh
M src/cpu/o3/dyn_inst_impl.hh
M src/cpu/static_inst.hh
M src/cpu/trace/trace_cpu.cc
M src/cpu/trace/trace_cpu.hh
27 files changed, 108 insertions(+), 205 deletions(-)



diff --git a/src/arch/SConscript b/src/arch/SConscript
index 5fb543e..273fd3e 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -186,8 +186,6 @@
 add_gen('exec-g.cc.inc')
 add_gen('exec-ns.cc.inc')

-add_gen('max_inst_regs.hh')
-

 # These generated files are also top level sources.
 def source_gen(name):
diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh
index 630a145..7751db6 100644
--- a/src/arch/arm/registers.hh
+++ b/src/arch/arm/registers.hh
@@ -42,7 +42,6 @@
 #define __ARCH_ARM_REGISTERS_HH__

 #include "arch/arm/ccregs.hh"
-#include "arch/arm/generated/max_inst_regs.hh"
 #include "arch/arm/intregs.hh"
 #include "arch/arm/miscregs.hh"
 #include "arch/arm/types.hh"
@@ -52,13 +51,6 @@
 namespace ArmISA {


-// For a predicated instruction, we need all the
-// destination registers to also be sources
-const int MaxInstSrcRegs = ArmISAInst::MaxInstDestRegs +
-ArmISAInst::MaxInstSrcRegs;
-using ArmISAInst::MaxInstDestRegs;
-using ArmISAInst::MaxMiscDestRegs;
-
 // Number of VecElem per Vector Register considering only pre-SVE
 // Advanced SIMD registers.
 constexpr unsigned NumVecElemPerNeonVecReg = 4;
diff --git a/src/arch/isa_parser/isa_parser.py b/src/arch/isa_parser/isa_parser.py
index 80d50b7..b80ec09 100755
--- a/src/arch/isa_parser/isa_parser.py
+++ b/src/arch/isa_parser/isa_parser.py
@@ -47,6 +47,7 @@
 from . import operands

 from m5.util.grammar import Grammar
+from .bitfields import *
 from .operand_list import *
 from .util import *

@@ -281,47 +282,6 @@

 #
 #
-#  Bitfield Operator Support
-#
-#
-
-bitOp1ArgRE = re.compile(r'<\s*(\w+)\s*:\s*>')
-
-bitOpWordRE = re.compile(r'(?')
-bitOpExprRE = re.compile(r'\)<\s*(\w+)\s*:\s*(\w+)\s*>')
-
-def substBitOps(code):
-# first convert single-bit selectors to two-index form
-# i.e.,  --> 
-code = bitOp1ArgRE.sub(r'<\1:\1>', code)
-# simple case: selector applied to ID (name)
-# i.e., foo --> bits(foo, a, b)
-code = bitOpWordRE.sub(r'bits(\1, \2, \3)', code)
-# if selector is applied to expression (ending in ')'),
-# we need to search backward for matching '('
-match = bitOpExprRE.search(code)
-while match:
-exprEnd = match.start()
-here = exprEnd - 1
-nestLevel = 1
-while nestLevel > 0:
-if code[here] == '(':
-nestLevel -= 1
-elif code[here] == ')':
-nestLevel += 1
-here -= 1
-if here < 0:
-sys.exit("Didn't find '('!")
-exprStart = here+1
-newExpr = r'bits(%s, %s, %s)' % (code[exprStart:exprEnd+1],
- match.group(1), match.group(2))
-code = code[:exprStart] + newExpr + code[match.end():]
-match = bitOpExprRE.search(code)
-return code
-
-
-#
-#
 # Code Parser
 #
 # The remaining code is the support for automatically extracting
@@ -380,8 +340,7 @@
 # The header of the constructor declares the variables to be used
 # in the body of the constructor.
 header = ''
-header += '\n\t_numSrcRegs = 0;'
-header += '\n\t_numDestRegs = 0;'
+header += '\n\t_numMiscDestRegs = 0;'
 header += '\n\t_numFPDestRegs = 0;'
 header += 

[gem5-dev] Change in gem5/gem5[develop]: arch: Clean up the __init__s in (Sub)OperandList.

2020-10-09 Thread Gabe Black (Gerrit) via gem5-dev
Gabe Black has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35818 )



Change subject: arch: Clean up the __init__s in (Sub)OperandList.
..

arch: Clean up the __init__s in (Sub)OperandList.

These had a lot of for loops and ifs and nesting. Python lets you avoid
that, which makes the code easier to read and more intuitive to
understand.

Change-Id: I576bf1de9e5b2268717a535ca42f2db669d83ed2
---
M src/arch/isa_parser/operand_list.py
1 file changed, 51 insertions(+), 75 deletions(-)



diff --git a/src/arch/isa_parser/operand_list.py  
b/src/arch/isa_parser/operand_list.py

index 86de5a5..12a23d9 100755
--- a/src/arch/isa_parser/operand_list.py
+++ b/src/arch/isa_parser/operand_list.py
@@ -101,59 +101,42 @@
 self.append(op_desc)

 self.sort()
+
 # enumerate source & dest register operands... used in building
 # constructor later
-self.numSrcRegs = 0
-self.numDestRegs = 0
-self.numFPDestRegs = 0
-self.numIntDestRegs = 0
-self.numVecDestRegs = 0
-self.numVecPredDestRegs = 0
-self.numCCDestRegs = 0
-self.numMiscDestRegs = 0
-self.memOperand = None
+regs = list(filter(lambda i: i.isReg(), self.items))
+mem = list(filter(lambda i: i.isMem(), self.items))
+srcs = list(filter(lambda r: r.is_src, regs))
+dests = list(filter(lambda r: r.is_dest, regs))
+
+for idx, reg in enumerate(srcs):
+reg.src_reg_idx = idx
+for idx, reg in enumerate(dests):
+reg.dest_reg_idx = idx
+
+self.numSrcRegs = len(srcs)
+self.numDestRegs = len(dests)
+self.numFPDestRegs = sum(r.isFloatReg() for r in dests)
+self.numIntDestRegs = sum(r.isIntReg() for r in dests)
+self.numVecDestRegs = sum(r.isVecReg() for r in dests)
+self.numVecPredDestRegs = sum(r.isVecPredReg() for r in dests)
+self.numCCDestRegs = sum(r.isCCReg() for r in dests)
+self.numMiscDestRegs = sum(r.isControlReg() for r in dests)
+
+if len(mem) > 1:
+error("Code block has more than one memory operand")
+
+self.memOperand = mem[0] if mem else None

 # Flags to keep track if one or more operands are to be  
read/written

 # conditionally.
-self.predRead = False
-self.predWrite = False
+self.predRead = any(i.hasReadPred() for i in self.items)
+self.predWrite = any(i.hasWritePred() for i in self.items)

-for op_desc in self.items:
-if op_desc.isReg():
-if op_desc.is_src:
-op_desc.src_reg_idx = self.numSrcRegs
-self.numSrcRegs += 1
-if op_desc.is_dest:
-op_desc.dest_reg_idx = self.numDestRegs
-self.numDestRegs += 1
-if op_desc.isFloatReg():
-self.numFPDestRegs += 1
-elif op_desc.isIntReg():
-self.numIntDestRegs += 1
-elif op_desc.isVecReg():
-self.numVecDestRegs += 1
-elif op_desc.isVecPredReg():
-self.numVecPredDestRegs += 1
-elif op_desc.isCCReg():
-self.numCCDestRegs += 1
-elif op_desc.isControlReg():
-self.numMiscDestRegs += 1
-elif op_desc.isMem():
-if self.memOperand:
-error("Code block has more than one memory operand.")
-self.memOperand = op_desc
-
-# Check if this operand has read/write predication. If true,  
then

-# the microop will dynamically index source/dest registers.
-self.predRead = self.predRead or op_desc.hasReadPred()
-self.predWrite = self.predWrite or op_desc.hasWritePred()
-
-if parser.maxInstSrcRegs < self.numSrcRegs:
-parser.maxInstSrcRegs = self.numSrcRegs
-if parser.maxInstDestRegs < self.numDestRegs:
-parser.maxInstDestRegs = self.numDestRegs
-if parser.maxMiscDestRegs < self.numMiscDestRegs:
-parser.maxMiscDestRegs = self.numMiscDestRegs
+parser.maxInstSrcRegs = max(parser.maxInstSrcRegs, self.numSrcRegs)
+parser.maxInstDestRegs = max(parser.maxInstDestRegs,  
self.numDestRegs)

+parser.maxMiscDestRegs = max(parser.maxInstDestRegs,
+ self.numMiscDestRegs)

 # now make a final pass to finalize op_desc fields that may depend
 # on the register enumeration
@@ -238,40 +221,33 @@
 self.append(requestor_list.bases[op_base])

 self.sort()
-self.memOperand = None
+
+pcs = list(filter(lambda i: i.isPCState(), self.items))
+mem = list(filter(lambda 

[gem5-dev] Change in gem5/gem5[develop]: arch: Pull the (Sub)OperandList classes into their own file.

2020-10-09 Thread Gabe Black (Gerrit) via gem5-dev
Gabe Black has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35816 )



Change subject: arch: Pull the (Sub)OperandList classes into their own file.
..

arch: Pull the (Sub)OperandList classes into their own file.

Another step in breaking down the isa parser into more manageable parts.

Change-Id: I0c5e70fe481bd17c0069b768129731e99a93ed0d
---
M src/arch/isa_parser/isa_parser.py
A src/arch/isa_parser/operand_list.py
M src/arch/isa_parser/util.py
3 files changed, 306 insertions(+), 264 deletions(-)



diff --git a/src/arch/isa_parser/isa_parser.py  
b/src/arch/isa_parser/isa_parser.py

index eddba0c..999d92f 100755
--- a/src/arch/isa_parser/isa_parser.py
+++ b/src/arch/isa_parser/isa_parser.py
@@ -45,6 +45,7 @@
 from types import *

 from m5.util.grammar import Grammar
+from .operand_list import *
 from .operand_types import *
 from .util import *

@@ -340,270 +341,6 @@
 else:
 return [ arg ]

-class OperandList(object):
-'''Find all the operands in the given code block.  Returns an operand
-descriptor list (instance of class OperandList).'''
-def __init__(self, parser, code):
-self.items = []
-self.bases = {}
-# delete strings and comments so we don't match on operands inside
-for regEx in (stringRE, commentRE):
-code = regEx.sub('', code)
-# search for operands
-next_pos = 0
-while 1:
-match = parser.operandsRE().search(code, next_pos)
-if not match:
-# no more matches: we're done
-break
-op = match.groups()
-# regexp groups are operand full name, base, and extension
-(op_full, op_base, op_ext) = op
-# If is a elem operand, define or update the corresponding
-# vector operand
-isElem = False
-if op_base in parser.elemToVector:
-isElem = True
-elem_op = (op_base, op_ext)
-op_base = parser.elemToVector[op_base]
-op_ext = '' # use the default one
-# if the token following the operand is an assignment, this is
-# a destination (LHS), else it's a source (RHS)
-is_dest = (assignRE.match(code, match.end()) != None)
-is_src = not is_dest
-
-# see if we've already seen this one
-op_desc = self.find_base(op_base)
-if op_desc:
-if op_ext and op_ext != '' and op_desc.ext != op_ext:
-error ('Inconsistent extensions for operand %s: %s  
- %s' \

-% (op_base, op_desc.ext, op_ext))
-op_desc.is_src = op_desc.is_src or is_src
-op_desc.is_dest = op_desc.is_dest or is_dest
-if isElem:
-(elem_base, elem_ext) = elem_op
-found = False
-for ae in op_desc.active_elems:
-(ae_base, ae_ext) = ae
-if ae_base == elem_base:
-if ae_ext != elem_ext:
-error('Inconsistent extensions for elem'
-  ' operand %s' % elem_base)
-else:
-found = True
-if not found:
-op_desc.active_elems.append(elem_op)
-else:
-# new operand: create new descriptor
-op_desc = parser.operandNameMap[op_base](parser,
-op_full, op_ext, is_src, is_dest)
-# if operand is a vector elem, add the corresponding vector
-# operand if not already done
-if isElem:
-op_desc.elemExt = elem_op[1]
-op_desc.active_elems = [elem_op]
-self.append(op_desc)
-# start next search after end of current match
-next_pos = match.end()
-self.sort()
-# enumerate source & dest register operands... used in building
-# constructor later
-self.numSrcRegs = 0
-self.numDestRegs = 0
-self.numFPDestRegs = 0
-self.numIntDestRegs = 0
-self.numVecDestRegs = 0
-self.numVecPredDestRegs = 0
-self.numCCDestRegs = 0
-self.numMiscDestRegs = 0
-self.memOperand = None
-
-# Flags to keep track if one or more operands are to be  
read/written

-# conditionally.
-self.predRead = False
-self.predWrite = False
-
-for op_desc in self.items:
-if op_desc.isReg():
-if op_desc.is_src:
-op_desc.src_reg_idx = self.numSrcRegs
-self.numSrcRegs += 1
-if op_desc.is_dest:
-op_desc.dest_reg_idx = self.numDestRegs
- 

[gem5-dev] Change in gem5/gem5[develop]: arch: Use finditer in the (Sub)OperandList classes.

2020-10-09 Thread Gabe Black (Gerrit) via gem5-dev
Gabe Black has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35817 )



Change subject: arch: Use finditer in the (Sub)OperandList classes.
..

arch: Use finditer in the (Sub)OperandList classes.

This method returns an iterator which goes through all the
non-overlapping matches for the given RE, without having to hand code
that same behavior with the more basic "search" method.

Change-Id: I4c4d95cfc8f72125566222aebb56604c3e9e2b03
---
M src/arch/isa_parser/operand_list.py
1 file changed, 5 insertions(+), 16 deletions(-)



diff --git a/src/arch/isa_parser/operand_list.py  
b/src/arch/isa_parser/operand_list.py

index 076b77e..86de5a5 100755
--- a/src/arch/isa_parser/operand_list.py
+++ b/src/arch/isa_parser/operand_list.py
@@ -49,13 +49,9 @@
 # delete strings and comments so we don't match on operands inside
 for regEx in (stringRE, commentRE):
 code = regEx.sub('', code)
+
 # search for operands
-next_pos = 0
-while 1:
-match = parser.operandsRE().search(code, next_pos)
-if not match:
-# no more matches: we're done
-break
+for match in parser.operandsRE().finditer(code):
 op = match.groups()
 # regexp groups are operand full name, base, and extension
 (op_full, op_base, op_ext) = op
@@ -103,8 +99,7 @@
 op_desc.elemExt = elem_op[1]
 op_desc.active_elems = [elem_op]
 self.append(op_desc)
-# start next search after end of current match
-next_pos = match.end()
+
 self.sort()
 # enumerate source & dest register operands... used in building
 # constructor later
@@ -219,13 +214,9 @@
 # delete strings and comments so we don't match on operands inside
 for regEx in (stringRE, commentRE):
 code = regEx.sub('', code)
+
 # search for operands
-next_pos = 0
-while 1:
-match = parser.operandsRE().search(code, next_pos)
-if not match:
-# no more matches: we're done
-break
+for match in parser.operandsRE().finditer(code):
 op = match.groups()
 # regexp groups are operand full name, base, and extension
 (op_full, op_base, op_ext) = op
@@ -246,8 +237,6 @@
 # if not, add a reference to it to this sub list
 self.append(requestor_list.bases[op_base])

-# start next search after end of current match
-next_pos = match.end()
 self.sort()
 self.memOperand = None
 # Whether the whole PC needs to be read so parts of it can be  
accessed


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/35817
To unsubscribe, or for help writing mail filters, visit  
https://gem5-review.googlesource.com/settings


Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I4c4d95cfc8f72125566222aebb56604c3e9e2b03
Gerrit-Change-Number: 35817
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black 
Gerrit-MessageType: newchange
___
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

[gem5-dev] Change in gem5/gem5[develop]: arch: Move bitfield support into its own file for isa_parser.

2020-10-09 Thread Gabe Black (Gerrit) via gem5-dev
Gabe Black has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35820 )


Change subject: arch: Move bitfield support into its own file for isa_parser.
..

arch: Move bitfield support into its own file for isa_parser.

Change-Id: Idd2101e65c0ea22830d8e61a2e8b1d7e8ddc9ea3
---
A src/arch/isa_parser/bitfields.py
1 file changed, 81 insertions(+), 0 deletions(-)



diff --git a/src/arch/isa_parser/bitfields.py b/src/arch/isa_parser/bitfields.py
new file mode 100755
index 000..a3fd883
--- /dev/null
+++ b/src/arch/isa_parser/bitfields.py
@@ -0,0 +1,81 @@
+# Copyright (c) 2014, 2016, 2018-2019 ARM Limited
+# All rights reserved
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder.  You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# Copyright (c) 2003-2005 The Regents of The University of Michigan
+# Copyright (c) 2013,2015 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.
+
+import re
+import sys
+
+#
+#
+#  Bitfield Operator Support
+#
+#
+
+bitOp1ArgRE = re.compile(r'<\s*(\w+)\s*:\s*>')
+
+bitOpWordRE = re.compile(r'(?')
+bitOpExprRE = re.compile(r'\)<\s*(\w+)\s*:\s*(\w+)\s*>')
+
+def substBitOps(code):
+# first convert single-bit selectors to two-index form
+# i.e.,  --> 
+code = bitOp1ArgRE.sub(r'<\1:\1>', code)
+# simple case: selector applied to ID (name)
+# i.e., foo --> bits(foo, a, b)
+code = bitOpWordRE.sub(r'bits(\1, \2, \3)', code)
+# if selector is applied to expression (ending in ')'),
+# we need to search backward for matching '('
+match = bitOpExprRE.search(code)
+while match:
+exprEnd = match.start()
+here = exprEnd - 1
+nestLevel = 1
+while nestLevel > 0:
+if code[here] == '(':
+nestLevel -= 1
+elif code[here] == ')':
+nestLevel += 1
+here -= 1
+if here < 0:
+sys.exit("Didn't find '('!")
+exprStart = here+1
+newExpr = r'bits(%s, %s, %s)' % (code[exprStart:exprEnd+1],
+ match.group(1), match.group(2))
+code = code[:exprStart] + newExpr + code[match.end():]
+match = bitOpExprRE.search(code)
+return code

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/35820
To unsubscribe, or for help writing mail filters, visit

[gem5-dev] Change in gem5/gem5[develop]: x86: Change how IO port devices are structured in the PC platform.

Gabe Black has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35515 )


Change subject: x86: Change how IO port devices are structured in the PC  
platform.

..

x86: Change how IO port devices are structured in the PC platform.

Before, for historical reasons, the PCI host device was the default
responder on the IO bus, meaning that when there was any type of
transaction which didn't have a device to go to, it would end up
looking like a PCI config transaction. It's very unlikely that this is
what it actually was, and what would happen would be arbitrary and
probably not helpful.

Also, there was no device in place to respond to accesses in x86's IO
port address space. On a real system, these accesses just return junk
and are otherwise legal. On systems where there would be physical bus
wires they would probably return whatever the last data on the bus was.

This would have been helpful when the platform was first being set up
because it would make it obvious when the OS tried to access a device
that wasn't implemented, but there were a few cases where it would
purposefully fiddle with ports with nothing on them. These had one off
backing devices in the config which would handle the accesses
harmlessly, but if the OS changed and tried to access other ports, the
configs would need to be updated.

Now, the PCI host is just another device on the bus. It claims all of
the PCI config space addresses, so any config access, even ones which
don't go with a device, will go to it, and it can respond with all 1s
like it's supposed to.

In it's place, the default responder is now a bus. On that bus is
a device which responds to the entire IO port address range with 0s.
The default on *that* bus is a device which will mark any accesses
as bad.

With this setup, accesses which don't go to a device, including a
device on the IO port address space, will go to the IO bus's default
port. There, if the access was an IO access, it will go to the device
which replies successfully with all 0s. If not, it's marked as an
error.

The device which backs the entire IO address space doesn't conflict
with the actual IO devices, since the access will only go towards it
if it's otherwise unclaimed, and the devices on the default bus don't
participate in routing on the higher level IO bus.

Change-Id: Ie02ad7165dfad3ee6f4a762e2f01f7f1b8225168
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35515
Reviewed-by: Matthew Poremba 
Maintainer: Gabe Black 
Tested-by: kokoro 
---
M src/dev/x86/Pc.py
1 file changed, 16 insertions(+), 13 deletions(-)

Approvals:
  Matthew Poremba: Looks good to me, approved
  Gabe Black: Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/dev/x86/Pc.py b/src/dev/x86/Pc.py
index a0a9825..0ed2648 100644
--- a/src/dev/x86/Pc.py
+++ b/src/dev/x86/Pc.py
@@ -27,12 +27,13 @@
 from m5.params import *
 from m5.proxy import *

-from m5.objects.Device import IsaFake
+from m5.objects.Device import IsaFake, BadAddr
 from m5.objects.Platform import Platform
 from m5.objects.SouthBridge import SouthBridge
 from m5.objects.Terminal import Terminal
 from m5.objects.Uart import Uart8250
 from m5.objects.PciHost import GenericPciHost
+from m5.objects.XBar import IOXBar

 def x86IOAddress(port):
 IO_address_space_base = 0x8000
@@ -52,14 +53,6 @@
 south_bridge = SouthBridge()
 pci_host = PcPciHost()

-# "Non-existant" ports used for timing purposes by the linux kernel
-i_dont_exist1 = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1)
-i_dont_exist2 = IsaFake(pio_addr=x86IOAddress(0xed), pio_size=1)
-
-# Ports behind the pci config and data regsiters. These don't do  
anything,

-# but the linux kernel fiddles with them anway.
-behind_pci = IsaFake(pio_addr=x86IOAddress(0xcf8), pio_size=8)
-
 # Serial port and terminal
 com_1 = Uart8250()
 com_1.pio_addr = x86IOAddress(0x3f8)
@@ -73,14 +66,24 @@
 # A device to catch accesses to the non-existant floppy controller.
 fake_floppy = IsaFake(pio_addr=x86IOAddress(0x3f2), pio_size=2)

+# A bus for accesses not claimed by a specific device.
+default_bus = IOXBar()
+
+# A device to handle accesses to unclaimed IO ports.
+empty_isa = IsaFake(pio_addr=x86IOAddress(0), pio_size='64kB',
+ret_data8=0, ret_data16=0, ret_data32=0,  
ret_data64=0,

+pio=default_bus.mem_side_ports)
+
+# A device to handle any other type of unclaimed access.
+bad_addr = BadAddr(pio=default_bus.default)
+
 def attachIO(self, bus, dma_ports = []):
 self.south_bridge.attachIO(bus, dma_ports)
-self.i_dont_exist1.pio = bus.mem_side_ports
-self.i_dont_exist2.pio = bus.mem_side_ports
-self.behind_pci.pio = bus.mem_side_ports
 self.com_1.pio = bus.mem_side_ports
 self.fake_com_2.pio = 

[gem5-dev] Re: Build failed in Jenkins: Nightly #92

This just failed because I messed up the docker command for the test. I've
fixed this. I think they should pass tonight.

--
Dr. Bobby R. Bruce
Room 2235,
Kemper Hall, UC Davis
Davis,
CA, 95616

web: https://www.bobbybruce.net


On Fri, Oct 9, 2020 at 5:47 AM jenkins-no-reply--- via gem5-dev <
gem5-dev@gem5.org> wrote:

> See  >
>
> Changes:
>
> [giacomo.travaglini] arch-arm: Default ArmSystem to AArch64
>
> [Andreas.Sandberg] stats: Make Stats::Group::mergeStatGroup public
>
> [odanrc] mem-cache: Add missing StridePrefetcher invalidation
>
> [odanrc] mem-cache: Debug with blk's information instead of its state.
>
> [odanrc] mem-cache: Create a tagged entry class
>
> [odanrc] mem-cache: Isolate prefetching bit
>
> [odanrc] mem-cache: Isolate compression bit
>
> [odanrc] mem-cache: Encapsulate CacheBlk's status
>
> [tiago.muck] mem-ruby: MessageBuffer capacity check
>
> [tiago.muck] mem-ruby: Allow same-cycle enqueue
>
> [tiago.muck] mem-ruby: Network can use custom data msg size
>
> [tiago.muck] mem-ruby: additional WriteMask methods
>
> [tiago.muck] mem-ruby: fix include dependency
>
> [gabeblack] arch: Build the operand REs in the isa_parser on demand.
>
>
> --
> [...truncated 1.13 MB...]
> [   OK ] MicroPCTest.IsRomMicroPCTest (0 ms)
> [ RUN  ] MicroPCTest.IsNotRomMicroPCTest
> [   OK ] MicroPCTest.IsNotRomMicroPCTest (0 ms)
> [--] 5 tests from MicroPCTest (3 ms total)
>
> [--] 4 tests from TypesTest
> [ RUN  ] TypesTest.FloatToBits32
> [   OK ] TypesTest.FloatToBits32 (0 ms)
> [ RUN  ] TypesTest.floatToBits64
> [   OK ] TypesTest.floatToBits64 (0 ms)
> [ RUN  ] TypesTest.floatsToBitsDoubleInput
> [   OK ] TypesTest.floatsToBitsDoubleInput (0 ms)
> [ RUN  ] TypesTest.floatsToBitsFloatInput
> [   OK ] TypesTest.floatsToBitsFloatInput (0 ms)
> [--] 4 tests from TypesTest (2 ms total)
>
> [--] Global test environment tear-down
> [==] 19 tests from 3 test cases ran. (14 ms total)
> [  PASSED  ] 19 tests.
>  [ CXX] NULL/sim/byteswap.test.cc -> .po
>  [LINK]  -> NULL/base/uncontended_mutex.test.prof
> build/NULL/base/uncontended_mutex.test.prof
> --gtest_output=xml:build/NULL/unittests.prof/base/uncontended_mutex.test.xml
> Running main() from gtest_main.cc
> [==] Running 2 tests from 1 test case.
> [--] Global test environment set-up.
> [--] 2 tests from UncontendedMutex
> [ RUN  ] UncontendedMutex.Lock
> [   OK ] UncontendedMutex.Lock (201 ms)
> [ RUN  ] UncontendedMutex.HeavyContention
> [   OK ] UncontendedMutex.HeavyContention (79 ms)
> [--] 2 tests from UncontendedMutex (280 ms total)
>
> [--] Global test environment tear-down
> [==] 2 tests from 1 test case ran. (281 ms total)
> [  PASSED  ] 2 tests.
>  [LINK]  -> NULL/base/trie.test.prof
>  [ CXX] NULL/sim/guest_abi.test.cc -> .po
> build/NULL/base/trie.test.prof
> --gtest_output=xml:build/NULL/unittests.prof/base/trie.test.xml
> Running main() from gtest_main.cc
> [==] Running 7 tests from 1 test case.
> [--] Global test environment set-up.
> [--] 7 tests from TrieTestData
> [ RUN  ] TrieTestData.Empty
> [   OK ] TrieTestData.Empty (0 ms)
> [ RUN  ] TrieTestData.SingleEntry
> [   OK ] TrieTestData.SingleEntry (0 ms)
> [ RUN  ] TrieTestData.TwoOverlappingEntries
> [   OK ] TrieTestData.TwoOverlappingEntries (0 ms)
> [ RUN  ] TrieTestData.TwoOverlappingEntriesReversed
> [   OK ] TrieTestData.TwoOverlappingEntriesReversed (0 ms)
> [ RUN  ] TrieTestData.TwoIndependentEntries
> [   OK ] TrieTestData.TwoIndependentEntries (0 ms)
> [ RUN  ] TrieTestData.TwoEntries
> [   OK ] TrieTestData.TwoEntries (0 ms)
> [ RUN  ] TrieTestData.RemovingEntries
> [   OK ] TrieTestData.RemovingEntries (0 ms)
> [--] 7 tests from TrieTestData (0 ms total)
>
> [--] Global test environment tear-down
> [==] 7 tests from 1 test case ran. (0 ms total)
> [  PASSED  ] 7 tests.
>  [ CXX] NULL/sim/proxy_ptr.test.cc -> .po
>  [LINK]  -> NULL/base/str.test.prof
> build/NULL/base/str.test.prof
> --gtest_output=xml:build/NULL/unittests.prof/base/str.test.xml
> Running main() from gtest_main.cc
> [==] Running 42 tests from 1 test case.
> [--] Global test environment set-up.
> [--] 42 tests from StrTest
> [ RUN  ] StrTest.EatLeadWhite
> [   OK ] StrTest.EatLeadWhite (0 ms)
> [ RUN  ] StrTest.EatLeadWhiteNoLeadingWhitespace
> [   OK ] StrTest.EatLeadWhiteNoLeadingWhitespace (0 ms)
> [ RUN  ] StrTest.EatEndWhite
> [   OK ] StrTest.EatEndWhite (0 ms)
> [ RUN  ] StrTest.EatEndWhiteNoTrailingWhitespace
> [   OK ] StrTest.EatEndWhiteNoTrailingWhitespace (0 ms)
> [ RUN  ] StrTest.EatWhite
> [   OK ] StrTest.EatWhite (0 ms)
> [ RUN  ] 

[gem5-dev] Build failed in Jenkins: Nightly #92

See 

Changes:

[giacomo.travaglini] arch-arm: Default ArmSystem to AArch64

[Andreas.Sandberg] stats: Make Stats::Group::mergeStatGroup public

[odanrc] mem-cache: Add missing StridePrefetcher invalidation

[odanrc] mem-cache: Debug with blk's information instead of its state.

[odanrc] mem-cache: Create a tagged entry class

[odanrc] mem-cache: Isolate prefetching bit

[odanrc] mem-cache: Isolate compression bit

[odanrc] mem-cache: Encapsulate CacheBlk's status

[tiago.muck] mem-ruby: MessageBuffer capacity check

[tiago.muck] mem-ruby: Allow same-cycle enqueue

[tiago.muck] mem-ruby: Network can use custom data msg size

[tiago.muck] mem-ruby: additional WriteMask methods

[tiago.muck] mem-ruby: fix include dependency

[gabeblack] arch: Build the operand REs in the isa_parser on demand.


--
[...truncated 1.13 MB...]
[   OK ] MicroPCTest.IsRomMicroPCTest (0 ms)
[ RUN  ] MicroPCTest.IsNotRomMicroPCTest
[   OK ] MicroPCTest.IsNotRomMicroPCTest (0 ms)
[--] 5 tests from MicroPCTest (3 ms total)

[--] 4 tests from TypesTest
[ RUN  ] TypesTest.FloatToBits32
[   OK ] TypesTest.FloatToBits32 (0 ms)
[ RUN  ] TypesTest.floatToBits64
[   OK ] TypesTest.floatToBits64 (0 ms)
[ RUN  ] TypesTest.floatsToBitsDoubleInput
[   OK ] TypesTest.floatsToBitsDoubleInput (0 ms)
[ RUN  ] TypesTest.floatsToBitsFloatInput
[   OK ] TypesTest.floatsToBitsFloatInput (0 ms)
[--] 4 tests from TypesTest (2 ms total)

[--] Global test environment tear-down
[==] 19 tests from 3 test cases ran. (14 ms total)
[  PASSED  ] 19 tests.
 [ CXX] NULL/sim/byteswap.test.cc -> .po
 [LINK]  -> NULL/base/uncontended_mutex.test.prof
build/NULL/base/uncontended_mutex.test.prof 
--gtest_output=xml:build/NULL/unittests.prof/base/uncontended_mutex.test.xml
Running main() from gtest_main.cc
[==] Running 2 tests from 1 test case.
[--] Global test environment set-up.
[--] 2 tests from UncontendedMutex
[ RUN  ] UncontendedMutex.Lock
[   OK ] UncontendedMutex.Lock (201 ms)
[ RUN  ] UncontendedMutex.HeavyContention
[   OK ] UncontendedMutex.HeavyContention (79 ms)
[--] 2 tests from UncontendedMutex (280 ms total)

[--] Global test environment tear-down
[==] 2 tests from 1 test case ran. (281 ms total)
[  PASSED  ] 2 tests.
 [LINK]  -> NULL/base/trie.test.prof
 [ CXX] NULL/sim/guest_abi.test.cc -> .po
build/NULL/base/trie.test.prof 
--gtest_output=xml:build/NULL/unittests.prof/base/trie.test.xml
Running main() from gtest_main.cc
[==] Running 7 tests from 1 test case.
[--] Global test environment set-up.
[--] 7 tests from TrieTestData
[ RUN  ] TrieTestData.Empty
[   OK ] TrieTestData.Empty (0 ms)
[ RUN  ] TrieTestData.SingleEntry
[   OK ] TrieTestData.SingleEntry (0 ms)
[ RUN  ] TrieTestData.TwoOverlappingEntries
[   OK ] TrieTestData.TwoOverlappingEntries (0 ms)
[ RUN  ] TrieTestData.TwoOverlappingEntriesReversed
[   OK ] TrieTestData.TwoOverlappingEntriesReversed (0 ms)
[ RUN  ] TrieTestData.TwoIndependentEntries
[   OK ] TrieTestData.TwoIndependentEntries (0 ms)
[ RUN  ] TrieTestData.TwoEntries
[   OK ] TrieTestData.TwoEntries (0 ms)
[ RUN  ] TrieTestData.RemovingEntries
[   OK ] TrieTestData.RemovingEntries (0 ms)
[--] 7 tests from TrieTestData (0 ms total)

[--] Global test environment tear-down
[==] 7 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 7 tests.
 [ CXX] NULL/sim/proxy_ptr.test.cc -> .po
 [LINK]  -> NULL/base/str.test.prof
build/NULL/base/str.test.prof 
--gtest_output=xml:build/NULL/unittests.prof/base/str.test.xml
Running main() from gtest_main.cc
[==] Running 42 tests from 1 test case.
[--] Global test environment set-up.
[--] 42 tests from StrTest
[ RUN  ] StrTest.EatLeadWhite
[   OK ] StrTest.EatLeadWhite (0 ms)
[ RUN  ] StrTest.EatLeadWhiteNoLeadingWhitespace
[   OK ] StrTest.EatLeadWhiteNoLeadingWhitespace (0 ms)
[ RUN  ] StrTest.EatEndWhite
[   OK ] StrTest.EatEndWhite (0 ms)
[ RUN  ] StrTest.EatEndWhiteNoTrailingWhitespace
[   OK ] StrTest.EatEndWhiteNoTrailingWhitespace (0 ms)
[ RUN  ] StrTest.EatWhite
[   OK ] StrTest.EatWhite (0 ms)
[ RUN  ] StrTest.EatWhiteNoWhitespace
[   OK ] StrTest.EatWhiteNoWhitespace (0 ms)
[ RUN  ] StrTest.ToLower
[   OK ] StrTest.ToLower (0 ms)
[ RUN  ] StrTest.SplitFirst
[   OK ] StrTest.SplitFirst (0 ms)
[ RUN  ] StrTest.SplitFirstNoChar
[   OK ] StrTest.SplitFirstNoChar (0 ms)
[ RUN  ] StrTest.SplitFirstOnFirstChar
[   OK ] StrTest.SplitFirstOnFirstChar (0 ms)
[ RUN  ] StrTest.SplitLast
[   OK ] StrTest.SplitLast (0 ms)
[ RUN  ] StrTest.SplitLastNoChar
[   OK ] StrTest.SplitLastNoChar (0 ms)
[ RUN  

[gem5-dev] Change in gem5/gem5[develop]: stats: Output new-world stats before legacy stats

Andreas Sandberg has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35617 )


Change subject: stats: Output new-world stats before legacy stats
..

stats: Output new-world stats before legacy stats

Now that global stats have been converted to new-style stats, it's
desirable to output them before legacy stats. This ensures that global
statistics (e.g., host_seconds) show up first in the stat file.

Change-Id: Ib099d0152a6612ebbadd234c27f2f3448aef1260
Signed-off-by: Andreas Sandberg 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35617
Reviewed-by: Jason Lowe-Power 
Maintainer: Jason Lowe-Power 
Tested-by: kokoro 
---
M src/python/m5/stats/__init__.py
1 file changed, 3 insertions(+), 3 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/python/m5/stats/__init__.py  
b/src/python/m5/stats/__init__.py

index 6c4a42c..1fc6c9c 100644
--- a/src/python/m5/stats/__init__.py
+++ b/src/python/m5/stats/__init__.py
@@ -345,13 +345,13 @@
 for p in reversed(root.path_list()):
 visitor.endGroup()
 else:
+# New stats starting from root.
+dump_group(Root.getInstance())
+
 # Legacy stats
 for stat in stats_list:
 stat.visit(visitor)

-# New stats starting from root.
-dump_group(Root.getInstance())
-
 lastDump = 0
 # List[SimObject].
 global_dump_roots = []

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/35617
To unsubscribe, or for help writing mail filters, visit  
https://gem5-review.googlesource.com/settings


Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ib099d0152a6612ebbadd234c27f2f3448aef1260
Gerrit-Change-Number: 35617
Gerrit-PatchSet: 3
Gerrit-Owner: Andreas Sandberg 
Gerrit-Reviewer: Andreas Sandberg 
Gerrit-Reviewer: Ciro Santilli 
Gerrit-Reviewer: Jason Lowe-Power 
Gerrit-Reviewer: Jason Lowe-Power 
Gerrit-Reviewer: kokoro 
Gerrit-MessageType: merged
___
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

[gem5-dev] Change in gem5/gem5[develop]: sim, stats: Move global stats to Root

Andreas Sandberg has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/35616 )


Change subject: sim, stats: Move global stats to Root
..

sim, stats: Move global stats to Root

Global stats are currently exposed using the legacy stat system (i.e.,
without a parent group). This change moves global stats from
stat_control.cc to a group that gets exported from the Root object.

The implementation adds the Root::Stats class which has a single
global instance. This instance is exposed to the rest of the simulator
using the global rootStats symbol. The intention is that objects that
need global statistics in formulas access them through the rootStats
object.

The global names simSeconds, simTicks, simFreq, and hostSeconds are
now references to their respective members in the rootStats object.

Change-Id: I267b5244a0bcca93dd2dcf03388e7085bdd79c9e
Signed-off-by: Andreas Sandberg 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35616
Reviewed-by: Jason Lowe-Power 
Maintainer: Jason Lowe-Power 
Tested-by: kokoro 
---
M src/sim/SConscript
M src/sim/root.cc
M src/sim/root.hh
M src/sim/stat_control.cc
M src/sim/stat_control.hh
A src/sim/stats.cc
M src/sim/stats.hh
7 files changed, 164 insertions(+), 105 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/sim/SConscript b/src/sim/SConscript
index 6bda828..78d9bf5 100644
--- a/src/sim/SConscript
+++ b/src/sim/SConscript
@@ -81,6 +81,7 @@
 Source('mathexpr.cc')
 Source('power_state.cc')
 Source('power_domain.cc')
+Source('stats.cc')

 GTest('byteswap.test', 'byteswap.test.cc', '../base/types.cc')
 GTest('guest_abi.test', 'guest_abi.test.cc')
diff --git a/src/sim/root.cc b/src/sim/root.cc
index 5a17442..e1c6a7b 100644
--- a/src/sim/root.cc
+++ b/src/sim/root.cc
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2020 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * Copyright (c) 2011 Advanced Micro Devices, Inc.
  * All rights reserved.
@@ -27,6 +39,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */

+#include "base/hostinfo.hh"
 #include "base/logging.hh"
 #include "base/trace.hh"
 #include "config/the_isa.hh"
@@ -36,6 +49,56 @@
 #include "sim/root.hh"

 Root *Root::_root = NULL;
+Root::Stats Root::Stats::instance;
+Root::Stats  = Root::Stats::instance;
+
+Root::Stats::Stats()
+: Stats::Group(nullptr),
+simSeconds(this, "sim_seconds", "Number of seconds simulated"),
+simTicks(this, "sim_ticks", "Number of ticks simulated"),
+finalTick(this, "final_tick",
+  "Number of ticks from beginning of simulation "
+  "(restored from checkpoints and never reset)"),
+simFreq(this, "sim_freq", "Frequency of simulated ticks"),
+hostSeconds(this, "host_seconds", "Real time elapsed on the host"),
+hostTickRate(this, "host_tick_rate", "Simulator tick rate (ticks/s)"),
+hostMemory(this, "host_mem_usage", "Number of bytes of host memory  
used"),

+
+statTime(true),
+startTick(0)
+{
+simFreq.scalar(SimClock::Frequency);
+simTicks.functor([this]() { return curTick() - startTick; });
+finalTick.functor(curTick);
+
+hostMemory
+.functor(memUsage)
+.prereq(hostMemory)
+;
+
+hostSeconds
+.functor([this]() {
+Time now;
+now.setTimer();
+return now - statTime;
+})
+.precision(2)
+;
+
+hostTickRate.precision(0);
+
+simSeconds = simTicks / simFreq;
+hostTickRate = simTicks / hostSeconds;
+}
+
+void
+Root::Stats::resetStats()
+{
+statTime.setTimer();
+startTick = curTick();
+
+Stats::Group::resetStats();
+}

 /*
  * This function is called periodically by an event in M5 and ensures that
@@ -112,6 +175,12 @@
 lastTime.setTimer();

 simQuantum = p->sim_quantum;
+
+// Some of the statistics are global and need to be accessed by
+// stat formulas. The most convenient way to implement that is by
+// having a single global stat group for global stats. Merge that
+// group into the root object here.
+mergeStatGroup(::Stats::instance);
 }

 void
diff --git a/src/sim/root.hh b/src/sim/root.hh
index 0638559..a88673a 

[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: Simplify Ruby prefetcher's filter access functions

Daniel Carvalho has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/24534 )


Change subject: mem-ruby: Simplify Ruby prefetcher's filter access functions
..

mem-ruby: Simplify Ruby prefetcher's filter access functions

The signatures request many things that do not need to be passed
around.

Change-Id: If780e848b19056c9213092b6fc8673bd4f37b65f
Signed-off-by: Daniel R. Carvalho 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24534
Reviewed-by: Jason Lowe-Power 
Maintainer: Jason Lowe-Power 
Tested-by: kokoro 
---
M src/mem/ruby/structures/RubyPrefetcher.cc
M src/mem/ruby/structures/RubyPrefetcher.hh
2 files changed, 17 insertions(+), 40 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/mem/ruby/structures/RubyPrefetcher.cc  
b/src/mem/ruby/structures/RubyPrefetcher.cc

index b416269..aa6c7cd 100644
--- a/src/mem/ruby/structures/RubyPrefetcher.cc
+++ b/src/mem/ruby/structures/RubyPrefetcher.cc
@@ -140,36 +140,16 @@
 }
 }

-// check to see if this address is in the unit stride filter
-bool alloc = false;
-bool hit = accessUnitFilter(, line_addr, 1, alloc);
-if (alloc) {
-// allocate a new prefetch stream
-initializeStream(line_addr, 1, getLRUindex(), type);
-}
-if (hit) {
+// Check if address is in any of the stride filters
+if (accessUnitFilter(, line_addr, 1, type)) {
 DPRINTF(RubyPrefetcher, "  *** hit in unit stride buffer\n");
 return;
 }
-
-hit = accessUnitFilter(, line_addr, -1, alloc);
-if (alloc) {
-// allocate a new prefetch stream
-initializeStream(line_addr, -1, getLRUindex(), type);
-}
-if (hit) {
+if (accessUnitFilter(, line_addr, -1, type)) {
 DPRINTF(RubyPrefetcher, "  *** hit in unit negative unit  
buffer\n");

 return;
 }
-
-// check to see if this address is in the non-unit stride filter
-int stride = 0;  // NULL value
-hit = accessNonunitFilter(line_addr, , alloc);
-if (alloc) {
-assert(stride != 0);  // ensure non-zero stride prefetches
-initializeStream(line_addr, stride, getLRUindex(), type);
-}
-if (hit) {
+if (accessNonunitFilter(line_addr, type)) {
 DPRINTF(RubyPrefetcher, "  *** hit in non-unit stride buffer\n");
 return;
 }
@@ -310,17 +290,15 @@

 bool
 RubyPrefetcher::accessUnitFilter(CircularQueue* const  
filter,

-Addr line_addr, int stride, bool )
+Addr line_addr, int stride, const RubyRequestType& type)
 {
-//reset the alloc flag
-alloc = false;
-
 for (auto& entry : *filter) {
 if (entry.addr == line_addr) {
 entry.addr = makeNextStrideAddress(entry.addr, stride);
 entry.hits++;
 if (entry.hits >= m_train_misses) {
-alloc = true;
+// Allocate a new prefetch stream
+initializeStream(line_addr, stride, getLRUindex(), type);
 }
 return true;
 }
@@ -334,11 +312,9 @@
 }

 bool
-RubyPrefetcher::accessNonunitFilter(Addr line_addr, int *stride, bool  
)

+RubyPrefetcher::accessNonunitFilter(Addr line_addr,
+const RubyRequestType& type)
 {
-//reset the alloc flag
-alloc = false;
-
 /// look for non-unit strides based on a (user-defined) page size
 Addr page_addr = pageAddress(line_addr);

@@ -359,12 +335,14 @@
 // This stride HAS to be the multiplicative  
constant of

 // dataBlockBytes (bc makeNextStrideAddress is
 // calculated based on this multiplicative  
constant!)

-*stride = entry.stride /
+const int stride = entry.stride /
 RubySystem::getBlockSizeBytes();

 // clear this filter entry
 entry.clear();
-alloc = true;
+
+initializeStream(line_addr, stride, getLRUindex(),
+type);
 }
 } else {
 // If delta didn't match reset entry's hit count
diff --git a/src/mem/ruby/structures/RubyPrefetcher.hh  
b/src/mem/ruby/structures/RubyPrefetcher.hh

index 8e08fdf..b640cc3 100644
--- a/src/mem/ruby/structures/RubyPrefetcher.hh
+++ b/src/mem/ruby/structures/RubyPrefetcher.hh
@@ -181,23 +181,22 @@
  * @param filter Unit filter being accessed.
  * @param line_addr Address being accessed, block aligned.
  * @param stride The stride value.
- * @param alloc Whether a stream should be allocated on a hit.
+ * @param type Type of the request that generated the access.
  * @return True if a corresponding entry was found.
  */
 bool 

[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: Use CircularQueue for prefetcher's non unit filter

Daniel Carvalho has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/24533 )


Change subject: mem-ruby: Use CircularQueue for prefetcher's non unit filter
..

mem-ruby: Use CircularQueue for prefetcher's non unit filter

Ruby prefetcher's non-unit filter is a circular queue, so use the class
created for this functionality.

This changes the behavior, since previously iterating through the
filter was completely arbitrary, and now it iterates from the
beginning of the queue to the end when accessing and updating
the filter's contents.

Change-Id: I3148efcbef00da0c8f6cf2dee7fb86f6c2ddb27d
Signed-off-by: Daniel R. Carvalho 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24533
Reviewed-by: Jason Lowe-Power 
Maintainer: Jason Lowe-Power 
Tested-by: kokoro 
---
M src/mem/ruby/structures/RubyPrefetcher.cc
M src/mem/ruby/structures/RubyPrefetcher.hh
2 files changed, 58 insertions(+), 74 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/mem/ruby/structures/RubyPrefetcher.cc  
b/src/mem/ruby/structures/RubyPrefetcher.cc

index 02526aa..b416269 100644
--- a/src/mem/ruby/structures/RubyPrefetcher.cc
+++ b/src/mem/ruby/structures/RubyPrefetcher.cc
@@ -58,30 +58,14 @@
 : SimObject(p), m_num_streams(p->num_streams),
 m_array(p->num_streams), m_train_misses(p->train_misses),
 m_num_startup_pfs(p->num_startup_pfs),
-m_num_nonunit_filters(p->nonunit_filter),
 unitFilter(p->unit_filter),
 negativeFilter(p->unit_filter),
-m_nonunit_filter(p->nonunit_filter, 0),
+nonUnitFilter(p->nonunit_filter),
 m_prefetch_cross_pages(p->cross_page),
 m_page_shift(p->sys->getPageShift())
 {
 assert(m_num_streams > 0);
 assert(m_num_startup_pfs <= MAX_PF_INFLIGHT);
-
-// create nonunit stride filter
-m_nonunit_index = 0;
-m_nonunit_stride = new int[m_num_nonunit_filters];
-m_nonunit_hit= new uint32_t[m_num_nonunit_filters];
-for (int i =0; i < m_num_nonunit_filters; i++) {
-m_nonunit_stride[i] = 0;
-m_nonunit_hit[i]= 0;
-}
-}
-
-RubyPrefetcher::~RubyPrefetcher()
-{
-delete m_nonunit_stride;
-delete m_nonunit_hit;
 }

 void
@@ -180,7 +164,7 @@

 // check to see if this address is in the non-unit stride filter
 int stride = 0;  // NULL value
-hit = accessNonunitFilter(address, , alloc);
+hit = accessNonunitFilter(line_addr, , alloc);
 if (alloc) {
 assert(stride != 0);  // ensure non-zero stride prefetches
 initializeStream(line_addr, stride, getLRUindex(), type);
@@ -266,14 +250,6 @@
 }

 void
-RubyPrefetcher::clearNonunitEntry(uint32_t index)
-{
-m_nonunit_filter[index] = 0;
-m_nonunit_stride[index] = 0;
-m_nonunit_hit[index]= 0;
-}
-
-void
 RubyPrefetcher::initializeStream(Addr address, int stride,
  uint32_t index, const RubyRequestType& type)
 {
@@ -358,49 +334,46 @@
 }

 bool
-RubyPrefetcher::accessNonunitFilter(Addr address, int *stride,
-bool )
+RubyPrefetcher::accessNonunitFilter(Addr line_addr, int *stride, bool  
)

 {
 //reset the alloc flag
 alloc = false;

 /// look for non-unit strides based on a (user-defined) page size
-Addr page_addr = pageAddress(address);
-Addr line_addr = makeLineAddress(address);
+Addr page_addr = pageAddress(line_addr);

-for (uint32_t i = 0; i < m_num_nonunit_filters; i++) {
-if (pageAddress(m_nonunit_filter[i]) == page_addr) {
+for (auto& entry : nonUnitFilter) {
+if (pageAddress(entry.addr) == page_addr) {
 // hit in the non-unit filter
 // compute the actual stride (for this reference)
-int delta = line_addr - m_nonunit_filter[i];
+int delta = line_addr - entry.addr;

 if (delta != 0) {
 // no zero stride prefetches
 // check that the stride matches (for the last N times)
-if (delta == m_nonunit_stride[i]) {
+if (delta == entry.stride) {
 // -> stride hit
 // increment count (if > 2) allocate stream
-m_nonunit_hit[i]++;
-if (m_nonunit_hit[i] > m_train_misses) {
+entry.hits++;
+if (entry.hits > m_train_misses) {
 // This stride HAS to be the multiplicative  
constant of

 // dataBlockBytes (bc makeNextStrideAddress is
 // calculated based on this multiplicative  
constant!)

-*stride = m_nonunit_stride[i] /
-RubySystem::getBlockSizeBytes();
+*stride = entry.stride /
+RubySystem::getBlockSizeBytes();

 // clear this filter entry
-   

[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: Use CircularQueue for prefetcher's unit filter

Daniel Carvalho has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/24532 )


Change subject: mem-ruby: Use CircularQueue for prefetcher's unit filter
..

mem-ruby: Use CircularQueue for prefetcher's unit filter

Ruby prefetcher's unit filter is a circular queue, so use the class
created for this functionality.

This changes the behavior, since previously iterating through the
filter was completely arbitrary, and now it iterates from the
beginning of the queue to the end when accessing and updating
the filter's contents.

Change-Id: I834be88a33580d5857c38e9bae8b289c5a6250b9
Signed-off-by: Daniel R. Carvalho 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24532
Reviewed-by: Jason Lowe-Power 
Maintainer: Jason Lowe-Power 
Tested-by: kokoro 
---
M src/mem/ruby/structures/RubyPrefetcher.cc
M src/mem/ruby/structures/RubyPrefetcher.hh
2 files changed, 59 insertions(+), 67 deletions(-)

Approvals:
  Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/mem/ruby/structures/RubyPrefetcher.cc  
b/src/mem/ruby/structures/RubyPrefetcher.cc

index 8646b99..02526aa 100644
--- a/src/mem/ruby/structures/RubyPrefetcher.cc
+++ b/src/mem/ruby/structures/RubyPrefetcher.cc
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2020 Inria
  * Copyright (c) 2020 ARM Limited
  * All rights reserved
  *
@@ -40,6 +41,8 @@

 #include "mem/ruby/structures/RubyPrefetcher.hh"

+#include 
+
 #include "base/bitfield.hh"
 #include "debug/RubyPrefetcher.hh"
 #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
@@ -54,10 +57,10 @@
 RubyPrefetcher::RubyPrefetcher(const Params *p)
 : SimObject(p), m_num_streams(p->num_streams),
 m_array(p->num_streams), m_train_misses(p->train_misses),
-m_num_startup_pfs(p->num_startup_pfs),  
m_num_unit_filters(p->unit_filter),

+m_num_startup_pfs(p->num_startup_pfs),
 m_num_nonunit_filters(p->nonunit_filter),
-m_unit_filter(p->unit_filter, 0),
-m_negative_filter(p->unit_filter, 0),
+unitFilter(p->unit_filter),
+negativeFilter(p->unit_filter),
 m_nonunit_filter(p->nonunit_filter, 0),
 m_prefetch_cross_pages(p->cross_page),
 m_page_shift(p->sys->getPageShift())
@@ -65,20 +68,6 @@
 assert(m_num_streams > 0);
 assert(m_num_startup_pfs <= MAX_PF_INFLIGHT);

-// create +1 stride filter
-m_unit_filter_index = 0;
-m_unit_filter_hit = new uint32_t[m_num_unit_filters];
-for (uint32_t i =0; i < m_num_unit_filters; i++) {
-m_unit_filter_hit[i] = 0;
-}
-
-// create -1 stride filter
-m_negative_filter_index = 0;
-m_negative_filter_hit = new uint32_t[m_num_unit_filters];
-for (int i =0; i < m_num_unit_filters; i++) {
-m_negative_filter_hit[i] = 0;
-}
-
 // create nonunit stride filter
 m_nonunit_index = 0;
 m_nonunit_stride = new int[m_num_nonunit_filters];
@@ -91,8 +80,6 @@

 RubyPrefetcher::~RubyPrefetcher()
 {
-delete m_unit_filter_hit;
-delete m_negative_filter_hit;
 delete m_nonunit_stride;
 delete m_nonunit_hit;
 }
@@ -171,8 +158,7 @@

 // check to see if this address is in the unit stride filter
 bool alloc = false;
-bool hit = accessUnitFilter(m_unit_filter, m_unit_filter_hit,
-m_unit_filter_index, line_addr, 1, alloc);
+bool hit = accessUnitFilter(, line_addr, 1, alloc);
 if (alloc) {
 // allocate a new prefetch stream
 initializeStream(line_addr, 1, getLRUindex(), type);
@@ -182,8 +168,7 @@
 return;
 }

-hit = accessUnitFilter(m_negative_filter, m_negative_filter_hit,
-m_negative_filter_index, line_addr, -1, alloc);
+hit = accessUnitFilter(, line_addr, -1, alloc);
 if (alloc) {
 // allocate a new prefetch stream
 initializeStream(line_addr, -1, getLRUindex(), type);
@@ -348,35 +333,27 @@
 }

 bool
-RubyPrefetcher::accessUnitFilter(std::vector& filter_table,
-uint32_t *filter_hit, uint32_t , Addr address,
-int stride, bool )
+RubyPrefetcher::accessUnitFilter(CircularQueue* const  
filter,

+Addr line_addr, int stride, bool )
 {
 //reset the alloc flag
 alloc = false;

-Addr line_addr = makeLineAddress(address);
-for (int i = 0; i < m_num_unit_filters; i++) {
-if (filter_table[i] == line_addr) {
-filter_table[i] = makeNextStrideAddress(filter_table[i],  
stride);

-filter_hit[i]++;
-if (filter_hit[i] >= m_train_misses) {
+for (auto& entry : *filter) {
+if (entry.addr == line_addr) {
+entry.addr = makeNextStrideAddress(entry.addr, stride);
+entry.hits++;
+if (entry.hits >= m_train_misses) {
 alloc = true;
 }
 return true;
 }
 }

-// enter this address in the table
-int local_index = index;
-