source: CLRX/CLRadeonExtender/trunk/amdasm/AsmFormats.cpp @ 3575

Last change on this file since 3575 was 3575, checked in by matszpk, 20 months ago

CLRadeonExtender: Change Copyright dates.

File size: 7.4 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2018 Mateusz Szpakowski
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2.1 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#include <CLRX/Config.h>
21#include <cstring>
22#include <string>
23#include <vector>
24#include <utility>
25#include <algorithm>
26#include <CLRX/utils/Utilities.h>
27#include <CLRX/amdasm/Assembler.h>
28#include "AsmInternals.h"
29
30using namespace CLRX;
31
32AsmFormatException::AsmFormatException(const std::string& message) : Exception(message)
33{ }
34
35// common routine to initialize AMD HSA config (used by AMDCL2, Gallium and ROCm handlers)
36void AsmAmdHsaKernelConfig::initialize()
37{
38    // set default values to kernel config
39    ::memset(this, 0xff, 128);
40    ::memset(controlDirective, 0, 128);
41    computePgmRsrc1 = computePgmRsrc2 = 0;
42    enableSgprRegisterFlags = 0;
43    enableFeatureFlags = 0;
44    reserved1[0] = reserved1[1] = reserved1[2] = 0;
45    dimMask = 0;
46    usedVGPRsNum = BINGEN_DEFAULT;
47    usedSGPRsNum = BINGEN_DEFAULT;
48    userDataNum = BINGEN8_DEFAULT;
49    ieeeMode = false;
50    floatMode = 0xc0;
51    priority = 0;
52    exceptions = 0;
53    tgSize = false;
54    debugMode = false;
55    privilegedMode = false;
56    dx10Clamp = false;
57}
58
59AsmFormatHandler::AsmFormatHandler(Assembler& _assembler) : assembler(_assembler)
60{ }
61
62AsmFormatHandler::~AsmFormatHandler()
63{ }
64
65void AsmFormatHandler::handleLabel(const CString& label)
66{ }
67
68bool AsmFormatHandler::resolveSymbol(const AsmSymbol& symbol, uint64_t& value,
69                 cxuint& sectionId)
70{
71    return false;
72}
73
74bool AsmFormatHandler::resolveRelocation(const AsmExpression* expr, uint64_t& value,
75                 cxuint& sectionId)
76{
77    return false;
78}
79
80bool AsmFormatHandler::resolveLoHiRelocExpression(const AsmExpression* expr,
81                RelocType& relType, cxuint& relSectionId, uint64_t& relValue)
82{
83    const AsmExprTarget& target = expr->getTarget();
84    const AsmExprTargetType tgtType = target.type;
85    if ((tgtType!=ASMXTGT_DATA32 &&
86        !assembler.isaAssembler->relocationIsFit(32, tgtType)))
87    {
88        assembler.printError(expr->getSourcePos(),
89                        "Can't resolve expression for non 32-bit integer");
90        return false;
91    }
92    if (target.sectionId==ASMSECT_ABS ||
93        assembler.sections[target.sectionId].type!=AsmSectionType::CODE)
94    {
95        assembler.printError(expr->getSourcePos(), "Can't resolve expression outside "
96                "code section");
97        return false;
98    }
99    const Array<AsmExprOp>& ops = expr->getOps();
100   
101    size_t relOpStart = 0;
102    size_t relOpEnd = ops.size();
103    relType = RELTYPE_LOW_32BIT;
104    // checking what is expression
105    // get () OP () - operator between two parts
106    AsmExprOp lastOp = ops.back();
107    if (lastOp==AsmExprOp::BIT_AND || lastOp==AsmExprOp::MODULO ||
108        lastOp==AsmExprOp::SIGNED_MODULO || lastOp==AsmExprOp::DIVISION ||
109        lastOp==AsmExprOp::SIGNED_DIVISION || lastOp==AsmExprOp::SHIFT_RIGHT)
110    {
111        // check low or high relocation
112        relOpStart = 0;
113        relOpEnd = expr->toTop(ops.size()-2);
114        /// evaluate second argument
115        cxuint tmpSectionId;
116        uint64_t secondArg;
117        if (!expr->evaluate(assembler, relOpEnd, ops.size()-1, secondArg, tmpSectionId))
118            return false;
119        if (tmpSectionId!=ASMSECT_ABS)
120        {
121            // must be absolute
122            assembler.printError(expr->getSourcePos(),
123                        "Second argument for relocation operand must be absolute");
124            return false;
125        }
126        bool good = true;
127        switch (lastOp)
128        {
129            case AsmExprOp::BIT_AND:
130                // handle (x&0xffffffff)
131                relType = RELTYPE_LOW_32BIT;
132                good = ((secondArg & 0xffffffffULL) == 0xffffffffULL);
133                break;
134            case AsmExprOp::MODULO:
135            case AsmExprOp::SIGNED_MODULO:
136                // handle (x%0x100000000)
137                relType = RELTYPE_LOW_32BIT;
138                good = ((secondArg>>32)!=0 && (secondArg & 0xffffffffULL) == 0);
139                break;
140            case AsmExprOp::DIVISION:
141            case AsmExprOp::SIGNED_DIVISION:
142                // handle (x/0x100000000)
143                relType = RELTYPE_HIGH_32BIT;
144                good = (secondArg == 0x100000000ULL);
145                break;
146            case AsmExprOp::SHIFT_RIGHT:
147                // handle (x>>32)
148                relType = RELTYPE_HIGH_32BIT;
149                good = (secondArg == 32);
150                break;
151            default:
152                break;
153        }
154        if (!good)
155        {
156            assembler.printError(expr->getSourcePos(),
157                        "Can't resolve relocation for this expression");
158            return false;
159        }
160    }
161   
162    relSectionId = 0;
163    relValue = 0;
164    //
165    return expr->evaluate(assembler, relOpStart, relOpEnd, relValue, relSectionId);
166}
167
168/* raw code handler */
169
170AsmRawCodeHandler::AsmRawCodeHandler(Assembler& assembler): AsmFormatHandler(assembler)
171{
172    assembler.currentKernel = ASMKERN_GLOBAL;
173    assembler.currentSection = 0;
174}
175
176cxuint AsmRawCodeHandler::addKernel(const char* kernelName)
177{
178    throw AsmFormatException("In rawcode defining kernels is not allowed");
179}
180
181cxuint AsmRawCodeHandler::addSection(const char* name, cxuint kernelId)
182{
183    if (::strcmp(name, ".text")!=0)
184        throw AsmFormatException("Only section '.text' can be in raw code");
185    else
186        throw AsmFormatException("Section '.text' already exists");
187}
188
189cxuint AsmRawCodeHandler::getSectionId(const char* sectionName) const
190{
191    return ::strcmp(sectionName, ".text") ? ASMSECT_NONE : 0;
192}
193
194void AsmRawCodeHandler::setCurrentKernel(cxuint kernel)
195{
196    if (kernel != ASMKERN_GLOBAL)
197        throw AsmFormatException("No kernels available");
198}
199
200void AsmRawCodeHandler::setCurrentSection(cxuint sectionId)
201{
202    if (sectionId!=0)
203        throw AsmFormatException("Section doesn't exists");
204}
205
206AsmFormatHandler::SectionInfo AsmRawCodeHandler::getSectionInfo(cxuint sectionId) const
207{
208    if (sectionId!=0)
209        throw AsmFormatException("Section doesn't exists");
210    return { ".text", AsmSectionType::CODE, ASMSECT_ADDRESSABLE | ASMSECT_WRITEABLE };
211}
212
213bool AsmRawCodeHandler::parsePseudoOp(const CString& firstName,
214           const char* stmtPlace, const char* linePtr)
215{
216    // not recognized any pseudo-op
217    return false;
218}
219
220bool AsmRawCodeHandler::prepareBinary()
221{ return true; }
222
223void AsmRawCodeHandler::writeBinary(std::ostream& os) const
224{
225    const AsmSection& section = assembler.getSections()[0];
226    if (!section.content.empty())
227        os.write((char*)section.content.data(), section.content.size());
228}
229
230void AsmRawCodeHandler::writeBinary(Array<cxbyte>& array) const
231{
232    const AsmSection& section = assembler.getSections()[0];
233    array.assign(section.content.begin(), section.content.end());
234}
Note: See TracBrowser for help on using the repository browser.