Changeset 4998 in CLRX


Ignore:
Timestamp:
Nov 15, 2019, 5:59:09 PM (9 months ago)
Author:
matszpk
Message:

CLRadeonExtender: GCNASM: Preliminary support for SMRD 32-bit immediate literal if arch==GCN1.1.

Location:
CLRadeonExtender/trunk
Files:
4 edited

Legend:

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

    r4997 r4998  
    918918    RegRange soffsetReg(0, 0);
    919919    uint32_t soffsetVal = 0;
     920    bool haveLit = false;
    920921    std::unique_ptr<AsmExpression> soffsetExpr;
    921922    const GCNInsnMode mode1 = (gcnInsn.mode & GCN_MASK1);
     
    959960        if (!soffsetReg)
    960961        {
     962            soffsetReg.start = 255; // indicate an immediate
    961963            // parse immediate
    962             soffsetReg.start = 255; // indicate an immediate
    963             good &= parseImm(asmr, linePtr, soffsetVal, &soffsetExpr, 8, WS_UNSIGNED);
     964            if ((arch & ARCH_HD7X00) != 0)
     965                good &= parseImm(asmr, linePtr, soffsetVal, &soffsetExpr, 8, WS_UNSIGNED);
     966            else
     967                good &= parseSMRDImm(asmr, linePtr, soffsetVal, &soffsetExpr, haveLit);
    964968        }
    965969    }
     
    975979                    GCNDELOP_SMEMOP, GCNDELOP_NONE, gcnAsm->instrRVUs[0].rwFlags };
    976980   
    977     const cxuint wordsNum = 1;
     981    const cxuint wordsNum = haveLit ? 2 : 1;
    978982    if (!checkGCNEncodingSize(asmr, instrPlace, gcnEncSize, wordsNum))
    979983        return false;
    980984   
    981985    if (soffsetExpr!=nullptr)
    982         soffsetExpr->setTarget(AsmExprTarget(GCNTGT_SMRDOFFSET, asmr.currentSection,
    983                        output.size()));
     986        soffsetExpr->setTarget(AsmExprTarget(haveLit ? GCNTGT_LITIMM : GCNTGT_SMRDOFFSET,
     987                        asmr.currentSection, output.size()));
    984988   
    985989    // put data (instruction word)
     
    987991    SLEV(word, 0xc0000000U | (uint32_t(gcnInsn.code1)<<22) |
    988992            (uint32_t(dstReg.bstart())<<15) |
    989             ((sbaseReg.bstart()&~1U)<<8) | ((soffsetReg.isVal(255)) ? 0x100 : 0) |
    990             ((soffsetReg.isVal(255)) ? soffsetVal : soffsetReg.bstart()));
    991     output.insert(output.end(), reinterpret_cast<cxbyte*>(&word),
     993            (haveLit ? 0xff /* have literal */ :
     994             ((soffsetReg.isVal(255)) ? 0x100 : 0)) |
     995             ((sbaseReg.bstart()&~1U)<<8) |
     996            (haveLit ? 0 : ((soffsetReg.isVal(255)) ? soffsetVal : soffsetReg.bstart())));
     997    output.insert(output.end(), reinterpret_cast<cxbyte*>(&word),
    992998            reinterpret_cast<cxbyte*>(&word)+4);
     999    uint32_t lit32Val;
     1000    SLEV(lit32Val, soffsetVal);
     1001    if (haveLit)
     1002        output.insert(output.end(), reinterpret_cast<cxbyte*>(&lit32Val),
     1003            reinterpret_cast<cxbyte*>(&lit32Val)+4);
    9931004    /// prevent freeing expression
    9941005    soffsetExpr.release();
  • CLRadeonExtender/trunk/amdasm/GCNAsmHelpers.cpp

    r4860 r4998  
    952952        return true;
    953953    }
     954}
     955
     956bool GCNAsmUtils::parseSMRDImm(Assembler& asmr, const char*& linePtr, uint32_t& outValue,
     957            std::unique_ptr<AsmExpression>* outTargetExpr, bool &litimm)
     958{
     959    const char* end = asmr.line+asmr.lineSize;
     960    if (outTargetExpr!=nullptr)
     961        outTargetExpr->reset();
     962    skipSpacesToEnd(linePtr, end);
     963   
     964    bool haveLit = false;
     965    const char* oldLinePtr = linePtr;
     966    if (linePtr+4<end && toLower(linePtr[0])=='l' && toLower(linePtr[1])=='i' &&
     967            toLower(linePtr[2])=='t' && (isSpace(linePtr[3]) || linePtr[3]=='('))
     968    {
     969        // lit() - force encoding as literal
     970        linePtr+=3;
     971        skipSpacesToEnd(linePtr, end);
     972       
     973        // space between lit and (
     974        if (linePtr!=end && *linePtr=='(')
     975        {
     976            linePtr++;
     977            skipSpacesToEnd(linePtr, end);
     978            haveLit = true;
     979        }
     980        else // back to expression start
     981            linePtr = oldLinePtr;
     982    }
     983   
     984    uint64_t value;
     985    const char* exprPlace = linePtr;
     986    // if fast expression
     987    if (AsmExpression::fastExprEvaluate(asmr, linePtr, value))
     988    {
     989        asmr.printWarningForRange(32, value,
     990                        asmr.getSourcePos(exprPlace), WS_BOTH);
     991        outValue = value & ((1ULL<<32)-1ULL);
     992        if (haveLit)
     993        {
     994            if (linePtr==end || *linePtr!=')')
     995                ASM_FAIL_BY_ERROR(linePtr, "Expected ')' after expression at 'lit'")
     996            else // skip end of lit
     997                linePtr++;
     998        }
     999        litimm = haveLit || (outValue >= 0x100);
     1000        return true;
     1001    }
     1002   
     1003    std::unique_ptr<AsmExpression> expr(AsmExpression::parse(asmr, linePtr));
     1004    if (expr==nullptr) // error
     1005        return false;
     1006    if (expr->isEmpty())
     1007        ASM_FAIL_BY_ERROR(exprPlace, "Expected expression")
     1008    if (expr->getSymOccursNum()==0)
     1009    {
     1010        // resolved now
     1011        cxuint sectionId; // for getting
     1012        if (!expr->evaluate(asmr, value, sectionId)) // failed evaluation!
     1013            return false;
     1014        else if (sectionId != ASMSECT_ABS)
     1015            // if not absolute value
     1016            ASM_FAIL_BY_ERROR(exprPlace, "Expression must be absolute!")
     1017       
     1018        asmr.printWarningForRange(32, value,
     1019                        asmr.getSourcePos(exprPlace), WS_BOTH);
     1020        outValue = value & ((1ULL<<32)-1ULL);
     1021    }
     1022    else
     1023    {
     1024        // return output expression with symbols to resolve
     1025        if (outTargetExpr!=nullptr)
     1026            *outTargetExpr = std::move(expr);
     1027        else
     1028            ASM_FAIL_BY_ERROR(exprPlace, "Unresolved expression is illegal in this place")
     1029    }
     1030    litimm = haveLit || (outValue >= 0x100);
     1031    // end of 'lit('
     1032    if (haveLit)
     1033    {
     1034        skipSpacesToEnd(linePtr, end);
     1035        if (linePtr==end || *linePtr!=')')
     1036            ASM_FAIL_BY_ERROR(linePtr, "Expected ')' after expression at 'lit'")
     1037        else // skip end of lit
     1038            linePtr++;
     1039    }
     1040    return true;
    9541041}
    9551042
  • CLRadeonExtender/trunk/amdasm/GCNAsmInternals.h

    r4860 r4998  
    222222            std::unique_ptr<AsmExpression>* outTargetExpr, cxuint bits = 0,
    223223            cxbyte signess = WS_BOTH);
     224    static bool parseSMRDImm(Assembler& asmr, const char*& linePtr, uint32_t& value,
     225            std::unique_ptr<AsmExpression>* outTargetExpr, bool &litimm);
    224226   
    225227    // parse immediate value (for field) with specified bits (can be signed)
  • CLRadeonExtender/trunk/tests/amdasm/GCNAsmOpc11.cpp

    r4993 r4998  
    30023002    { "xxx: s_cbranch_cdbgsys_and_user xxx+16", 0xbf9a0003U, 0, false, true, "" },
    30033003    /* SMRD */
     3004    { "        s_buffer_load_dword s51, s[60:63], 0x13\n",
     3005        0xc219bd13U, 0, false, true, "" },
     3006    { "zyy=67; s_buffer_load_dword s51, s[60:63], zyy\n",
     3007        0xc219bd43U, 0, false, true, "" },
     3008    { "s_buffer_load_dword s51, s[60:63], ulol; ulol=89\n",
     3009        0xc219bd59U, 0, false, true, "" },
     3010    { "        s_buffer_load_dword s51, s[60:63], 0x13314\n",
     3011        0xc219bcffU, 0x13314, true, true, "" },
     3012    { "zx=0x62135; s_buffer_load_dword s51, s[60:63], zx\n",
     3013        0xc219bcffU, 0x62135, true, true, "" },
     3014    { "s_buffer_load_dword s51, s[60:63], lit(zx); zx=0x36ffac21\n",
     3015        0xc219bcffU, 0x36ffac21, true, true, "" },
     3016    { "        s_buffer_load_dword s51, s[60:63], lit(253)\n",
     3017        0xc219bcffU, 0xfd, true, true, "" },
     3018    { "        s_buffer_load_dword s51, s[60:63], lit  (  253)\n",
     3019        0xc219bcffU, 0xfd, true, true, "" },
     3020    { "        s_buffer_load_dword s51, s[60:63], lit  (  253   )\n",
     3021        0xc219bcffU, 0xfd, true, true, "" },
    30043022    { "   s_dcache_inv_vol", 0xc7400000U, 0, false, true, "" },
    30053023    /* VOP1 encoding */
Note: See TracChangeset for help on using the changeset viewer.