Changeset 4857 in CLRX


Ignore:
Timestamp:
Jul 28, 2019, 9:06:28 AM (3 weeks ago)
Author:
matszpk
Message:

CLRadeonExtender: GCNAsm: Fix parseVRegRangesLimited routine. Next stuff to handle MIMG GFX10 encoding.

Location:
CLRadeonExtender/trunk
Files:
3 edited

Legend:

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

    r4835 r4857  
    100100    GCNFIELD_VOP_VCC_SDST0,
    101101    GCNFIELD_VOP_VCC_SDST1,
    102     GCNFIELD_VOP_VCC_IMPL
     102    GCNFIELD_VOP_VCC_IMPL,
     103    GCNFIELD_M_VADDR_MULTI,
     104    GCNFIELD_M_VADDR_MULTI_MAX = GCNFIELD_M_VADDR_MULTI+15
    103105};
    104106
  • CLRadeonExtender/trunk/amdasm/GCNAsmEncode2.cpp

    r4855 r4857  
    487487}
    488488
     489struct GFX10MIMGDimInfoEntry
     490{
     491    cxuint value;
     492    cxuint dwordsNum;
     493    cxuint derivsNum; // deriv dwords num
     494};
     495
    489496// dim values names
    490 static const std::pair<const char*, cxuint> mimgDimNamesMap[] =
     497static const std::pair<const char*, GFX10MIMGDimInfoEntry> mimgDimNamesMap[] =
    491498{
    492     { "1d", 0 },
    493     { "1d_array", 4 },
    494     { "2d", 1 },
    495     { "2d_array", 5 },
    496     { "2d_msaa", 6 },
    497     { "2d_msaa_array", 7 },
    498     { "3d", 2 },
    499     { "cube", 3 },
     499    { "1d", { 0, 1, 2 } },
     500    { "1d_array",{ 4, 2, 2 } },
     501    { "2d", { 1, 2, 4 } },
     502    { "2d_array",{ 5, 3, 4 } },
     503    { "2d_msaa", { 6, 3, 4 } },
     504    { "2d_msaa_array", { 7, 4, 4 } },
     505    { "3d", { 2, 3, 6 } },
     506    { "cube", { 3, 3, 4 } },
    500507};
    501508
     
    513520    bool good = true;
    514521    RegRange vaddrReg(0, 0);
     522    std::vector<RegRange> vaddrRegList;
    515523    RegRange vdataReg(0, 0);
    516524    RegRange ssampReg(0, 0);
     
    530538    const char* vaddrPlace = linePtr;
    531539    gcnAsm->setCurrentRVU(1);
    532     // // parse VADDR (various VGPR number, verified later)
    533     good &= parseVRegRange(asmr, linePtr, vaddrReg, 0, GCNFIELD_M_VADDR, true,
    534                     INSTROP_SYMREGRANGE|INSTROP_READ);
    535     cxuint geRegRequired = (gcnInsn.mode&GCN_MIMG_VA_MASK)+1;
    536     cxuint vaddrRegsNum = vaddrReg.end-vaddrReg.start;
    537     cxuint vaddrMaxExtraRegs = (gcnInsn.mode&GCN_MIMG_VADERIV) ? 7 : 3;
    538     if (vaddrRegsNum < geRegRequired || vaddrRegsNum > geRegRequired+vaddrMaxExtraRegs)
    539     {
    540         char buf[60];
    541         snprintf(buf, 60, "Required (%u-%u) vector registers", geRegRequired,
    542                  geRegRequired+vaddrMaxExtraRegs);
    543         ASM_NOTGOOD_BY_ERROR(vaddrPlace, buf)
     540    if (!isGCN15 || linePtr==end || *linePtr!='[')
     541        // parse VADDR (various VGPR number, verified later)
     542        good &= parseVRegRange(asmr, linePtr, vaddrReg, 0, GCNFIELD_M_VADDR, true,
     543                        INSTROP_SYMREGRANGE|INSTROP_READ);
     544    else // for VADDR register list
     545        good &= parseVRegRangesLimited(asmr, linePtr, 13, vaddrRegList,
     546                   GCNFIELD_M_VADDR_MULTI, true, INSTROP_SYMREGRANGE|INSTROP_READ);
     547   
     548    if (!isGCN15)
     549    {
     550        cxuint geRegRequired = (gcnInsn.mode&GCN_MIMG_VA_MASK)+1;
     551        cxuint vaddrRegsNum = vaddrReg.end-vaddrReg.start;
     552        cxuint vaddrMaxExtraRegs = (gcnInsn.mode&GCN_MIMG_VADERIV) ? 7 : 3;
     553        if (vaddrRegsNum < geRegRequired || vaddrRegsNum > geRegRequired+vaddrMaxExtraRegs)
     554        {
     555            char buf[60];
     556            snprintf(buf, 60, "Required (%u-%u) vector registers", geRegRequired,
     557                    geRegRequired+vaddrMaxExtraRegs);
     558            ASM_NOTGOOD_BY_ERROR(vaddrPlace, buf)
     559        }
    544560    }
    545561   
     
    568584    bool haveDlc = false, haveDim = false;
    569585    cxbyte dimVal = 0;
     586    cxuint dimDwordsNum = 0, dimDerivsNum = 0;
    570587    cxbyte dmask = 0x1;
    571588    /* modifiers and modifiers */
     
    620637                        if (dimIdx!=8)
    621638                        {
    622                             dimVal = dimIdx;
     639                            dimVal = mimgDimNamesMap[dimIdx].second.value;
     640                            dimDwordsNum = mimgDimNamesMap[dimIdx].second.dwordsNum;
     641                            dimDerivsNum = mimgDimNamesMap[dimIdx].second.derivsNum;
    623642                            if (haveDim)
    624643                                asmr.printWarning(modPlace, "Dim is already defined");
     
    711730                    "Required 8 scalar registers")
    712731   
     732    cxuint totalVaddrRegs = 0;
     733    if (isGCN15)
     734    {
     735        if (!haveDim)
     736            ASM_FAIL_BY_ERROR(instrPlace,
     737                              "MIMG instruction for GFX10 requires DIM modifier")
     738       
     739        // check number of VADDR registers
     740        cxuint daddrsNum = dimDwordsNum;
     741        if ((gcnInsn.mode & GCN_MIMG_VADERIV)!=0)
     742            daddrsNum += dimDerivsNum;
     743        daddrsNum += ((gcnInsn.mode & GCN_MIMG_VA_MIP)!=0) +
     744                    ((gcnInsn.mode & GCN_MIMG_VA_C)!=0) +
     745                    ((gcnInsn.mode & GCN_MIMG_VA_CL)!=0) +
     746                    ((gcnInsn.mode & GCN_MIMG_VA_L)!=0) +
     747                    ((gcnInsn.mode & GCN_MIMG_VA_B)!=0) +
     748                    ((gcnInsn.mode & GCN_MIMG_VA_O)!=0);
     749        totalVaddrRegs = vaddrReg ? vaddrReg.end-vaddrReg.start : 0;
     750        if (!vaddrReg)
     751            for (const RegRange& rpair: vaddrRegList)
     752                totalVaddrRegs = rpair.end - rpair.start;
     753       
     754        if (totalVaddrRegs < daddrsNum)
     755        {
     756            char buf[60];
     757            sprintf(buf, "MIMG VADDR requires least %u registers", daddrsNum);
     758            ASM_FAIL_BY_ERROR(vaddrPlace, buf);
     759        }
     760        else if (totalVaddrRegs > 13)
     761            ASM_FAIL_BY_ERROR(vaddrPlace, "MIMG VADDR accepts no more than 13 registers");
     762    }
     763   
    713764    if (!good || !checkGarbagesAtEnd(asmr, linePtr))
    714765        return false;
    715    
    716     if (isGCN15 && !haveDim)
    717         ASM_FAIL_BY_ERROR(instrPlace, "MIMG instruction for GFX10 requires DIM modifier")
    718766   
    719767    /* checking modifiers conditions */
     
    736784    // put instruction words
    737785    uint32_t words[2];
     786    uint32_t extraDwordEnc = 0;
     787    cxbyte vaddrRegCodes[13];
     788    vaddrRegCodes[0] = vaddrReg.bstart()&0xff;
     789    if (isGCN15 && !vaddrReg) // if vaddr reg list
     790    {
     791        extraDwordEnc = (((totalVaddrRegs-1+3)>>2)&3)<<1;
     792        cxuint i = 0;
     793        for (const RegRange& rpair: vaddrRegList)
     794        {
     795            for (cxuint r = rpair.start; r < rpair.end; r++)
     796                vaddrRegCodes[i++] = rpair.isRegVar() ? 0 : (r&0xff);
     797        }
     798    }
     799   
    738800    SLEV(words[0], 0xf0000000U | (uint32_t(dmask&0xf)<<8) | (haveUnorm ? 0x1000U : 0) |
    739801        (haveGlc ? 0x2000U : 0) | (haveDa ? 0x4000U : 0) |
     802        (haveDim ? uint32_t(dimVal)<<3 : 0) | extraDwordEnc |
    740803        (haveR128|haveA16 ? 0x8000U : 0) | (haveDlc ? 0x80U : 0) |
    741804        (haveTfe ? 0x10000U : 0) | (haveLwe ? 0x20000U : 0) |
    742805        (uint32_t(gcnInsn.code1)<<18) | (haveSlc ? (1U<<25) : 0));
    743     SLEV(words[1], (vaddrReg.bstart()&0xff) | (uint32_t(vdataReg.bstart()&0xff)<<8) |
     806    SLEV(words[1], vaddrRegCodes[0] | (uint32_t(vdataReg.bstart()&0xff)<<8) |
    744807            (uint32_t(srsrcReg.bstart()>>2)<<16) | (uint32_t(ssampReg.bstart()>>2)<<21) |
    745808            (haveD16 ? (1U<<31) : 0));
    746809    output.insert(output.end(), reinterpret_cast<cxbyte*>(words),
    747810            reinterpret_cast<cxbyte*>(words + 2));
     811    if (isGCN15 && !vaddrReg)
     812    {
     813        output.insert(output.end(), vaddrRegCodes, vaddrRegCodes+totalVaddrRegs-1);
     814        // alignment to dword
     815        output.insert(output.end(), (4 - ((totalVaddrRegs-1)&3))&3, cxbyte(0));
     816    }
    748817   
    749818    // update register pool (instr loads or save old value) */
  • CLRadeonExtender/trunk/amdasm/GCNAsmHelpers.cpp

    r4856 r4857  
    477477        parsedVgprs += rpair.end-rpair.start;
    478478        skipSpacesToEnd(linePtr, end);
    479         if (linePtr!=end && *linePtr==']' && parsedVgprs!=vgprsLimit)
    480         {
    481             char buf[60];
    482             snprintf(buf, 60, "VGPR register list requires %u registers", vgprsLimit);
    483             ASM_FAIL_BY_ERROR(curRangePlace, buf)
    484         }
     479        if (linePtr!=end && *linePtr==']')
     480        {
     481            skipCharAndSpacesToEnd(linePtr, end);
     482            break; // end of register list
     483        }
     484       
    485485        else if (linePtr!=end && *linePtr==',')
    486486        {
Note: See TracChangeset for help on using the changeset viewer.