Changeset 3083 in CLRX


Ignore:
Timestamp:
May 27, 2017, 5:04:47 PM (2 years ago)
Author:
matszpk
Message:

CLRadeonExtender: GCNAsm: Add SMEM specific encoding mode and instructions for AMD VEGA arch.

Location:
CLRadeonExtender/trunk
Files:
3 edited

Legend:

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

    r3082 r3083  
    6767    GCNTGT_SOPCIMM8,
    6868    GCNTGT_SMEMIMM,
    69     GCNTGT_SMEMIMM2 // RXVEGA first soffset
     69    GCNTGT_SMEMOFFSETVEGA,
     70    GCNTGT_SMEMOFFSET2 // RXVEGA first soffset
    7071};
    7172
  • CLRadeonExtender/trunk/amdasm/GCNAssembler.cpp

    r3082 r3083  
    12181218    RegRange soffsetReg(0, 0);
    12191219    uint32_t soffsetVal = 0;
    1220     cxbyte soffsetVal2 = 0;
     1220    uint32_t soffset2Val = 0;
    12211221    std::unique_ptr<AsmExpression> soffsetExpr;
    12221222    std::unique_ptr<AsmExpression> simm7Expr;
     
    12251225   
    12261226    const char* soffsetPlace = nullptr;
     1227    AsmSourcePos soffsetPos;
    12271228   
    12281229    if (mode1 == GCN_SMRD_ONLYDST)
     
    12681269            skipSpacesToEnd(linePtr, end);
    12691270            soffsetPlace = linePtr;
     1271            soffsetPos = asmr.getSourcePos(soffsetPlace);
    12701272            good &= parseImm(asmr, linePtr, soffsetVal, &soffsetExpr,
    12711273                // for VEGA we check range later
     
    12751277    bool haveGlc = false;
    12761278    bool haveNv = false;
     1279    bool haveOffset = false;
    12771280    // modifiers
    12781281    while (linePtr != end)
     
    12901293            else if ((arch & ARCH_RXVEGA)!=0 && ::strcmp(name, "nv")==0)
    12911294                haveNv = true;
    1292             else if (::strcmp(name, "offset")==0)
    1293             {
    1294                 /*if (parseModImm(asmr, linePtr, soffset2Val, &soffset2Expr, "offset",
    1295                         WS_UNSIGNED))
     1295            else if ((arch & ARCH_RXVEGA)!=0 && ::strcmp(name, "offset")==0)
     1296            {
     1297                if (parseModImm(asmr, linePtr, soffset2Val, &soffset2Expr, "offset",
     1298                        21, WS_UNSIGNED))
    12961299                {
    12971300                    if (haveOffset)
     
    13001303                }
    13011304                else
    1302                     good = false;*/
     1305                    good = false;
    13031306            }
    13041307            else
     
    13111314            good = false;
    13121315    }
     1316    // check range for offset
     1317    if ((arch & ARCH_RXVEGA)!=0)
     1318        asmr.printWarningForRange(haveOffset ? 8 : 21, soffsetVal,
     1319                    soffsetPos, WS_UNSIGNED);
     1320    if (haveOffset)
     1321    {   // swap (offset2 is first offset)
     1322        std::swap(soffsetVal, soffset2Val);
     1323        std::swap(soffsetExpr, soffset2Expr);
     1324    }
    13131325    /// if errors
    13141326    if (!good || !checkGarbagesAtEnd(asmr, linePtr))
     
    13161328   
    13171329    if (soffsetExpr!=nullptr)
    1318         soffsetExpr->setTarget(AsmExprTarget(GCNTGT_SMEMOFFSET, asmr.currentSection,
    1319                        output.size()));
     1330        soffsetExpr->setTarget(AsmExprTarget((arch & ARCH_RXVEGA) ?
     1331                    GCNTGT_SMEMOFFSETVEGA : GCNTGT_SMEMOFFSET,
     1332                    asmr.currentSection, output.size()));
     1333    if (soffset2Expr!=nullptr)
     1334        soffset2Expr->setTarget(AsmExprTarget(GCNTGT_SMEMOFFSET2,
     1335                    asmr.currentSection, output.size()));
    13201336    if (simm7Expr!=nullptr)
    13211337        simm7Expr->setTarget(AsmExprTarget(GCNTGT_SMEMIMM, asmr.currentSection,
     
    13511367    SLEV(words[0], 0xc0000000U | (uint32_t(gcnInsn.code1)<<18) | (dataReg.bstart()<<6) |
    13521368            (sbaseReg.bstart()>>1) | ((soffsetReg.isVal(255)) ? 0x20000 : 0) |
    1353             (haveGlc ? 0x10000 : 0) | (haveNv ? 0x8000 : 0));
     1369            (haveGlc ? 0x10000 : 0) | (haveNv ? 0x8000 : 0) | (haveOffset ? 0x4000 : 0));
    13541370    SLEV(words[1], ((soffsetReg.isVal(255)) ?
    1355                 (soffsetVal | (uint32_t(soffsetVal2)<<24)) : soffsetReg.bstart()));
     1371                (soffsetVal | (uint32_t(soffset2Val)<<24)) : soffsetReg.bstart()));
    13561372   
    13571373    output.insert(output.end(), reinterpret_cast<cxbyte*>(words),
     
    13591375    /// prevent freeing expression
    13601376    soffsetExpr.release();
     1377    soffset2Expr.release();
    13611378    simm7Expr.release();
    13621379    if (!dataReg.isRegVar() && dataToWrite)
     
    36703687            return true;
    36713688        case GCNTGT_SMEMOFFSET:
     3689        case GCNTGT_SMEMOFFSETVEGA:
    36723690            if (sectionId != ASMSECT_ABS)
    36733691            {
     
    36753693                return false;
    36763694            }
    3677             SULEV(*reinterpret_cast<uint32_t*>(sectionData+offset+4), value&0xfffffU);
    3678             printWarningForRange(20, value, sourcePos, WS_UNSIGNED);
     3695            if (targetType==GCNTGT_SMEMOFFSETVEGA)
     3696            {
     3697                uint32_t oldV = ULEV(*reinterpret_cast<uint32_t*>(sectionData+offset+4));
     3698                SULEV(*reinterpret_cast<uint32_t*>(sectionData+offset+4),
     3699                            (oldV & 0xffe00000U) | (value&0x1fffffU));
     3700            }
     3701            else
     3702                SULEV(*reinterpret_cast<uint32_t*>(sectionData+offset+4), value&0xfffffU);
     3703            printWarningForRange(targetType==GCNTGT_SMEMOFFSETVEGA ? 21 : 20,
     3704                                 value, sourcePos, WS_UNSIGNED);
     3705            return true;
     3706        case GCNTGT_SMEMOFFSET2:
     3707            if (sectionId != ASMSECT_ABS)
     3708            {
     3709                printError(sourcePos, "Relative value is illegal in offset expressions");
     3710                return false;
     3711            }
     3712            sectionData[offset+7] = value;
     3713            printWarningForRange(8, value, sourcePos, WS_UNSIGNED);
    36793714            return true;
    36803715        case GCNTGT_SMEMIMM:
  • CLRadeonExtender/trunk/tests/amdasm/GCNAsmOpc14.cpp

    r3081 r3083  
    199199    { "s_waitcnt       " "vmcnt(0) & expcnt(0) & lgkmcnt(0)\n",
    200200        0xbf8c0000U, 0, false, true, "" },
     201    /* SMEM encoding */
     202    { "s_load_dword    s50, s[58:59], s91\n", 0xc0000c9dU, 0x5b, true, true, "" },
     203    { "s_load_dword    s50, s[58:59], 0x5b\n", 0xc0020c9dU, 0x5b, true, true, "" },
     204    { "s_load_dword    s50, s[58:59], 0x13da5b\n", 0xc0020c9dU, 0x13da5b, true, true, "" },
     205    { "s_load_dword    s50, s[58:59], 0x5b nv\n", 0xc0028c9dU, 0x5b, true, true, "" },
     206    { "s_load_dword    s50, s[58:59], 0x5b nv glc\n", 0xc0038c9dU, 0x5b, true, true, "" },
     207    { "s_load_dword    s50, s[58:59], 0x32 offset:0x5b\n",
     208        0xc0024c9dU, 0x3200005b, true, true, "" },
     209    { "s_load_dword    s50, s[58:59], 0x32 offset:0x13da5b\n",
     210        0xc0024c9dU, 0x3213da5b, true, true, "" },
     211    { "s_load_dword    s50, s[58:59], zz\nzz=0x13da5b",
     212        0xc0020c9dU, 0x13da5b, true, true, "" },
     213    { "s_load_dword    s50, s[58:59], zz1 offset:zz2\nzz1=0x32\nzz2=0x13da5b",
     214        0xc0024c9dU, 0x3213da5b, true, true, "" },
     215    { "s_load_dword    s50, s[58:59], 0x32 offset:0x33da5b\n",
     216        0xc0024c9dU, 0x3213da5b, true, true,
     217        "test.s:1:44: Warning: Value 0x33da5b truncated to 0x13da5b\n" },
     218    { "s_load_dword    s50, s[58:59], zz1 offset:zz2\nzz1=0x132\nzz2=0x33da5b",
     219        0xc0024c9dU, 0x3213da5b, true, true,
     220        "test.s:1:32: Warning: Value 0x132 truncated to 0x32\n"
     221        "test.s:1:43: Warning: Value 0x33da5b truncated to 0x13da5b\n" },
     222    /* SMEM instructions */
     223    { "        s_atomic_swap s50, s[60:61], 0x5b\n", 0xc2020c9eU, 0x5b, true, true, "" },
     224    { "        s_atomic_cmpswap s[50:51], s[60:61], 0x5b\n",
     225        0xc2060c9eU, 0x5b, true, true, "" },
     226    { "        s_atomic_add s50, s[60:61], 0x5b\n", 0xc20a0c9eU, 0x5b, true, true, "" },
     227    { "        s_atomic_sub s50, s[60:61], 0x5b\n", 0xc20e0c9eU, 0x5b, true, true, "" },
     228    { "        s_atomic_smin s50, s[60:61], 0x5b\n", 0xc2120c9eU, 0x5b, true, true, "" },
     229    { "        s_atomic_umin s50, s[60:61], 0x5b\n", 0xc2160c9eU, 0x5b, true, true, "" },
     230    { "        s_atomic_smax s50, s[60:61], 0x5b\n", 0xc21a0c9eU, 0x5b, true, true, "" },
     231    { "        s_atomic_umax s50, s[60:61], 0x5b\n", 0xc21e0c9eU, 0x5b, true, true, "" },
     232    { "        s_atomic_and s50, s[60:61], 0x5b\n", 0xc2220c9eU, 0x5b, true, true, "" },
     233    { "        s_atomic_or s50, s[60:61], 0x5b\n", 0xc2260c9eU, 0x5b, true, true, "" },
     234    { "        s_atomic_xor s50, s[60:61], 0x5b\n", 0xc22a0c9eU, 0x5b, true, true, "" },
     235    { "        s_atomic_inc s50, s[60:61], 0x5b\n", 0xc22e0c9eU, 0x5b, true, true, "" },
     236    { "        s_atomic_dec s50, s[60:61], 0x5b\n", 0xc2320c9eU, 0x5b, true, true, "" },
     237    { "        s_atomic_swap_x2 s[50:51], s[60:61], 0x5b\n",
     238        0xc2820c9eU, 0x5b, true, true, "" },
     239    { "        s_atomic_cmpswap_x2 s[52:55], s[60:61], 0x5b\n",
     240        0xc2860d1eU, 0x5b, true, true, "" },
     241    { "        s_atomic_add_x2 s[50:51], s[60:61], 0x5b\n",
     242        0xc28a0c9eU, 0x5b, true, true, "" },
     243    { "        s_atomic_sub_x2 s[50:51], s[60:61], 0x5b\n",
     244        0xc28e0c9eU, 0x5b, true, true, "" },
     245    { "        s_atomic_smin_x2 s[50:51], s[60:61], 0x5b\n",
     246        0xc2920c9eU, 0x5b, true, true, "" },
     247    { "        s_atomic_umin_x2 s[50:51], s[60:61], 0x5b\n",
     248        0xc2960c9eU, 0x5b, true, true, "" },
     249    { "        s_atomic_smax_x2 s[50:51], s[60:61], 0x5b\n",
     250        0xc29a0c9eU, 0x5b, true, true, "" },
     251    { "        s_atomic_umax_x2 s[50:51], s[60:61], 0x5b\n",
     252        0xc29e0c9eU, 0x5b, true, true, "" },
     253    { "        s_atomic_and_x2 s[50:51], s[60:61], 0x5b\n",
     254        0xc2a20c9eU, 0x5b, true, true, "" },
     255    { "        s_atomic_or_x2 s[50:51], s[60:61], 0x5b\n",
     256        0xc2a60c9eU, 0x5b, true, true, "" },
     257    { "        s_atomic_xor_x2 s[50:51], s[60:61], 0x5b\n",
     258        0xc2aa0c9eU, 0x5b, true, true, "" },
     259    { "        s_atomic_inc_x2 s[50:51], s[60:61], 0x5b\n",
     260        0xc2ae0c9eU, 0x5b, true, true, "" },
     261    { "        s_atomic_dec_x2 s[50:51], s[60:61], 0x5b\n",
     262        0xc2b20c9eU, 0x5b, true, true, "" },
    201263    { nullptr, 0, 0, false, false, 0 }
    202264};
Note: See TracChangeset for help on using the changeset viewer.