blob: 8bcac0b0553b92f91b6220c01fdb0dd8826e012d [file] [log] [blame]
// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Ali Saidi
// Gabe Black
// Steve Reinhardt
def template ROrImmDecode {{
{
return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
: (SparcStaticInst *)(new %(class_name)s(machInst)));
}
}};
output header {{
union DoubleSingle
{
double d;
uint64_t ui;
uint32_t s[2];
DoubleSingle(double _d) : d(_d)
{}
DoubleSingle(uint64_t _ui) : ui(_ui)
{}
DoubleSingle(uint32_t _s0, uint32_t _s1)
{
s[0] = _s0;
s[1] = _s1;
}
};
}};
let {{
def filterDoubles(code):
assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
for opName in ("Frd", "Frs1", "Frs2", "Frd_N"):
next_pos = 0
operandsREString = (r'''
(?<!\w) # neg. lookbehind assertion: prevent partial matches
((%s)(?:_([^\W_]+))?) # match: operand with optional '.' then suffix
(?!\w) # neg. lookahead assertion: prevent partial matches
''' % opName)
operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
is_src = False
is_dest = False
extension = None
foundOne = False
while 1:
match = operandsRE.search(code, next_pos)
if not match:
break
foundOne = True
op = match.groups()
(op_full, op_base, op_ext) = op
is_dest_local = (assignRE.match(code, match.end()) != None)
is_dest = is_dest or is_dest_local
is_src = is_src or not is_dest_local
if extension and extension != op_ext:
raise Exception, "Inconsistent extensions in double filter."
extension = op_ext
next_pos = match.end()
if foundOne:
# Get rid of any unwanted extension
code = operandsRE.sub(op_base, code)
is_int = False
member = "d"
if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
is_int = True
member = "ui"
if is_src:
code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
(opName, opName, opName, member)) + code
if is_dest:
code += '''
%s_low = DoubleSingle(%s).s[1];
%s_high = DoubleSingle(%s).s[0];''' % \
(opName, opName, opName, opName)
if is_int:
code = ("uint64_t %s;" % opName) + code
else:
code = ("double %s;" % opName) + code
return code
}};
let {{
def splitOutImm(code):
matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?')
rOrImmMatch = matcher.search(code)
if (rOrImmMatch == None):
return (False, code, '', '', '')
rString = rOrImmMatch.group("rNum")
if (rOrImmMatch.group("typeQual") != None):
rString += rOrImmMatch.group("typeQual")
iString = rOrImmMatch.group("iNum")
orig_code = code
code = matcher.sub('Rs' + rString, orig_code)
imm_code = matcher.sub('imm', orig_code)
return (True, code, imm_code, rString, iString)
}};
output exec {{
/// Check "FP enabled" machine status bit. Called when executing any FP
/// instruction.
/// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
/// if not. Non-full-system mode: always returns NoFault.
static inline Fault
checkFpEnableFault(ExecContext *xc)
{
if (FullSystem) {
PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE);
if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) {
return NoFault;
} else {
return std::make_shared<FpDisabled>();
}
} else {
return NoFault;
}
}
static inline Fault
checkVecEnableFault(ExecContext *xc)
{
return std::make_shared<VecDisabled>();
}
}};