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

Last change on this file since 3771 was 3771, checked in by matszpk, 2 years ago

CLRadeonExtender: AsmROCm: Next prepping before implementing section diffs.

File size: 7.5 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        sectionDiffsResolvable(false)
61{ }
62
63AsmFormatHandler::~AsmFormatHandler()
64{ }
65
66void AsmFormatHandler::handleLabel(const CString& label)
67{ }
68
69bool AsmFormatHandler::resolveSymbol(const AsmSymbol& symbol, uint64_t& value,
70                 cxuint& sectionId)
71{
72    return false;
73}
74
75bool AsmFormatHandler::resolveRelocation(const AsmExpression* expr, uint64_t& value,
76                 cxuint& sectionId)
77{
78    return false;
79}
80
81bool AsmFormatHandler::resolveLoHiRelocExpression(const AsmExpression* expr,
82                RelocType& relType, cxuint& relSectionId, uint64_t& relValue)
83{
84    const AsmExprTarget& target = expr->getTarget();
85    const AsmExprTargetType tgtType = target.type;
86    if ((tgtType!=ASMXTGT_DATA32 &&
87        !assembler.isaAssembler->relocationIsFit(32, tgtType)))
88    {
89        assembler.printError(expr->getSourcePos(),
90                        "Can't resolve expression for non 32-bit integer");
91        return false;
92    }
93    if (target.sectionId==ASMSECT_ABS ||
94        assembler.sections[target.sectionId].type!=AsmSectionType::CODE)
95    {
96        assembler.printError(expr->getSourcePos(), "Can't resolve expression outside "
97                "code section");
98        return false;
99    }
100    const Array<AsmExprOp>& ops = expr->getOps();
101   
102    size_t relOpStart = 0;
103    size_t relOpEnd = ops.size();
104    relType = RELTYPE_LOW_32BIT;
105    // checking what is expression
106    // get () OP () - operator between two parts
107    AsmExprOp lastOp = ops.back();
108    if (lastOp==AsmExprOp::BIT_AND || lastOp==AsmExprOp::MODULO ||
109        lastOp==AsmExprOp::SIGNED_MODULO || lastOp==AsmExprOp::DIVISION ||
110        lastOp==AsmExprOp::SIGNED_DIVISION || lastOp==AsmExprOp::SHIFT_RIGHT)
111    {
112        // check low or high relocation
113        relOpStart = 0;
114        relOpEnd = expr->toTop(ops.size()-2);
115        /// evaluate second argument
116        cxuint tmpSectionId;
117        uint64_t secondArg;
118        if (!expr->evaluate(assembler, relOpEnd, ops.size()-1, secondArg, tmpSectionId))
119            return false;
120        if (tmpSectionId!=ASMSECT_ABS)
121        {
122            // must be absolute
123            assembler.printError(expr->getSourcePos(),
124                        "Second argument for relocation operand must be absolute");
125            return false;
126        }
127        bool good = true;
128        switch (lastOp)
129        {
130            case AsmExprOp::BIT_AND:
131                // handle (x&0xffffffff)
132                relType = RELTYPE_LOW_32BIT;
133                good = ((secondArg & 0xffffffffULL) == 0xffffffffULL);
134                break;
135            case AsmExprOp::MODULO:
136            case AsmExprOp::SIGNED_MODULO:
137                // handle (x%0x100000000)
138                relType = RELTYPE_LOW_32BIT;
139                good = ((secondArg>>32)!=0 && (secondArg & 0xffffffffULL) == 0);
140                break;
141            case AsmExprOp::DIVISION:
142            case AsmExprOp::SIGNED_DIVISION:
143                // handle (x/0x100000000)
144                relType = RELTYPE_HIGH_32BIT;
145                good = (secondArg == 0x100000000ULL);
146                break;
147            case AsmExprOp::SHIFT_RIGHT:
148                // handle (x>>32)
149                relType = RELTYPE_HIGH_32BIT;
150                good = (secondArg == 32);
151                break;
152            default:
153                break;
154        }
155        if (!good)
156        {
157            assembler.printError(expr->getSourcePos(),
158                        "Can't resolve relocation for this expression");
159            return false;
160        }
161    }
162   
163    relSectionId = 0;
164    relValue = 0;
165    //
166    return expr->evaluate(assembler, relOpStart, relOpEnd, relValue, relSectionId);
167}
168
169bool AsmFormatHandler::prepareSectionDiffsResolving()
170{
171    return false;
172}
173
174/* raw code handler */
175
176AsmRawCodeHandler::AsmRawCodeHandler(Assembler& assembler): AsmFormatHandler(assembler)
177{
178    assembler.currentKernel = ASMKERN_GLOBAL;
179    assembler.currentSection = 0;
180}
181
182cxuint AsmRawCodeHandler::addKernel(const char* kernelName)
183{
184    throw AsmFormatException("In rawcode defining kernels is not allowed");
185}
186
187cxuint AsmRawCodeHandler::addSection(const char* name, cxuint kernelId)
188{
189    if (::strcmp(name, ".text")!=0)
190        throw AsmFormatException("Only section '.text' can be in raw code");
191    else
192        throw AsmFormatException("Section '.text' already exists");
193}
194
195cxuint AsmRawCodeHandler::getSectionId(const char* sectionName) const
196{
197    return ::strcmp(sectionName, ".text") ? ASMSECT_NONE : 0;
198}
199
200void AsmRawCodeHandler::setCurrentKernel(cxuint kernel)
201{
202    if (kernel != ASMKERN_GLOBAL)
203        throw AsmFormatException("No kernels available");
204}
205
206void AsmRawCodeHandler::setCurrentSection(cxuint sectionId)
207{
208    if (sectionId!=0)
209        throw AsmFormatException("Section doesn't exists");
210}
211
212AsmFormatHandler::SectionInfo AsmRawCodeHandler::getSectionInfo(cxuint sectionId) const
213{
214    if (sectionId!=0)
215        throw AsmFormatException("Section doesn't exists");
216    return { ".text", AsmSectionType::CODE, ASMSECT_ADDRESSABLE | ASMSECT_WRITEABLE };
217}
218
219bool AsmRawCodeHandler::parsePseudoOp(const CString& firstName,
220           const char* stmtPlace, const char* linePtr)
221{
222    // not recognized any pseudo-op
223    return false;
224}
225
226bool AsmRawCodeHandler::prepareBinary()
227{ return true; }
228
229void AsmRawCodeHandler::writeBinary(std::ostream& os) const
230{
231    const AsmSection& section = assembler.getSections()[0];
232    if (!section.content.empty())
233        os.write((char*)section.content.data(), section.content.size());
234}
235
236void AsmRawCodeHandler::writeBinary(Array<cxbyte>& array) const
237{
238    const AsmSection& section = assembler.getSections()[0];
239    array.assign(section.content.begin(), section.content.end());
240}
Note: See TracBrowser for help on using the repository browser.