blob: 8b118f4f0c5ddbfa391c824c980271c7e6d48e36 [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.
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)
int_extensions = ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw")
operand_names = ("Frd", "Frs1", "Frs2", "Frd_N")
class Operand(object):
def __init__(self, name, ext):
self.name = name
self.ext = ext
self.src = False
self.dest = False
operands = {}
operandsREString = (r'''
# neg. lookbehind assertion: prevent partial matches
(?<!\w)
# match: operand with optional '.' then suffix
((?P<name>%s)(_(?P<ext>[^\W_]+))?)
# neg. lookahead assertion: prevent partial matches
(?!\w)
''' % '|'.join(operand_names))
operandsRE = re.compile(operandsREString, re.MULTILINE | re.VERBOSE)
for match in operandsRE.finditer(code):
name = match.group('name')
ext = match.group('ext')
operand = operands.setdefault(name, Operand(name, ext))
if assignRE.match(code, match.end()):
operand.dest = True
else:
operand.src = True
if operand.ext != ext:
raise Exception("Inconsistent extensions in double filter")
# Get rid of any unwanted extension
code = operandsRE.sub('\g<name>', code)
for op in operands.values():
is_int = op.ext in int_extensions
member, type = ('ui', 'uint64_t') if is_int else ('d', 'double')
if op.src:
code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
(op.name, op.name, op.name, member)) + code
if op.dest:
code += '''
%s_low = DoubleSingle(%s).s[1];
%s_high = DoubleSingle(%s).s[0];''' % \
(op.name, op.name, op.name, op.name)
code = ("%s %s;" % (type, op.name)) + 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 code, None, None
orig_code = code
reg_code = matcher.sub('Rs\g<rNum>\g<typeQual>', code)
imm_code = matcher.sub('imm', code)
return reg_code, imm_code, rOrImmMatch.group('iNum')
}};
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.
static inline Fault
checkFpEnabled(PSTATE pstate, RegVal fprs)
{
if (pstate.pef && fprs & 0x4) {
return NoFault;
} else {
return std::make_shared<FpDisabled>();
}
}
}};