Changeset 3762 in CLRX


Ignore:
Timestamp:
Feb 9, 2018, 6:20:46 PM (15 months ago)
Author:
matszpk
Message:

CLRadeonExtender: Asm: First stuff to handle section differences (untested and not working).

Location:
CLRadeonExtender/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/CLRX/amdasm/AsmDefs.h

    r3761 r3762  
    285285};
    286286
     287/// class of return value for a trying routines
     288enum class AsmTryStatus
     289{
     290    FAILED = 0, ///< if failed now, no later trial
     291    TRY_LATER,  ///< try later (after some)
     292    SUCCESS     ///< succeed, no trial needed
     293};
     294
    287295/// assembler expression class
    288296class AsmExpression: public NonCopyableAndNonMovable
     
    339347    { target = _target; }
    340348   
     349    /// try to evaluate expression with/without section differences
     350    /**
     351     * \param assembler assembler instace
     352     * \param value output value
     353     * \param sectionId output section id
     354     * \param withSectionDiffs evaluate including precalculated section differences
     355     * \return operation status
     356     */
     357    AsmTryStatus tryEvaluate(Assembler& assembler, size_t opStart, size_t opEnd,
     358                  uint64_t& value, cxuint& sectionId, bool withSectionDiffs = false) const;
     359   
    341360    /// try to evaluate expression
    342361    /**
     
    347366     */
    348367    bool evaluate(Assembler& assembler, uint64_t& value, cxuint& sectionId) const
    349     { return evaluate(assembler, 0, ops.size(), value, sectionId); }
     368    { return tryEvaluate(assembler, 0, ops.size(), value, sectionId) !=
     369                    AsmTryStatus::FAILED; }
    350370   
    351371    /// try to evaluate expression
     
    359379     */
    360380    bool evaluate(Assembler& assembler, size_t opStart, size_t opEnd,
    361                   uint64_t& value, cxuint& sectionId) const;
     381                  uint64_t& value, cxuint& sectionId) const
     382    { return tryEvaluate(assembler, opStart, opEnd, value, sectionId) !=
     383                    AsmTryStatus::FAILED; }
    362384   
    363385    /// parse expression. By default, also gets values of symbol or  creates them
  • CLRadeonExtender/trunk/CLRX/amdasm/Assembler.h

    r3630 r3762  
    443443    std::vector<CString> includeDirs;
    444444    std::vector<AsmSection> sections;
     445    std::vector<Array<cxuint> > relSpacesSections;
    445446    std::unordered_set<AsmSymbolEntry*> symbolSnapshots;
    446447    std::vector<AsmRelocation> relocations;
     
    469470    const char* line;
    470471    bool endOfAssembly;
     472    bool sectionDiffsPrepared;
    471473   
    472474    cxuint filenameIndex;
     
    753755    const std::vector<AsmSection>& getSections() const
    754756    { return sections; }
     757    // get first sections for rel spaces
     758    const std::vector<Array<cxuint> >& getRelSpacesSections() const
     759    { return relSpacesSections; }
    755760    /// get kernel map
    756761    const KernelMap& getKernelMap() const
  • CLRadeonExtender/trunk/amdasm/AsmExpression.cpp

    r3631 r3762  
    2424#include <algorithm>
    2525#include <unordered_set>
     26#include <unordered_map>
    2627#include <CLRX/utils/Utilities.h>
    2728#include <CLRX/amdasm/Assembler.h>
     
    113114    }
    114115
    115 bool AsmExpression::evaluate(Assembler& assembler, size_t opStart, size_t opEnd,
    116                  uint64_t& outValue, cxuint& outSectionId) const
     116// expression with relative symbols
     117struct RelMultiply
     118{
     119    // multiplication of section
     120    uint64_t multiply;
     121    cxuint sectionId;
     122};
     123
     124// check whether sections is in resolvable section diffs
     125static bool checkSectionDiffs(size_t n, const RelMultiply* relMultiplies,
     126                    const std::vector<AsmSection>& sections, bool withSectionDiffs,
     127                    bool sectDiffsPreppared, bool& tryLater)
     128{
     129    if (n == 0)
     130        return true;
     131   
     132    if (!withSectionDiffs || sectDiffsPreppared)
     133        return false;
     134   
     135    for (size_t i = 0; i < n; i++)
     136        if (sections[relMultiplies[i].sectionId].relSpace == UINT_MAX)
     137            return false; // if found section not in anything relocation space
     138    tryLater = true;
     139    return true;
     140}
     141
     142#define CHKSREL(rel) checkSectionDiffs(rel.size(), rel.data(), sections, \
     143                withSectionDiffs, sectDiffsPreppared, tryLater)
     144
     145AsmTryStatus AsmExpression::tryEvaluate(Assembler& assembler, size_t opStart, size_t opEnd,
     146                 uint64_t& outValue, cxuint& outSectionId, bool withSectionDiffs) const
    117147{
    118148    if (symOccursNum != 0)
     
    121151   
    122152    bool failed = false;
     153    bool tryLater = false;
    123154    uint64_t value = 0; // by default is zero
    124155    cxuint sectionId = 0;
     
    333364    else
    334365    {
    335         // expression with relative symbols
    336         struct RelMultiply
    337         {
    338             // multiplication of section
    339             uint64_t multiply;
    340             cxuint sectionId;
    341         };
     366        const bool sectDiffsPreppared = (assembler.formatHandler != nullptr &&
     367             assembler.formatHandler->isSectionDiffsResolvable());
     368       
    342369        // structure that contains relatives info: offset value and mult. of sections
    343370        struct ValueAndMultiplies
     
    368395        }
    369396       
     397        const std::vector<Array<cxuint> >& relSpacesSects = assembler.relSpacesSections;
     398        const std::vector<AsmSection>& sections = assembler.sections;
     399       
    370400        while (opPos < opEnd)
    371401        {
     
    374404            {
    375405                if (args[argPos].relValue.sectionId != ASMSECT_ABS)
    376                     stack.push(ValueAndMultiplies(args[argPos].relValue.value,
    377                                 args[argPos].relValue.sectionId));
     406                {
     407                    uint64_t ovalue = args[argPos].relValue.value;
     408                    cxuint osectId = args[argPos].relValue.sectionId;
     409                    if (sectDiffsPreppared && sections[osectId].relSpace!=UINT_MAX)
     410                    {
     411                        // resolve section in relspace
     412                        cxuint rsectId = relSpacesSects[sections[osectId].relSpace][0];
     413                        ovalue += sections[osectId].relAddress -
     414                                sections[rsectId].relAddress;
     415                        osectId = rsectId;
     416                    }
     417                    stack.push(ValueAndMultiplies(ovalue, osectId));
     418                }
    378419                else
    379420                    stack.push(args[argPos].value);
     
    401442                        break;
    402443                    case AsmExprOp::LOGICAL_NOT:
    403                         if (!relatives.empty())
     444                        if (!CHKSREL(relatives))
    404445                            ASMX_FAILED_BY_ERROR(sourcePos,
    405446                                 "Logical negation is not allowed to relative values")
     
    447488                    case AsmExprOp::MULTIPLY:
    448489                        // we do not multiply with relatives in two operands
    449                         if (!relatives.empty() && !relatives2.empty())
     490                        if (!CHKSREL(relatives) && !CHKSREL(relatives2))
    450491                            ASMX_FAILED_BY_ERROR(sourcePos,
    451492                                 "Multiplication is not allowed for two relative values")
     
    472513                        break;
    473514                    case AsmExprOp::DIVISION:
    474                         if (!relatives.empty() || !relatives2.empty())
     515                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    475516                            ASMX_FAILED_BY_ERROR(sourcePos,
    476517                                 "Division is not allowed for any relative value")
     
    487528                        break;
    488529                    case AsmExprOp::SIGNED_DIVISION:
    489                         if (!relatives.empty() || !relatives2.empty())
     530                        if (!CHKSREL(relatives)|| !CHKSREL(relatives2))
    490531                            ASMX_FAILED_BY_ERROR(sourcePos,
    491532                                 "Signed division is not allowed for any relative value")
     
    502543                        break;
    503544                    case AsmExprOp::MODULO:
    504                         if (!relatives.empty() || !relatives2.empty())
     545                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    505546                            ASMX_FAILED_BY_ERROR(sourcePos,
    506547                                 "Modulo is not allowed for any relative value")
     
    517558                        break;
    518559                    case AsmExprOp::SIGNED_MODULO:
    519                         if (!relatives.empty() || !relatives2.empty())
     560                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    520561                            ASMX_FAILED_BY_ERROR(sourcePos,
    521562                                 "Signed Modulo is not allowed for any relative value")
     
    532573                        break;
    533574                    case AsmExprOp::BIT_AND:
    534                         if (!relatives.empty() || !relatives2.empty())
     575                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    535576                            ASMX_FAILED_BY_ERROR(sourcePos,
    536577                                 "Binary AND is not allowed for any relative value")
     
    538579                        break;
    539580                    case AsmExprOp::BIT_OR:
    540                         if (!relatives.empty() || !relatives2.empty())
     581                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    541582                            ASMX_FAILED_BY_ERROR(sourcePos,
    542583                                 "Binary OR is not allowed for any relative value")
     
    544585                        break;
    545586                    case AsmExprOp::BIT_XOR:
    546                         if (!relatives.empty() || !relatives2.empty())
     587                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    547588                            ASMX_FAILED_BY_ERROR(sourcePos,
    548589                                 "Binary XOR is not allowed for any relative value")
     
    550591                        break;
    551592                    case AsmExprOp::BIT_ORNOT:
    552                         if (!relatives.empty() || !relatives2.empty())
     593                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    553594                            ASMX_FAILED_BY_ERROR(sourcePos,
    554595                                 "Binary ORNOT is not allowed for any relative value")
     
    556597                        break;
    557598                    case AsmExprOp::SHIFT_LEFT:
    558                         if (!relatives.empty())
     599                        if (!CHKSREL(relatives))
    559600                            ASMX_FAILED_BY_ERROR(sourcePos, "Shift left is not allowed "
    560601                                    "for any for relative second value")
     
    575616                        break;
    576617                    case AsmExprOp::SHIFT_RIGHT:
    577                         if (!relatives.empty() || !relatives2.empty())
     618                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    578619                            ASMX_FAILED_BY_ERROR(sourcePos,
    579620                                 "Shift right is not allowed for any relative value")
     
    589630                        break;
    590631                    case AsmExprOp::SIGNED_SHIFT_RIGHT:
    591                         if (!relatives.empty() || !relatives2.empty())
     632                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    592633                            ASMX_FAILED_BY_ERROR(sourcePos, "Signed shift right is not "
    593634                                    "allowed for any relative value")
     
    603644                        break;
    604645                    case AsmExprOp::LOGICAL_AND:
    605                         if (!relatives.empty() || !relatives2.empty())
     646                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    606647                            ASMX_FAILED_BY_ERROR(sourcePos,
    607648                                 "Logical AND is not allowed for any relative value")
     
    609650                        break;
    610651                    case AsmExprOp::LOGICAL_OR:
    611                         if (!relatives.empty() || !relatives2.empty())
     652                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    612653                            ASMX_FAILED_BY_ERROR(sourcePos,
    613654                                 "Logical OR is not allowed for any relative value")
     
    697738                const Array<RelMultiply> relatives3 = stack.top().relatives;
    698739                stack.pop();
    699                 if (!relatives3.empty())
     740                if (!CHKSREL(relatives3))
    700741                    ASMX_FAILED_BY_ERROR(sourcePos,
    701742                         "Choice is not allowed for first relative value")
     
    722763            ASMX_FAILED_BY_ERROR(sourcePos,
    723764                     "Only one relative=1 (section) can be result of expression")
    724     }
     765       
     766        if (sectDiffsPreppared && sectionId != ASMSECT_ABS &&
     767            sections[sectionId].relSpace != UINT_MAX)
     768        {   // find proper section
     769            const Array<cxuint>& rlSections  = relSpacesSects[
     770                                sections[sectionId].relSpace];
     771            auto it = std::lower_bound(rlSections.begin(), rlSections.end(), sectionId,
     772                [&sections](cxuint a, cxuint b)
     773                { return sections[a].relAddress < sections[b].relAddress; });
     774            cxuint newSectionId =  (it != rlSections.end()) ? *it : rlSections.front();
     775            value += sections[sectionId].relAddress - sections[newSectionId].relAddress;
     776        }
     777    }
     778    if (tryLater)
     779        return AsmTryStatus::TRY_LATER;
    725780    if (!failed)
    726781    {
     
    729784        outValue = value;
    730785    }
    731     return !failed;
     786    return failed ? AsmTryStatus::FAILED : AsmTryStatus::SUCCESS;
    732787}
    733788
  • CLRadeonExtender/trunk/amdasm/Assembler.cpp

    r3740 r3762  
    26342634{
    26352635    resolvingRelocs = false;
     2636    sectionDiffsPrepared = false;
    26362637   
    26372638    for (const DefSym& defSym: defSyms)
Note: See TracChangeset for help on using the changeset viewer.