Changeset 4993 in CLRX


Ignore:
Timestamp:
Sep 24, 2019, 2:41:30 PM (3 weeks ago)
Author:
matszpk
Message:

CLRadeonExtender: GCNAsm: Allow shortened form of FLAT/GLOBAL atomics with 2 operands (addr and data).

Location:
CLRadeonExtender/trunk
Files:
5 edited

Legend:

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

    r4968 r4993  
    319319   
    320320    void setRegVarUsage(const AsmRegVarUsage& rvu);
     321   
     322    void moveRVUToNext(cxbyte index);
     323    void setRVUFieldAndRWFlags(cxbyte index, AsmRegField rfield, cxbyte rwFlags);
    321324   
    322325    void flushInstrRVUs(ISAUsageHandler* usageHandler)
  • CLRadeonExtender/trunk/amdasm/GCNAsmEncode2.cpp

    r4869 r4993  
    10101010    const char* vdstPlace = nullptr;
    10111011   
     1012    bool vdstOff = false; // for shortened for for ATOMICS
    10121013    bool vaddrOff = false;
    10131014    const cxuint dregsNum = ((gcnInsn.mode&GCN_DSIZE_MASK)>>GCN_SHIFT2)+1;
     
    10161017                (flatMode==GCN_FLAT_FLAT ? 2 : 0)  : 1);
    10171018    const char* addrPlace = nullptr;
     1019   
     1020    const bool atomic = (gcnInsn.mode & GCN_MATOMIC)!=0;
     1021   
    10181022    if ((gcnInsn.mode & GCN_FLAT_ADST) == 0)
    10191023    {
    10201024        // first is destination
    10211025        vdstPlace = linePtr;
    1022        
    1023         gcnAsm->setCurrentRVU(0);
    1024         good &= parseVRegRange(asmr, linePtr, vdstReg, 0, GCNFIELD_FLAT_VDST, true,
    1025                         INSTROP_SYMREGRANGE|INSTROP_WRITE);
     1026        if (atomic && flatMode == GCN_FLAT_SCRATCH && linePtr+3<=end &&
     1027            strncasecmp(linePtr, "off", 3)==0 && (linePtr+3==end || !isAlnum(linePtr[3])))
     1028        {
     1029            // // if 'off' word
     1030            vdstOff = true;
     1031            linePtr+=3;
     1032        }
     1033        else
     1034        {
     1035            gcnAsm->setCurrentRVU(0);
     1036            good &= parseVRegRange(asmr, linePtr, vdstReg, 0, GCNFIELD_FLAT_VDST, true,
     1037                            INSTROP_SYMREGRANGE|INSTROP_WRITE);
     1038        }
    10261039        if (!skipRequiredComma(asmr, linePtr))
    10271040            return false;
     
    10391052            gcnAsm->setCurrentRVU(1);
    10401053            // parse VADDR (1 or 2 VGPR's)
    1041             good &= parseVRegRange(asmr, linePtr, vaddrReg, addrRegsNum,
    1042                     GCNFIELD_FLAT_ADDR, true, INSTROP_SYMREGRANGE|INSTROP_READ);
     1054            if (!atomic)
     1055                good &= parseVRegRange(asmr, linePtr, vaddrReg, addrRegsNum,
     1056                        GCNFIELD_FLAT_ADDR, true, INSTROP_SYMREGRANGE|INSTROP_READ);
     1057            else
     1058                // we don't know whether is
     1059                good &= parseVRegRange(asmr, linePtr, vaddrReg, 0,
     1060                        GCNFIELD_FLAT_ADDR, true, INSTROP_SYMREGRANGE|INSTROP_READ);
    10431061        }
    10441062    }
     
    10751093    }
    10761094   
     1095    bool moveRVUNext = false;
     1096   
    10771097    if ((gcnInsn.mode & GCN_FLAT_NODATA) == 0) /* print data */
    10781098    {
    1079         if (!skipRequiredComma(asmr, linePtr))
    1080             return false;
    1081         gcnAsm->setCurrentRVU(2);
    1082         // parse VDATA (VGPRS, 1-4 registers)
    1083         good &= parseVRegRange(asmr, linePtr, vdataReg, dregsNum, GCNFIELD_FLAT_DATA,
    1084                                true, INSTROP_SYMREGRANGE|INSTROP_READ);
     1099        if (!atomic)
     1100        {
     1101            if (!skipRequiredComma(asmr, linePtr))
     1102                return false;
     1103            gcnAsm->setCurrentRVU(2);
     1104            // parse VDATA (VGPRS, 1-4 registers)
     1105            good &= parseVRegRange(asmr, linePtr, vdataReg, dregsNum, GCNFIELD_FLAT_DATA,
     1106                                true, INSTROP_SYMREGRANGE|INSTROP_READ);
     1107        }
     1108        else if (flatMode != 0)
     1109        {
     1110            const char* oldLinePtr = linePtr;
     1111            if (!skipRequiredComma(asmr, linePtr))
     1112                return false;
     1113            gcnAsm->setCurrentRVU(2);
     1114            good &= parseVRegRange(asmr, linePtr, vdataReg, dregsNum, GCNFIELD_FLAT_DATA,
     1115                                false, INSTROP_SYMREGRANGE|INSTROP_READ);
     1116            if (!vdataReg)
     1117            {
     1118                // this is shorten version
     1119                linePtr = oldLinePtr;
     1120                moveRVUNext = true;
     1121            }
     1122        }
     1123        else
     1124        {
     1125            bool haveComma = false;
     1126            if (!skipComma(asmr, haveComma, linePtr, false))
     1127                return false;
     1128            if (!haveComma)
     1129                // this is shorten version
     1130                moveRVUNext = true;
     1131            else
     1132            {
     1133                gcnAsm->setCurrentRVU(2);
     1134                good &= parseVRegRange(asmr, linePtr, vdataReg, dregsNum, GCNFIELD_FLAT_DATA,
     1135                                true, INSTROP_SYMREGRANGE|INSTROP_READ);
     1136            }
     1137        }
     1138    }
     1139   
     1140    if (moveRVUNext)
     1141    {
     1142        // shorten version for atomic
     1143        gcnAsm->moveRVUToNext(1);
     1144        gcnAsm->moveRVUToNext(0);
     1145        gcnAsm->setRVUFieldAndRWFlags(2, GCNFIELD_FLAT_DATA, ASMRVU_READ);
     1146        gcnAsm->setRVUFieldAndRWFlags(1, GCNFIELD_FLAT_ADDR, ASMRVU_READ);
     1147        vaddrOff = vdstOff;
     1148        vdstOff = false;
     1149        vdataReg = vaddrReg;
     1150        vaddrReg = vdstReg;
     1151        vdstReg = RegRange(0, 0);
     1152        // checking register number
     1153        if (addrRegsNum!=0 && !isXRegRange(vaddrReg, addrRegsNum))
     1154        {
     1155            char errorMsg[40];
     1156            snprintf(errorMsg, 40, "Required %u vector register%s", addrRegsNum,
     1157                     (addrRegsNum>1) ? "s" : "");
     1158            ASM_NOTGOOD_BY_ERROR(vdstPlace, errorMsg)
     1159        }
     1160        if (!isXRegRange(vdataReg, dregsNum))
     1161        {
     1162            char errorMsg[40];
     1163            snprintf(errorMsg, 40, "Required %u vector register%s", dregsNum,
     1164                     (dregsNum>1) ? "s" : "");
     1165            ASM_NOTGOOD_BY_ERROR(addrPlace, errorMsg)
     1166        }
    10851167    }
    10861168   
     
    11911273            ASM_NOTGOOD_BY_ERROR(modPlace, "Unknown FLAT modifier")
    11921274    }
     1275   
     1276    if (vdstOff)
     1277        ASM_NOTGOOD_BY_ERROR(instrPlace, "OFF in VDST field is illegal")
     1278   
     1279    if (moveRVUNext && haveGlc)
     1280        ASM_NOTGOOD_BY_ERROR(instrPlace, "GLC modifier requires VDST field")
     1281   
    11931282    /* check register ranges */
    11941283    bool dstToWrite = vdstReg && ((gcnInsn.mode & GCN_MATOMIC)==0 || haveGlc);
  • CLRadeonExtender/trunk/amdasm/GCNAssembler.cpp

    r4968 r4993  
    176176        isSpecialSGPRRegister(curArchMask, rvu.rstart))
    177177        instrRVUs[currentRVUIndex] = rvu;
     178}
     179
     180void GCNAssembler::moveRVUToNext(cxbyte index)
     181{
     182    instrRVUs[index+1] = instrRVUs[index];
     183    instrRVUs[index] = AsmRegVarUsage{};
     184}
     185
     186void GCNAssembler::setRVUFieldAndRWFlags(cxbyte index, AsmRegField rfield, cxbyte rwFlags)
     187{
     188    instrRVUs[index].regField = rfield;
     189    instrRVUs[index].rwFlags = (instrRVUs[index].rwFlags & ~ASMRVU_ACCESS_MASK) | rwFlags;
    178190}
    179191
  • CLRadeonExtender/trunk/tests/amdasm/GCNAsmOpc11.cpp

    r4862 r4993  
    31173117        0xdcc70000U, 0x2f0041bbU, true, true, "" },
    31183118    { "flat_atomic_add v47, v[187:188], v65", 0xdcc80000U, 0x2f0041bbU, true, true, "" },
     3119    { "flat_atomic_add v[187:188], v65", 0xdcc80000U, 0x000041bbU, true, true, "" },
     3120    { "flat_atomic_add v[187:188], v65 slc", 0xdcca0000U, 0x000041bbU, true, true, "" },
     3121    { "flat_atomic_add v[187:188], v65 glc", 0, 0, false, false,
     3122        "test.s:1:1: Error: GLC modifier requires VDST field\n" },
    31193123    { "flat_atomic_sub v47, v[187:188], v65", 0xdccc0000U, 0x2f0041bbU, true, true, "" },
    31203124    { "flat_atomic_smin v47, v[187:188], v65", 0xdcd40000U, 0x2f0041bbU, true, true, "" },
  • CLRadeonExtender/trunk/tests/amdasm/GCNAsmOpc14.cpp

    r4845 r4993  
    917917    { "global_atomic_add v47, v187, v65, s[50:51] glc slc\n",
    918918        0xdd0b8000U, 0x2f3241bbU, true, true, "" },
     919    { "global_atomic_add v187, v65, s[50:51] slc\n",
     920        0xdd0a8000U, 0x003241bbU, true, true, "" }, // no dst
    919921    { "global_atomic_sub v47, v187, v65, s[50:51] glc slc\n",
    920922        0xdd0f8000U, 0x2f3241bbU, true, true, "" },
Note: See TracChangeset for help on using the changeset viewer.