997cbe1c09
By using an underscore, the "." is still available and can unambiguously be used to refer to members of a structure if an operand is a structure, class, etc. This change mostly just replaces the appropriate "."s with "_"s, but there were also a few places where the ISA descriptions where handling the extensions themselves and had their own regular expressions to update. The regular expressions in the isa parser were updated as well. It also now looks for one of the defined type extensions specifically after connecting "_" where before it would look for any sequence of characters after a "." following an operand name and try to use it as the extension. This helps to disambiguate cases where a "_" may legitimately be part of an operand name but not separate the name from the type suffix. Because leaving the "_" and suffix on the variable name still leaves a valid C++ identifier and all extensions need to be consistent in a given context, I considered leaving them on as a breadcrumb that would show what the intended type was for that operand. Unfortunately the operands can be referred to in code templates, the Mem operand in particular, and since the exact type of Mem can be different for different uses of the same template, that broke things.
134 lines
4.7 KiB
C++
134 lines
4.7 KiB
C++
// -*- mode:c++ -*-
|
|
|
|
// Copyright (c) 2003-2005 The Regents of The University of Michigan
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are
|
|
// met: redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer;
|
|
// redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution;
|
|
// neither the name of the copyright holders nor the names of its
|
|
// contributors may be used to endorse or promote products derived from
|
|
// this software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// Authors: Steve Reinhardt
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Integer operate instructions
|
|
//
|
|
|
|
output header {{
|
|
/**
|
|
* Base class for integer immediate instructions.
|
|
*/
|
|
class IntegerImm : public AlphaStaticInst
|
|
{
|
|
protected:
|
|
/// Immediate operand value (unsigned 8-bit int).
|
|
uint8_t imm;
|
|
|
|
/// Constructor
|
|
IntegerImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
|
|
: AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM)
|
|
{
|
|
}
|
|
|
|
std::string
|
|
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
|
};
|
|
}};
|
|
|
|
output decoder {{
|
|
std::string
|
|
IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
|
{
|
|
std::stringstream ss;
|
|
|
|
ccprintf(ss, "%-10s ", mnemonic);
|
|
|
|
// just print the first source reg... if there's
|
|
// a second one, it's a read-modify-write dest (Rc),
|
|
// e.g. for CMOVxx
|
|
if (_numSrcRegs > 0) {
|
|
printReg(ss, _srcRegIdx[0]);
|
|
ss << ",";
|
|
}
|
|
|
|
ss << (int)imm;
|
|
|
|
if (_numDestRegs > 0) {
|
|
ss << ",";
|
|
printReg(ss, _destRegIdx[0]);
|
|
}
|
|
|
|
return ss.str();
|
|
}
|
|
}};
|
|
|
|
|
|
def template RegOrImmDecode {{
|
|
{
|
|
AlphaStaticInst *i =
|
|
(IMM) ? (AlphaStaticInst *)new %(class_name)sImm(machInst)
|
|
: (AlphaStaticInst *)new %(class_name)s(machInst);
|
|
if (RC == 31) {
|
|
i = makeNop(i);
|
|
}
|
|
return i;
|
|
}
|
|
}};
|
|
|
|
// Primary format for integer operate instructions:
|
|
// - Generates both reg-reg and reg-imm versions if Rb_or_imm is used.
|
|
// - Generates NOP if RC == 31.
|
|
def format IntegerOperate(code, *opt_flags) {{
|
|
# If the code block contains 'Rb_or_imm', we define two instructions,
|
|
# one using 'Rb' and one using 'imm', and have the decoder select
|
|
# the right one.
|
|
uses_imm = (code.find('Rb_or_imm') != -1)
|
|
if uses_imm:
|
|
orig_code = code
|
|
# base code is reg version:
|
|
# rewrite by substituting 'Rb' for 'Rb_or_imm'
|
|
code = re.sub(r'Rb_or_imm', 'Rb', orig_code)
|
|
# generate immediate version by substituting 'imm'
|
|
# note that imm takes no extenstion, so we extend
|
|
# the regexp to replace any extension as well
|
|
imm_code = re.sub(r'Rb_or_imm(_\w+)?', 'imm', orig_code)
|
|
|
|
# generate declaration for register version
|
|
iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_flags)
|
|
header_output = BasicDeclare.subst(iop)
|
|
decoder_output = BasicConstructor.subst(iop)
|
|
exec_output = BasicExecute.subst(iop)
|
|
|
|
if uses_imm:
|
|
# append declaration for imm version
|
|
imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_code,
|
|
opt_flags)
|
|
header_output += BasicDeclare.subst(imm_iop)
|
|
decoder_output += BasicConstructor.subst(imm_iop)
|
|
exec_output += BasicExecute.subst(imm_iop)
|
|
# decode checks IMM bit to pick correct version
|
|
decode_block = RegOrImmDecode.subst(iop)
|
|
else:
|
|
# no imm version: just check for nop
|
|
decode_block = OperateNopCheckDecode.subst(iop)
|
|
}};
|