Changeset 3778 in CLRX


Ignore:
Timestamp:
Feb 13, 2018, 2:00:58 PM (14 months ago)
Author:
matszpk
Message:

CLRadeonExtender: AsmExpr?: Ignore relatives with relSpaces while checking whether if relatives is must no be present
(if sectionDiffs and before section diffs preparing).

File:
1 edited

Legend:

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

    r3775 r3778  
    2020#include <CLRX/Config.h>
    2121#include <string>
     22#include <iterator>
    2223#include <vector>
    2324#include <stack>
     
    122123};
    123124
    124 static inline bool compareRelMSectionLess(const RelMultiply& r1, const RelMultiply& r2)
    125 { return r1.sectionId < r2.sectionId; }
    126 
    127 static 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 
    149 static void convertRelSpaces(const RelMultiply& relative,
    150         RelMultiply& relSpace, const std::vector<AsmSection>& sections,
    151         const std::vector<Array<cxuint> >& relSpacesSects, uint64_t fixAddr1)
    152 {
    153     if (sections[relative.sectionId].relSpace != UINT_MAX)
    154     {
    155         cxuint osectId = relative.sectionId;
    156         relSpace = { relative.multiply, sections[osectId].relSpace };
    157         if (!relSpacesSects.empty())
    158         {
    159             cxuint rsectId = relSpacesSects[sections[osectId].relSpace][0];
    160             fixAddr1 += relative.multiply*(sections[osectId].relAddress -
    161                     sections[rsectId].relAddress);
    162         }
    163     }
    164     else // treat as separate relSpace
    165         relSpace = { relative.multiply, 0x80000000U | relative.sectionId };
    166 }
    167 
    168 static bool checkRelativesEquality(Assembler& assembler,
    169             std::vector<RelMultiply>& relatives,
    170             const Array<RelMultiply>& relatives2, bool checkRelSpaces,
    171             uint64_t& fixAddr1, uint64_t& fixAddr2)
    172 {
    173     fixAddr1 = 0;
    174     fixAddr2 = 0;
    175     // if no check relspaces or if no real rel spaces in relatives
    176     bool equal = true;
     125template<typename T1, typename T2>
     126static bool checkRelativesEqualityInt(T1& relatives, const T2& relatives2)
     127{
    177128    size_t requals = 0;
    178129    if (relatives2.size() != relatives.size())
    179         equal = false;
     130        return false;
    180131    else
    181132    {
     
    191142                }
    192143        if (requals != relatives.size())
    193             equal = false;
    194     }
    195    
    196     if (equal) // if equal in previous method
     144            return false;
     145    }
     146    return true;
     147}
     148
     149// check relatives equality
     150// if check relSpaces then check relSpaces from relatives and check their equality
     151static bool checkRelativesEquality(Assembler& assembler,
     152            std::vector<RelMultiply>& relatives,
     153            const Array<RelMultiply>& relatives2, bool withSectionDiffs,
     154            bool sectDiffsPrepared)
     155{
     156    if (!withSectionDiffs || sectDiffsPrepared) // otherwise is not equal
     157        return checkRelativesEqualityInt(relatives, relatives2);
     158    else
     159    {
     160        const std::vector<AsmSection>& sections = assembler.getSections();
     161        // compare with ignoring sections with relspaces
     162        std::vector<RelMultiply> orels1;
     163        std::vector<RelMultiply> orels2;
     164        std::copy_if(relatives.begin(), relatives.end(), std::back_inserter(orels1),
     165                     [&sections](const RelMultiply& r)
     166                     { return sections[r.sectionId].relSpace == UINT_MAX; });
     167        std::copy_if(relatives2.begin(), relatives2.end(), std::back_inserter(orels2),
     168                     [&sections](const RelMultiply& r)
     169                     { return sections[r.sectionId].relSpace == UINT_MAX; });
     170        // now compare
     171        return checkRelativesEqualityInt(orels1, orels2);
     172    }
     173}
     174
     175// check whether sections is in resolvable section diffs
     176static bool checkSectionDiffs(size_t n, const RelMultiply* relMultiplies,
     177                    const std::vector<AsmSection>& sections, bool withSectionDiffs,
     178                    bool sectDiffsPreppared, bool& tryLater)
     179{
     180    if (n == 0)
    197181        return true;
    198182   
    199     if (!checkRelSpaces) // otherwise is not equal
     183    if (!withSectionDiffs || sectDiffsPreppared)
    200184        return false;
    201185   
    202     std::vector<RelMultiply> relSpaces1(relatives.size());
    203     std::vector<RelMultiply> relSpaces2(relatives2.size());
    204     const std::vector<AsmSection>& sections = assembler.getSections();
    205     const std::vector<Array<cxuint> >& relSpacesSects = assembler.getRelSpacesSections();
    206    
    207     // convert sections to relspaces
    208     for (size_t i = 0; i < relSpaces1.size(); i++)
    209         convertRelSpaces(relatives[i], relSpaces1[i], sections, relSpacesSects, fixAddr1);
    210    
    211     for (size_t i = 0; i < relSpaces2.size(); i++)
    212         convertRelSpaces(relatives2[i], relSpaces2[i], sections, relSpacesSects, fixAddr2);
    213    
    214     // sort
    215     std::sort(relSpaces1.begin(), relSpaces1.end(), compareRelMSectionLess);
    216     std::sort(relSpaces2.begin(), relSpaces2.end(), compareRelMSectionLess);
    217     // reduce relspaces by sum multiplies
    218     reduceRelMultiplies(relSpaces1);
    219     reduceRelMultiplies(relSpaces2);
    220    
    221     /// compare relspaces
    222     if (relSpaces1.size() != relSpaces2.size())
    223         return false;
    224     for (size_t i = 0; i < relSpaces1.size(); i++)
    225         if (relSpaces1[i].multiply != relSpaces2[i].multiply ||
    226             relSpaces1[i].sectionId != relSpaces2[i].sectionId)
    227             return false;
     186    for (size_t i = 0; i < n; i++)
     187        if (sections[relMultiplies[i].sectionId].relSpace == UINT_MAX)
     188            return false; // if found section not in anything relocation space
     189    //tryLater = true;
    228190    return true;
    229191}
     192
     193#define CHKSREL(rel) checkSectionDiffs(rel.size(), rel.data(), sections, \
     194                withSectionDiffs, sectDiffsPrepared, tryLater)
    230195
    231196AsmTryStatus AsmExpression::tryEvaluate(Assembler& assembler, size_t opStart, size_t opEnd,
     
    573538                    case AsmExprOp::MULTIPLY:
    574539                        // we do not multiply with relatives in two operands
    575                         if (!relatives.empty() && !relatives2.empty())
     540                        if (!CHKSREL(relatives) && !CHKSREL(relatives2))
    576541                            ASMX_FAILED_BY_ERROR(sourcePos,
    577542                                 "Multiplication is not allowed for two relative values")
     
    598563                        break;
    599564                    case AsmExprOp::DIVISION:
    600                         if (!relatives.empty() || !relatives2.empty())
     565                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    601566                            ASMX_FAILED_BY_ERROR(sourcePos,
    602567                                 "Division is not allowed for any relative value")
     
    613578                        break;
    614579                    case AsmExprOp::SIGNED_DIVISION:
    615                         if (!relatives.empty()|| !relatives2.empty())
     580                        if (!CHKSREL(relatives)|| !CHKSREL(relatives2))
    616581                            ASMX_FAILED_BY_ERROR(sourcePos,
    617582                                 "Signed division is not allowed for any relative value")
     
    628593                        break;
    629594                    case AsmExprOp::MODULO:
    630                         if (!relatives.empty() || !relatives2.empty())
     595                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    631596                            ASMX_FAILED_BY_ERROR(sourcePos,
    632597                                 "Modulo is not allowed for any relative value")
     
    643608                        break;
    644609                    case AsmExprOp::SIGNED_MODULO:
    645                         if (!relatives.empty() || !relatives2.empty())
     610                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    646611                            ASMX_FAILED_BY_ERROR(sourcePos,
    647612                                 "Signed Modulo is not allowed for any relative value")
     
    658623                        break;
    659624                    case AsmExprOp::BIT_AND:
    660                         if (!relatives.empty() || !relatives2.empty())
     625                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    661626                            ASMX_FAILED_BY_ERROR(sourcePos,
    662627                                 "Binary AND is not allowed for any relative value")
     
    664629                        break;
    665630                    case AsmExprOp::BIT_OR:
    666                         if (!relatives.empty() || !relatives2.empty())
     631                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    667632                            ASMX_FAILED_BY_ERROR(sourcePos,
    668633                                 "Binary OR is not allowed for any relative value")
     
    670635                        break;
    671636                    case AsmExprOp::BIT_XOR:
    672                         if (!relatives.empty() || !relatives2.empty())
     637                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    673638                            ASMX_FAILED_BY_ERROR(sourcePos,
    674639                                 "Binary XOR is not allowed for any relative value")
     
    676641                        break;
    677642                    case AsmExprOp::BIT_ORNOT:
    678                         if (!relatives.empty() || !relatives2.empty())
     643                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    679644                            ASMX_FAILED_BY_ERROR(sourcePos,
    680645                                 "Binary ORNOT is not allowed for any relative value")
     
    682647                        break;
    683648                    case AsmExprOp::SHIFT_LEFT:
    684                         if (!relatives.empty())
     649                        if (!CHKSREL(relatives))
    685650                            ASMX_FAILED_BY_ERROR(sourcePos, "Shift left is not allowed "
    686651                                    "for any for relative second value")
     
    701666                        break;
    702667                    case AsmExprOp::SHIFT_RIGHT:
    703                         if (!relatives.empty() || !relatives2.empty())
     668                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    704669                            ASMX_FAILED_BY_ERROR(sourcePos,
    705670                                 "Shift right is not allowed for any relative value")
     
    715680                        break;
    716681                    case AsmExprOp::SIGNED_SHIFT_RIGHT:
    717                         if (!relatives.empty() || !relatives2.empty())
     682                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    718683                            ASMX_FAILED_BY_ERROR(sourcePos, "Signed shift right is not "
    719684                                    "allowed for any relative value")
     
    729694                        break;
    730695                    case AsmExprOp::LOGICAL_AND:
    731                         if (!relatives.empty() || !relatives2.empty())
     696                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    732697                            ASMX_FAILED_BY_ERROR(sourcePos,
    733698                                 "Logical AND is not allowed for any relative value")
     
    735700                        break;
    736701                    case AsmExprOp::LOGICAL_OR:
    737                         if (!relatives.empty() || !relatives2.empty())
     702                        if (!CHKSREL(relatives) || !CHKSREL(relatives2))
    738703                            ASMX_FAILED_BY_ERROR(sourcePos,
    739704                                 "Logical OR is not allowed for any relative value")
     
    751716                    case AsmExprOp::ABOVE_EQ:
    752717                    {
    753                         uint64_t fixAddr1 = 0, fixAddr2 = 0;
    754718                        if (!checkRelativesEquality(assembler, relatives, relatives2,
    755                                     withSectionDiffs && !sectDiffsPrepared,
    756                                     fixAddr1, fixAddr2))
     719                                    withSectionDiffs, sectDiffsPrepared))
    757720                            ASMX_FAILED_BY_ERROR(sourcePos, "For comparisons "
    758721                                        "two values must have this same relatives!")
     
    760723                            tryLater = true; // must be evaluated later
    761724                        relatives.clear();
    762                         value += fixAddr1;
    763                         value2 += fixAddr2;
    764725                        switch(op)
    765726                        {
     
    813774                const Array<RelMultiply> relatives3 = stack.top().relatives;
    814775                stack.pop();
    815                 if (!relatives3.empty())
     776                if (!CHKSREL(relatives3))
    816777                    ASMX_FAILED_BY_ERROR(sourcePos,
    817778                         "Choice is not allowed for first relative value")
Note: See TracChangeset for help on using the changeset viewer.