arch: ISA parser additions of vector registers
Reiley's update :) of the isa parser definitions. My addition of the vector element operand concept for the ISA parser. Nathanael's modification creating a hierarchy between vector registers and its constituencies to the isa parser. Some fixes/updates on top to consider instructions as vectors instead of floating when they use the VectorRF. Some counters added to all the models to keep faithful counts. Change-Id: Id8f162a525240dfd7ba884c5a4d9fa69f4050101 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2706 Reviewed-by: Anthony Gutierrez <anthony.gutierrez@amd.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
committed by
Andreas Sandberg
parent
00da089029
commit
166da650a3
@@ -98,6 +98,13 @@ FaultName FloatEnableFault::_name = "fen";
|
||||
FaultVect FloatEnableFault::_vect = 0x0581;
|
||||
FaultStat FloatEnableFault::_count;
|
||||
|
||||
/* We use the same fault vector, as for the guest system these should be the
|
||||
* same, but for host purposes, having differentiation is helpful for
|
||||
* debug/monitorization purposes. */
|
||||
FaultName VectorEnableFault::_name = "ven";
|
||||
FaultVect VectorEnableFault::_vect = 0x0581;
|
||||
FaultStat VectorEnableFault::_count;
|
||||
|
||||
FaultName PalFault::_name = "pal";
|
||||
FaultVect PalFault::_vect = 0x2001;
|
||||
FaultStat PalFault::_count;
|
||||
|
||||
@@ -299,6 +299,19 @@ class FloatEnableFault : public AlphaFault
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class VectorEnableFault : public AlphaFault
|
||||
{
|
||||
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 PalFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -50,6 +50,9 @@ output exec {{
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
inline Fault checkVectorEnableFault(CPU_EXEC_CONTEXT *xc) {
|
||||
return std::make_shared<VectorEnableFault>();
|
||||
}
|
||||
}};
|
||||
|
||||
output header {{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2012-2013 ARM Limited
|
||||
// Copyright (c) 2012-2013, 2016 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -123,9 +123,11 @@ let {{
|
||||
exec_output += BasicExecute.subst(fmovCoreRegXIop);
|
||||
|
||||
fmovUCoreRegXCode = vfp64EnabledCheckCode + '''
|
||||
/* Explicitly merge with previous value */
|
||||
AA64FpDestP0_uw = AA64FpDestP0_uw;
|
||||
AA64FpDestP1_uw = AA64FpDestP1_uw;
|
||||
AA64FpDestP2_uw = XOp1_ud;
|
||||
AA64FpDestP3_uw = XOp1_ud >> 32;
|
||||
'''
|
||||
AA64FpDestP3_uw = XOp1_ud >> 32;'''
|
||||
fmovUCoreRegXIop = InstObjParams("fmov", "FmovUCoreRegX", "FpRegRegOp",
|
||||
{ "code": fmovUCoreRegXCode,
|
||||
"op_class": "FloatMiscOp" }, [])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode: c++ -*-
|
||||
|
||||
// Copyright (c) 2012-2013, 2015 ARM Limited
|
||||
// Copyright (c) 2012-2013, 2015-2016 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -225,11 +225,16 @@ let {{
|
||||
AA64FpDestP%(destReg)d_uw = gtoh(destReg.regs[%(reg)d]);
|
||||
''' % { "reg" : reg, "destReg": destReg }
|
||||
destReg += 1
|
||||
if destCnt < 4 and not hi: # zero upper half
|
||||
for reg in range(destCnt, 4):
|
||||
eWalkCode += '''
|
||||
AA64FpDestP%(reg)d_uw = 0;
|
||||
''' % { "reg" : reg }
|
||||
if destCnt < 4:
|
||||
if hi: # Explicitly merge with lower half
|
||||
for reg in range(0, destCnt):
|
||||
eWalkCode += '''
|
||||
AA64FpDestP%(reg)d_uw = AA64FpDestP%(reg)d_uw;''' % { "reg" : reg }
|
||||
else: # zero upper half
|
||||
for reg in range(destCnt, 4):
|
||||
eWalkCode += '''
|
||||
AA64FpDestP%(reg)d_uw = 0;''' % { "reg" : reg }
|
||||
|
||||
iop = InstObjParams(name, Name,
|
||||
"DataX2RegImmOp" if byElem else "DataX2RegOp",
|
||||
{ "code": eWalkCode,
|
||||
@@ -429,11 +434,16 @@ let {{
|
||||
AA64FpDestP%(destReg)d_uw = gtoh(destReg.regs[%(reg)d]);
|
||||
''' % { "reg" : reg, "destReg": destReg }
|
||||
destReg += 1
|
||||
if not hi:
|
||||
if hi:
|
||||
for reg in range(0, 2): # Explicitly merge with the lower half
|
||||
eWalkCode += '''
|
||||
AA64FpDestP%(reg)d_uw = AA64FpDestP%(reg)d_uw;''' % { "reg" : reg }
|
||||
else:
|
||||
for reg in range(2, 4): # zero upper half
|
||||
eWalkCode += '''
|
||||
AA64FpDestP%(reg)d_uw = 0;
|
||||
''' % { "reg" : reg }
|
||||
|
||||
iop = InstObjParams(name, Name,
|
||||
"DataX1RegImmOp" if hasImm else "DataX1RegOp",
|
||||
{ "code": eWalkCode,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// -*- mode:c++ -*-
|
||||
// Copyright (c) 2010-2014 ARM Limited
|
||||
// Copyright (c) 2010-2014, 2016 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -49,7 +49,10 @@ def operand_types {{
|
||||
'ud' : 'uint64_t',
|
||||
'tud' : 'Twin64_t',
|
||||
'sf' : 'float',
|
||||
'df' : 'double'
|
||||
'df' : 'double',
|
||||
'vc' : 'TheISA::VecRegContainer',
|
||||
# For operations that are implemented as a template
|
||||
'x' : 'TPElem',
|
||||
}};
|
||||
|
||||
let {{
|
||||
@@ -117,6 +120,15 @@ let {{
|
||||
srtMode = 1
|
||||
srtEPC = 0
|
||||
|
||||
def vectorElem(idx, elem):
|
||||
return ('VecElem', 'sf', (idx, elem), 'IsVectorElem', srtNormal)
|
||||
|
||||
def vectorReg(idx, elems = None):
|
||||
return ('VecReg', 'vc', (idx, elems) , 'IsVector', srtNormal)
|
||||
|
||||
def vectorRegElem(elem, ext = 'sf', zeroing = False):
|
||||
return (elem, ext, zeroing)
|
||||
|
||||
def floatReg(idx):
|
||||
return ('FloatReg', 'sf', idx, 'IsFloating', srtNormal)
|
||||
|
||||
@@ -297,86 +309,203 @@ def operands {{
|
||||
'FpOp2P3': floatReg('(op2 + 3)'),
|
||||
|
||||
# Create AArch64 unpacked view of the FP registers
|
||||
'AA64FpOp1P0': floatReg('((op1 * 4) + 0)'),
|
||||
'AA64FpOp1P1': floatReg('((op1 * 4) + 1)'),
|
||||
'AA64FpOp1P2': floatReg('((op1 * 4) + 2)'),
|
||||
'AA64FpOp1P3': floatReg('((op1 * 4) + 3)'),
|
||||
'AA64FpOp2P0': floatReg('((op2 * 4) + 0)'),
|
||||
'AA64FpOp2P1': floatReg('((op2 * 4) + 1)'),
|
||||
'AA64FpOp2P2': floatReg('((op2 * 4) + 2)'),
|
||||
'AA64FpOp2P3': floatReg('((op2 * 4) + 3)'),
|
||||
'AA64FpOp3P0': floatReg('((op3 * 4) + 0)'),
|
||||
'AA64FpOp3P1': floatReg('((op3 * 4) + 1)'),
|
||||
'AA64FpOp3P2': floatReg('((op3 * 4) + 2)'),
|
||||
'AA64FpOp3P3': floatReg('((op3 * 4) + 3)'),
|
||||
'AA64FpDestP0': floatReg('((dest * 4) + 0)'),
|
||||
'AA64FpDestP1': floatReg('((dest * 4) + 1)'),
|
||||
'AA64FpDestP2': floatReg('((dest * 4) + 2)'),
|
||||
'AA64FpDestP3': floatReg('((dest * 4) + 3)'),
|
||||
'AA64FpDest2P0': floatReg('((dest2 * 4) + 0)'),
|
||||
'AA64FpDest2P1': floatReg('((dest2 * 4) + 1)'),
|
||||
'AA64FpDest2P2': floatReg('((dest2 * 4) + 2)'),
|
||||
'AA64FpDest2P3': floatReg('((dest2 * 4) + 3)'),
|
||||
# Name ::= 'AA64Vec' OpSpec [LaneSpec]
|
||||
# OpSpec ::= IOSpec [Index] [Plus]
|
||||
# IOSpec ::= 'S' | 'D'
|
||||
# Index ::= '0' | ... | '9'
|
||||
# Plus ::= [PlusAmount] ['l']
|
||||
# PlusAmount ::= 'p' [PlusAmount]
|
||||
# LaneSpec ::= 'L' Index
|
||||
#
|
||||
# All the constituents are hierarchically defined as part of the Vector
|
||||
# Register they belong to
|
||||
|
||||
'AA64FpOp1P0V0': floatReg('((((op1+0)) * 4) + 0)'),
|
||||
'AA64FpOp1P1V0': floatReg('((((op1+0)) * 4) + 1)'),
|
||||
'AA64FpOp1P2V0': floatReg('((((op1+0)) * 4) + 2)'),
|
||||
'AA64FpOp1P3V0': floatReg('((((op1+0)) * 4) + 3)'),
|
||||
'AA64FpOp1': vectorReg('op1',
|
||||
{
|
||||
'AA64FpOp1P0': vectorRegElem('0'),
|
||||
'AA64FpOp1P1': vectorRegElem('1'),
|
||||
'AA64FpOp1P2': vectorRegElem('2'),
|
||||
'AA64FpOp1P3': vectorRegElem('3'),
|
||||
'AA64FpOp1S': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1D': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1Q': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpOp1P0V1': floatReg('((((op1+1)) * 4) + 0)'),
|
||||
'AA64FpOp1P1V1': floatReg('((((op1+1)) * 4) + 1)'),
|
||||
'AA64FpOp1P2V1': floatReg('((((op1+1)) * 4) + 2)'),
|
||||
'AA64FpOp1P3V1': floatReg('((((op1+1)) * 4) + 3)'),
|
||||
'AA64FpOp2': vectorReg('op2',
|
||||
{
|
||||
'AA64FpOp2P0': vectorRegElem('0'),
|
||||
'AA64FpOp2P1': vectorRegElem('1'),
|
||||
'AA64FpOp2P2': vectorRegElem('2'),
|
||||
'AA64FpOp2P3': vectorRegElem('3'),
|
||||
'AA64FpOp2S': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp2D': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp2Q': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpOp1P0V2': floatReg('((((op1+2)) * 4) + 0)'),
|
||||
'AA64FpOp1P1V2': floatReg('((((op1+2)) * 4) + 1)'),
|
||||
'AA64FpOp1P2V2': floatReg('((((op1+2)) * 4) + 2)'),
|
||||
'AA64FpOp1P3V2': floatReg('((((op1+2)) * 4) + 3)'),
|
||||
'AA64FpOp3': vectorReg('op3',
|
||||
{
|
||||
'AA64FpOp3P0': vectorRegElem('0'),
|
||||
'AA64FpOp3P1': vectorRegElem('1'),
|
||||
'AA64FpOp3P2': vectorRegElem('2'),
|
||||
'AA64FpOp3P3': vectorRegElem('3'),
|
||||
'AA64FpOp3S': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp3D': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp3Q': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpOp1P0V3': floatReg('((((op1+3)) * 4) + 0)'),
|
||||
'AA64FpOp1P1V3': floatReg('((((op1+3)) * 4) + 1)'),
|
||||
'AA64FpOp1P2V3': floatReg('((((op1+3)) * 4) + 2)'),
|
||||
'AA64FpOp1P3V3': floatReg('((((op1+3)) * 4) + 3)'),
|
||||
'AA64FpDest': vectorReg('dest',
|
||||
{
|
||||
'AA64FpDestP0': vectorRegElem('0'),
|
||||
'AA64FpDestP1': vectorRegElem('1'),
|
||||
'AA64FpDestP2': vectorRegElem('2'),
|
||||
'AA64FpDestP3': vectorRegElem('3'),
|
||||
'AA64FpDestS': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpDestD': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpDestQ': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpOp1P0V0S': floatReg('((((op1+0)%32) * 4) + 0)'),
|
||||
'AA64FpOp1P1V0S': floatReg('((((op1+0)%32) * 4) + 1)'),
|
||||
'AA64FpOp1P2V0S': floatReg('((((op1+0)%32) * 4) + 2)'),
|
||||
'AA64FpOp1P3V0S': floatReg('((((op1+0)%32) * 4) + 3)'),
|
||||
'AA64FpDest2': vectorReg('dest2',
|
||||
{
|
||||
'AA64FpDest2P0': vectorRegElem('0'),
|
||||
'AA64FpDest2P1': vectorRegElem('1'),
|
||||
'AA64FpDest2P2': vectorRegElem('2'),
|
||||
'AA64FpDest2P3': vectorRegElem('3'),
|
||||
'AA64FpDest2S': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpDest2D': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpDest2Q': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpOp1P0V1S': floatReg('((((op1+1)%32) * 4) + 0)'),
|
||||
'AA64FpOp1P1V1S': floatReg('((((op1+1)%32) * 4) + 1)'),
|
||||
'AA64FpOp1P2V1S': floatReg('((((op1+1)%32) * 4) + 2)'),
|
||||
'AA64FpOp1P3V1S': floatReg('((((op1+1)%32) * 4) + 3)'),
|
||||
'AA64FpOp1V0': vectorReg('op1',
|
||||
{
|
||||
'AA64FpOp1P0V0': vectorRegElem('0'),
|
||||
'AA64FpOp1P1V0': vectorRegElem('1'),
|
||||
'AA64FpOp1P2V0': vectorRegElem('2'),
|
||||
'AA64FpOp1P3V0': vectorRegElem('3'),
|
||||
'AA64FpOp1SV0': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1DV0': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1QV0': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpOp1P0V2S': floatReg('((((op1+2)%32) * 4) + 0)'),
|
||||
'AA64FpOp1P1V2S': floatReg('((((op1+2)%32) * 4) + 1)'),
|
||||
'AA64FpOp1P2V2S': floatReg('((((op1+2)%32) * 4) + 2)'),
|
||||
'AA64FpOp1P3V2S': floatReg('((((op1+2)%32) * 4) + 3)'),
|
||||
'AA64FpOp1V1': vectorReg('op1+1',
|
||||
{
|
||||
'AA64FpOp1P0V1': vectorRegElem('0'),
|
||||
'AA64FpOp1P1V1': vectorRegElem('1'),
|
||||
'AA64FpOp1P2V1': vectorRegElem('2'),
|
||||
'AA64FpOp1P3V1': vectorRegElem('3'),
|
||||
'AA64FpOp1SV1': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1DV1': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1QV1': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpOp1P0V3S': floatReg('((((op1+3)%32) * 4) + 0)'),
|
||||
'AA64FpOp1P1V3S': floatReg('((((op1+3)%32) * 4) + 1)'),
|
||||
'AA64FpOp1P2V3S': floatReg('((((op1+3)%32) * 4) + 2)'),
|
||||
'AA64FpOp1P3V3S': floatReg('((((op1+3)%32) * 4) + 3)'),
|
||||
'AA64FpOp1V2': vectorReg('op1+2',
|
||||
{
|
||||
'AA64FpOp1P0V2': vectorRegElem('0'),
|
||||
'AA64FpOp1P1V2': vectorRegElem('1'),
|
||||
'AA64FpOp1P2V2': vectorRegElem('2'),
|
||||
'AA64FpOp1P3V2': vectorRegElem('3'),
|
||||
'AA64FpOp1SV2': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1DV2': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1QV2': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpDestP0V0': floatReg('((((dest+0)) * 4) + 0)'),
|
||||
'AA64FpDestP1V0': floatReg('((((dest+0)) * 4) + 1)'),
|
||||
'AA64FpDestP2V0': floatReg('((((dest+0)) * 4) + 2)'),
|
||||
'AA64FpDestP3V0': floatReg('((((dest+0)) * 4) + 3)'),
|
||||
'AA64FpOp1V3': vectorReg('op1+3',
|
||||
{
|
||||
'AA64FpOp1P0V3': vectorRegElem('0'),
|
||||
'AA64FpOp1P1V3': vectorRegElem('1'),
|
||||
'AA64FpOp1P2V3': vectorRegElem('2'),
|
||||
'AA64FpOp1P3V3': vectorRegElem('3'),
|
||||
'AA64FpOp1SV3': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1DV3': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1QV3': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpDestP0V1': floatReg('((((dest+1)) * 4) + 0)'),
|
||||
'AA64FpDestP1V1': floatReg('((((dest+1)) * 4) + 1)'),
|
||||
'AA64FpDestP2V1': floatReg('((((dest+1)) * 4) + 2)'),
|
||||
'AA64FpDestP3V1': floatReg('((((dest+1)) * 4) + 3)'),
|
||||
'AA64FpOp1V0S': vectorReg('(op1+0)%32',
|
||||
{
|
||||
'AA64FpOp1P0V0S': vectorRegElem('0'),
|
||||
'AA64FpOp1P1V0S': vectorRegElem('1'),
|
||||
'AA64FpOp1P2V0S': vectorRegElem('2'),
|
||||
'AA64FpOp1P3V0S': vectorRegElem('3'),
|
||||
'AA64FpOp1SV0S': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1DV0S': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1QV0S': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpDestP0V0L': floatReg('((((dest+0)%32) * 4) + 0)'),
|
||||
'AA64FpDestP1V0L': floatReg('((((dest+0)%32) * 4) + 1)'),
|
||||
'AA64FpDestP2V0L': floatReg('((((dest+0)%32) * 4) + 2)'),
|
||||
'AA64FpDestP3V0L': floatReg('((((dest+0)%32) * 4) + 3)'),
|
||||
'AA64FpOp1V1S': vectorReg('(op1+1)%32',
|
||||
{
|
||||
'AA64FpOp1P0V1S': vectorRegElem('0'),
|
||||
'AA64FpOp1P1V1S': vectorRegElem('1'),
|
||||
'AA64FpOp1P2V1S': vectorRegElem('2'),
|
||||
'AA64FpOp1P3V1S': vectorRegElem('3'),
|
||||
'AA64FpOp1SV1S': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1DV1S': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1QV1S': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpDestP0V1L': floatReg('((((dest+1)%32) * 4) + 0)'),
|
||||
'AA64FpDestP1V1L': floatReg('((((dest+1)%32) * 4) + 1)'),
|
||||
'AA64FpDestP2V1L': floatReg('((((dest+1)%32) * 4) + 2)'),
|
||||
'AA64FpDestP3V1L': floatReg('((((dest+1)%32) * 4) + 3)'),
|
||||
'AA64FpOp1V2S': vectorReg('(op1+2)%32',
|
||||
{
|
||||
'AA64FpOp1P0V2S': vectorRegElem('0'),
|
||||
'AA64FpOp1P1V2S': vectorRegElem('1'),
|
||||
'AA64FpOp1P2V2S': vectorRegElem('2'),
|
||||
'AA64FpOp1P3V2S': vectorRegElem('3'),
|
||||
'AA64FpOp1SV2S': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1DV2S': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1QV2S': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpOp1V3S': vectorReg('(op1+3)%32',
|
||||
{
|
||||
'AA64FpOp1P0V3S': vectorRegElem('0'),
|
||||
'AA64FpOp1P1V3S': vectorRegElem('1'),
|
||||
'AA64FpOp1P2V3S': vectorRegElem('2'),
|
||||
'AA64FpOp1P3V3S': vectorRegElem('3'),
|
||||
'AA64FpOp1SV3S': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpOp1DV3S': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpOp1QV3S': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpDestV0': vectorReg('(dest+0)',
|
||||
{
|
||||
'AA64FpDestP0V0': vectorRegElem('0'),
|
||||
'AA64FpDestP1V0': vectorRegElem('1'),
|
||||
'AA64FpDestP2V0': vectorRegElem('2'),
|
||||
'AA64FpDestP3V0': vectorRegElem('3'),
|
||||
'AA64FpDestSV0': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpDestDV0': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpDestQV0': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpDestV1': vectorReg('(dest+1)',
|
||||
{
|
||||
'AA64FpDestP0V1': vectorRegElem('0'),
|
||||
'AA64FpDestP1V1': vectorRegElem('1'),
|
||||
'AA64FpDestP2V1': vectorRegElem('2'),
|
||||
'AA64FpDestP3V1': vectorRegElem('3'),
|
||||
'AA64FpDestSV1': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpDestDV1': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpDestQV1': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpDestV0L': vectorReg('(dest+0)%32',
|
||||
{
|
||||
'AA64FpDestP0V0L': vectorRegElem('0'),
|
||||
'AA64FpDestP1V0L': vectorRegElem('1'),
|
||||
'AA64FpDestP2V0L': vectorRegElem('2'),
|
||||
'AA64FpDestP3V0L': vectorRegElem('3'),
|
||||
'AA64FpDestSV0L': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpDestDV0L': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpDestQV0L': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
'AA64FpDestV1L': vectorReg('(dest+1)%32',
|
||||
{
|
||||
'AA64FpDestP0V1L': vectorRegElem('0'),
|
||||
'AA64FpDestP1V1L': vectorRegElem('1'),
|
||||
'AA64FpDestP2V1L': vectorRegElem('2'),
|
||||
'AA64FpDestP3V1L': vectorRegElem('3'),
|
||||
'AA64FpDestSV1L': vectorRegElem('0', 'sf', zeroing = True),
|
||||
'AA64FpDestDV1L': vectorRegElem('0', 'df', zeroing = True),
|
||||
'AA64FpDestQV1L': vectorRegElem('0', 'tud', zeroing = True)
|
||||
}),
|
||||
|
||||
#Abstracted control reg operands
|
||||
'MiscDest': cntrlReg('dest'),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2010, 2012, 2014 ARM Limited
|
||||
// Copyright (c) 2010, 2012, 2014, 2016 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -1150,7 +1150,7 @@ def template LoadRegConstructor {{
|
||||
#if %(use_uops)d
|
||||
assert(numMicroops >= 2);
|
||||
uops = new StaticInstPtr[numMicroops];
|
||||
if (_dest == INTREG_PC && !isFloating()) {
|
||||
if (_dest == INTREG_PC && !isFloating() && !isVector()) {
|
||||
IntRegIndex wbIndexReg = index;
|
||||
uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
|
||||
_shiftAmt, _shiftType, _index);
|
||||
@@ -1187,7 +1187,7 @@ def template LoadRegConstructor {{
|
||||
|
||||
}
|
||||
#else
|
||||
if (_dest == INTREG_PC && !isFloating()) {
|
||||
if (_dest == INTREG_PC && !isFloating() && !isVector()) {
|
||||
flags[IsControl] = true;
|
||||
flags[IsIndirectControl] = true;
|
||||
if (conditional)
|
||||
@@ -1216,7 +1216,7 @@ def template LoadImmConstructor {{
|
||||
#if %(use_uops)d
|
||||
assert(numMicroops >= 2);
|
||||
uops = new StaticInstPtr[numMicroops];
|
||||
if (_dest == INTREG_PC && !isFloating()) {
|
||||
if (_dest == INTREG_PC && !isFloating() && !isVector()) {
|
||||
uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
|
||||
_imm);
|
||||
uops[0]->setDelayedCommit();
|
||||
@@ -1250,7 +1250,7 @@ def template LoadImmConstructor {{
|
||||
uops[1]->setLastMicroop();
|
||||
}
|
||||
#else
|
||||
if (_dest == INTREG_PC && !isFloating()) {
|
||||
if (_dest == INTREG_PC && !isFloating() && !isVector()) {
|
||||
flags[IsControl] = true;
|
||||
flags[IsIndirectControl] = true;
|
||||
if (conditional)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2010 ARM Limited
|
||||
// Copyright (c) 2010, 2016 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -77,7 +77,7 @@ def template DataImmConstructor {{
|
||||
}
|
||||
}
|
||||
|
||||
if (%(is_branch)s && !isFloating()){
|
||||
if (%(is_branch)s && !isFloating() && !isVector()){
|
||||
flags[IsControl] = true;
|
||||
flags[IsIndirectControl] = true;
|
||||
if (condCode == COND_AL || condCode == COND_UC)
|
||||
@@ -117,7 +117,7 @@ def template DataRegConstructor {{
|
||||
}
|
||||
}
|
||||
|
||||
if (%(is_branch)s && !isFloating()){
|
||||
if (%(is_branch)s && !isFloating() && !isVector()){
|
||||
flags[IsControl] = true;
|
||||
flags[IsIndirectControl] = true;
|
||||
if (condCode == COND_AL || condCode == COND_UC)
|
||||
|
||||
@@ -493,6 +493,12 @@ class Operand(object):
|
||||
def isControlReg(self):
|
||||
return 0
|
||||
|
||||
def isVecReg(self):
|
||||
return 0
|
||||
|
||||
def isVecElem(self):
|
||||
return 0
|
||||
|
||||
def isPCState(self):
|
||||
return 0
|
||||
|
||||
@@ -658,6 +664,200 @@ class FloatRegOperand(Operand):
|
||||
}''' % (self.ctype, self.base_name, wp)
|
||||
return wb
|
||||
|
||||
class VecRegOperand(Operand):
|
||||
reg_class = 'VecRegClass'
|
||||
|
||||
def __init__(self, parser, full_name, ext, is_src, is_dest):
|
||||
Operand.__init__(self, parser, full_name, ext, is_src, is_dest)
|
||||
self.elemExt = None
|
||||
self.parser = parser
|
||||
|
||||
def isReg(self):
|
||||
return 1
|
||||
|
||||
def isVecReg(self):
|
||||
return 1
|
||||
|
||||
def makeDeclElem(self, elem_op):
|
||||
(elem_name, elem_ext) = elem_op
|
||||
(elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
|
||||
if elem_ext:
|
||||
ext = elem_ext
|
||||
else:
|
||||
ext = dflt_elem_ext
|
||||
ctype = self.parser.operandTypeMap[ext]
|
||||
return '\n\t%s %s = 0;' % (ctype, elem_name)
|
||||
|
||||
def makeDecl(self):
|
||||
if not self.is_dest and self.is_src:
|
||||
c_decl = '\t/* Vars for %s*/' % (self.base_name)
|
||||
if hasattr(self, 'active_elems'):
|
||||
if self.active_elems:
|
||||
for elem in self.active_elems:
|
||||
c_decl += self.makeDeclElem(elem)
|
||||
return c_decl + '\t/* End vars for %s */\n' % (self.base_name)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def makeConstructor(self, predRead, predWrite):
|
||||
c_src = ''
|
||||
c_dest = ''
|
||||
|
||||
numAccessNeeded = 1
|
||||
|
||||
if self.is_src:
|
||||
c_src = src_reg_constructor % (self.reg_class, self.reg_spec)
|
||||
|
||||
if self.is_dest:
|
||||
c_dest = dst_reg_constructor % (self.reg_class, self.reg_spec)
|
||||
c_dest += '\n\t_numVecDestRegs++;'
|
||||
|
||||
return c_src + c_dest
|
||||
|
||||
# Read destination register to write
|
||||
def makeReadWElem(self, elem_op):
|
||||
(elem_name, elem_ext) = elem_op
|
||||
(elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
|
||||
if elem_ext:
|
||||
ext = elem_ext
|
||||
else:
|
||||
ext = dflt_elem_ext
|
||||
ctype = self.parser.operandTypeMap[ext]
|
||||
c_read = '\t\t%s& %s = %s[%s];\n' % \
|
||||
(ctype, elem_name, self.base_name, elem_spec)
|
||||
return c_read
|
||||
|
||||
def makeReadW(self, predWrite):
|
||||
func = 'getWritableVecRegOperand'
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(func)
|
||||
|
||||
if predWrite:
|
||||
rindex = '_destIndex++'
|
||||
else:
|
||||
rindex = '%d' % self.dest_reg_idx
|
||||
|
||||
c_readw = '\t\t%s& tmp_d%s = xc->%s(this, %s);\n'\
|
||||
% ('TheISA::VecRegContainer', rindex, func, rindex)
|
||||
if self.elemExt:
|
||||
c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
|
||||
rindex, self.parser.operandTypeMap[self.elemExt])
|
||||
if self.ext:
|
||||
c_readw += '\t\tauto %s = tmp_d%s.as<%s>();\n' % (self.base_name,
|
||||
rindex, self.parser.operandTypeMap[self.ext])
|
||||
if hasattr(self, 'active_elems'):
|
||||
if self.active_elems:
|
||||
for elem in self.active_elems:
|
||||
c_readw += self.makeReadWElem(elem)
|
||||
return c_readw
|
||||
|
||||
# Normal source operand read
|
||||
def makeReadElem(self, elem_op, name):
|
||||
(elem_name, elem_ext) = elem_op
|
||||
(elem_spec, dflt_elem_ext, zeroing) = self.elems[elem_name]
|
||||
|
||||
if elem_ext:
|
||||
ext = elem_ext
|
||||
else:
|
||||
ext = dflt_elem_ext
|
||||
ctype = self.parser.operandTypeMap[ext]
|
||||
c_read = '\t\t%s = %s[%s];\n' % \
|
||||
(elem_name, name, elem_spec)
|
||||
return c_read
|
||||
|
||||
def makeRead(self, predRead):
|
||||
func = 'readVecRegOperand'
|
||||
if self.read_code != None:
|
||||
return self.buildReadCode(func)
|
||||
|
||||
if predRead:
|
||||
rindex = '_sourceIndex++'
|
||||
else:
|
||||
rindex = '%d' % self.src_reg_idx
|
||||
|
||||
name = self.base_name
|
||||
if self.is_dest and self.is_src:
|
||||
name += '_merger'
|
||||
|
||||
c_read = '\t\t%s& tmp_s%s = xc->%s(this, %s);\n' \
|
||||
% ('const TheISA::VecRegContainer', rindex, func, rindex)
|
||||
# If the parser has detected that elements are being access, create
|
||||
# the appropriate view
|
||||
if self.elemExt:
|
||||
c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \
|
||||
(name, rindex, self.parser.operandTypeMap[self.elemExt])
|
||||
if self.ext:
|
||||
c_read += '\t\tauto %s = tmp_s%s.as<%s>();\n' % \
|
||||
(name, rindex, self.parser.operandTypeMap[self.ext])
|
||||
if hasattr(self, 'active_elems'):
|
||||
if self.active_elems:
|
||||
for elem in self.active_elems:
|
||||
c_read += self.makeReadElem(elem, name)
|
||||
return c_read
|
||||
|
||||
def makeWrite(self, predWrite):
|
||||
func = 'setVecRegOperand'
|
||||
if self.write_code != None:
|
||||
return self.buildWriteCode(func)
|
||||
|
||||
wb = '''
|
||||
if (traceData) {
|
||||
panic("Vectors not supported yet in tracedata");
|
||||
/*traceData->setData(final_val);*/
|
||||
}
|
||||
'''
|
||||
return wb
|
||||
|
||||
def finalize(self, predRead, predWrite):
|
||||
super(VecRegOperand, self).finalize(predRead, predWrite)
|
||||
if self.is_dest:
|
||||
self.op_rd = self.makeReadW(predWrite) + self.op_rd
|
||||
|
||||
class VecElemOperand(Operand):
|
||||
reg_class = 'VectorElemClass'
|
||||
|
||||
def isReg(self):
|
||||
return 1
|
||||
|
||||
def isVecElem(self):
|
||||
return 1
|
||||
|
||||
def makeDecl(self):
|
||||
if self.is_dest and not self.is_src:
|
||||
return '\n\t%s %s;' % (self.ctype, self.base_name)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def makeConstructor(self, predRead, predWrite):
|
||||
c_src = ''
|
||||
c_dest = ''
|
||||
|
||||
numAccessNeeded = 1
|
||||
regId = 'RegId(%s, %s * numVecElemPerVecReg + elemIdx, %s)' % \
|
||||
(self.reg_class, self.reg_spec)
|
||||
|
||||
if self.is_src:
|
||||
c_src = ('\n\t_srcRegIdx[_numSrcRegs++] = RegId(%s, %s, %s);' %
|
||||
(self.reg_class, self.reg_spec, self.elem_spec))
|
||||
|
||||
if self.is_dest:
|
||||
c_dest = ('\n\t_destRegIdx[_numDestRegs++] = RegId(%s, %s, %s);' %
|
||||
(self.reg_class, self.reg_spec, self.elem_spec))
|
||||
c_dest += '\n\t_numVecElemDestRegs++;'
|
||||
return c_src + c_dest
|
||||
|
||||
def makeRead(self, predRead):
|
||||
c_read = ('\n/* Elem is kept inside the operand description */' +
|
||||
'\n\tVecElem %s = xc->readVecElemOperand(this, %d);' %
|
||||
(self.base_name, self.src_reg_idx))
|
||||
return c_read
|
||||
|
||||
def makeWrite(self, predWrite):
|
||||
c_write = ('\n/* Elem is kept inside the operand description */' +
|
||||
'\n\txc->setVecElemOperand(this, %d, %s);' %
|
||||
(self.dest_reg_idx, self.base_name))
|
||||
return c_write
|
||||
|
||||
class CCRegOperand(Operand):
|
||||
reg_class = 'CCRegClass'
|
||||
|
||||
@@ -857,22 +1057,49 @@ class OperandList(object):
|
||||
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_desc.ext != op_ext:
|
||||
error ('Inconsistent extensions for operand %s' % \
|
||||
op_base)
|
||||
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()
|
||||
@@ -883,6 +1110,7 @@ class OperandList(object):
|
||||
self.numDestRegs = 0
|
||||
self.numFPDestRegs = 0
|
||||
self.numIntDestRegs = 0
|
||||
self.numVecDestRegs = 0
|
||||
self.numCCDestRegs = 0
|
||||
self.numMiscDestRegs = 0
|
||||
self.memOperand = None
|
||||
@@ -904,6 +1132,8 @@ class OperandList(object):
|
||||
self.numFPDestRegs += 1
|
||||
elif op_desc.isIntReg():
|
||||
self.numIntDestRegs += 1
|
||||
elif op_desc.isVecReg():
|
||||
self.numVecDestRegs += 1
|
||||
elif op_desc.isCCReg():
|
||||
self.numCCDestRegs += 1
|
||||
elif op_desc.isControlReg():
|
||||
@@ -994,6 +1224,11 @@ class SubOperandList(OperandList):
|
||||
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
|
||||
if op_base in parser.elemToVector:
|
||||
elem_op = op_base
|
||||
op_base = parser.elemToVector[elem_op]
|
||||
# find this op in the master list
|
||||
op_desc = master_list.find_base(op_base)
|
||||
if not op_desc:
|
||||
@@ -1105,6 +1340,8 @@ class InstObjParams(object):
|
||||
header += '\n\t_numSrcRegs = 0;'
|
||||
header += '\n\t_numDestRegs = 0;'
|
||||
header += '\n\t_numFPDestRegs = 0;'
|
||||
header += '\n\t_numVecDestRegs = 0;'
|
||||
header += '\n\t_numVecElemDestRegs = 0;'
|
||||
header += '\n\t_numIntDestRegs = 0;'
|
||||
header += '\n\t_numCCDestRegs = 0;'
|
||||
|
||||
@@ -1149,6 +1386,8 @@ class InstObjParams(object):
|
||||
self.op_class = 'MemReadOp'
|
||||
elif 'IsFloating' in self.flags:
|
||||
self.op_class = 'FloatAddOp'
|
||||
elif 'IsVector' in self.flags:
|
||||
self.op_class = 'SimdAddOp'
|
||||
else:
|
||||
self.op_class = 'IntAluOp'
|
||||
|
||||
@@ -1158,8 +1397,12 @@ class InstObjParams(object):
|
||||
|
||||
# if 'IsFloating' is set, add call to the FP enable check
|
||||
# function (which should be provided by isa_desc via a declare)
|
||||
# if 'IsVector' is set, add call to the Vector enable check
|
||||
# function (which should be provided by isa_desc via a declare)
|
||||
if 'IsFloating' in self.flags:
|
||||
self.fp_enable_check = 'fault = checkFpEnableFault(xc);'
|
||||
elif 'IsVector' in self.flags:
|
||||
self.fp_enable_check = 'fault = checkVecEnableFault(xc);'
|
||||
else:
|
||||
self.fp_enable_check = ''
|
||||
|
||||
@@ -2300,6 +2543,16 @@ StaticInstPtr
|
||||
if dflt_ext:
|
||||
dflt_ctype = self.operandTypeMap[dflt_ext]
|
||||
attrList.extend(['dflt_ctype', 'dflt_ext'])
|
||||
# reg_spec is either just a string or a dictionary
|
||||
# (for elems of vector)
|
||||
if isinstance(reg_spec, tuple):
|
||||
(reg_spec, elem_spec) = reg_spec
|
||||
if isinstance(elem_spec, str):
|
||||
attrList.append('elem_spec')
|
||||
else:
|
||||
assert(isinstance(elem_spec, dict))
|
||||
elems = elem_spec
|
||||
attrList.append('elems')
|
||||
for attr in attrList:
|
||||
tmp_dict[attr] = eval(attr)
|
||||
tmp_dict['base_name'] = op_name
|
||||
@@ -2323,6 +2576,15 @@ StaticInstPtr
|
||||
|
||||
# Define operand variables.
|
||||
operands = user_dict.keys()
|
||||
# Add the elems defined in the vector operands and
|
||||
# build a map elem -> vector (used in OperandList)
|
||||
elem_to_vec = {}
|
||||
for op in user_dict.keys():
|
||||
if hasattr(self.operandNameMap[op], 'elems'):
|
||||
for elem in self.operandNameMap[op].elems.keys():
|
||||
operands.append(elem)
|
||||
elem_to_vec[elem] = op
|
||||
self.elemToVector = elem_to_vec
|
||||
extensions = self.operandTypeMap.keys()
|
||||
|
||||
operandsREString = r'''
|
||||
|
||||
@@ -108,6 +108,12 @@ template<> SparcFaultBase::FaultVals
|
||||
SparcFault<FpDisabled>::vals =
|
||||
{"fp_disabled", 0x020, 800, {P, P, H}, FaultStat()};
|
||||
|
||||
/* SPARCv8 and SPARCv9 define just fp_disabled trap. SIMD is not contemplated
|
||||
* as a separate part. Therefore, we use the same code and TT */
|
||||
template<> SparcFaultBase::FaultVals
|
||||
SparcFault<VecDisabled>::vals =
|
||||
{"fp_disabled", 0x020, 800, {P, P, H}, FaultStat()};
|
||||
|
||||
template<> SparcFaultBase::FaultVals
|
||||
SparcFault<FpExceptionIEEE754>::vals =
|
||||
{"fp_exception_ieee_754", 0x021, 1110, {P, P, H}, FaultStat()};
|
||||
|
||||
@@ -122,6 +122,7 @@ class PrivilegedOpcode : public SparcFault<PrivilegedOpcode> {};
|
||||
// class UnimplementedSTD : public SparcFault<UnimplementedSTD> {};
|
||||
|
||||
class FpDisabled : public SparcFault<FpDisabled> {};
|
||||
class VecDisabled : public SparcFault<VecDisabled> {};
|
||||
|
||||
class FpExceptionIEEE754 : public SparcFault<FpExceptionIEEE754> {};
|
||||
|
||||
|
||||
@@ -578,6 +578,11 @@ output exec {{
|
||||
return NoFault;
|
||||
}
|
||||
}
|
||||
static inline Fault
|
||||
checkVecEnableFault(CPU_EXEC_CONTEXT *xc)
|
||||
{
|
||||
return std::make_shared<VecDisabled>();
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@ class StaticInstFlags(Enum):
|
||||
'IsInteger', # References integer regs.
|
||||
'IsFloating', # References FP regs.
|
||||
'IsCC', # References CC regs.
|
||||
'IsVector', # References Vector regs.
|
||||
'IsVectorElem', # References Vector reg elems.
|
||||
|
||||
'IsMemRef', # References memory (load, store, or prefetch)
|
||||
'IsLoad', # Reads from memory (load or prefetch).
|
||||
|
||||
@@ -517,6 +517,7 @@ class BaseDynInst : public ExecContext, public RefCounted
|
||||
bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
|
||||
bool isInteger() const { return staticInst->isInteger(); }
|
||||
bool isFloating() const { return staticInst->isFloating(); }
|
||||
bool isVector() const { return staticInst->isVector(); }
|
||||
bool isControl() const { return staticInst->isControl(); }
|
||||
bool isCall() const { return staticInst->isCall(); }
|
||||
bool isReturn() const { return staticInst->isReturn(); }
|
||||
|
||||
@@ -517,6 +517,8 @@ class DefaultCommit
|
||||
Stats::Vector statComMembars;
|
||||
/** Total number of committed branches. */
|
||||
Stats::Vector statComBranches;
|
||||
/** Total number of vector instructions */
|
||||
Stats::Vector statComVector;
|
||||
/** Total number of floating point instructions */
|
||||
Stats::Vector statComFloating;
|
||||
/** Total number of integer instructions */
|
||||
|
||||
@@ -260,6 +260,13 @@ DefaultCommit<Impl>::regStats()
|
||||
.flags(total)
|
||||
;
|
||||
|
||||
statComVector
|
||||
.init(cpu->numThreads)
|
||||
.name(name() + ".vec_insts")
|
||||
.desc("Number of committed Vector instructions.")
|
||||
.flags(total)
|
||||
;
|
||||
|
||||
statComInteger
|
||||
.init(cpu->numThreads)
|
||||
.name(name()+".int_insts")
|
||||
@@ -1404,6 +1411,9 @@ DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
|
||||
// Floating Point Instruction
|
||||
if (inst->isFloating())
|
||||
statComFloating[tid]++;
|
||||
// Vector Instruction
|
||||
if (inst->isVector())
|
||||
statComVector[tid]++;
|
||||
|
||||
// Function Calls
|
||||
if (inst->isCall())
|
||||
|
||||
@@ -543,10 +543,14 @@ class InstructionQueue
|
||||
Stats::Scalar intInstQueueWakeupAccesses;
|
||||
Stats::Scalar fpInstQueueReads;
|
||||
Stats::Scalar fpInstQueueWrites;
|
||||
Stats::Scalar fpInstQueueWakeupQccesses;
|
||||
Stats::Scalar fpInstQueueWakeupAccesses;
|
||||
Stats::Scalar vecInstQueueReads;
|
||||
Stats::Scalar vecInstQueueWrites;
|
||||
Stats::Scalar vecInstQueueWakeupAccesses;
|
||||
|
||||
Stats::Scalar intAluAccesses;
|
||||
Stats::Scalar fpAluAccesses;
|
||||
Stats::Scalar vecAluAccesses;
|
||||
};
|
||||
|
||||
#endif //__CPU_O3_INST_QUEUE_HH__
|
||||
|
||||
@@ -364,7 +364,7 @@ InstructionQueue<Impl>::regStats()
|
||||
.desc("Number of floating instruction queue writes")
|
||||
.flags(total);
|
||||
|
||||
fpInstQueueWakeupQccesses
|
||||
fpInstQueueWakeupAccesses
|
||||
.name(name() + ".fp_inst_queue_wakeup_accesses")
|
||||
.desc("Number of floating instruction queue wakeup accesses")
|
||||
.flags(total);
|
||||
@@ -567,7 +567,13 @@ template <class Impl>
|
||||
void
|
||||
InstructionQueue<Impl>::insert(DynInstPtr &new_inst)
|
||||
{
|
||||
new_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++;
|
||||
if (new_inst->isFloating()) {
|
||||
fpInstQueueWrites++;
|
||||
} else if (new_inst->isVector()) {
|
||||
vecInstQueueWrites++;
|
||||
} else {
|
||||
intInstQueueWrites++;
|
||||
}
|
||||
// Make sure the instruction is valid
|
||||
assert(new_inst);
|
||||
|
||||
@@ -609,7 +615,13 @@ InstructionQueue<Impl>::insertNonSpec(DynInstPtr &new_inst)
|
||||
{
|
||||
// @todo: Clean up this code; can do it by setting inst as unable
|
||||
// to issue, then calling normal insert on the inst.
|
||||
new_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++;
|
||||
if (new_inst->isFloating()) {
|
||||
fpInstQueueWrites++;
|
||||
} else if (new_inst->isVector()) {
|
||||
vecInstQueueWrites++;
|
||||
} else {
|
||||
intInstQueueWrites++;
|
||||
}
|
||||
|
||||
assert(new_inst);
|
||||
|
||||
@@ -660,8 +672,10 @@ InstructionQueue<Impl>::getInstToExecute()
|
||||
assert(!instsToExecute.empty());
|
||||
DynInstPtr inst = instsToExecute.front();
|
||||
instsToExecute.pop_front();
|
||||
if (inst->isFloating()){
|
||||
if (inst->isFloating()) {
|
||||
fpInstQueueReads++;
|
||||
} else if (inst->isVector()) {
|
||||
vecInstQueueReads++;
|
||||
} else {
|
||||
intInstQueueReads++;
|
||||
}
|
||||
@@ -783,7 +797,13 @@ InstructionQueue<Impl>::scheduleReadyInsts()
|
||||
|
||||
DynInstPtr issuing_inst = readyInsts[op_class].top();
|
||||
|
||||
issuing_inst->isFloating() ? fpInstQueueReads++ : intInstQueueReads++;
|
||||
if (issuing_inst->isFloating()) {
|
||||
fpInstQueueReads++;
|
||||
} else if (issuing_inst->isVector()) {
|
||||
vecInstQueueReads++;
|
||||
} else {
|
||||
intInstQueueReads++;
|
||||
}
|
||||
|
||||
assert(issuing_inst->seqNum == (*order_it).oldestInst);
|
||||
|
||||
@@ -810,7 +830,13 @@ InstructionQueue<Impl>::scheduleReadyInsts()
|
||||
|
||||
if (op_class != No_OpClass) {
|
||||
idx = fuPool->getUnit(op_class);
|
||||
issuing_inst->isFloating() ? fpAluAccesses++ : intAluAccesses++;
|
||||
if (issuing_inst->isFloating()) {
|
||||
fpAluAccesses++;
|
||||
} else if (issuing_inst->isVector()) {
|
||||
vecAluAccesses++;
|
||||
} else {
|
||||
intAluAccesses++;
|
||||
}
|
||||
if (idx > FUPool::NoFreeFU) {
|
||||
op_latency = fuPool->getOpLatency(op_class);
|
||||
}
|
||||
@@ -955,7 +981,9 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
|
||||
|
||||
// The instruction queue here takes care of both floating and int ops
|
||||
if (completed_inst->isFloating()) {
|
||||
fpInstQueueWakeupQccesses++;
|
||||
fpInstQueueWakeupAccesses++;
|
||||
} else if (completed_inst->isVector()) {
|
||||
vecInstQueueWakeupAccesses++;
|
||||
} else {
|
||||
intInstQueueWakeupAccesses++;
|
||||
}
|
||||
@@ -1189,7 +1217,13 @@ InstructionQueue<Impl>::doSquash(ThreadID tid)
|
||||
(*squash_it)->seqNum > squashedSeqNum[tid]) {
|
||||
|
||||
DynInstPtr squashed_inst = (*squash_it);
|
||||
squashed_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++;
|
||||
if (squashed_inst->isFloating()) {
|
||||
fpInstQueueWrites++;
|
||||
} else if (squashed_inst->isVector()) {
|
||||
vecInstQueueWrites++;
|
||||
} else {
|
||||
intInstQueueWrites++;
|
||||
}
|
||||
|
||||
// Only handle the instruction if it actually is in the IQ and
|
||||
// hasn't already been squashed in the IQ.
|
||||
|
||||
@@ -252,6 +252,11 @@ BaseSimpleCPU::regStats()
|
||||
.desc("Number of float alu accesses")
|
||||
;
|
||||
|
||||
t_info.numVecAluAccesses
|
||||
.name(thread_str + ".num_vec_alu_accesses")
|
||||
.desc("Number of vector alu accesses")
|
||||
;
|
||||
|
||||
t_info.numCallsReturns
|
||||
.name(thread_str + ".num_func_calls")
|
||||
.desc("number of times a function call or return occured")
|
||||
@@ -272,6 +277,11 @@ BaseSimpleCPU::regStats()
|
||||
.desc("number of float instructions")
|
||||
;
|
||||
|
||||
t_info.numVecInsts
|
||||
.name(thread_str + ".num_vec_insts")
|
||||
.desc("number of vector instructions")
|
||||
;
|
||||
|
||||
t_info.numIntRegReads
|
||||
.name(thread_str + ".num_int_register_reads")
|
||||
.desc("number of times the integer registers were read")
|
||||
@@ -613,6 +623,12 @@ BaseSimpleCPU::postExecute()
|
||||
t_info.numFpInsts++;
|
||||
}
|
||||
|
||||
//vector alu accesses
|
||||
if (curStaticInst->isVector()){
|
||||
t_info.numVecAluAccesses++;
|
||||
t_info.numVecInsts++;
|
||||
}
|
||||
|
||||
//number of function calls/returns to get window accesses
|
||||
if (curStaticInst->isCall() || curStaticInst->isReturn()){
|
||||
t_info.numCallsReturns++;
|
||||
|
||||
@@ -94,6 +94,9 @@ class SimpleExecContext : public ExecContext {
|
||||
// Number of float alu accesses
|
||||
Stats::Scalar numFpAluAccesses;
|
||||
|
||||
// Number of vector alu accesses
|
||||
Stats::Scalar numVecAluAccesses;
|
||||
|
||||
// Number of function calls/returns
|
||||
Stats::Scalar numCallsReturns;
|
||||
|
||||
@@ -106,6 +109,9 @@ class SimpleExecContext : public ExecContext {
|
||||
// Number of float instructions
|
||||
Stats::Scalar numFpInsts;
|
||||
|
||||
// Number of vector instructions
|
||||
Stats::Scalar numVecInsts;
|
||||
|
||||
// Number of integer register file accesses
|
||||
Stats::Scalar numIntRegReads;
|
||||
Stats::Scalar numIntRegWrites;
|
||||
|
||||
@@ -150,6 +150,7 @@ class StaticInst : public RefCounted, public StaticInstFlags
|
||||
|
||||
bool isInteger() const { return flags[IsInteger]; }
|
||||
bool isFloating() const { return flags[IsFloating]; }
|
||||
bool isVector() const { return flags[IsVector]; }
|
||||
bool isCC() const { return flags[IsCC]; }
|
||||
|
||||
bool isControl() const { return flags[IsControl]; }
|
||||
|
||||
Reference in New Issue
Block a user