Changeset 3189 in CLRX


Ignore:
Timestamp:
Jun 24, 2017, 1:36:19 PM (22 months ago)
Author:
matszpk
Message:

CLRadeonExtender: GCNAsm: Add new alignment rule for SGPRs in vector instructions.

Location:
CLRadeonExtender/trunk
Files:
6 edited

Legend:

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

    r3111 r3189  
    241241            }
    242242            /// check aligned for scalar registers
    243             if ((flags & INSTROP_UNALIGNED) == 0 && rstart<maxSGPRsNum)
    244                 if ((rend-rstart==2 && (rstart&1)!=0) || (rend-rstart>2 && (rstart&3)!=0))
    245                 {
    246                     asmr.printError(regRangePlace, "Unaligned scalar register range");
    247                     return false;
    248                 }
     243            if (rstart<maxSGPRsNum)
     244            {
     245                if ((flags & INSTROP_UNALIGNED) == 0)
     246                {
     247                    if ((rend-rstart==2 && (rstart&1)!=0) ||
     248                        (rend-rstart>2 && (rstart&3)!=0))
     249                    {
     250                        asmr.printError(regRangePlace, "Unaligned scalar register range");
     251                        return false;
     252                    }
     253                }   
     254                else if ((flags & INSTROP_UNALIGNED) == INSTROP_SGPR_UNALIGNED)
     255                    if ((rstart & 0xfc) != ((rend-1) & 0xfc))
     256                    { // unaligned, but some restrictions
     257                        asmr.printError(regRangePlace,
     258                                "Scalar register range cross two register lines");
     259                        return false;
     260                    }
     261            }
    249262           
    250263            if (regField != ASMFIELD_NONE)
     
    694707        }
    695708        /// check alignment
    696         if (!ttmpReg && (flags & INSTROP_UNALIGNED)==0)
    697             if ((value2-value1==1 && (value1&1)!=0) || (value2-value1>1 && (value1&3)!=0))
    698             {
    699                 asmr.printError(sgprRangePlace, "Unaligned scalar register range");
    700                 return false;
    701             }
     709       
    702710        if (!ttmpReg)
    703711        {
     712            if ((flags & INSTROP_UNALIGNED)==0)
     713            {
     714                if ((value2-value1==1 && (value1&1)!=0) ||
     715                    (value2-value1>1 && (value1&3)!=0))
     716                {
     717                    asmr.printError(sgprRangePlace, "Unaligned scalar register range");
     718                    return false;
     719                }
     720            }
     721            else  if ((flags & INSTROP_UNALIGNED)==INSTROP_SGPR_UNALIGNED)
     722                if ((value1 & 0xfc) != ((value2) & 0xfc))
     723                { // unaligned, but some restrictions
     724                    asmr.printError(sgprRangePlace,
     725                            "Scalar register range cross two register lines");
     726                    return false;
     727                }
    704728            regPair = { value1, uint16_t(value2)+1 };
    705729            if (regField != ASMFIELD_NONE)
  • CLRadeonExtender/trunk/amdasm/GCNAsmInternals.h

    r3105 r3189  
    5353    INSTROP_F16 = 0x2000,   // half floating point literal
    5454    INSTROP_V64BIT = 0x3000, // 64-bit value (specific for vector instructions)
    55     INSTROP_UNALIGNED = 0x8000, // not aligned, use by parseRegisterRange
     55    INSTROP_UNALIGNED = 0xc000, // not aligned, use by parseRegisterRange
     56    INSTROP_ALIGNED = 0x0000,
     57    INSTROP_SGPR_UNALIGNED = 0x4000,
    5658   
    5759    INSTROP_READ = 0x10000,
  • CLRadeonExtender/trunk/amdasm/GCNAssembler.cpp

    r3120 r3189  
    14451445        good &= parseSRegRange(asmr, linePtr, dstReg, arch,
    14461446                       (gcnInsn.mode&GCN_REG_DST_64)?2:1, GCNFIELD_VOP_SDST, true,
    1447                        INSTROP_SYMREGRANGE|INSTROP_UNALIGNED|INSTROP_WRITE);
     1447                       INSTROP_SYMREGRANGE|INSTROP_SGPR_UNALIGNED|INSTROP_WRITE);
    14481448    else // if VGPRS as destination
    14491449    {
     
    14621462        gcnAsm->setCurrentRVU(1);
    14631463        good &= parseSRegRange(asmr, linePtr, dstCCReg, arch, 2, GCNFIELD_VOP3_SDST1, true,
    1464                                INSTROP_SYMREGRANGE|INSTROP_UNALIGNED|INSTROP_WRITE);
     1464                               INSTROP_SYMREGRANGE|INSTROP_SGPR_UNALIGNED|INSTROP_WRITE);
    14651465    }
    14661466   
     
    14781478    good &= parseOperand(asmr, linePtr, src0Op, &src0OpExpr, arch, regsNum,
    14791479            correctOpType(regsNum, literalConstsFlags) | vopOpModFlags |
    1480             INSTROP_UNALIGNED|INSTROP_VREGS|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_LDS|
     1480            INSTROP_SGPR_UNALIGNED|INSTROP_VREGS|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_LDS|
    14811481            INSTROP_READ, GCNFIELD_VOP_SRC0);
    14821482   
     
    15001500            correctOpType(regsNum, literalConstsFlags) | vopOpModFlags |
    15011501            (!sgprRegInSrc1 ? INSTROP_VREGS : 0)|INSTROP_SSOURCE|INSTROP_SREGS|
    1502             INSTROP_UNALIGNED | (src0Op.range.start==255 ? INSTROP_ONLYINLINECONSTS : 0)|
     1502            INSTROP_SGPR_UNALIGNED |
     1503            (src0Op.range.start==255 ? INSTROP_ONLYINLINECONSTS : 0)|
    15031504            INSTROP_READ, (!sgprRegInSrc1) ? GCNFIELD_VOP_VSRC1 : GCNFIELD_VOP_SSRC1);
    15041505   
     
    17631764            good &= parseSRegRange(asmr, linePtr, dstReg, arch,
    17641765                           (gcnInsn.mode&GCN_REG_DST_64)?2:1, GCNFIELD_VOP_SDST, true,
    1765                            INSTROP_SYMREGRANGE|INSTROP_UNALIGNED|INSTROP_WRITE);
     1766                           INSTROP_SYMREGRANGE|INSTROP_SGPR_UNALIGNED|INSTROP_WRITE);
    17661767        else // if VGPRS as destination
    17671768            good &= parseVRegRange(asmr, linePtr, dstReg,
     
    17781779        good &= parseOperand(asmr, linePtr, src0Op, &src0OpExpr, arch, regsNum,
    17791780                    correctOpType(regsNum, literalConstsFlags)|INSTROP_VREGS|
    1780                     INSTROP_UNALIGNED|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_LDS|
     1781                    INSTROP_SGPR_UNALIGNED|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_LDS|
    17811782                    INSTROP_VOP3MODS|INSTROP_READ, GCNFIELD_VOP_SRC0);
    17821783    }
     
    19331934    gcnAsm->setCurrentRVU(0);
    19341935    good &= parseSRegRange(asmr, linePtr, dstReg, arch, 2, GCNFIELD_VOP3_SDST0, true,
    1935                            INSTROP_SYMREGRANGE|INSTROP_UNALIGNED|INSTROP_WRITE);
     1936                           INSTROP_SYMREGRANGE|INSTROP_SGPR_UNALIGNED|INSTROP_WRITE);
    19361937    if (!skipRequiredComma(asmr, linePtr))
    19371938        return false;
     
    19431944    good &= parseOperand(asmr, linePtr, src0Op, &src0OpExpr, arch, regsNum,
    19441945                    correctOpType(regsNum, literalConstsFlags)|INSTROP_VREGS|
    1945                     INSTROP_UNALIGNED|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_LDS|
     1946                    INSTROP_SGPR_UNALIGNED|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_LDS|
    19461947                    INSTROP_VOP3MODS|INSTROP_READ, GCNFIELD_VOP_SRC0);
    19471948   
     
    19521953    good &= parseOperand(asmr, linePtr, src1Op, &src1OpExpr, arch, regsNum,
    19531954                correctOpType(regsNum, literalConstsFlags) | INSTROP_VOP3MODS|
    1954                 INSTROP_UNALIGNED|INSTROP_VREGS|INSTROP_SSOURCE|INSTROP_SREGS|
     1955                INSTROP_SGPR_UNALIGNED|INSTROP_VREGS|INSTROP_SSOURCE|INSTROP_SREGS|
    19551956                INSTROP_READ| (src0Op.range.isVal(255) ? INSTROP_ONLYINLINECONSTS : 0),
    19561957                GCNFIELD_VOP_VSRC1);
     
    21652166            good &= parseSRegRange(asmr, linePtr, dstReg, arch,
    21662167                       (gcnInsn.mode&GCN_REG_DST_64)?2:1, GCNFIELD_VOP3_SDST0, true,
    2167                        INSTROP_SYMREGRANGE|INSTROP_UNALIGNED|INSTROP_WRITE);
     2168                       INSTROP_SYMREGRANGE|INSTROP_SGPR_UNALIGNED|INSTROP_WRITE);
    21682169        if (!skipRequiredComma(asmr, linePtr))
    21692170            return false;
     
    21752176            gcnAsm->setCurrentRVU(1);
    21762177            good &= parseSRegRange(asmr, linePtr, sdstReg, arch, 2, GCNFIELD_VOP3_SDST1,
    2177                        true, INSTROP_SYMREGRANGE|INSTROP_WRITE|INSTROP_UNALIGNED);
     2178                       true, INSTROP_SYMREGRANGE|INSTROP_WRITE|INSTROP_SGPR_UNALIGNED);
    21782179            if (!skipRequiredComma(asmr, linePtr))
    21792180                return false;
     
    21892190            good &= parseOperand(asmr, linePtr, src0Op, nullptr, arch, regsNum,
    21902191                    correctOpType(regsNum, literalConstsFlags)|INSTROP_VREGS|
    2191                     INSTROP_UNALIGNED|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_LDS|vop3Mods|
    2192                     INSTROP_ONLYINLINECONSTS|INSTROP_NOLITERALERROR|INSTROP_READ,
     2192                    INSTROP_SGPR_UNALIGNED|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_LDS|
     2193                    vop3Mods|INSTROP_ONLYINLINECONSTS|INSTROP_NOLITERALERROR|INSTROP_READ,
    21932194                    GCNFIELD_VOP3_SRC0);
    21942195            operands++;
     
    22182219                gcnAsm->setCurrentRVU(4);
    22192220                good &= parseOperand(asmr, linePtr, src2Op, nullptr, arch,
    2220                     (gcnInsn.mode&GCN_REG_SRC2_64)?2:1, INSTROP_UNALIGNED|INSTROP_VREGS|
    2221                     INSTROP_SREGS|INSTROP_READ, GCNFIELD_VOP3_SRC2);
     2221                    (gcnInsn.mode&GCN_REG_SRC2_64)?2:1, INSTROP_SGPR_UNALIGNED|
     2222                    INSTROP_VREGS|INSTROP_SREGS|INSTROP_READ, GCNFIELD_VOP3_SRC2);
    22222223            }
    22232224            // high and vop3
     
    22792280            good &= parseOperand(asmr, linePtr, src1Op, nullptr, arch, regsNum,
    22802281                    correctOpType(regsNum, literalConstsFlags)|INSTROP_VREGS|
    2281                     INSTROP_UNALIGNED|INSTROP_SSOURCE|INSTROP_SREGS|vop3Mods|
     2282                    INSTROP_SGPR_UNALIGNED|INSTROP_SSOURCE|INSTROP_SREGS|vop3Mods|
    22822283                    INSTROP_ONLYINLINECONSTS|INSTROP_NOLITERALERROR|INSTROP_READ,
    22832284                    GCNFIELD_VOP3_SRC1);
     
    22922293                good &= parseOperand(asmr, linePtr, src2Op, nullptr, arch,
    22932294                        is128Ops ? 4 : regsNum,
    2294                         correctOpType(regsNum, literalConstsFlags)|INSTROP_UNALIGNED|
     2295                        correctOpType(regsNum, literalConstsFlags)|INSTROP_SGPR_UNALIGNED|
    22952296                        INSTROP_VREGS|INSTROP_SSOURCE|INSTROP_SREGS|INSTROP_READ|
    22962297                        vop3Mods|INSTROP_ONLYINLINECONSTS|INSTROP_NOLITERALERROR,
  • CLRadeonExtender/trunk/doc/GcnOperands.md

    r3143 r3189  
    55
    66**Important**: Two SGPR's must be aligned to 2. Four or more SGPR's must be aligned to 4.
     7This rule do not apply to vector instruction where is more complex rule:
     8SGPR's can be unaligned only if SGPR register range do not cross line (4 SGPR registers).
    79
    810Following list describes all operand codes values:
  • CLRadeonExtender/trunk/tests/amdasm/GCNAsmOpc11.cpp

    r3098 r3189  
    796796    { "    v_sub_u32  v55, s[10:11], s27, -v90",
    797797        0xd24c0a37U, 0x4002b41bU, true, true, "" },
    798     { "    v_sub_i32  v55, s[11:12], s27, -v90",
    799         0xd24c0b37U, 0x4002b41bU, true, true, "" },
     798    { "    v_sub_i32  v55, s[13:14], s27, -v90",
     799        0xd24c0d37U, 0x4002b41bU, true, true, "" },
    800800    { "    v_subrev_i32  v154, vcc, v21, v107", 0x4f34d715U, 0, false, true, "" },
    801801    { "    v_subrev_i32  v55, s[10:11], s27, -v90",
     
    956956    { "    v_rsq_f32  v55, v27 vop3", 0xd35c0037U, 0x0000011bU, true, true, "" },
    957957    { "    v_rcp_f64  v[158:159], v[79:80]", 0x7f3c5f4fU, 0, false, true, "" },
    958     { "    v_rcp_f64  v[158:159], s[79:80]", 0x7f3c5e4fU, 0, false, true, "" },
     958    { "    v_rcp_f64  v[158:159], s[81:82]", 0x7f3c5e51U, 0, false, true, "" },
    959959    { "    v_rcp_f64  v[55:56], v[27:28] vop3", 0xd35e0037U, 0x0000011bU, true, true, "" },
    960960    { "    v_rcp_clamp_f64  v[158:159], v[79:80]", 0x7f3c614fU, 0, false, true, "" },
     
    17101710        "test.s:1:29: Error: Required 2 vector registers\n"
    17111711        "test.s:1:37: Error: Required 2 vector registers\n" },
    1712     { "   v_fma_f64  v[55:56], s[79:80], v[166:167], s[29:30]", 0, 0, false, false,
     1712    { "   v_fma_f64  v[55:56], s[77:78], v[166:167], s[30:31]", 0, 0, false, false,
    17131713        "test.s:1:4: Error: More than one SGPR to read in instruction\n" },
    17141714    { "   v_div_scale_f32  v55, s[36:37], v79, v166, v79 clamp", 0, 0, false, false,
     
    17661766    { "   v_mul_f64  v[55:56], v[79:80], v[166:167]",
    17671767        0xd2ca0037U, 0x00034d4fU, true, true, "" },
     1768    // sgpr alignment check
     1769    { "   v_mul_f64  v[55:56], s[79:80], v[166:167]", 0, 0, false, false,
     1770        "test.s:1:25: Error: Scalar register range cross two register lines\n" },
     1771    { "z=%s[70:89] ;v_mul_f64  v[55:56], z[9:10], v[166:167]", 0, 0, false, false,
     1772        "test.s:1:35: Error: Scalar register range cross two register lines\n" },
     1773    { "   v_mul_f64  v[55:56], s[77:78], v[166:167]",
     1774        0xd2ca0037U, 0x00034c4dU, true, true, "" },
    17681775    { "   v_min_f64  v[55:56], v[79:80], v[166:167]",
    17691776        0xd2cc0037U, 0x00034d4fU, true, true, "" },
     
    17781785    { "   v_div_scale_f32  v55, s[38:39], v79, v166, v79",
    17791786        0xd2da2637U, 0x053f4d4fU, true, true, "" },
    1780     { "   v_div_scale_f32  v55, s[39:40], v79, v166, v79",
    1781         0xd2da2737U, 0x053f4d4fU, true, true, "" },
     1787    { "   v_div_scale_f32  v55, s[37:38], v79, v166, v79",
     1788        0xd2da2537U, 0x053f4d4fU, true, true, "" },
    17821789    { "   v_div_scale_f32  v55, s[38:39], v79, v79, v229",
    17831790        0xd2da2637U, 0x07969f4fU, true, true, "" },
     
    29232930    { "    v_mqsad_u32_u8  v[55:58], v[79:80], v166, v[229:232]",
    29242931        0xd2ea0037U, 0x07974d4fU, true, true, "" },
    2925     { "    v_mqsad_u32_u8  v[55:58], v[79:80], v166, s[29:32]",
    2926         0xd2ea0037U, 0x00774d4fU, true, true, "" },
     2932    { "    v_mqsad_u32_u8  v[55:58], v[79:80], v166, s[28:31]",
     2933        0xd2ea0037U, 0x00734d4fU, true, true, "" },
    29272934    { "    v_mad_u64_u32  v[55:56], s[46:47], v79, v166, v[229:230]",
    29282935        0xd2ec2e37U, 0x07974d4fU, true, true, "" },
  • CLRadeonExtender/trunk/tests/amdasm/GCNRegVarUsage.cpp

    r3120 r3189  
    510510        "v_cvt_f32_i32 v51, s19\n"
    511511        "v_rcp_f64 v[72:73], v[27:28]\n"
    512         "v_rcp_f64 v[72:73], s[27:28]\n"
     512        "v_rcp_f64 v[72:73], s[26:27]\n"
    513513        "v_readfirstlane_b32 s35, v91\n"
    514514        "v_rcp_f64 v[55:56], v[87:88] vop3\n"
     
    559559            // v_rcp_f64 v[72:73], s[27:28]
    560560            { 80, nullptr, 256+72, 256+74, GCNFIELD_VOP_VDST, ASMRVU_WRITE, 0 },
    561             { 80, nullptr, 27, 29, GCNFIELD_VOP_SRC0, ASMRVU_READ, 0 },
     561            { 80, nullptr, 26, 28, GCNFIELD_VOP_SRC0, ASMRVU_READ, 0 },
    562562            // v_readfirstlane_b32 s35, v91
    563563            { 84, nullptr, 35, 36, GCNFIELD_VOP_SDST, ASMRVU_WRITE, 0 },
     
    641641        "v_mad_f32 v67, v83, s43, v91\n"
    642642        "v_mad_f32 v67, v83, v43, s91\n"
    643         "v_fma_f64 v[153:154], v[73:74], s[83:84], v[17:18]\n"
     643        "v_fma_f64 v[153:154], v[73:74], s[82:83], v[17:18]\n"
    644644        "v_div_scale_f32 v184, s[93:94], v53, v14, v89\n",
    645645        {
     
    716716            { 112, nullptr, 256+153, 256+155, GCNFIELD_VOP3_VDST, ASMRVU_WRITE, 0 },
    717717            { 112, nullptr, 256+73, 256+75, GCNFIELD_VOP3_SRC0, ASMRVU_READ, 0 },
    718             { 112, nullptr, 83, 85, GCNFIELD_VOP3_SRC1, ASMRVU_READ, 0 },
     718            { 112, nullptr, 82, 84, GCNFIELD_VOP3_SRC1, ASMRVU_READ, 0 },
    719719            { 112, nullptr, 256+17, 256+19, GCNFIELD_VOP3_SRC2, ASMRVU_READ, 0 },
    720720            // v_div_scale_f32 v184, s[93:94], v53, v14, v89
Note: See TracChangeset for help on using the changeset viewer.