Changeset 3764 in CLRX


Ignore:
Timestamp:
Feb 10, 2018, 8:56:10 AM (15 months ago)
Author:
matszpk
Message:

CLRadeonExtender: Asm: Prepare resolving section differences in main assembler code (in this same places where symbol resolving is possible later).

Location:
CLRadeonExtender/trunk
Files:
5 edited

Legend:

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

    r3762 r3764  
    350350    /**
    351351     * \param assembler assembler instace
     352     * \param opStart start operand
     353     * \param opEnd end operand
    352354     * \param value output value
    353355     * \param sectionId output section id
     
    357359    AsmTryStatus tryEvaluate(Assembler& assembler, size_t opStart, size_t opEnd,
    358360                  uint64_t& value, cxuint& sectionId, bool withSectionDiffs = false) const;
     361   
     362    /// try to evaluate expression with/without section differences
     363    /**
     364     * \param assembler assembler instace
     365     * \param value output value
     366     * \param sectionId output section id
     367     * \param withSectionDiffs evaluate including precalculated section differences
     368     * \return operation status
     369     */
     370    AsmTryStatus tryEvaluate(Assembler& assembler, uint64_t& value, cxuint& sectionId,
     371                    bool withSectionDiffs = false) const
     372    { return tryEvaluate(assembler, 0, ops.size(), value, sectionId, withSectionDiffs); }
    359373   
    360374    /// try to evaluate expression
  • CLRadeonExtender/trunk/CLRX/amdasm/Assembler.h

    r3762 r3764  
    445445    std::vector<Array<cxuint> > relSpacesSections;
    446446    std::unordered_set<AsmSymbolEntry*> symbolSnapshots;
     447    std::vector<AsmExpression*> unevalExpressions;
    447448    std::vector<AsmRelocation> relocations;
    448449    AsmScope globalScope;
     
    487488    uint64_t& currentOutPos;
    488489   
     490    bool withSectionDiffs() const
     491    { return formatHandler!=nullptr && formatHandler->isSectionDiffsResolvable(); }
     492   
    489493    AsmSourcePos getSourcePos(LineCol lineCol) const
    490494    {
     
    648652    void tryToResolveSymbols(AsmScope* scope);
    649653    void printUnresolvedSymbols(AsmScope* scope);
     654   
     655    bool resolveExprTarget(const AsmExpression* expr, uint64_t value, cxuint sectionId);
    650656   
    651657protected:
  • CLRadeonExtender/trunk/amdasm/AsmPseudoOps.cpp

    r3639 r3764  
    701701                // put directly to section
    702702                cxuint sectionId;
    703                 if (expr->evaluate(asmr, value, sectionId))
     703                AsmTryStatus  evalStatus = expr->tryEvaluate(asmr, value, sectionId,
     704                                        asmr.withSectionDiffs());
     705                if (evalStatus == AsmTryStatus::SUCCESS)
    704706                {
    705707                    if (sectionId == ASMSECT_ABS)
     
    714716                    else
    715717                        asmr.printError(exprPlace, "Expression must be absolute!");
     718                }
     719                else if (evalStatus == AsmTryStatus::TRY_LATER)
     720                {
     721                    // if section diffs to resolve later
     722                    expr->setTarget(AsmExprTarget::dataTarget<T>(
     723                                    asmr.currentSection, asmr.currentOutPos));
     724                    asmr.unevalExpressions.push_back(expr.release());
     725                    asmr.reserveData(sizeof(T));
    716726                }
    717727            }
  • CLRadeonExtender/trunk/amdasm/Assembler.cpp

    r3762 r3764  
    317317    {
    318318        cxuint sectionId;
    319         if (!expr->evaluate(asmr, value, sectionId)) // failed evaluation!
     319        AsmTryStatus evalStatus = expr->tryEvaluate(asmr, value, sectionId,
     320                            asmr.withSectionDiffs());
     321        if (evalStatus == AsmTryStatus::FAILED) // failed evaluation!
    320322            return false;
     323        else if (evalStatus == AsmTryStatus::TRY_LATER)
     324        {
     325            // store out target expression (some symbols is not resolved)
     326            asmr.unevalExpressions.push_back(expr.get());
     327            outTargetExpr = std::move(expr);
     328            return true;
     329        }
    321330        if (sectionId != asmr.currentSection)
    322331            // if jump outside current section (.text)
     
    764773    for (auto& entry: symbolSnapshots)
    765774        delete entry;
     775   
     776    for (auto& expr: unevalExpressions)
     777        delete expr;
    766778}
    767779
     
    13081320}
    13091321
     1322bool Assembler::resolveExprTarget(const AsmExpression* expr,
     1323                        uint64_t value, cxuint sectionId)
     1324{
     1325    const AsmExprTarget& target = expr->getTarget();
     1326    switch(target.type)
     1327    {
     1328        case ASMXTGT_SYMBOL:
     1329            // resolve symbol
     1330            setSymbol(*target.symbol, value, sectionId);
     1331            break;
     1332        case ASMXTGT_DATA8:
     1333            if (sectionId != ASMSECT_ABS)
     1334                THIS_FAIL_BY_ERROR(expr->getSourcePos(),
     1335                        "Relative value is illegal in data expressions")
     1336            else
     1337            {
     1338                printWarningForRange(8, value, expr->getSourcePos());
     1339                sections[target.sectionId].content[target.offset] = cxbyte(value);
     1340            }
     1341            break;
     1342        case ASMXTGT_DATA16:
     1343            if (sectionId != ASMSECT_ABS)
     1344                THIS_FAIL_BY_ERROR(expr->getSourcePos(),
     1345                        "Relative value is illegal in data expressions")
     1346            else
     1347            {
     1348                printWarningForRange(16, value, expr->getSourcePos());
     1349                SULEV(*reinterpret_cast<uint16_t*>(sections[target.sectionId]
     1350                        .content.data() + target.offset), uint16_t(value));
     1351            }
     1352            break;
     1353        case ASMXTGT_DATA32:
     1354            if (sectionId != ASMSECT_ABS)
     1355                THIS_FAIL_BY_ERROR(expr->getSourcePos(),
     1356                        "Relative value is illegal in data expressions")
     1357            else
     1358            {
     1359                printWarningForRange(32, value, expr->getSourcePos());
     1360                SULEV(*reinterpret_cast<uint32_t*>(sections[target.sectionId]
     1361                        .content.data() + target.offset), uint32_t(value));
     1362            }
     1363            break;
     1364        case ASMXTGT_DATA64:
     1365            if (sectionId != ASMSECT_ABS)
     1366                THIS_FAIL_BY_ERROR(expr->getSourcePos(),
     1367                        "Relative value is illegal in data expressions")
     1368            else
     1369                SULEV(*reinterpret_cast<uint64_t*>(sections[target.sectionId]
     1370                        .content.data() + target.offset), uint64_t(value));
     1371            break;
     1372        // special case for Code flow
     1373        case ASMXTGT_CODEFLOW:
     1374            if (target.sectionId != sectionId)
     1375                THIS_FAIL_BY_ERROR(expr->getSourcePos(), "Jump over current section!")
     1376            else
     1377                sections[target.sectionId].codeFlow[target.cflowId].target = value;
     1378            break;
     1379        default:
     1380            // ISA assembler resolves this dependency
     1381            if (!isaAssembler->resolveCode(expr->getSourcePos(),
     1382                    target.sectionId, sections[target.sectionId].content.data(),
     1383                    target.offset, target.type, sectionId, value))
     1384                return false;
     1385            break;
     1386    }
     1387    return true;
     1388}
     1389
    13101390bool Assembler::setSymbol(AsmSymbolEntry& symEntry, uint64_t value, cxuint sectionId)
    13111391{
     
    13671447               
    13681448                // resolving
    1369                 switch(target.type)
    1370                 {
    1371                     case ASMXTGT_SYMBOL:
    1372                     {    // resolve symbol
    1373                         AsmSymbolEntry& curSymEntry = *target.symbol;
    1374                         if (!curSymEntry.second.resolving &&
    1375                             (!curSymEntry.second.regRange &&
    1376                              curSymEntry.second.expression==expr))
    1377                         {
    1378                             curSymEntry.second.value = value;
    1379                             curSymEntry.second.sectionId = sectionId;
    1380                             curSymEntry.second.hasValue =
    1381                                 isResolvableSection(sectionId) || resolvingRelocs;
    1382                             symbolStack.push(std::make_pair(&curSymEntry, 0));
    1383                             if (!curSymEntry.second.hasValue)
    1384                                 continue;
    1385                             curSymEntry.second.resolving = true;
    1386                         }
    1387                         // otherwise we ignore circular dependencies
    1388                         break;
     1449                if (target.type == ASMXTGT_SYMBOL)
     1450                {    // resolve symbol
     1451                    AsmSymbolEntry& curSymEntry = *target.symbol;
     1452                    if (!curSymEntry.second.resolving &&
     1453                        (!curSymEntry.second.regRange &&
     1454                            curSymEntry.second.expression==expr))
     1455                    {
     1456                        curSymEntry.second.value = value;
     1457                        curSymEntry.second.sectionId = sectionId;
     1458                        curSymEntry.second.hasValue =
     1459                            isResolvableSection(sectionId) || resolvingRelocs;
     1460                        symbolStack.push(std::make_pair(&curSymEntry, 0));
     1461                        if (!curSymEntry.second.hasValue)
     1462                            continue;
     1463                        curSymEntry.second.resolving = true;
    13891464                    }
    1390                     case ASMXTGT_DATA8:
    1391                         if (sectionId != ASMSECT_ABS)
    1392                             THIS_NOTGOOD_BY_ERROR(expr->getSourcePos(),
    1393                                    "Relative value is illegal in data expressions")
    1394                         else
    1395                         {
    1396                             printWarningForRange(8, value, expr->getSourcePos());
    1397                             sections[target.sectionId].content[target.offset] =
    1398                                     cxbyte(value);
    1399                         }
    1400                         break;
    1401                     case ASMXTGT_DATA16:
    1402                         if (sectionId != ASMSECT_ABS)
    1403                             THIS_NOTGOOD_BY_ERROR(expr->getSourcePos(),
    1404                                    "Relative value is illegal in data expressions")
    1405                         else
    1406                         {
    1407                             printWarningForRange(16, value, expr->getSourcePos());
    1408                             SULEV(*reinterpret_cast<uint16_t*>(sections[target.sectionId]
    1409                                     .content.data() + target.offset), uint16_t(value));
    1410                         }
    1411                         break;
    1412                     case ASMXTGT_DATA32:
    1413                         if (sectionId != ASMSECT_ABS)
    1414                             THIS_NOTGOOD_BY_ERROR(expr->getSourcePos(),
    1415                                    "Relative value is illegal in data expressions")
    1416                         else
    1417                         {
    1418                             printWarningForRange(32, value, expr->getSourcePos());
    1419                             SULEV(*reinterpret_cast<uint32_t*>(sections[target.sectionId]
    1420                                     .content.data() + target.offset), uint32_t(value));
    1421                         }
    1422                         break;
    1423                     case ASMXTGT_DATA64:
    1424                         if (sectionId != ASMSECT_ABS)
    1425                             THIS_NOTGOOD_BY_ERROR(expr->getSourcePos(),
    1426                                    "Relative value is illegal in data expressions")
    1427                         else
    1428                             SULEV(*reinterpret_cast<uint64_t*>(sections[target.sectionId]
    1429                                     .content.data() + target.offset), uint64_t(value));
    1430                         break;
    1431                     // special case for Code flow
    1432                     case ASMXTGT_CODEFLOW:
    1433                         if (target.sectionId != sectionId)
    1434                             THIS_NOTGOOD_BY_ERROR(expr->getSourcePos(),
    1435                                             "Jump over current section!")
    1436                         else
    1437                             sections[target.sectionId].
    1438                                     codeFlow[target.cflowId].target = value;
    1439                         break;
    1440                     default:
    1441                         // ISA assembler resolves this dependency
    1442                         if (!isaAssembler->resolveCode(expr->getSourcePos(),
    1443                                 target.sectionId, sections[target.sectionId].content.data(),
    1444                                 target.offset, target.type, sectionId, value))
    1445                             good = false;
    1446                         break;
     1465                    // otherwise we ignore circular dependencies
    14471466                }
     1467                else
     1468                    good &= resolveExprTarget(expr, value, sectionId);
    14481469                delete occurrence.expression; // delete expression
    14491470            }
     
    15881609    AsmSymbolEntry& symEntry = *res.first;
    15891610   
     1611    bool tryLater = false;
    15901612    if (!expr)
    15911613    {
     
    15981620        uint64_t value;
    15991621        cxuint sectionId;
    1600         if (!expr->evaluate(*this, value, sectionId))
     1622       
     1623        AsmTryStatus evalStatus = expr->tryEvaluate(*this, value, sectionId,
     1624                                    withSectionDiffs());
     1625        if (evalStatus == AsmTryStatus::FAILED)
    16011626            return false;
    1602        
    1603         setSymbol(symEntry, value, sectionId);
    1604         symEntry.second.onceDefined = !reassign;
    1605     }
    1606     else // set expression
     1627        else if (evalStatus == AsmTryStatus::TRY_LATER)
     1628            tryLater = true;
     1629        else
     1630        {   // success
     1631            setSymbol(symEntry, value, sectionId);
     1632            symEntry.second.onceDefined = !reassign;
     1633        }
     1634    }
     1635    else
     1636        tryLater = true;
     1637   
     1638    if (tryLater) // set expression
    16071639    {
    16081640        expr->setTarget(AsmExprTarget::symbolTarget(&symEntry));
     
    28512883    }
    28522884   
     2885    if (withSectionDiffs())
     2886        formatHandler->prepareSectionDiffsResolving();
     2887   
    28532888    resolvingRelocs = true;
    28542889    tryToResolveSymbols(&globalScope);
     2890   
     2891    if (withSectionDiffs())
     2892        for (AsmExpression* expr: unevalExpressions)
     2893        {
     2894            // try to resolve unevaluated expressions
     2895            uint64_t value;
     2896            cxuint sectionId;
     2897            if (expr->evaluate(*this, value, sectionId))
     2898                resolveExprTarget(expr, value, sectionId);
     2899            delete expr;
     2900        }
     2901   
    28552902    printUnresolvedSymbols(&globalScope);
    28562903   
  • CLRadeonExtender/trunk/amdasm/GCNAsmHelpers.cpp

    r3575 r3764  
    14551455            if (expr->isEmpty())
    14561456                ASM_FAIL_BY_ERROR(exprPlace, "Expected expression")
     1457           
     1458            bool tryLater = false;
    14571459            if (expr->getSymOccursNum()==0)
    14581460            {
    14591461                // resolved now
    14601462                cxuint sectionId; // for getting
    1461                 if (!expr->evaluate(asmr, value, sectionId)) // failed evaluation!
     1463                AsmTryStatus evalStatus = expr->tryEvaluate(asmr, value, sectionId,
     1464                                        asmr.withSectionDiffs());
     1465               
     1466                if (evalStatus == AsmTryStatus::FAILED) // failed evaluation!
    14621467                    return false;
     1468                else if (evalStatus == AsmTryStatus::TRY_LATER)
     1469                {
     1470                    if (outTargetExpr!=nullptr)
     1471                        asmr.unevalExpressions.push_back(expr.get());
     1472                    tryLater = true;
     1473                }
    14631474                else if (sectionId != ASMSECT_ABS)
    14641475                    // if not absolute value
     
    14661477            }
    14671478            else
     1479                tryLater = true;
     1480           
     1481            if (tryLater)
    14681482            {
    14691483                // return output expression with symbols to resolve
Note: See TracChangeset for help on using the changeset viewer.