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

Last change on this file since 3761 was 3761, checked in by matszpk, 19 months ago

CLRadeonExtender: Asm: Preliminaries to section differences in expressions.

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
169void AsmFormatHandler::prepareSectionDiffsResolving()
170{ }
171
172/* raw code handler */
173
174AsmRawCodeHandler::AsmRawCodeHandler(Assembler& assembler): AsmFormatHandler(assembler)
175{
176    assembler.currentKernel = ASMKERN_GLOBAL;
177    assembler.currentSection = 0;
178}
179
180cxuint AsmRawCodeHandler::addKernel(const char* kernelName)
181{
182    throw AsmFormatException("In rawcode defining kernels is not allowed");
183}
184
185cxuint AsmRawCodeHandler::addSection(const char* name, cxuint kernelId)
186{
187    if (::strcmp(name, ".text")!=0)
188        throw AsmFormatException("Only section '.text' can be in raw code");
189    else
190        throw AsmFormatException("Section '.text' already exists");
191}
192
193cxuint AsmRawCodeHandler::getSectionId(const char* sectionName) const
194{
195    return ::strcmp(sectionName, ".text") ? ASMSECT_NONE : 0;
196}
197
198void AsmRawCodeHandler::setCurrentKernel(cxuint kernel)
199{
200    if (kernel != ASMKERN_GLOBAL)
201        throw AsmFormatException("No kernels available");
202}
203
204void AsmRawCodeHandler::setCurrentSection(cxuint sectionId)
205{
206    if (sectionId!=0)
207        throw AsmFormatException("Section doesn't exists");
208}
209
210AsmFormatHandler::SectionInfo AsmRawCodeHandler::getSectionInfo(cxuint sectionId) const
211{
212    if (sectionId!=0)
213        throw AsmFormatException("Section doesn't exists");
214    return { ".text", AsmSectionType::CODE, ASMSECT_ADDRESSABLE | ASMSECT_WRITEABLE };
215}
216
217bool AsmRawCodeHandler::parsePseudoOp(const CString& firstName,
218           const char* stmtPlace, const char* linePtr)
219{
220    // not recognized any pseudo-op
221    return false;
222}
223
224bool AsmRawCodeHandler::prepareBinary()
225{ return true; }
226
227void AsmRawCodeHandler::writeBinary(std::ostream& os) const
228{
229    const AsmSection& section = assembler.getSections()[0];
230    if (!section.content.empty())
231        os.write((char*)section.content.data(), section.content.size());
232}
233
234void AsmRawCodeHandler::writeBinary(Array<cxbyte>& array) const
235{
236    const AsmSection& section = assembler.getSections()[0];
237    array.assign(section.content.begin(), section.content.end());
238}
Note: See TracBrowser for help on using the repository browser.