Changeset 3768 in CLRX


Ignore:
Timestamp:
Feb 10, 2018, 1:45:06 PM (17 months ago)
Author:
matszpk
Message:

CLRadeonExtender: Asm: Add handling relspaces while comparing two values (compare operators).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/amdasm/AsmExpression.cpp

    r3767 r3768  
    122122};
    123123
     124static inline bool compareRelMSectionLess(const RelMultiply& r1, const RelMultiply& r2)
     125{ return r1.sectionId < r2.sectionId; }
     126
     127static void reduceRelMultiplies(std::vector<RelMultiply>& relmuls)
     128{
     129    size_t i = 0, j = 0;
     130    uint64_t multiply = 0;
     131    cxuint prevSect = ASMSECT_ABS;
     132    for (i = 0; i < relmuls.size(); i++)
     133    {
     134        if (relmuls[i].sectionId != prevSect)
     135        {
     136            if (i != 0)
     137                relmuls[j++] = { multiply, prevSect };
     138            multiply = relmuls[i].multiply;
     139            prevSect = relmuls[i].sectionId;
     140        }
     141        else
     142            multiply += relmuls[i].multiply;
     143    }
     144    if (i != 0)
     145        relmuls[j++] = { multiply, prevSect };
     146    relmuls.resize(j);
     147}
     148
     149static bool checkRelativesEquality(Assembler& assembler,
     150            std::vector<RelMultiply>& relatives,
     151            const Array<RelMultiply>& relatives2, bool checkRelSpaces)
     152{
     153    std::vector<RelMultiply> relSpaces1(relatives.size());
     154    std::vector<RelMultiply> relSpaces2(relatives2.size());
     155    const std::vector<AsmSection>& sections = assembler.getSections();
     156   
     157    bool haveRealRelSpaces = false;
     158    if (checkRelSpaces)
     159    {
     160        // convert sections to relspaces
     161        for (size_t i = 0; i < relSpaces1.size(); i++)
     162            if (sections[relatives[i].sectionId].relSpace != UINT_MAX)
     163            {
     164                relSpaces1[i] = { relatives[i].multiply,
     165                        sections[relatives[i].sectionId].relSpace };
     166                haveRealRelSpaces = true;
     167            }
     168            else // treat as separate relSpace
     169                relSpaces1[i] = { relatives[i].multiply,
     170                        0x80000000 | relatives[i].sectionId };
     171       
     172        for (size_t i = 0; i < relSpaces2.size(); i++)
     173            if (sections[relatives2[i].sectionId].relSpace != UINT_MAX)
     174            {
     175                relSpaces2[i] = { relatives2[i].multiply,
     176                        sections[relatives2[i].sectionId].relSpace };
     177                haveRealRelSpaces = true;
     178            }
     179            else // treat as separate relSpace
     180                relSpaces2[i] = { relatives2[i].multiply,
     181                        0x80000000 | relatives2[i].sectionId };
     182    }
     183   
     184    if (!checkRelSpaces || !haveRealRelSpaces)
     185    {
     186        // if no check relspaces or if no real rel spaces in relatives
     187        size_t requals = 0;
     188        if (relatives2.size() != relatives.size())
     189            return false;
     190        else
     191        {
     192            // check whether relatives as same in two operands
     193            for (const RelMultiply& r: relatives2)
     194                for (RelMultiply& r2: relatives)
     195                    if (r.multiply == r2.multiply &&
     196                            r.sectionId == r2.sectionId)
     197                    {
     198                        r2.sectionId = ASMSECT_ABS; // ignore in next iter
     199                        requals++;
     200                        break;
     201                    }
     202            if (requals != relatives.size())
     203                return false;
     204        }
     205    }
     206    else
     207    {
     208        // sort
     209        std::sort(relSpaces1.begin(), relSpaces1.end(), compareRelMSectionLess);
     210        std::sort(relSpaces2.begin(), relSpaces2.end(), compareRelMSectionLess);
     211        // reduce relspaces by sum multiplies
     212        reduceRelMultiplies(relSpaces1);
     213        reduceRelMultiplies(relSpaces2);
     214       
     215        /// compare relspaces
     216        if (relSpaces1.size() != relSpaces2.size())
     217            return false;
     218        for (size_t i = 0; i < relSpaces1.size(); i++)
     219            if (relSpaces1[i].multiply != relSpaces2[i].multiply ||
     220                relSpaces1[i].sectionId != relSpaces2[i].sectionId)
     221                return false;
     222    }
     223    return true;
     224}
     225
    124226AsmTryStatus AsmExpression::tryEvaluate(Assembler& assembler, size_t opStart, size_t opEnd,
    125227                 uint64_t& outValue, cxuint& outSectionId, bool withSectionDiffs) const
     
    645747                    case AsmExprOp::ABOVE_EQ:
    646748                    {
    647                         // TODO: include relspace before section diffs resolving
    648                         size_t requals = 0;
    649                         if (relatives2.size() != relatives.size())
     749                        if (!checkRelativesEquality(assembler, relatives, relatives2,
     750                                    withSectionDiffs && !sectDiffsPrepared))
    650751                            ASMX_FAILED_BY_ERROR(sourcePos, "For comparisons "
    651752                                        "two values must have this same relatives!")
    652                         else
    653                         {
    654                             // check whether relatives as same in two operands
    655                             for (const RelMultiply& r: relatives2)
    656                                 for (RelMultiply& r2: relatives)
    657                                     if (r.multiply == r2.multiply &&
    658                                             r.sectionId == r2.sectionId)
    659                                     {
    660                                         r2.sectionId = ASMSECT_ABS; // ignore in next iter
    661                                         requals++;
    662                                         break;
    663                                     }
    664                             if (requals != relatives.size())
    665                                 ASMX_FAILED_BY_ERROR(sourcePos, "For comparisons "
    666                                         "two values must have this same relatives!")
    667                         }
     753                       
     754                        if (withSectionDiffs && !sectDiffsPrepared)
     755                            tryLater = true; // must be evaluated later
    668756                        relatives.clear();
    669757                        switch(op)
Note: See TracChangeset for help on using the changeset viewer.