Changeset 3631 in CLRX


Ignore:
Timestamp:
Jan 18, 2018, 6:28:41 PM (3 years ago)
Author:
matszpk
Message:

CLRadeonExtender: Asm: Tentative implementation of '.for' pseudo-op (repetition).

Location:
CLRadeonExtender/trunk
Files:
7 edited

Legend:

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

    r3629 r3631  
    257257    /// constructor
    258258    explicit AsmRepeat(const AsmSourcePos& pos, uint64_t repeatsNum);
     259    virtual ~AsmRepeat();
    259260   
    260261    /// adds line to repeat from source
     
    293294private:
    294295    void* iterSymEntry;
    295     std::unique_ptr<const AsmExpression> condExpr;
    296     std::unique_ptr<const AsmExpression> nextExpr;
     296    std::unique_ptr<AsmExpression> condExpr;
     297    std::unique_ptr<AsmExpression> nextExpr;
    297298public:
    298299    /// constructor
    299300    explicit AsmFor(const AsmSourcePos& pos, void* iterSymEntry,
    300             const AsmExpression* condExpr, const AsmExpression* nextExpr);
     301            AsmExpression* condExpr, AsmExpression* nextExpr);
     302   
     303    virtual ~AsmFor();
    301304   
    302305    /// get iteration symbol entry
  • CLRadeonExtender/trunk/amdasm/AsmExpression.cpp

    r3630 r3631  
    10471047    bool good = true;
    10481048    // try to resolve symbols
    1049     for (AsmExprOp op: ops)
     1049    for (AsmExprOp& op: newExpr->ops)
    10501050        if (AsmExpression::isArg(op))
    10511051        {
     
    10801080                        arg.relValue.value = symEntry->second.value;
    10811081                        newExpr->symOccursNum--;
     1082                        op = AsmExprOp::ARG_VALUE;
    10821083                    }
    10831084                }
     
    10861087        }
    10871088   
     1089    if (!good)
     1090        return nullptr;
    10881091    // add expression into symbol occurrences in expressions
    1089     for (size_t i = 0, j = 0; j < argsNum; i++)
    1090         if (newExpr->ops[i] == AsmExprOp::ARG_SYMBOL)
    1091         {
    1092             newExpr->args[j].symbol->second.addOccurrenceInExpr(newExpr.get(), j, i);
    1093             j++;
    1094         }
    1095         else if (newExpr->ops[i]==AsmExprOp::ARG_VALUE)
    1096             j++;
    1097    
    10981092    for (AsmSymbolEntry* symEntry: symbolSnapshots)
    10991093    {
  • CLRadeonExtender/trunk/amdasm/AsmInternals.h

    r3575 r3631  
    287287    static void doIRP(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr,
    288288                      bool perChar = false);
     289    // do 'for'
     290    static void doFor(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
    289291    // do open scope (.scope)
    290292    static void openScope(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr);
  • CLRadeonExtender/trunk/amdasm/AsmPseudoOps.cpp

    r3629 r3631  
    18821882}
    18831883
     1884void AsmPseudoOps::doFor(Assembler& asmr, const char* pseudoOpPlace, const char* linePtr)
     1885{
     1886    const char* end = asmr.line+asmr.lineSize;
     1887    skipSpacesToEnd(linePtr, end);
     1888    const char* symNamePlace = linePtr;
     1889    AsmSymbolEntry* iterSymbol = nullptr;
     1890    const CString symName = extractScopedSymName(linePtr, end, false);
     1891    if (symName.empty())
     1892        ASM_RETURN_BY_ERROR(symNamePlace, "Illegal symbol name")
     1893    size_t symNameLength = symName.size();
     1894    // special case for '.' symbol (check whether is in global scope)
     1895    if (symNameLength >= 3 && symName.compare(symNameLength-3, 3, "::.")==0)
     1896        ASM_RETURN_BY_ERROR(symNamePlace, "Symbol '.' can be only in global scope")
     1897   
     1898    bool good = true;
     1899    skipSpacesToEnd(linePtr, end);
     1900    if (linePtr==end || *linePtr!='=')
     1901        ASM_NOTGOOD_BY_ERROR(linePtr, "Expected '='")
     1902    skipCharAndSpacesToEnd(linePtr, end);
     1903    uint64_t value = 0;
     1904    cxuint sectionId = ASMSECT_ABS;
     1905    good &= AsmParseUtils::getAnyValueArg(asmr, value, sectionId, linePtr);
     1906    if (good)
     1907    {
     1908        std::pair<AsmSymbolEntry*, bool> res = asmr.insertSymbolInScope(symName,
     1909                    AsmSymbol(sectionId, value));
     1910        if (!res.second)
     1911        {
     1912            // if symbol found
     1913            if (res.first->second.onceDefined && res.first->second.isDefined()) // if label
     1914            {
     1915                asmr.printError(symNamePlace, (std::string("Symbol '")+symName.c_str()+
     1916                            "' is already defined").c_str());
     1917                good = false;
     1918            }
     1919            else // set value of symbol
     1920                asmr.setSymbol(*res.first, value, sectionId);
     1921        }
     1922        else // set hasValue (by isResolvableSection
     1923            res.first->second.hasValue = asmr.isResolvableSection(sectionId);
     1924        iterSymbol = res.first;
     1925    }
     1926   
     1927    if (!skipRequiredComma(asmr, linePtr))
     1928        return;
     1929    std::unique_ptr<AsmExpression> condExpr(AsmExpression::parse(asmr, linePtr, true));
     1930    if (!skipRequiredComma(asmr, linePtr))
     1931        return;
     1932    std::unique_ptr<AsmExpression> nextExpr(AsmExpression::parse(asmr, linePtr, true));
     1933   
     1934    if (!good || !checkGarbagesAtEnd(asmr, linePtr))
     1935        return;
     1936   
     1937    if (condExpr==nullptr || nextExpr==nullptr)
     1938        return; // if no expressions
     1939   
     1940    // check depth of repetitions
     1941    if (asmr.repetitionLevel == 1000)
     1942        PSEUDOOP_RETURN_BY_ERROR("Repetition level is greater than 1000")
     1943   
     1944    // create AsmFor
     1945    asmr.pushClause(pseudoOpPlace, AsmClauseType::REPEAT);
     1946    std::unique_ptr<AsmFor> repeat(new AsmFor(
     1947                asmr.getSourcePos(pseudoOpPlace), iterSymbol, condExpr.get(), nextExpr.get()));
     1948    condExpr.release();
     1949    nextExpr.release();
     1950    if (asmr.putRepetitionContent(*repeat))
     1951    {
     1952        // and input stream filter
     1953        std::unique_ptr<AsmInputFilter> newInputFilter(
     1954                    new AsmForInputFilter(repeat.release()));
     1955        asmr.asmInputFilters.push(newInputFilter.release());
     1956        asmr.currentInputFilter = asmr.asmInputFilters.top();
     1957        asmr.repetitionLevel++;
     1958    }
     1959}
     1960
    18841961void AsmPseudoOps::purgeMacro(Assembler& asmr, const char* linePtr)
    18851962{
     
    24502527            break;
    24512528        case ASMOP_FOR:
     2529            AsmPseudoOps::doFor(*this, stmtPlace, linePtr);
    24522530            break;
    24532531        case ASMOP_FORMAT:
  • CLRadeonExtender/trunk/amdasm/AsmSource.cpp

    r3630 r3631  
    9797{ }
    9898
     99AsmRepeat::~AsmRepeat()
     100{ }
     101
    99102// add line to repetition
    100103void AsmRepeat::addLine(RefPtr<const AsmMacroSubst> macro, RefPtr<const AsmSource> source,
     
    113116
    114117AsmFor::AsmFor(const AsmSourcePos& _pos, void* _iterSymEntry,
    115                 const AsmExpression* _condExpr, const AsmExpression* _nextExpr)
     118                AsmExpression* _condExpr, AsmExpression* _nextExpr)
    116119        : AsmRepeat(_pos, 0), iterSymEntry(_iterSymEntry), condExpr(_condExpr),
    117120                    nextExpr(_nextExpr)
     121{ }
     122
     123AsmFor::~AsmFor()
    118124{ }
    119125
     
    971977        uint64_t value = 0;
    972978        cxuint sectionId = ASMSECT_ABS;
    973         {
    974             std::unique_ptr<AsmExpression> condEvExpr(asmFor->getCondExpr()->
    975                         createExprToEvaluate(assembler));
    976             if (!condEvExpr->evaluate(assembler, value, sectionId) ||
    977                         sectionId != ASMSECT_ABS)
    978                 value = 0;
    979         }
     979        bool good = true;
    980980        {
    981981            std::unique_ptr<AsmExpression> nextEvExpr(asmFor->getNextExpr()->
     
    983983            uint64_t nextValue = 0;
    984984            cxuint nextSectionId = ASMSECT_ABS;
    985             if (nextEvExpr->evaluate(assembler, nextValue, nextSectionId) &&
     985            if (nextEvExpr != nullptr &&
     986                nextEvExpr->evaluate(assembler, nextValue, nextSectionId) &&
    986987                        nextSectionId == ASMSECT_ABS)
    987988                assembler.setSymbol(*(AsmSymbolEntry*)asmFor->getIterSymEntry(),
    988989                                    nextValue, ASMSECT_ABS);
    989990            else
     991                good = false;
     992        }
     993        if (good)
     994        {
     995            std::unique_ptr<AsmExpression> condEvExpr(asmFor->getCondExpr()->
     996                        createExprToEvaluate(assembler));
     997            if (condEvExpr==nullptr || !condEvExpr->evaluate(assembler, value, sectionId) ||
     998                        sectionId != ASMSECT_ABS)
    990999                value = 0;
    9911000        }
    9921001       
    993         if (value==0 || contentSize==0)
     1002        if (!good || value==0 || contentSize==0)
    9941003        {
    9951004            lineSize = 0;
  • CLRadeonExtender/trunk/doc/ClrxAsmPseudoOps.md

    r3572 r3631  
    299299assembler stores 0 and warn about no value.
    300300This pseudo-operation accepts only single precision floating point literals.
     301
     302### .for
     303
     304Syntax: .for SYMBOL=INITVALUE, COND-EXPR, NEXT-EXPR
     305
     306Open 'for' repetition. Before repetition, SYMBOL is initialized by INITVALUE.
     307For every repetition SYMBOL value will be replaced by value evaluted by NEXT-EXPR.
     308The code between this pseudo-operation and `.endr` will be repeated
     309until COND-EXPR returns zero. Example:
     310
     311```
     312.for x=1,x<16,x+x
     313    .int x
     314.endr
     315```
     316
     317generates:
     318
     319```
     320.int x      # x=1
     321.int x      # x=2
     322.int x      # x=4
     323.int x      # x=8
     324```
    301325
    302326### .format
  • CLRadeonExtender/trunk/tests/amdasm/AsmBasicsCases2.cpp

    r3575 r3631  
    19601960        }, true, "", ""
    19611961    },
     1962    /* 70 - '.for' repetition */
     1963    {
     1964        R"ffDXD(
     1965            .for  x = 1  ,  x<  16,  x+x
     1966                .int x
     1967            .endr
     1968)ffDXD",
     1969        BinaryFormat::AMD, GPUDeviceType::CAPE_VERDE, false, { },
     1970        { { nullptr, ASMKERN_GLOBAL, AsmSectionType::DATA,
     1971            {
     1972                0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
     1973                0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00
     1974            } } },
     1975        {
     1976            { ".", 16U, 0, 0U, true, false, false, 0, 0 },
     1977            { "x", 16U, ASMSECT_ABS, 0U, true, false, false, 0, 0 }
     1978        }, true, "", ""
     1979    },
     1980    /* 71 - '.for' repetition (error if x is onceDefined) */
     1981    {
     1982        R"ffDXD(
     1983            .equiv x, 0
     1984            .for  x = 1  ,  x<  16,  x+x
     1985                .int x
     1986            .endr
     1987)ffDXD",
     1988        BinaryFormat::AMD, GPUDeviceType::CAPE_VERDE, false, { },
     1989        { { nullptr, ASMKERN_GLOBAL, AsmSectionType::DATA,
     1990            {
     1991                0x00, 0x00, 0x00, 0x00
     1992            } } },
     1993        {
     1994            { ".", 4U, 0, 0U, true, false, false, 0, 0 },
     1995            { "x", 0U, ASMSECT_ABS, 0U, true, true, false, 0, 0 }
     1996        }, false, "test.s:3:19: Error: Symbol 'x' is already defined\n"
     1997            "test.s:5:13: Error: No '.rept' before '.endr'\n", ""
     1998    },
     1999    /* 72 - '.for' repetition (error due to undefined symbols) */
     2000    {
     2001        R"ffDXD(
     2002            .for  x = 1  ,  x<  16,  x+x+vv
     2003                .int x
     2004            .endr
     2005)ffDXD",
     2006        BinaryFormat::AMD, GPUDeviceType::CAPE_VERDE, false, { },
     2007        { { nullptr, ASMKERN_GLOBAL, AsmSectionType::DATA,
     2008            {
     2009                0x01, 0x00, 0x00, 0x00
     2010            } } },
     2011        {
     2012            { ".", 4U, 0, 0U, true, false, false, 0, 0 },
     2013            { "vv", 0U, ASMSECT_ABS, 0U, false, false, false, 0, 0 },
     2014            { "x", 1U, ASMSECT_ABS, 0U, true, false, false, 0, 0 }
     2015        }, false, "test.s:2:36: Error: Expression have unresolved symbol 'vv'\n", ""
     2016    },
     2017    /* 73 - '.for' repetition (error due to undefined symbols) */
     2018    {
     2019        R"ffDXD(
     2020            .for  x = 1  ,  x<  16+vv ,  x+x
     2021                .int x
     2022            .endr
     2023)ffDXD",
     2024        BinaryFormat::AMD, GPUDeviceType::CAPE_VERDE, false, { },
     2025        { { nullptr, ASMKERN_GLOBAL, AsmSectionType::DATA,
     2026            {
     2027                0x01, 0x00, 0x00, 0x00
     2028            } } },
     2029        {
     2030            { ".", 4U, 0, 0U, true, false, false, 0, 0 },
     2031            { "vv", 0U, ASMSECT_ABS, 0U, false, false, false, 0, 0 },
     2032            { "x", 2U, ASMSECT_ABS, 0U, true, false, false, 0, 0 }
     2033        }, false, "test.s:2:27: Error: Expression have unresolved symbol 'vv'\n", ""
     2034    },
     2035    /* 74 - '.for' repetition - with expr symbol */
     2036    {   R"ffDXD(
     2037        .eqv c,11+d
     2038        d=7
     2039        .for x =  1,x<16+c,x+x
     2040            .int x
     2041        .endr
     2042        .int c
     2043)ffDXD",
     2044        BinaryFormat::AMD, GPUDeviceType::CAPE_VERDE, false, { },
     2045        { { nullptr, ASMKERN_GLOBAL, AsmSectionType::DATA,
     2046            {
     2047                0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
     2048                0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
     2049                0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
     2050                0x12, 0x00, 0x00, 0x00
     2051            } } },
     2052        {
     2053            { ".", 28U, 0, 0U, true, false, false, 0, 0 },
     2054            { "c", 0U, ASMSECT_ABS, 0U, false, true, true, 0, 0 },
     2055            { "d", 7U, ASMSECT_ABS, 0U, true, false, false, 0, 0 },
     2056            { "x", 64U, ASMSECT_ABS, 0U, true, false, false, 0, 0 }
     2057        }, true, "", ""
     2058    },
    19622059    { nullptr }
    19632060};
Note: See TracChangeset for help on using the changeset viewer.