mirror of
https://github.com/intel/intel-graphics-compiler.git
synced 2025-11-04 08:21:06 +08:00
Update IGA
Change-Id: Ieb4e0c55ea8f63270492c9f32c71aed725f4c648
This commit is contained in:
committed by
Aleksander Stojanowski
parent
8a5091dd1d
commit
1d3ef54716
@ -66,11 +66,6 @@ set_property( TARGET GEDLibrary APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:GED_DEBUG>
|
||||
)
|
||||
|
||||
if (IGC_BUILD AND MSVC)
|
||||
#set up standard defines from the common WDK path.
|
||||
bs_set_wdk(GEDLibrary)
|
||||
endif()
|
||||
|
||||
# hidden visibility suppresses PLT entries from being created for GED and functions and trims the interface down to a minimal size
|
||||
#Was manifested when IGA was used in GT-PIN which also uses GED. IGA ended up using GED library linked with GT-PIN not IGA one
|
||||
#https://gcc.gnu.org/wiki/Visibility
|
||||
|
||||
@ -24,4 +24,4 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
======================= end_copyright_notice ==================================*/
|
||||
|
||||
const char* gedVersion = "dev (8e84a7de)";
|
||||
const char* gedVersion = "dev (fc70de55)";
|
||||
|
||||
@ -80,7 +80,7 @@ private:
|
||||
inline static bool HandleNonEnumEncodingRestrictions(const ged_ins_field_entry_t* dataEntry, NumType& val);
|
||||
|
||||
template<typename NumType>
|
||||
static bool HandleNonEnumEncodingRestriction(GEDFORASSERT(const ged_ins_field_entry_t* dataEntry) COMMA
|
||||
static bool HandleNonEnumEncodingRestriction(const ged_ins_field_entry_t* dataEntry,
|
||||
const ged_field_restriction_t* restriction, NumType& val);
|
||||
|
||||
private:
|
||||
@ -319,14 +319,14 @@ bool GEDRestrictionsHandler::HandleNonEnumEncodingRestrictions(const ged_ins_fie
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (NULL == dataEntry->_restrictions[i]) return true;
|
||||
if (!HandleNonEnumEncodingRestriction(GEDFORASSERT(dataEntry) COMMA dataEntry->_restrictions[i], val)) return false;
|
||||
if (!HandleNonEnumEncodingRestriction(dataEntry, dataEntry->_restrictions[i], val)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename NumType>
|
||||
bool GEDRestrictionsHandler::HandleNonEnumEncodingRestriction(GEDFORASSERT(const ged_ins_field_entry_t* dataEntry) COMMA
|
||||
bool GEDRestrictionsHandler::HandleNonEnumEncodingRestriction(const ged_ins_field_entry_t* dataEntry,
|
||||
const ged_field_restriction_t* restriction, NumType& val)
|
||||
{
|
||||
GEDASSERT(NULL != restriction);
|
||||
@ -334,16 +334,16 @@ bool GEDRestrictionsHandler::HandleNonEnumEncodingRestriction(GEDFORASSERT(const
|
||||
switch (restriction->_restrictionType)
|
||||
{
|
||||
case GED_FIELD_RESTRICTIONS_TYPE_VALUE:
|
||||
GEDASSERT(CheckMaxValue(val, dataEntry->_bitSize));
|
||||
if (!CheckMaxValue(val, dataEntry->_bitSize)) return false; // TODO: This was an assert, should switch back for optimization?
|
||||
return VerifyValueRestriction(val, restriction->_value);
|
||||
case GED_FIELD_RESTRICTIONS_TYPE_RANGE:
|
||||
GEDASSERT(CheckMaxValue(val, dataEntry->_bitSize));
|
||||
if (!CheckMaxValue(val, dataEntry->_bitSize)) return false; // TODO: This was an assert, should switch back for optimization?
|
||||
return VerifyRangeRestriction(val, restriction->_range);
|
||||
case GED_FIELD_RESTRICTIONS_TYPE_MASK:
|
||||
GEDASSERT(CheckMaxValue(val, dataEntry->_bitSize));
|
||||
if (!CheckMaxValue(val, dataEntry->_bitSize)) return false; // TODO: This was an assert, should switch back for optimization?
|
||||
return VerifyMaskRestriction(val, restriction->_mask);
|
||||
case GED_FIELD_RESTRICTIONS_TYPE_PADDING:
|
||||
GEDASSERT(CheckMaxValue(val, dataEntry->_bitSize)); // TODO: This should probably be checked always, not as an assertion.
|
||||
if (!CheckMaxValue(val, dataEntry->_bitSize)) return false;
|
||||
return ((NumType)(restriction->_padding._value) == ((NumType)(restriction->_padding._mask) & val));
|
||||
case GED_FIELD_RESTRICTIONS_TYPE_FIELD_TYPE:
|
||||
GEDASSERT(GED_QWORD_BITS >= restriction->_fieldType._attr._bits);
|
||||
|
||||
@ -246,8 +246,8 @@ typedef enum
|
||||
* Channel Enable. Four channel enables are defined for controlling which channels will be written into the destination region.
|
||||
* These channel mask bits are applied in a modulo-four manner to all ExecSize channels. There is 1-bit Channel Enable for each
|
||||
* channel within the group of 4. If the bit is cleared, the write for the corresponding channel is disabled. If the bit is set,
|
||||
* the write is enabled. Mnemonic for the bit being set for the group of 4 is "x", "y", "z", and "w",
|
||||
* respectively, where "x" corresponds to Channel 0 in the group and "w" corresponds to channel 3 in the group.
|
||||
* the write is enabled. Mnemonic for the bit being set for the group of 4 is "x", "y", "z", and "w", respectively, where "x"
|
||||
* corresponds to Channel 0 in the group and "w" corresponds to channel 3 in the group.
|
||||
*
|
||||
* For a send instruction, this field applies to the CurrDst.
|
||||
*
|
||||
@ -321,8 +321,8 @@ typedef enum
|
||||
/*!
|
||||
* Channel Select. This field controls the channel swizzle for the first source operand (src0). The normally sequential channel
|
||||
* assignment can be altered by explicitly identifying neighboring data elements for each channel. Out of the 8-bit field, 2 bits
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1
|
||||
* ("y"), 2 ("z"), and 3 ("w") in the group, respectively.
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1 ("y"), 2
|
||||
* ("z"), and 3 ("w") in the group, respectively.
|
||||
*
|
||||
* @par Models: all
|
||||
*/
|
||||
@ -437,8 +437,8 @@ typedef enum
|
||||
/*!
|
||||
* Channel Select. This field controls the channel swizzle for the second source operand (src1). The normally sequential channel
|
||||
* assignment can be altered by explicitly identifying neighboring data elements for each channel. Out of the 8-bit field, 2 bits
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1
|
||||
* ("y"), 2 ("z"), and 3 ("w") in the group, respectively.
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1 ("y"), 2
|
||||
* ("z"), and 3 ("w") in the group, respectively.
|
||||
*
|
||||
* @par Models: all
|
||||
*/
|
||||
@ -586,8 +586,8 @@ typedef enum
|
||||
/*!
|
||||
* Channel Select. This field controls the channel swizzle for the third source operand (src2). The normally sequential channel
|
||||
* assignment can be altered by explicitly identifying neighboring data elements for each channel. Out of the 8-bit field, 2 bits
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1
|
||||
* ("y"), 2 ("z"), and 3 ("w") in the group, respectively.
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1 ("y"), 2
|
||||
* ("z"), and 3 ("w") in the group, respectively.
|
||||
*
|
||||
* @par Models: all
|
||||
*/
|
||||
|
||||
@ -246,8 +246,8 @@ typedef enum
|
||||
* Channel Enable. Four channel enables are defined for controlling which channels will be written into the destination region.
|
||||
* These channel mask bits are applied in a modulo-four manner to all ExecSize channels. There is 1-bit Channel Enable for each
|
||||
* channel within the group of 4. If the bit is cleared, the write for the corresponding channel is disabled. If the bit is set,
|
||||
* the write is enabled. Mnemonic for the bit being set for the group of 4 is "x", "y", "z", and "w",
|
||||
* respectively, where "x" corresponds to Channel 0 in the group and "w" corresponds to channel 3 in the group.
|
||||
* the write is enabled. Mnemonic for the bit being set for the group of 4 is "x", "y", "z", and "w", respectively, where "x"
|
||||
* corresponds to Channel 0 in the group and "w" corresponds to channel 3 in the group.
|
||||
*
|
||||
* For a send instruction, this field applies to the CurrDst.
|
||||
*
|
||||
@ -321,8 +321,8 @@ typedef enum
|
||||
/*!
|
||||
* Channel Select. This field controls the channel swizzle for the first source operand (src0). The normally sequential channel
|
||||
* assignment can be altered by explicitly identifying neighboring data elements for each channel. Out of the 8-bit field, 2 bits
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1
|
||||
* ("y"), 2 ("z"), and 3 ("w") in the group, respectively.
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1 ("y"), 2
|
||||
* ("z"), and 3 ("w") in the group, respectively.
|
||||
*
|
||||
* @par Models: all
|
||||
*/
|
||||
@ -437,8 +437,8 @@ typedef enum
|
||||
/*!
|
||||
* Channel Select. This field controls the channel swizzle for the second source operand (src1). The normally sequential channel
|
||||
* assignment can be altered by explicitly identifying neighboring data elements for each channel. Out of the 8-bit field, 2 bits
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1
|
||||
* ("y"), 2 ("z"), and 3 ("w") in the group, respectively.
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1 ("y"), 2
|
||||
* ("z"), and 3 ("w") in the group, respectively.
|
||||
*
|
||||
* @par Models: all
|
||||
*/
|
||||
@ -586,8 +586,8 @@ typedef enum
|
||||
/*!
|
||||
* Channel Select. This field controls the channel swizzle for the third source operand (src2). The normally sequential channel
|
||||
* assignment can be altered by explicitly identifying neighboring data elements for each channel. Out of the 8-bit field, 2 bits
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1
|
||||
* ("y"), 2 ("z"), and 3 ("w") in the group, respectively.
|
||||
* are assigned for each channel within the group of 4. ChanSel[1:0], [3.2], [5.4] and [7,6] are for channel 0 ("x"), 1 ("y"), 2
|
||||
* ("z"), and 3 ("w") in the group, respectively.
|
||||
*
|
||||
* @par Models: all
|
||||
*/
|
||||
|
||||
@ -369,15 +369,18 @@ namespace iga
|
||||
|
||||
return
|
||||
decodeField<RegRef>(
|
||||
iga::pstg12::FLAGREG,
|
||||
fFLAGREG,
|
||||
F0_0,"f0.0",
|
||||
F0_1,"f0.1",
|
||||
F1_0,"f1.0",
|
||||
F1_1,"f1.1");
|
||||
}
|
||||
|
||||
void decodeFlagModifierField(const Field &fFLAGMOD) {
|
||||
RegRef flagReg = peekFlagRegRef(iga::pstg12::FLAGREG);
|
||||
void decodeFlagModifierField(
|
||||
const Field &fFLAGMOD,
|
||||
const Field &fFLAGREG)
|
||||
{
|
||||
RegRef flagReg = peekFlagRegRef(fFLAGREG);
|
||||
FlagModifier invalidModifier = static_cast<FlagModifier>(-1);
|
||||
FlagModifier zeroValue = FlagModifier::NONE;
|
||||
const char *zeroString = "";
|
||||
@ -505,13 +508,14 @@ namespace iga
|
||||
reportError("ERROR: expected 64b type");
|
||||
}
|
||||
ss << ")";
|
||||
addDecodedField(iga::pstg12::BAS_SRC0_IMM32L, "LO32" + ss.str());
|
||||
addDecodedField(iga::pstg12::BAS_SRC0_IMM32H, "HI32" + ss.str());
|
||||
addDecodedField(fIMM32L, "LO32" + ss.str());
|
||||
addDecodedField(fIMM32H, "HI32" + ss.str());
|
||||
return immVal;
|
||||
}
|
||||
|
||||
void decodeExecOffsetInfo(
|
||||
const Field &fEXECSIZE, const Field &fCHANOFF)
|
||||
const Field &fEXECSIZE,
|
||||
const Field &fCHANOFF)
|
||||
{
|
||||
ExecSize execSize = decodeExecSizeBits(bits.getField(fEXECSIZE));
|
||||
if (execSize == ExecSize::INVALID) {
|
||||
@ -519,7 +523,7 @@ namespace iga
|
||||
}
|
||||
std::stringstream ssEs;
|
||||
ssEs << "(" << ToSyntax(execSize) << "|...)";
|
||||
addDecodedField(iga::pstg12::EXECSIZE, ssEs.str());
|
||||
addDecodedField(fEXECSIZE, ssEs.str());
|
||||
|
||||
ChannelOffset chOff = decodeChannelOffsetBits(bits.getField(fCHANOFF));
|
||||
if (chOff < ChannelOffset::M0 || chOff > ChannelOffset::M28) {
|
||||
@ -532,9 +536,9 @@ namespace iga
|
||||
builder.InstExecInfo(loc, execSize, loc, chOff);
|
||||
}
|
||||
|
||||
DstModifier decodeDstModifier() {
|
||||
DstModifier decodeDstModifier(const Field &fSATURATE) {
|
||||
return
|
||||
decodeField(iga::pstg12::SATURATE,
|
||||
decodeField(fSATURATE,
|
||||
DstModifier::NONE, "",
|
||||
DstModifier::SAT, "(sat)");
|
||||
}
|
||||
@ -557,57 +561,47 @@ namespace iga
|
||||
const Field &fSUBREG)
|
||||
{
|
||||
std::string typeValue;
|
||||
if (os.isDpasSubfunc() && opIndex > OpIx::TER_SRC0) {
|
||||
auto srb = bits.getField(fSUBREG); // ternary src's have all 5 bits
|
||||
opInfo.regOpReg.subRegNum = BytesOffsetToSubReg(
|
||||
(uint8_t)srb,
|
||||
opInfo.regOpName,
|
||||
opInfo.subBytePrecision);
|
||||
typeValue = ToSyntax(opInfo.subBytePrecision);
|
||||
} else {
|
||||
peekRegularSubReg(opIndex, opInfo, fSUBREG, opInfo.type);
|
||||
typeValue = ToSyntax(opInfo.type);
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << "." << (int)opInfo.regOpReg.subRegNum << typeValue;
|
||||
addDecodedField(fSUBREG, ss.str());
|
||||
decodeSubRegWithType(
|
||||
opIndex, opInfo, fSUBREG, opInfo.type, ToSyntax(opInfo.type));
|
||||
}
|
||||
void decodeRegularSubReg(
|
||||
// e.g. for subregisters without proper types
|
||||
void decodeSubRegWithImplicitType(
|
||||
OpIx opIndex,
|
||||
OperandInfo &opInfo,
|
||||
const Field &fSUBREG,
|
||||
Type type)
|
||||
Type t)
|
||||
{
|
||||
peekRegularSubReg(opIndex, opInfo, fSUBREG, type);
|
||||
std::stringstream ss;
|
||||
ss << "." << (int)opInfo.regOpReg.subRegNum << ToSyntax(type);
|
||||
addDecodedField(fSUBREG, ss.str());
|
||||
std::string typeValue;
|
||||
decodeSubRegWithType(opIndex, opInfo, fSUBREG, t, "");
|
||||
}
|
||||
void peekRegularSubReg(
|
||||
void decodeSubRegWithType(
|
||||
OpIx opIndex,
|
||||
OperandInfo &opInfo,
|
||||
const Field &fSUBREG,
|
||||
Type type)
|
||||
Type type,
|
||||
std::string typeSyntax)
|
||||
{
|
||||
auto srb = (int)bits.getField(fSUBREG);
|
||||
if (opIndex == OpIx::TER_DST) {
|
||||
srb <<= 3; // ternary dst only stores high two bits
|
||||
}
|
||||
if (IsRegisterScaled(opInfo.regOpName)) {
|
||||
auto typeSize = TypeSizeWithDefault(type,4);
|
||||
if (srb % typeSize != 0) {
|
||||
std::stringstream ess;
|
||||
if (IsDst(opIndex)) {
|
||||
ess << "dst";
|
||||
} else {
|
||||
ess << "src" << ToSrcIndex(opIndex);
|
||||
}
|
||||
ess << " subregister is not divisible by type size";
|
||||
reportError(ess.str());
|
||||
auto scaled = BytesOffsetToSubReg(srb, opInfo.regOpName, type);
|
||||
auto unscaled = SubRegToBytesOffset((int)scaled, opInfo.regOpName, type);
|
||||
if (unscaled != srb) {
|
||||
std::stringstream ess;
|
||||
if (IsDst(opIndex)) {
|
||||
ess << "dst";
|
||||
} else {
|
||||
ess << "src" << ToSrcIndex(opIndex);
|
||||
}
|
||||
srb /= typeSize;
|
||||
ess << " subregister offset is misaligned for type size";
|
||||
reportError(ess.str());
|
||||
}
|
||||
opInfo.regOpReg.subRegNum = (uint8_t)srb;
|
||||
opInfo.regOpReg.subRegNum = scaled;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "." << (int)opInfo.regOpReg.subRegNum << typeSyntax;
|
||||
addDecodedField(fSUBREG, ss.str());
|
||||
}
|
||||
|
||||
void decodeRegDirectFields(
|
||||
@ -627,7 +621,9 @@ namespace iga
|
||||
opInfo.kind = Operand::Kind::DIRECT;
|
||||
decodeSubReg(opIndex, opInfo, fSUBREG);
|
||||
if (fSUBREG.length < 5) { // ternary has some reserved bits
|
||||
addReserved(fSUBREG.offset - 5 + fSUBREG.length, 5 - fSUBREG.length);
|
||||
addReserved(
|
||||
fSUBREG.offset - 5 + fSUBREG.length,
|
||||
5 - fSUBREG.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -665,15 +661,15 @@ namespace iga
|
||||
|
||||
ImplAcc decodeImplAccField(const Field &fSPCACC) {
|
||||
return decodeField<ImplAcc>(fSPCACC, ImplAcc::INVALID,{
|
||||
{ImplAcc::ACC2,".acc2"},
|
||||
{ImplAcc::ACC3,".acc3"},
|
||||
{ImplAcc::ACC4,".acc4"},
|
||||
{ImplAcc::ACC5,".acc5"},
|
||||
{ImplAcc::ACC6,".acc6"},
|
||||
{ImplAcc::ACC7,".acc7"},
|
||||
{ImplAcc::ACC8,".acc8"},
|
||||
{ImplAcc::ACC9,".acc9"},
|
||||
{ImplAcc::NOACC,".noacc"}});
|
||||
{ImplAcc::ACC2,".sacc2"},
|
||||
{ImplAcc::ACC3,".sacc3"},
|
||||
{ImplAcc::ACC4,".sacc4"},
|
||||
{ImplAcc::ACC5,".sacc5"},
|
||||
{ImplAcc::ACC6,".sacc6"},
|
||||
{ImplAcc::ACC7,".sacc7"},
|
||||
{ImplAcc::ACC8,".sacc8"},
|
||||
{ImplAcc::ACC9,".sacc9"},
|
||||
{ImplAcc::NOACC,".nosacc"}});
|
||||
}
|
||||
|
||||
bool decodeInstOpt(const Field &fINSTOPT, InstOpt opt) {
|
||||
|
||||
@ -349,11 +349,20 @@ namespace iga
|
||||
}
|
||||
|
||||
inline void InstEncoder::encode(const Field &f, ImplAcc acc) {
|
||||
uint64_t val = 0;
|
||||
switch (acc) {
|
||||
case ImplAcc::INVALID: break;
|
||||
default:
|
||||
encodeFieldBits(f, static_cast<uint64_t>(acc));
|
||||
ENCODING_CASE(ImplAcc::ACC2, 0x0);
|
||||
ENCODING_CASE(ImplAcc::ACC3, 0x1);
|
||||
ENCODING_CASE(ImplAcc::ACC4, 0x2);
|
||||
ENCODING_CASE(ImplAcc::ACC5, 0x3);
|
||||
ENCODING_CASE(ImplAcc::ACC6, 0x4);
|
||||
ENCODING_CASE(ImplAcc::ACC7, 0x5);
|
||||
ENCODING_CASE(ImplAcc::ACC8, 0x6);
|
||||
ENCODING_CASE(ImplAcc::ACC9, 0x7);
|
||||
ENCODING_CASE(ImplAcc::NOACC, 0x8);
|
||||
default: internalErrorBadIR(f);
|
||||
}
|
||||
encodeFieldBits(f, val);
|
||||
}
|
||||
|
||||
inline void InstEncoder::encode(const Field &f, Region::Vert vt) {
|
||||
|
||||
@ -26,13 +26,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#ifndef _BUFFEREDLEXER_H
|
||||
#define _BUFFEREDLEXER_H
|
||||
|
||||
#include "Lexemes.hpp"
|
||||
#include "../IR/Loc.hpp"
|
||||
#include "../asserts.hpp"
|
||||
#include "../IR/Loc.hpp"
|
||||
#include "Lexemes.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// #define DUMP_LEXEMES
|
||||
@ -182,11 +183,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void DumpLookaheads(int n = 1) const {
|
||||
DEBUG_TRACE("LEXER: Next %d lookaheads are:\n", n);
|
||||
void DumpLookaheads(std::ostream &os, int n = 1) const {
|
||||
os << "LEXER: Next " << n << " lookaheads are:\n";
|
||||
for (int i = 0; i < n; i++) {
|
||||
const Token &tk = Next(i);
|
||||
DEBUG_TRACE(GetTokenString(tk, m_input).c_str());
|
||||
os << " " << GetTokenString(tk, m_input).c_str() << "\n";
|
||||
if (tk.lexeme == Lexeme::END_OF_FILE) {
|
||||
break;
|
||||
}
|
||||
@ -208,16 +209,18 @@ public:
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Consume(Lexeme lx, int i = 0) {
|
||||
if (LookingAt(lx,i)) {
|
||||
bool Consume(Lexeme lxm) {
|
||||
if (LookingAt(lxm)) {
|
||||
(void)Skip(1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LookingAt(Lexeme lx, int i = 0) const {
|
||||
bool LookingAt(Lexeme lxm) const {
|
||||
return LookingAtFrom(0,lxm);
|
||||
}
|
||||
bool LookingAtFrom(int i, Lexeme lx) const {
|
||||
return Next(i).lexeme == lx;
|
||||
}
|
||||
|
||||
|
||||
@ -34,7 +34,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "../Models/Models.hpp"
|
||||
#include "../strings.hpp"
|
||||
#ifndef DISABLE_ENCODER_EXCEPTIONS
|
||||
#include "../Backend/GED/Decoder.hpp"
|
||||
#include "../Backend/GED/Interface.hpp"
|
||||
#include "../Backend/Native/Interface.hpp"
|
||||
#endif
|
||||
#include "../Backend/GED/IGAToGEDTranslation.hpp"
|
||||
#include "../Backend/Native/MInst.hpp"
|
||||
@ -819,7 +820,7 @@ void Formatter::formatDstOp(const OpSpec &os, const Operand &dst) {
|
||||
if (!os.hasImplicitDstRegion() ||
|
||||
(dstRgn != os.implicitDstRegion() && dstRgn != Region::INVALID))
|
||||
{
|
||||
// math dpas does not have dst regions
|
||||
// some instructions don't have dst regions
|
||||
formatDstRegion(os, dst.getRegion());
|
||||
}
|
||||
formatDstType(os, dst.getType());
|
||||
@ -1014,13 +1015,22 @@ void FormatInstruction(
|
||||
std::ostream &o,
|
||||
const FormatOpts &opts,
|
||||
size_t startPc,
|
||||
const void *bits)
|
||||
const void *bits,
|
||||
bool useNativeDecoder)
|
||||
{
|
||||
const iga::Model *model =
|
||||
iga::Model::LookupModel(static_cast<iga::Platform>(opts.platform));
|
||||
iga::Decoder dec(*model, e);
|
||||
iga::Kernel *k = dec.decodeKernelNumeric(bits,
|
||||
((const MInst *)bits)->isCompact() ? 8 : 16);
|
||||
|
||||
size_t instLen = ((const MInst *)bits)->isCompact() ? 8 : 16;
|
||||
|
||||
DecoderOpts dopts;
|
||||
dopts.useNumericLabels = true;
|
||||
iga::Kernel *k = nullptr;
|
||||
if (useNativeDecoder && iga::native::IsDecodeSupported(*model, dopts)) {
|
||||
k = iga::native::Decode(*model, dopts, e, bits, instLen);
|
||||
} else {
|
||||
k = iga::ged::Decode(*model, dopts, e, bits, instLen);
|
||||
}
|
||||
if (e.hasErrors()) {
|
||||
for (const auto &err : e.getErrors()) {
|
||||
o << err.message << "\n";
|
||||
|
||||
@ -107,7 +107,8 @@ namespace iga {
|
||||
std::ostream &o,
|
||||
const FormatOpts &opts,
|
||||
size_t startPc,
|
||||
const void *bits);
|
||||
const void *bits,
|
||||
bool useNativeDecoder = false);
|
||||
void FormatInstruction(
|
||||
ErrorHandler &e,
|
||||
std::ostream &o,
|
||||
|
||||
@ -138,7 +138,7 @@ void GenParser::ParseExecInfo(
|
||||
// jmpi (1) ...
|
||||
// We resolve that by looking ahead two symbols
|
||||
int execSizeVal = 1;
|
||||
if (LookingAt(LPAREN) && (LookingAt(2,RPAREN) || LookingAt(2,PIPE))) {
|
||||
if (LookingAt(LPAREN) && (LookingAtFrom(2,RPAREN) || LookingAtFrom(2,PIPE))) {
|
||||
Skip();
|
||||
execSizeLoc = NextLoc();
|
||||
ConsumeIntLitOrFail(execSizeVal, "expected SIMD width");
|
||||
@ -210,7 +210,7 @@ Type GenParser::ParseSendOperandTypeWithDefault(int srcIx) {
|
||||
if (!LookingAt(IDENT)) {
|
||||
Fail("expected a send operand type");
|
||||
}
|
||||
if (!IdentLookup(0, DST_TYPES, t)) {
|
||||
if (!IdentLookupFrom(0, DST_TYPES, t)) {
|
||||
Fail("unexpected operand type for send");
|
||||
}
|
||||
Skip();
|
||||
@ -838,7 +838,9 @@ void GenParser::initSymbolMaps()
|
||||
}
|
||||
}
|
||||
|
||||
class KernelParser : GenParser {
|
||||
|
||||
class KernelParser : GenParser
|
||||
{
|
||||
// maps mnemonics and registers for faster lookup
|
||||
std::map<std::string,const OpSpec*> opmap;
|
||||
|
||||
@ -1430,8 +1432,14 @@ private:
|
||||
}
|
||||
|
||||
|
||||
// Mnemoninc = Ident SubMnemonic? | Ident BrCtl
|
||||
// SubMnemoninc = '.' [Ident]SubFunc
|
||||
//
|
||||
// Mnemoninc
|
||||
// = Ident SubMnemonic?
|
||||
// | Ident BrCtl
|
||||
// SubMnemoninc
|
||||
// = '.' Ident
|
||||
// | '.' HEX_INT | '.' DEC_INT
|
||||
//
|
||||
// BrCtl = '.b'
|
||||
//
|
||||
const OpSpec *ParseMnemonic() {
|
||||
@ -1441,25 +1449,8 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
if (pOs->format == OpSpec::GROUP) {
|
||||
// e.g. math.*, sync.*, send.*, etc...
|
||||
ConsumeOrFail(DOT, "expected operation subfunction");
|
||||
if (LookingAt(IDENT)) {
|
||||
auto sfLoc = NextLoc();
|
||||
auto sfIdent = GetTokenAsString(Next());
|
||||
// look up the function by the fully qualified name
|
||||
std::stringstream ss;
|
||||
ss << pOs->mnemonic << "." << sfIdent;
|
||||
auto itr = opmap.find(ss.str());
|
||||
if (itr == opmap.end()) {
|
||||
failWithUnexpectedSubfunction(sfLoc, sfIdent);
|
||||
} else {
|
||||
// resolve to idiv etc...
|
||||
Skip();
|
||||
pOs = itr->second;
|
||||
}
|
||||
} else {
|
||||
Fail("expected subfunction");
|
||||
}
|
||||
// e.g. math.*, send.*, etc...
|
||||
pOs = ParseSubOp(pOs);
|
||||
}
|
||||
if (!m_hasWrEn && pOs->op == Op::JMPI) {
|
||||
Warning(mnemonicLoc,
|
||||
@ -1483,8 +1474,8 @@ private:
|
||||
Fail("saturation flag goes on destination operand: "
|
||||
"e.g. op (..) (sat)dst ...");
|
||||
} else if (
|
||||
IdentLookup(1, FLAGMODS, fm) ||
|
||||
IdentLookup(1, FLAGMODS_LEGACY, fm))
|
||||
IdentLookupFrom(1, FLAGMODS, fm) ||
|
||||
IdentLookupFrom(1, FLAGMODS_LEGACY, fm))
|
||||
{
|
||||
Fail("conditional modifier follows execution mask "
|
||||
"info: e.g. op (16|M0) (le)f0.0 ...");
|
||||
@ -1497,6 +1488,52 @@ private:
|
||||
return pOs;
|
||||
}
|
||||
|
||||
// SubMnemoninc
|
||||
// = '.' Ident
|
||||
// | '.' HEX_INT | '.' DEC_INT
|
||||
//
|
||||
// E.g.
|
||||
// math.inv
|
||||
// math.1
|
||||
// math.0x1
|
||||
const OpSpec* ParseSubOp(const OpSpec *pParent)
|
||||
{
|
||||
const OpSpec *pOp = nullptr;
|
||||
ConsumeOrFail(DOT, "expected operation subfunction");
|
||||
|
||||
auto sfLoc = NextLoc();
|
||||
if (LookingAt(IDENT)) {
|
||||
auto sfIdent = GetTokenAsString(Next());
|
||||
// look up the function by the fully qualified name
|
||||
std::stringstream ss;
|
||||
ss << pParent->mnemonic << "." << sfIdent;
|
||||
auto itr = opmap.find(ss.str());
|
||||
if (itr == opmap.end()) {
|
||||
failWithUnexpectedSubfunction(sfLoc, sfIdent);
|
||||
} else {
|
||||
// resolve to idiv etc...
|
||||
Skip();
|
||||
pOp = itr->second;
|
||||
if (pOp->format == OpSpec::GROUP) {
|
||||
return ParseSubOp(pOp);
|
||||
}
|
||||
}
|
||||
} else if (LookingAtAnyOf(INTLIT10,INTLIT16)) {
|
||||
// e.g. math.0x1
|
||||
unsigned sfVal;
|
||||
ParseIntFrom<unsigned>(NextLoc(), sfVal);
|
||||
Skip(1);
|
||||
pOp = &m_model.lookupGroupSubOp(pParent->op, sfVal);
|
||||
if (!pOp->isValid()) {
|
||||
Fail(sfLoc, "subfunction is out of bounds");
|
||||
}
|
||||
} else {
|
||||
Fail(sfLoc, "invalid subfunction");
|
||||
}
|
||||
|
||||
return pOp;
|
||||
}
|
||||
|
||||
|
||||
// FlagModifierOpt = '(' FlagModif ')' FlagReg
|
||||
void ParseFlagModOpt() {
|
||||
@ -1532,9 +1569,9 @@ private:
|
||||
if (!LookingAt(LPAREN)) {
|
||||
return false;
|
||||
}
|
||||
if (!IdentLookup(1, FLAGMODS, flagMod)) {
|
||||
if (!IdentLookupFrom(1, FLAGMODS, flagMod)) {
|
||||
Loc loc = NextLoc(1);
|
||||
if (!IdentLookup(1, FLAGMODS_LEGACY, flagMod)) {
|
||||
if (!IdentLookupFrom(1, FLAGMODS_LEGACY, flagMod)) {
|
||||
return false;
|
||||
} else if (m_parseOpts.deprecatedSyntaxWarnings) {
|
||||
// deprecated syntax
|
||||
@ -1649,8 +1686,7 @@ private:
|
||||
"expected implicit accumulator operand "
|
||||
"(e.g. .noacc, .acc2, ..., .acc9)";
|
||||
ConsumeOrFail(DOT, expected);
|
||||
ConsumeIdentOneOfOrFail<ImplAcc>(
|
||||
IMPLACCS, implAcc, expected, expected);
|
||||
ConsumeIdentOneOfOrFail<ImplAcc>(IMPLACCS, implAcc, expected, expected);
|
||||
return implAcc;
|
||||
}
|
||||
|
||||
@ -2559,7 +2595,7 @@ private:
|
||||
SrcModifier ParseSrcModifierOpt(bool &pipeAbs) {
|
||||
if (!m_opSpec->supportsSourceModifiers()) {
|
||||
if (LookingAt(SUB) &&
|
||||
LookingAtAnyOf(1, {INTLIT02, INTLIT10, INTLIT16}))
|
||||
LookingAtAnyOfFrom(1, {INTLIT02, INTLIT10, INTLIT16}))
|
||||
{
|
||||
// e.g. jmpi (...) -16:d
|
||||
// ^ we will convert the literal
|
||||
@ -2702,7 +2738,7 @@ private:
|
||||
return Type::INVALID;
|
||||
}
|
||||
Type type = Type::INVALID;
|
||||
if (IdentLookup(1, types, type)) {
|
||||
if (IdentLookupFrom(1, types, type)) {
|
||||
Skip(2);
|
||||
}
|
||||
return type;
|
||||
|
||||
@ -23,12 +23,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
======================= end_copyright_notice ==================================*/
|
||||
#ifndef _LEXEMES_HPP_
|
||||
#define _LEXEMES_HPP_
|
||||
#ifndef _IGA_LEXEMES_HPP_
|
||||
#define _IGA_LEXEMES_HPP_
|
||||
|
||||
namespace iga {
|
||||
|
||||
enum Lexeme {
|
||||
enum Lexeme
|
||||
{
|
||||
LEXICAL_ERROR = 0, // Windows GDI #define's "ERROR"
|
||||
NEWLINE,
|
||||
|
||||
|
||||
@ -42,10 +42,10 @@ namespace iga
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DEBUGGING
|
||||
//
|
||||
void Parser::ShowCurrentLexicalContext(const Loc &loc) const {
|
||||
std::stringstream ss;
|
||||
WriteTokenContext(m_lexer.GetSource(), loc, ss);
|
||||
DEBUG_TRACE(ss.str().c_str());
|
||||
void Parser::ShowCurrentLexicalContext(
|
||||
std::ostream &os, const Loc &loc) const
|
||||
{
|
||||
WriteTokenContext(m_lexer.GetSource(), loc, os);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -122,14 +122,14 @@ namespace iga
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// QUERYING (non-destructive lookahead)
|
||||
bool Parser::LookingAt(int k, Lexeme lxm) const {
|
||||
return m_lexer.LookingAt(lxm,k);
|
||||
bool Parser::LookingAtFrom(int k, Lexeme lxm) const {
|
||||
return m_lexer.LookingAtFrom(k, lxm);
|
||||
}
|
||||
|
||||
bool Parser::LookingAtSeq(std::initializer_list<Lexeme> lxms) const {
|
||||
int i = 0;
|
||||
for (Lexeme lxm : lxms) {
|
||||
if (!LookingAt(i++, lxm)) {
|
||||
if (!LookingAtFrom(i++, lxm)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -137,15 +137,15 @@ namespace iga
|
||||
}
|
||||
|
||||
bool Parser::LookingAtAnyOf(std::initializer_list<Lexeme> lxms) const {
|
||||
return LookingAtAnyOf(0, lxms);
|
||||
return LookingAtAnyOfFrom(0, lxms);
|
||||
}
|
||||
|
||||
bool Parser::LookingAtAnyOf(int i, std::initializer_list<Lexeme> lxms)
|
||||
bool Parser::LookingAtAnyOfFrom(int i, std::initializer_list<Lexeme> lxms)
|
||||
const
|
||||
{
|
||||
int off = 0;
|
||||
for (Lexeme lxm : lxms) {
|
||||
if (LookingAt(off + i, lxm)) {
|
||||
if (LookingAtFrom(off + i, lxm)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,13 +28,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "BufferedLexer.hpp"
|
||||
#include "../ErrorHandler.hpp"
|
||||
// FIXME: needed for for ident_value<T> (want to make this agnostic IGA GEN IR types)
|
||||
#include "../Models/Models.hpp"
|
||||
#include "../IR/Loc.hpp"
|
||||
|
||||
|
||||
#include <cstdarg>
|
||||
#include <initializer_list>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
@ -63,10 +63,12 @@ namespace iga
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Recursive descent parser.
|
||||
// The nomaclaure for method names is roughly:
|
||||
// Looking**** peeks at the token, doesn't consume
|
||||
// Consume**** consume next token if some criteria is true
|
||||
// Parse****** generally corresponds to a non-terminal or some
|
||||
// complicated lexemes
|
||||
// Looking**** peeks at the token, doesn't consume
|
||||
// Looking**From peeks relative to the lexer's current offset
|
||||
// Consume**** consume next token if some criteria is true
|
||||
// Parse****** generally corresponds to a non-terminal or some
|
||||
// complicated lexemes
|
||||
//
|
||||
//
|
||||
class Parser {
|
||||
protected:
|
||||
@ -81,9 +83,11 @@ namespace iga
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DEBUGGING
|
||||
void DumpLookaheads(int n = 1) const {m_lexer.DumpLookaheads(n); }
|
||||
void ShowCurrentLexicalContext() {ShowCurrentLexicalContext(NextLoc());}
|
||||
void ShowCurrentLexicalContext(const Loc &loc) const;
|
||||
// void DumpLookaheads(int n = 1) const {m_lexer.DumpLookaheads(n); }
|
||||
void ShowCurrentLexicalContext(std::ostream &os) const {
|
||||
ShowCurrentLexicalContext(os,NextLoc());
|
||||
}
|
||||
void ShowCurrentLexicalContext(std::ostream &os,const Loc &loc) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ERRORS and WARNINGS
|
||||
@ -136,27 +140,25 @@ namespace iga
|
||||
|
||||
bool Skip(int k = 1) {return m_lexer.Skip(k);}
|
||||
|
||||
// be sure nothing else fits before you use this
|
||||
std::string GetTokenAsString(const Token &token) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// QUERYING (non-destructive lookahead)
|
||||
bool LookingAt(Lexeme lxm) const {return LookingAt(0,lxm);}
|
||||
bool LookingAt(int k, Lexeme lxm) const;
|
||||
bool LookingAt(Lexeme lxm) const {return LookingAtFrom(0,lxm);}
|
||||
bool LookingAtFrom(int k, Lexeme lxm) const;
|
||||
|
||||
bool LookingAtSeq(Lexeme lxm0, Lexeme lxm1) const {return LookingAtSeq({lxm0,lxm1});}
|
||||
bool LookingAtSeq(std::initializer_list<Lexeme> lxms) const;
|
||||
|
||||
bool LookingAtAnyOf(Lexeme lxm0, Lexeme lxm1) const {return LookingAtAnyOf({lxm0,lxm1}); }
|
||||
bool LookingAtAnyOf(std::initializer_list<Lexeme> lxms) const;
|
||||
bool LookingAtAnyOf(int i, std::initializer_list<Lexeme> lxms) const;
|
||||
bool LookingAtAnyOfFrom(int i, std::initializer_list<Lexeme> lxms) const;
|
||||
|
||||
bool LookingAtPrefix(const char *pfx) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CONSUMPTION (destructive lookahead)
|
||||
bool Consume(Lexeme lxm) {return Consume(0, lxm);}
|
||||
bool Consume(int k, Lexeme lxm) {return m_lexer.Consume(lxm,k);}
|
||||
bool Consume(Lexeme lxm) {return m_lexer.Consume(lxm);}
|
||||
void ConsumeOrFail(Lexeme lxm, const char *msg);
|
||||
// same as above, but the error location chosen is the end of the
|
||||
// previous token; i.e. the suffix is screwed up
|
||||
@ -182,8 +184,8 @@ namespace iga
|
||||
bool TokenEq(const Token &tk, const char *eq) const;
|
||||
|
||||
template <typename T>
|
||||
bool IdentLookup(int k, const IdentMap<T> &map, T &value) const {
|
||||
if (!LookingAt(k,IDENT)) {
|
||||
bool IdentLookupFrom(int k, const IdentMap<T> &map, T &value) const {
|
||||
if (!LookingAtFrom(k,IDENT)) {
|
||||
return false;
|
||||
}
|
||||
for (const std::pair<const char *,T> &p : map) {
|
||||
@ -205,7 +207,7 @@ namespace iga
|
||||
if (!LookingAt(IDENT)) {
|
||||
Fail(errExpecting);
|
||||
}
|
||||
if (!IdentLookup(0, map, value)) {
|
||||
if (!IdentLookupFrom(0, map, value)) {
|
||||
Fail(errInvalid);
|
||||
}
|
||||
Skip();
|
||||
@ -213,7 +215,7 @@ namespace iga
|
||||
|
||||
template <typename T>
|
||||
bool ConsumeIdentOneOf(const IdentMap<T> &map, T &value) {
|
||||
if (LookingAt(IDENT) && IdentLookup(0, map, value)) {
|
||||
if (LookingAt(IDENT) && IdentLookupFrom(0, map, value)) {
|
||||
Skip();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -24,11 +24,11 @@ set(IGA_IR_Open
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Types.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Types.hpp
|
||||
)
|
||||
set(IGA_IR_Embargoed )
|
||||
set(IGA_IR_Extended )
|
||||
|
||||
set(IGA_IR
|
||||
${IGA_IR_Open}
|
||||
${IGA_IR_Embargoed}
|
||||
${IGA_IR_Extended}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <tuple>
|
||||
|
||||
#include "../EnumBitset.hpp"
|
||||
#include "../Models/bxml/iga_bxml_enums.hpp"
|
||||
@ -137,6 +138,79 @@ enum class ImplAcc
|
||||
};
|
||||
|
||||
|
||||
// how much to shift <right,left> to get to from byte offset
|
||||
// to subregister offset
|
||||
// I.e. subReg = (byteOff << left) >> right;
|
||||
// this allows us to scale a subregister byte offset up OR down
|
||||
static inline std::tuple<int,int> TypeSizeShiftsOffsetToSubreg(Type type)
|
||||
{
|
||||
int shl = 0, shr = 0; // by default no scaling
|
||||
|
||||
switch (type) {
|
||||
// 1-byte types
|
||||
case Type::UB:
|
||||
case Type::B:
|
||||
break;
|
||||
// 2-byte types
|
||||
case Type::UW:
|
||||
case Type::W:
|
||||
case Type::HF:
|
||||
shr = 1;
|
||||
break;
|
||||
// 4-byte types
|
||||
case Type::UD:
|
||||
case Type::D:
|
||||
case Type::F:
|
||||
case Type::NF: // NF regions the same as F
|
||||
shr = 2;
|
||||
break;
|
||||
case Type::UQ:
|
||||
case Type::Q:
|
||||
case Type::DF:
|
||||
shr = 3;
|
||||
break;
|
||||
default: // invalid types
|
||||
break;
|
||||
}
|
||||
return std::make_tuple(shl,shr);
|
||||
}
|
||||
// static inline bool TypeIsSubByte(Type t) {
|
||||
// return std::get<1>(TypeSizeShiftsOffsetToSubreg(t)) > 0;
|
||||
// }
|
||||
|
||||
// Returns the type size ***in bits****
|
||||
//
|
||||
// e.g. Type::UD == 32
|
||||
static inline int TypeSizeInBits(Type t)
|
||||
{
|
||||
auto ti = TypeSizeShiftsOffsetToSubreg(t);
|
||||
return (8 << std::get<1>(ti)) >> std::get<0>(ti);
|
||||
}
|
||||
static inline int TypeSizeInBitsWithDefault(Type type, int dft = 0)
|
||||
{
|
||||
return type == Type::INVALID ? dft : TypeSizeInBits(type);
|
||||
}
|
||||
static inline bool TypeIs64b(Type t)
|
||||
{
|
||||
return TypeSizeInBitsWithDefault(t,0) == 64;
|
||||
}
|
||||
static bool TypeIsFloating(Type t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case Type::F:
|
||||
case Type::HF:
|
||||
case Type::DF:
|
||||
case Type::VF:
|
||||
case Type::NF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// DEPRECATED
|
||||
static inline int LogTypeSize(Type type, int dft = -1)
|
||||
{
|
||||
switch (type)
|
||||
@ -167,15 +241,21 @@ static inline int LogTypeSize(Type type, int dft = -1)
|
||||
return dft;
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// DEPRECATED
|
||||
static inline int TypeSize(Type type)
|
||||
{
|
||||
return 1 << LogTypeSize(type);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// DEPRECATED
|
||||
static inline int TypeSizeWithDefault(Type type, int dft = 0)
|
||||
{
|
||||
return type == Type::INVALID ? dft : TypeSize(type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum class FlagModifier
|
||||
{
|
||||
NONE = 0, // no flag modification
|
||||
|
||||
@ -45,7 +45,7 @@ using namespace iga;
|
||||
|
||||
static std::string disassembleInst(
|
||||
Platform platform,
|
||||
bool useNativeDencoder,
|
||||
bool useNativeDecoder,
|
||||
size_t fromPc,
|
||||
const void *bits)
|
||||
{
|
||||
@ -55,7 +55,8 @@ static std::string disassembleInst(
|
||||
fopts.numericLabels = true;
|
||||
// fopts.hexFloats = opts.printHexFloats;
|
||||
fopts.hexFloats = false;
|
||||
FormatInstruction(eh, ss, fopts, fromPc, bits);
|
||||
|
||||
FormatInstruction(eh, ss, fopts, fromPc, bits, useNativeDecoder);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
@ -206,13 +207,13 @@ static void decodeFieldHeaders(std::ostream &os)
|
||||
}
|
||||
|
||||
static bool decodeFieldsForInst(
|
||||
bool useNativeDencoder,
|
||||
bool useNativeDecoder,
|
||||
std::ostream &os,
|
||||
size_t pc,
|
||||
const Model &model,
|
||||
const MInst *mi)
|
||||
{
|
||||
auto syntax = disassembleInst(model.platform, useNativeDencoder, pc, (const void *)mi);
|
||||
auto syntax = disassembleInst(model.platform, useNativeDecoder, pc, (const void *)mi);
|
||||
os << fmtPc(mi, pc) << " " << syntax << "\n";
|
||||
os.flush();
|
||||
bool success = true;
|
||||
@ -274,7 +275,7 @@ static bool decodeFieldsForInst(
|
||||
|
||||
iga_status_t iga::DecodeFields(
|
||||
Platform p,
|
||||
bool useNativeDencoder, // TODO: use this once decoder is implemented
|
||||
bool useNativeDecoder, // TODO: use this once decoder is implemented
|
||||
std::ostream &os,
|
||||
const uint8_t *bits,
|
||||
size_t bitsLen)
|
||||
@ -302,7 +303,7 @@ iga_status_t iga::DecodeFields(
|
||||
break;
|
||||
}
|
||||
|
||||
success &= decodeFieldsForInst(useNativeDencoder, os, pc, *model, mi);
|
||||
success &= decodeFieldsForInst(useNativeDecoder, os, pc, *model, mi);
|
||||
|
||||
pc += iLen;
|
||||
}
|
||||
@ -717,7 +718,7 @@ static bool listInstructionCompaction(
|
||||
|
||||
iga_status_t iga::DebugCompaction(
|
||||
Platform p,
|
||||
bool useNativeDencoder,
|
||||
bool useNativeDecoder,
|
||||
std::ostream &os,
|
||||
const uint8_t *bits,
|
||||
size_t bitsLen)
|
||||
@ -746,11 +747,11 @@ iga_status_t iga::DebugCompaction(
|
||||
}
|
||||
|
||||
os << "============================================================\n";
|
||||
auto syntax = disassembleInst(p, useNativeDencoder, pc, (const void *)mi);
|
||||
auto syntax = disassembleInst(p, useNativeDecoder, pc, (const void *)mi);
|
||||
os << fmtPc(mi, pc) << " " << syntax << "\n";
|
||||
os.flush();
|
||||
success &= listInstructionCompaction(
|
||||
useNativeDencoder, os, cs, *model, pc, mi);
|
||||
useNativeDecoder, os, cs, *model, pc, mi);
|
||||
pc += iLen;
|
||||
}
|
||||
os << "\n";
|
||||
@ -846,7 +847,7 @@ iga_status_t iga::DebugCompaction(
|
||||
PC pc = missExample.first;
|
||||
int totalMissesForThisPc = missExample.second;
|
||||
os << " misses " << totalMissesForThisPc << ": "
|
||||
<< disassembleInst(p, useNativeDencoder, pc, bits+pc)
|
||||
<< disassembleInst(p, useNativeDecoder, pc, bits+pc)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,10 +9,10 @@ set(IGA_ModelsOpen
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bxml/Model10.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bxml/iga_bxml_enums.hpp
|
||||
)
|
||||
set(IGA_ModelsEmbargoed )
|
||||
set(IGA_ModelsExteneded )
|
||||
|
||||
set(IGA_Models
|
||||
${IGA_ModelsOpen}
|
||||
${IGA_ModelsEmbargoed}
|
||||
${IGA_ModelsExteneded}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@ -16,7 +16,7 @@ set(IGA_API_HeadersOpen
|
||||
|
||||
set(IGA_API_Headers
|
||||
${IGA_API_HeadersOpen}
|
||||
${IGA_API_HeadersEmbargoed}
|
||||
${IGA_API_HeadersExtended}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
|
||||
@ -318,14 +318,14 @@ int32_t kv_get_opgroup(const kv_t *kv, int32_t pc)
|
||||
case Op::ENDIF: return (int32_t)kv_opgroup_t::KV_OPGROUP_ENDIF;
|
||||
case Op::ELSE: return (int32_t)kv_opgroup_t::KV_OPGROUP_ELSE;
|
||||
case Op::WHILE: return (int32_t)kv_opgroup_t::KV_OPGROUP_WHILE;
|
||||
case Op::SEND:
|
||||
case Op::SENDS:
|
||||
case Op::SENDC:
|
||||
case Op::SENDSC:
|
||||
if (inst->hasInstOpt(InstOpt::EOT)) {
|
||||
default:
|
||||
if (inst->getOpSpec().isSendOrSendsFamily() &&
|
||||
inst->hasInstOpt(InstOpt::EOT))
|
||||
{
|
||||
return (int32_t)kv_opgroup_t::KV_OPGROUP_SEND_EOT;
|
||||
} else {
|
||||
return (int32_t)kv_opgroup_t::KV_OPGROUP_OTHER;
|
||||
}
|
||||
default: return (int32_t)kv_opgroup_t::KV_OPGROUP_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef _IGA_VERSION_HPP_
|
||||
#define _IGA_VERSION_HPP_
|
||||
#define IGA_VERSION_STRING "2.1p0"
|
||||
#define IGA_VERSION_STRING "2.1p1"
|
||||
|
||||
|
||||
#endif // _IGA_VERSION_HPP_
|
||||
|
||||
Reference in New Issue
Block a user