xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/cm/cm_visa.h (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file      cm_visa.h
24 //! \brief     Contains Class ISAfile definitions
25 //!
26 
27 #ifndef VISA_H
28 #define VISA_H
29 
30 #include <cstdint>
31 #include <cstring>
32 #include <vector>
33 #include <array>
34 
35 namespace vISA {
36     enum Datatype { ONE, TWO, FOUR, EIGHT, VARCHAR, VARCHAR_POOL, GDATA, STRUCT, REMOVED };
37 
38     //!
39     //! \brief      Field Struct.
40     //! \details    This struct represents any field from the ISA file.
41     //!             Fields are tagged according their data size in bytes (1 to 8 bytes).
42     //!             Regular strings are tagged as VARCHAR and strings from the String
43     //!             Pool as VARCHAR_POOL.
44     //!
45     struct Field {
46         Datatype type;
47         uint8_t countField;
48         uint32_t size;
49         union {
50             int8_t number8;
51             int16_t number16;
52             int32_t number32;
53             int64_t number64;
54             int8_t ui8[8];
55             char *varchar;
56             const uint8_t *gdata;
57         };
58 
59         //!
60         //! \brief      Constructor of Field struct.
61         //!
FieldField62         Field() : countField(0), number64(0) {}
63 
64         //!
65         //! \brief      Constructor of Field struct.
66         //!
FieldField67         Field(Datatype t) : type(t), countField(0), size(0), number64(0) {}
68 
69         //!
70         //! \brief      Constructor of Field struct.
71         //!
FieldField72         Field(Datatype t, uint8_t cf) : type(t), countField(cf), size(0), number64(0) {}
73 
74         //!
75         //! \brief      Destructor of Field struct.
76         //!
~FieldField77         ~Field() {
78             if (type == Datatype::VARCHAR || type == Datatype::VARCHAR_POOL)
79                 delete[] varchar;
80             else if (type == Datatype::GDATA)
81                 delete[] gdata;
82         }
83     };
84 
85     class Header;
86     class KernelBody;
87     class FunctionBody;
88 
89     //!
90     //! \brief      ISAfile Class.
91     //! \details     This class provides the functionality to manage ISA files: read
92     //!             parse and write ISA files. Access to Header, Kernels and
93     //!             Functions is also provided.
94     //!             It supports from vISA 3.4.
95     //!
96     class ISAfile
97     {
98     private:
99         unsigned version;
100         const uint8_t *data;
101         const uint8_t *end;
102         unsigned size;
103         const char *error;
104         unsigned errorIndex;
105         Header *header;
106         bool kernel_data_loaded;
107         bool function_data_loaded;
108         std::vector<KernelBody*> kernel_data;
109         std::vector<FunctionBody*> function_data;
110 
111         //!
112         //! \brief      Reads and parses the Header from ISA file.
113         //! \retval     True if sucessfully parsers the header.
114         //!             False otherwise.
115         //!
116         bool loadHeader();
117 
118         //!
119         //! \brief      Reads and parses the kernels from ISA file.
120         //! \retval     True if sucessfully parsers all the kernels.
121         //!             False otherwise.
122         //!
123         bool loadKernelData();
124 
125         //!
126         //! \brief      Reads and parses the functions from ISA file.
127         //! \retval     True if sucessfully parsers all the functions.
128         //!             False otherwise.
129         //!
130         bool loadFunctionData();
131     public:
132         //!
133         //! \brief      Constructor of ISAfile class.
134         //! \param      [in] data.
135         //!             Pointer to buffer data from ISA file.
136         //! \param      [in] size.
137         //!             Size of ISA file buffer.
138         //!
139         ISAfile(const uint8_t *data, unsigned size);
140 
141         //!
142         //! \brief      Copy Constructor of ISAfile class.
143         //! \param      [in] other.
144         //!             Reference to object to copy.
145         //!
146         ISAfile(const ISAfile& other);
147 
148         //!
149         //! \brief      Assignment operator.
150         //! \param      [in] other.
151         //!             Reference to object to copy.
152         //!
153         ISAfile& operator= (const ISAfile& other);
154 
155         //!
156         //! \brief      Destructor of ISAfile class.
157         //!
158         ~ISAfile();
159 
160         //!
161         //! \brief      Reads the ISA file.
162         //! \retval     True if it reads successfully.
163         //!
164         bool readFile();
165 
166         //!
167         //! \brief      Returns the Header object.
168         //! \retval     The pointer to Header object.
169         //!
getHeader()170         Header *getHeader() { return header; }
171 
172         //!
173         //! \brief      Returns the vector of kernels.
174         //! \retval     The reference to the vector with the kernels.
175         //!
176         std::vector<KernelBody*> &getKernelsData();
177 
178         //!
179         //! \brief      Returns the vector of functions.
180         //! \retval     The reference to the vector with the functions.
181         //!
182         std::vector<FunctionBody*> &getFunctionsData();
183 
184         //!
185         //! \brief      Reads a value from buffer and assigns to field.
186         //! \param      [in] p.
187         //!             Pointer to buffer data from ISA file.
188         //! \param      [in] buffEnd.
189         //!             Pointer to the end of buffer data from ISA file.
190         //! \param      [out] field.
191         //!             Reference to field.
192         //! \param      [in] size.
193         //!             Size of the value to be read.
194         //! \retval     The pointer to buffer after reading the value.
195         //!
196         const uint8_t* readField(const uint8_t *p, const uint8_t *buffEnd, Field &field, unsigned size);
197 
198         //!
199         //! \brief      Returns the error message.
200         //! \retval     The pointer to string with the error message.
201         //!
getError()202         const char *getError() { return error; }
203 
204         //!
205         //! \brief      Returns the error index.
206         //! \retval     The index to the error.
207         //!
getErrorOffset()208         unsigned getErrorOffset() { return errorIndex; }
209 
210         //!
211         //! \brief      Sets the error message.
212         //! \param      [int] e.
213         //!             Error message.
214         //! \param      [in] index.
215         //!              Index to the error.
216         //!
217         const uint8_t *setError(const char * e, unsigned index);
218 
219         //!
220         //! \brief      Returns the vISA version of current file.
221         //! \retval     The vISA version as integer.
222         //!
getCurrentVISAVersion()223         unsigned getCurrentVISAVersion() { return version; }
224 
225         //!
226         //! \brief      Sets the ISA file version
227         //! \param      The ISA file version
228         //!
setCurrentVISAVersion(unsigned v)229         void setCurrentVISAVersion(unsigned v) { version = v; }
230 
231         //!
232         //! \brief      Writes a new ISA file with the current information in this class.
233         //! \param      [in] filename.
234         //!             String with the file name.
235         //! \param      [in] originalBuffer.
236         //!             Buffer data of the original ISA file.
237         //! \retval     True if successfully writes the ISA file.
238         //!
239         bool writeToFile(const char *filename, std::vector<uint8_t> &originalBuffer);
240 
241         //!
242         //! \brief      Adds the value from a field to buffer.
243         //!             This function is called when writing a ISA file.
244         //! \param      [in] field.
245         //!             The field to get its value.
246         //! \param      [out] buffer.
247         //!             Buffer data where the field's field is added.
248         //!
249         void addToBuffer(Field &field, std::vector<char> &buffer);
250 
251     };
252 
253     //!
254     //! \brief      AttributeInfo Class.
255     //! \details    This class represents the AttributeInfo from vISA Object Format.
256     //!             Provides getters, setters for its fields and structs as well as
257     //!             functions to read/write it from/to file.
258     //!
259     class AttributeInfo {
260     public:
261         std::array<Field, 3> fields = std::array<Field, 3>
262         {
263             Field(Datatype::FOUR), // name
264                 Field(Datatype::ONE), // size
265                 Field(Datatype::GDATA, 1) // value
266         };
267 
268         //!
269         //! \brief      Constructor of AttributeInfo class.
270         //! \param      [in] version.
271         //!             Version of current ISA file.
272         //!
AttributeInfo(unsigned version)273         AttributeInfo(unsigned version) {
274             if (version <= 303) setVersion303();
275         }
276 
277         //!
278         //! \brief      Constructor of AttributeInfo class.
279         //!
AttributeInfo()280         AttributeInfo() { }
281 
282         //!
283         //! \brief      Destructor of AttributeInfo class.
284         //!
~AttributeInfo()285         ~AttributeInfo() {
286         }
287 
288         //!
289         //! \brief      Returns the integer value of the Name field.
290         //! \details    Name field is at index 0 in the internal
291         //!             array of Fields.
292         //! \retval     An integer.
293         //!
getName()294         uint32_t getName() {
295             return (uint32_t)fields[0].number32;
296         }
297 
298         //!
299         //! \brief      Sets the integer value of the Name field.
300         //! \details    Name field is at index 0 in the internal
301         //!             array of Fields.
302         //! \param      [in] value.
303         //!             Integer be assigned.
304         //!
setName(uint32_t value)305         void setName(uint32_t value) {
306             fields[0].number32 = value;
307         }
308 
309         //!
310         //! \brief      Returns the integer value of the Size field.
311         //! \details    Size field is at index 1 in the internal
312         //!             array of Fields.
313         //! \retval     An integer.
314         //!
getSize()315         uint8_t getSize() {
316             return (uint8_t)fields[1].number8;
317         }
318 
319         //!
320         //! \brief      Sets the integer value of the Size field.
321         //! \details    Size field is at index 1 in the internal
322         //!             array of Fields.
323         //! \param      [in] value.
324         //!             Integer be assigned.
325         //!
setSize(uint8_t value)326         void setSize(uint8_t value) {
327             fields[1].number8 = value;
328         }
329 
330         //!
331         //! \brief      Returns the pointer to buffer data from Value field.
332         //! \details    Value field is at index 2 in the internal
333         //!             array of Fields.
334         //! \retval     A pointer to buffer data (const uint8_t*).
335         //!
getValue()336         const uint8_t* getValue() {
337             return fields[2].gdata;
338         }
339 
340         //!
341         //! \brief      Sets the pointer to buffer data of the Value field.
342         //! \details    Value field is at index 2 in the internal
343         //!             array of Fields.
344         //! \param      [in] value.
345         //!             Pointer to buffer data (uint8_t*) to be assigned.
346         //!
setValue(uint8_t * value)347         void setValue(uint8_t * value) {
348             fields[2].gdata = value;
349         }
350 
351         //!
352         //! \brief      Parses one AttributeInfo object from ISA file.
353         //! \details    Reads and parses all the fields of the AttributeInfo object
354         //!             from the file buffer and returns the pointer immediately
355         //!             after all this data.
356         //!             If this class contains internal structs, their Parse
357         //!             functions are called when corresponding.
358         //! \param      [in] p.
359         //!             Pointer to file buffer to start reading.
360         //! \param      [in] end.
361         //!             Pointer to end of file buffer.
362         //! \param      [in] m.
363         //!             Pointer ISAfile object.
364         //! \retval     Pointer to file buffe after parsing one AttributeInfo object.
365         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)366         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
367             unsigned i = 0;
368             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
369                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
370                 if (!p) return m->setError("bad offset/size for AttributeInfo's field", i);
371                 i++;
372             }
373             return p;
374         }
375 
376         //!
377         //! \brief      Adds all the AttributeInfo's fields to a buffer.
378         //! \details    Every field from this class is added to a buffer
379         //!             in order to be written into an ISA file afterwards
380         //!             If this class contains other internal structus, their addToBuffer
381         //!             functions are called when corresponding.
382         //! \param      [out] buffer.
383         //!             The buffer where the fields data will be added.
384         //! \param      [in] m.
385         //!             Pointer to ISAfile object.
386         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)387         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
388             unsigned i = 0;
389             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
390                 m->addToBuffer(fields[i], buffer);
391                 i++;
392             }
393         }
394 
395         //!
396         //! \brief      Makes the changes needed to support 303 version's AttributeInfo.
397         //! \details    This function is called when the current ISA file has the 303 version.
398         //!             Initially all the objects are created with last version's format, so
399         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
400         //!             of fields can be needed.
401         //!
setVersion303()402         void setVersion303() {
403             fields[0] = Datatype::TWO;
404         }
405     };
406 
407     //!
408     //! \brief      InputInfo Class.
409     //! \details    This class represents the InputInfo from vISA Object Format.
410     //!             Provides getters, setters for its fields and structs as well as
411     //!             functions to read/write it from/to file.
412     //!
413     class InputInfo {
414     public:
415         std::array<Field, 4> fields = std::array<Field, 4>
416         {
417             Field(Datatype::ONE), // kind
418                 Field(Datatype::FOUR), // id
419                 Field(Datatype::TWO), // offset
420                 Field(Datatype::TWO) // size
421         };
422 
423         //!
424         //! \brief      Constructor of InputInfo class.
425         //! \param      [in] version.
426         //!             Version of current ISA file.
427         //!
InputInfo(unsigned version)428         InputInfo(unsigned version) {
429             if (version <= 303) setVersion303();
430         }
431 
432         //!
433         //! \brief      Destructor of InputInfo class.
434         //!
~InputInfo()435         ~InputInfo() {
436         }
437 
438         //!
439         //! \brief      Returns the integer value of the Kind field.
440         //! \details    Kind field is at index 0 in the internal
441         //!             array of Fields.
442         //! \retval     An integer.
443         //!
getKind()444         int8_t getKind() {
445             return fields[0].number8;
446         }
447 
448         //!
449         //! \brief      Sets the integer value of the Kind field.
450         //! \details    Kind field is at index 0 in the internal
451         //!             array of Fields.
452         //! \param      [in] value.
453         //!             Integer be assigned.
454         //!
setKind(int8_t value)455         void setKind(int8_t value) {
456             fields[0].number8 = value;
457         }
458 
459         //!
460         //! \brief      Returns the integer value of the Id field.
461         //! \details    Id field is at index 1 in the internal
462         //!             array of Fields.
463         //! \retval     An integer.
464         //!
getId()465         uint32_t getId() {
466             return (uint32_t)fields[1].number32;
467         }
468 
469         //!
470         //! \brief      Sets the integer value of the Id field.
471         //! \details    Id field is at index 1 in the internal
472         //!             array of Fields.
473         //! \param      [in] value.
474         //!             Integer be assigned.
475         //!
setId(uint32_t value)476         void setId(uint32_t value) {
477             fields[1].number32 = value;
478         }
479 
480         //!
481         //! \brief      Returns the integer value of the Offset field.
482         //! \details    Offset field is at index 2 in the internal
483         //!             array of Fields.
484         //! \retval     An integer.
485         //!
getOffset()486         int16_t getOffset() {
487             return fields[2].number16;
488         }
489 
490         //!
491         //! \brief      Sets the integer value of the Offset field.
492         //! \details    Offset field is at index 2 in the internal
493         //!             array of Fields.
494         //! \param      [in] value.
495         //!             Integer be assigned.
496         //!
setOffset(int16_t value)497         void setOffset(int16_t value) {
498             fields[2].number16 = value;
499         }
500 
501         //!
502         //! \brief      Returns the integer value of the Size field.
503         //! \details    Size field is at index 3 in the internal
504         //!             array of Fields.
505         //! \retval     An integer.
506         //!
getSize()507         uint16_t getSize() {
508             return (uint16_t)fields[3].number16;
509         }
510 
511         //!
512         //! \brief      Sets the integer value of the Size field.
513         //! \details    Size field is at index 3 in the internal
514         //!             array of Fields.
515         //! \param      [in] value.
516         //!             Integer be assigned.
517         //!
setSize(uint16_t value)518         void setSize(uint16_t value) {
519             fields[3].number16 = value;
520         }
521 
522         //!
523         //! \brief      Parses one InputInfo object from ISA file.
524         //! \details    Reads and parses all the fields of the InputInfo object
525         //!             from the file buffer and returns the pointer immediately
526         //!             after all this data.
527         //!             If this class contains internal structs, their Parse
528         //!             functions are called when corresponding.
529         //! \param      [in] p.
530         //!             Pointer to file buffer to start reading.
531         //! \param      [in] end.
532         //!             Pointer to end of file buffer.
533         //! \param      [in] m.
534         //!             Pointer ISAfile object.
535         //! \retval     Pointer to file buffe after parsing one InputInfo object.
536         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)537         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
538             unsigned i = 0;
539             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
540                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
541                 if (!p) return m->setError("bad offset/size for InputInfo's field", i);
542                 i++;
543             }
544             return p;
545         }
546 
547         //!
548         //! \brief      Adds all the InputInfo's fields to a buffer.
549         //! \details    Every field from this class is added to a buffer
550         //!             in order to be written into an ISA file afterwards
551         //!             If this class contains other internal structus, their addToBuffer
552         //!             functions are called when corresponding.
553         //! \param      [out] buffer.
554         //!             The buffer where the fields data will be added.
555         //! \param      [in] m.
556         //!             Pointer to ISAfile object.
557         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)558         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
559             unsigned i = 0;
560             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
561                 m->addToBuffer(fields[i], buffer);
562                 i++;
563             }
564         }
565 
566         //!
567         //! \brief      Makes the changes needed to support 303 version's InputInfo.
568         //! \details    This function is called when the current ISA file has the 303 version.
569         //!             Initially all the objects are created with last version's format, so
570         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
571         //!             of fields can be needed.
572         //!
setVersion303()573         void setVersion303() {
574             fields[1] = Datatype::TWO;
575         }
576     };
577 
578     //!
579     //! \brief      VmeInfo Class.
580     //! \details    This class represents the VmeInfo from vISA Object Format.
581     //!             Provides getters, setters for its fields and structs as well as
582     //!             functions to read/write it from/to file.
583     //!
584     class VmeInfo {
585     public:
586         std::array<Field, 4> fields = std::array<Field, 4>
587         {
588             Field(Datatype::FOUR), // name_index
589                 Field(Datatype::TWO), // num_elements
590                 Field(Datatype::ONE), // attribute_count
591                 Field(Datatype::STRUCT, 2), // attribute_info
592         };
593         std::vector<AttributeInfo*> attribute_info;
594 
595         //!
596         //! \brief      Constructor of VmeInfo class.
597         //! \param      [in] version.
598         //!             Version of current ISA file.
599         //!
VmeInfo(unsigned version)600         VmeInfo(unsigned version) {
601             if (version <= 303) setVersion303();
602         }
603 
604         //!
605         //! \brief      Destructor of VmeInfo class.
606         //!
~VmeInfo()607         ~VmeInfo() {
608             for (AttributeInfo *s : attribute_info) delete s;
609         }
610 
611         //!
612         //! \brief      Returns the integer value of the NameIndex field.
613         //! \details    NameIndex field is at index 0 in the internal
614         //!             array of Fields.
615         //! \retval     An integer.
616         //!
getNameIndex()617         uint32_t getNameIndex() {
618             return (uint32_t)fields[0].number32;
619         }
620 
621         //!
622         //! \brief      Sets the integer value of the NameIndex field.
623         //! \details    NameIndex field is at index 0 in the internal
624         //!             array of Fields.
625         //! \param      [in] value.
626         //!             Integer be assigned.
627         //!
setNameIndex(uint32_t value)628         void setNameIndex(uint32_t value) {
629             fields[0].number32 = value;
630         }
631 
632         //!
633         //! \brief      Returns the integer value of the NumElements field.
634         //! \details    NumElements field is at index 1 in the internal
635         //!             array of Fields.
636         //! \retval     An integer.
637         //!
getNumElements()638         uint16_t getNumElements() {
639             return (uint16_t)fields[1].number16;
640         }
641 
642         //!
643         //! \brief      Sets the integer value of the NumElements field.
644         //! \details    NumElements field is at index 1 in the internal
645         //!             array of Fields.
646         //! \param      [in] value.
647         //!             Integer be assigned.
648         //!
setNumElements(uint16_t value)649         void setNumElements(uint16_t value) {
650             fields[1].number16 = value;
651         }
652 
653         //!
654         //! \brief      Returns the integer value of the AttributeCount field.
655         //! \details    AttributeCount field is at index 2 in the internal
656         //!             array of Fields.
657         //! \retval     An integer.
658         //!
getAttributeCount()659         uint8_t getAttributeCount() {
660             return (uint8_t)fields[2].number8;
661         }
662 
663         //!
664         //! \brief      Sets the integer value of the AttributeCount field.
665         //! \details    AttributeCount field is at index 2 in the internal
666         //!             array of Fields.
667         //! \param      [in] value.
668         //!             Integer be assigned.
669         //!
setAttributeCount(uint8_t value)670         void setAttributeCount(uint8_t value) {
671             fields[2].number8 = value;
672         }
673 
674         //!
675         //! \brief      Returns the reference to the vector of AttributeInfo objects.
676         //! \details    VmeInfo has a vector of AttributeInfo objects
677         //!             that represents another entity within the vISA object format.
678         //! \retval     Reference to the vector of AttributeInfo*.
679         //!
getAttributeInfo()680         std::vector<AttributeInfo*> &getAttributeInfo() {
681             return attribute_info;
682         }
683 
684         //!
685         //! \brief      Parses one VmeInfo object from ISA file.
686         //! \details    Reads and parses all the fields of the VmeInfo object
687         //!             from the file buffer and returns the pointer immediately
688         //!             after all this data.
689         //!             If this class contains internal structs, their Parse
690         //!             functions are called when corresponding.
691         //! \param      [in] p.
692         //!             Pointer to file buffer to start reading.
693         //! \param      [in] end.
694         //!             Pointer to end of file buffer.
695         //! \param      [in] m.
696         //!             Pointer ISAfile object.
697         //! \retval     Pointer to file buffe after parsing one VmeInfo object.
698         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)699         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
700             unsigned i = 0, count = 0;
701             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
702                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
703                 if (!p) return m->setError("bad offset/size for VmeInfo's field", i);
704                 i++;
705             }
706             // AttributeInfo
707             count = fields[fields[i].countField].number32;
708             attribute_info.resize(count);
709             for (unsigned j = 0; j < count; j++) {
710                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
711                 p = r->parse(p, end, m);
712                 if (!p) {
713                     delete r;
714                     return 0;
715                 }
716                 attribute_info[j] = r;
717             }
718             i++;
719             return p;
720         }
721 
722         //!
723         //! \brief      Adds all the VmeInfo's fields to a buffer.
724         //! \details    Every field from this class is added to a buffer
725         //!             in order to be written into an ISA file afterwards
726         //!             If this class contains other internal structus, their addToBuffer
727         //!             functions are called when corresponding.
728         //! \param      [out] buffer.
729         //!             The buffer where the fields data will be added.
730         //! \param      [in] m.
731         //!             Pointer to ISAfile object.
732         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)733         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
734             unsigned i = 0;
735             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
736                 m->addToBuffer(fields[i], buffer);
737                 i++;
738             }
739             // AttributeInfo
740             for (AttributeInfo *r : attribute_info) {
741                 r->addToBuffer(buffer, m);
742             }
743             i++;
744         }
745 
746         //!
747         //! \brief      Makes the changes needed to support 303 version's VmeInfo.
748         //! \details    This function is called when the current ISA file has the 303 version.
749         //!             Initially all the objects are created with last version's format, so
750         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
751         //!             of fields can be needed.
752         //!
setVersion303()753         void setVersion303() {
754             fields[0] = Datatype::TWO;
755         }
756     };
757 
758     //!
759     //! \brief      SurfaceInfo Class.
760     //! \details    This class represents the SurfaceInfo from vISA Object Format.
761     //!             Provides getters, setters for its fields and structs as well as
762     //!             functions to read/write it from/to file.
763     //!
764     class SurfaceInfo {
765     public:
766         std::array<Field, 4> fields = std::array<Field, 4>
767         {
768             Field(Datatype::FOUR), // name_index
769                 Field(Datatype::TWO), // num_elements
770                 Field(Datatype::ONE), // attribute_count
771                 Field(Datatype::STRUCT, 2), // attribute_info
772         };
773         std::vector<AttributeInfo*> attribute_info;
774 
775         //!
776         //! \brief      Constructor of SurfaceInfo class.
777         //! \param      [in] version.
778         //!             Version of current ISA file.
779         //!
SurfaceInfo(unsigned version)780         SurfaceInfo(unsigned version) {
781             if (version <= 303) setVersion303();
782         }
783 
784         //!
785         //! \brief      Destructor of SurfaceInfo class.
786         //!
~SurfaceInfo()787         ~SurfaceInfo() {
788             for (AttributeInfo *s : attribute_info) delete s;
789         }
790 
791         //!
792         //! \brief      Returns the integer value of the NameIndex field.
793         //! \details    NameIndex field is at index 0 in the internal
794         //!             array of Fields.
795         //! \retval     An integer.
796         //!
getNameIndex()797         uint32_t getNameIndex() {
798             return (uint32_t)fields[0].number32;
799         }
800 
801         //!
802         //! \brief      Sets the integer value of the NameIndex field.
803         //! \details    NameIndex field is at index 0 in the internal
804         //!             array of Fields.
805         //! \param      [in] value.
806         //!             Integer be assigned.
807         //!
setNameIndex(uint32_t value)808         void setNameIndex(uint32_t value) {
809             fields[0].number32 = value;
810         }
811 
812         //!
813         //! \brief      Returns the integer value of the NumElements field.
814         //! \details    NumElements field is at index 1 in the internal
815         //!             array of Fields.
816         //! \retval     An integer.
817         //!
getNumElements()818         uint16_t getNumElements() {
819             return (uint16_t)fields[1].number16;
820         }
821 
822         //!
823         //! \brief      Sets the integer value of the NumElements field.
824         //! \details    NumElements field is at index 1 in the internal
825         //!             array of Fields.
826         //! \param      [in] value.
827         //!             Integer be assigned.
828         //!
setNumElements(uint16_t value)829         void setNumElements(uint16_t value) {
830             fields[1].number16 = value;
831         }
832 
833         //!
834         //! \brief      Returns the integer value of the AttributeCount field.
835         //! \details    AttributeCount field is at index 2 in the internal
836         //!             array of Fields.
837         //! \retval     An integer.
838         //!
getAttributeCount()839         uint8_t getAttributeCount() {
840             return (uint8_t)fields[2].number8;
841         }
842 
843         //!
844         //! \brief      Sets the integer value of the AttributeCount field.
845         //! \details    AttributeCount field is at index 2 in the internal
846         //!             array of Fields.
847         //! \param      [in] value.
848         //!             Integer be assigned.
849         //!
setAttributeCount(uint8_t value)850         void setAttributeCount(uint8_t value) {
851             fields[2].number8 = value;
852         }
853 
854         //!
855         //! \brief      Returns the reference to the vector of AttributeInfo objects.
856         //! \details    SurfaceInfo has a vector of AttributeInfo objects
857         //!             that represents another entity within the vISA object format.
858         //! \retval     Reference to the vector of AttributeInfo*.
859         //!
getAttributeInfo()860         std::vector<AttributeInfo*> &getAttributeInfo() {
861             return attribute_info;
862         }
863 
864         //!
865         //! \brief      Parses one SurfaceInfo object from ISA file.
866         //! \details    Reads and parses all the fields of the SurfaceInfo object
867         //!             from the file buffer and returns the pointer immediately
868         //!             after all this data.
869         //!             If this class contains internal structs, their Parse
870         //!             functions are called when corresponding.
871         //! \param      [in] p.
872         //!             Pointer to file buffer to start reading.
873         //! \param      [in] end.
874         //!             Pointer to end of file buffer.
875         //! \param      [in] m.
876         //!             Pointer ISAfile object.
877         //! \retval     Pointer to file buffe after parsing one SurfaceInfo object.
878         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)879         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
880             unsigned i = 0, count = 0;
881             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
882                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
883                 if (!p) return m->setError("bad offset/size for SurfaceInfo's field", i);
884                 i++;
885             }
886             // AttributeInfo
887             count = fields[fields[i].countField].number32;
888             attribute_info.resize(count);
889             for (unsigned j = 0; j < count; j++) {
890                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
891                 p = r->parse(p, end, m);
892                 if (!p) {
893                     delete r;
894                     return 0;
895                 }
896                 attribute_info[j] = r;
897             }
898             i++;
899             return p;
900         }
901 
902         //!
903         //! \brief      Adds all the SurfaceInfo's fields to a buffer.
904         //! \details    Every field from this class is added to a buffer
905         //!             in order to be written into an ISA file afterwards
906         //!             If this class contains other internal structus, their addToBuffer
907         //!             functions are called when corresponding.
908         //! \param      [out] buffer.
909         //!             The buffer where the fields data will be added.
910         //! \param      [in] m.
911         //!             Pointer to ISAfile object.
912         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)913         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
914             unsigned i = 0;
915             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
916                 m->addToBuffer(fields[i], buffer);
917                 i++;
918             }
919             // AttributeInfo
920             for (AttributeInfo *r : attribute_info) {
921                 r->addToBuffer(buffer, m);
922             }
923             i++;
924         }
925 
926         //!
927         //! \brief      Makes the changes needed to support 303 version's SurfaceInfo.
928         //! \details    This function is called when the current ISA file has the 303 version.
929         //!             Initially all the objects are created with last version's format, so
930         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
931         //!             of fields can be needed.
932         //!
setVersion303()933         void setVersion303() {
934             fields[0] = Datatype::TWO;
935         }
936     };
937 
938     //!
939     //! \brief      SamplerInfo Class.
940     //! \details    This class represents the SamplerInfo from vISA Object Format.
941     //!             Provides getters, setters for its fields and structs as well as
942     //!             functions to read/write it from/to file.
943     //!
944     class SamplerInfo {
945     public:
946         std::array<Field, 4> fields = std::array<Field, 4>
947         {
948             Field(Datatype::FOUR), // name_index
949                 Field(Datatype::TWO), // num_elements
950                 Field(Datatype::ONE), // attribute_count
951                 Field(Datatype::STRUCT, 2), // attribute_info
952         };
953         std::vector<AttributeInfo*> attribute_info;
954 
955         //!
956         //! \brief      Constructor of SamplerInfo class.
957         //! \param      [in] version.
958         //!             Version of current ISA file.
959         //!
SamplerInfo(unsigned version)960         SamplerInfo(unsigned version) {
961             if (version <= 303) setVersion303();
962         }
963 
964         //!
965         //! \brief      Destructor of SamplerInfo class.
966         //!
~SamplerInfo()967         ~SamplerInfo() {
968             for (AttributeInfo *s : attribute_info) delete s;
969         }
970 
971         //!
972         //! \brief      Returns the integer value of the NameIndex field.
973         //! \details    NameIndex field is at index 0 in the internal
974         //!             array of Fields.
975         //! \retval     An integer.
976         //!
getNameIndex()977         uint32_t getNameIndex() {
978             return (uint32_t)fields[0].number32;
979         }
980 
981         //!
982         //! \brief      Sets the integer value of the NameIndex field.
983         //! \details    NameIndex field is at index 0 in the internal
984         //!             array of Fields.
985         //! \param      [in] value.
986         //!             Integer be assigned.
987         //!
setNameIndex(uint32_t value)988         void setNameIndex(uint32_t value) {
989             fields[0].number32 = value;
990         }
991 
992         //!
993         //! \brief      Returns the integer value of the NumElements field.
994         //! \details    NumElements field is at index 1 in the internal
995         //!             array of Fields.
996         //! \retval     An integer.
997         //!
getNumElements()998         uint16_t getNumElements() {
999             return (uint16_t)fields[1].number16;
1000         }
1001 
1002         //!
1003         //! \brief      Sets the integer value of the NumElements field.
1004         //! \details    NumElements field is at index 1 in the internal
1005         //!             array of Fields.
1006         //! \param      [in] value.
1007         //!             Integer be assigned.
1008         //!
setNumElements(uint16_t value)1009         void setNumElements(uint16_t value) {
1010             fields[1].number16 = value;
1011         }
1012 
1013         //!
1014         //! \brief      Returns the integer value of the AttributeCount field.
1015         //! \details    AttributeCount field is at index 2 in the internal
1016         //!             array of Fields.
1017         //! \retval     An integer.
1018         //!
getAttributeCount()1019         uint8_t getAttributeCount() {
1020             return (uint8_t)fields[2].number8;
1021         }
1022 
1023         //!
1024         //! \brief      Sets the integer value of the AttributeCount field.
1025         //! \details    AttributeCount field is at index 2 in the internal
1026         //!             array of Fields.
1027         //! \param      [in] value.
1028         //!             Integer be assigned.
1029         //!
setAttributeCount(uint8_t value)1030         void setAttributeCount(uint8_t value) {
1031             fields[2].number8 = value;
1032         }
1033 
1034         //!
1035         //! \brief      Returns the reference to the vector of AttributeInfo objects.
1036         //! \details    SamplerInfo has a vector of AttributeInfo objects
1037         //!             that represents another entity within the vISA object format.
1038         //! \retval     Reference to the vector of AttributeInfo*.
1039         //!
getAttributeInfo()1040         std::vector<AttributeInfo*> &getAttributeInfo() {
1041             return attribute_info;
1042         }
1043 
1044         //!
1045         //! \brief      Parses one SamplerInfo object from ISA file.
1046         //! \details    Reads and parses all the fields of the SamplerInfo object
1047         //!             from the file buffer and returns the pointer immediately
1048         //!             after all this data.
1049         //!             If this class contains internal structs, their Parse
1050         //!             functions are called when corresponding.
1051         //! \param      [in] p.
1052         //!             Pointer to file buffer to start reading.
1053         //! \param      [in] end.
1054         //!             Pointer to end of file buffer.
1055         //! \param      [in] m.
1056         //!             Pointer ISAfile object.
1057         //! \retval     Pointer to file buffe after parsing one SamplerInfo object.
1058         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)1059         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
1060             unsigned i = 0, count = 0;
1061             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1062                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
1063                 if (!p) return m->setError("bad offset/size for SamplerInfo's field", i);
1064                 i++;
1065             }
1066             // AttributeInfo
1067             count = fields[fields[i].countField].number32;
1068             attribute_info.resize(count);
1069             for (unsigned j = 0; j < count; j++) {
1070                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
1071                 p = r->parse(p, end, m);
1072                 if (!p) {
1073                     delete r;
1074                     return 0;
1075                 }
1076                 attribute_info[j] = r;
1077             }
1078             i++;
1079             return p;
1080         }
1081 
1082         //!
1083         //! \brief      Adds all the SamplerInfo's fields to a buffer.
1084         //! \details    Every field from this class is added to a buffer
1085         //!             in order to be written into an ISA file afterwards
1086         //!             If this class contains other internal structus, their addToBuffer
1087         //!             functions are called when corresponding.
1088         //! \param      [out] buffer.
1089         //!             The buffer where the fields data will be added.
1090         //! \param      [in] m.
1091         //!             Pointer to ISAfile object.
1092         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)1093         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
1094             unsigned i = 0;
1095             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1096                 m->addToBuffer(fields[i], buffer);
1097                 i++;
1098             }
1099             // AttributeInfo
1100             for (AttributeInfo *r : attribute_info) {
1101                 r->addToBuffer(buffer, m);
1102             }
1103             i++;
1104         }
1105 
1106         //!
1107         //! \brief      Makes the changes needed to support 303 version's SamplerInfo.
1108         //! \details    This function is called when the current ISA file has the 303 version.
1109         //!             Initially all the objects are created with last version's format, so
1110         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
1111         //!             of fields can be needed.
1112         //!
setVersion303()1113         void setVersion303() {
1114             fields[0] = Datatype::TWO;
1115         }
1116     };
1117 
1118     //!
1119     //! \brief      LabelInfo Class.
1120     //! \details    This class represents the LabelInfo from vISA Object Format.
1121     //!             Provides getters, setters for its fields and structs as well as
1122     //!             functions to read/write it from/to file.
1123     //!
1124     class LabelInfo {
1125     public:
1126         std::array<Field, 4> fields = std::array<Field, 4>
1127         {
1128             Field(Datatype::FOUR), // name_index
1129                 Field(Datatype::ONE), // kind
1130                 Field(Datatype::ONE), // attribute_count
1131                 Field(Datatype::STRUCT, 2), // attribute_info
1132         };
1133         std::vector<AttributeInfo*> attribute_info;
1134 
1135         //!
1136         //! \brief      Constructor of LabelInfo class.
1137         //! \param      [in] version.
1138         //!             Version of current ISA file.
1139         //!
LabelInfo(unsigned version)1140         LabelInfo(unsigned version) {
1141             if (version <= 303) setVersion303();
1142         }
1143 
1144         //!
1145         //! \brief      Destructor of LabelInfo class.
1146         //!
~LabelInfo()1147         ~LabelInfo() {
1148             for (AttributeInfo *s : attribute_info) delete s;
1149         }
1150 
1151         //!
1152         //! \brief      Returns the integer value of the NameIndex field.
1153         //! \details    NameIndex field is at index 0 in the internal
1154         //!             array of Fields.
1155         //! \retval     An integer.
1156         //!
getNameIndex()1157         uint32_t getNameIndex() {
1158             return (uint32_t)fields[0].number32;
1159         }
1160 
1161         //!
1162         //! \brief      Sets the integer value of the NameIndex field.
1163         //! \details    NameIndex field is at index 0 in the internal
1164         //!             array of Fields.
1165         //! \param      [in] value.
1166         //!             Integer be assigned.
1167         //!
setNameIndex(uint32_t value)1168         void setNameIndex(uint32_t value) {
1169             fields[0].number32 = value;
1170         }
1171 
1172         //!
1173         //! \brief      Returns the integer value of the Kind field.
1174         //! \details    Kind field is at index 1 in the internal
1175         //!             array of Fields.
1176         //! \retval     An integer.
1177         //!
getKind()1178         uint8_t getKind() {
1179             return (uint8_t)fields[1].number8;
1180         }
1181 
1182         //!
1183         //! \brief      Sets the integer value of the Kind field.
1184         //! \details    Kind field is at index 1 in the internal
1185         //!             array of Fields.
1186         //! \param      [in] value.
1187         //!             Integer be assigned.
1188         //!
setKind(uint8_t value)1189         void setKind(uint8_t value) {
1190             fields[1].number8 = value;
1191         }
1192 
1193         //!
1194         //! \brief      Returns the integer value of the AttributeCount field.
1195         //! \details    AttributeCount field is at index 2 in the internal
1196         //!             array of Fields.
1197         //! \retval     An integer.
1198         //!
getAttributeCount()1199         uint8_t getAttributeCount() {
1200             return (uint8_t)fields[2].number8;
1201         }
1202 
1203         //!
1204         //! \brief      Sets the integer value of the AttributeCount field.
1205         //! \details    AttributeCount field is at index 2 in the internal
1206         //!             array of Fields.
1207         //! \param      [in] value.
1208         //!             Integer be assigned.
1209         //!
setAttributeCount(uint8_t value)1210         void setAttributeCount(uint8_t value) {
1211             fields[2].number8 = value;
1212         }
1213 
1214         //!
1215         //! \brief      Returns the reference to the vector of AttributeInfo objects.
1216         //! \details    LabelInfo has a vector of AttributeInfo objects
1217         //!             that represents another entity within the vISA object format.
1218         //! \retval     Reference to the vector of AttributeInfo*.
1219         //!
getAttributeInfo()1220         std::vector<AttributeInfo*> &getAttributeInfo() {
1221             return attribute_info;
1222         }
1223 
1224         //!
1225         //! \brief      Parses one LabelInfo object from ISA file.
1226         //! \details    Reads and parses all the fields of the LabelInfo object
1227         //!             from the file buffer and returns the pointer immediately
1228         //!             after all this data.
1229         //!             If this class contains internal structs, their Parse
1230         //!             functions are called when corresponding.
1231         //! \param      [in] p.
1232         //!             Pointer to file buffer to start reading.
1233         //! \param      [in] end.
1234         //!             Pointer to end of file buffer.
1235         //! \param      [in] m.
1236         //!             Pointer ISAfile object.
1237         //! \retval     Pointer to file buffe after parsing one LabelInfo object.
1238         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)1239         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
1240             unsigned i = 0, count = 0;
1241             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1242                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
1243                 if (!p) return m->setError("bad offset/size for LabelInfo's field", i);
1244                 i++;
1245             }
1246             // AttributeInfo
1247             count = fields[fields[i].countField].number32;
1248             attribute_info.resize(count);
1249             for (unsigned j = 0; j < count; j++) {
1250                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
1251                 p = r->parse(p, end, m);
1252                 if (!p) {
1253                     delete r;
1254                     return 0;
1255                 }
1256                 attribute_info[j] = r;
1257             }
1258             i++;
1259             return p;
1260         }
1261 
1262         //!
1263         //! \brief      Adds all the LabelInfo's fields to a buffer.
1264         //! \details    Every field from this class is added to a buffer
1265         //!             in order to be written into an ISA file afterwards
1266         //!             If this class contains other internal structus, their addToBuffer
1267         //!             functions are called when corresponding.
1268         //! \param      [out] buffer.
1269         //!             The buffer where the fields data will be added.
1270         //! \param      [in] m.
1271         //!             Pointer to ISAfile object.
1272         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)1273         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
1274             unsigned i = 0;
1275             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1276                 m->addToBuffer(fields[i], buffer);
1277                 i++;
1278             }
1279             // AttributeInfo
1280             for (AttributeInfo *r : attribute_info) {
1281                 r->addToBuffer(buffer, m);
1282             }
1283             i++;
1284         }
1285 
1286         //!
1287         //! \brief      Makes the changes needed to support 303 version's LabelInfo.
1288         //! \details    This function is called when the current ISA file has the 303 version.
1289         //!             Initially all the objects are created with last version's format, so
1290         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
1291         //!             of fields can be needed.
1292         //!
setVersion303()1293         void setVersion303() {
1294             fields[0] = Datatype::TWO;
1295         }
1296     };
1297 
1298     //!
1299     //! \brief      PredicateInfo Class.
1300     //! \details    This class represents the PredicateInfo from vISA Object Format.
1301     //!             Provides getters, setters for its fields and structs as well as
1302     //!             functions to read/write it from/to file.
1303     //!
1304     class PredicateInfo {
1305     public:
1306         std::array<Field, 4> fields = std::array<Field, 4>
1307         {
1308             Field(Datatype::FOUR), // name_index
1309                 Field(Datatype::TWO), // num_elements
1310                 Field(Datatype::ONE), // attribute_count
1311                 Field(Datatype::STRUCT, 2), // attribute_info
1312         };
1313         std::vector<AttributeInfo*> attribute_info;
1314 
1315         //!
1316         //! \brief      Constructor of PredicateInfo class.
1317         //! \param      [in] version.
1318         //!             Version of current ISA file.
1319         //!
PredicateInfo(unsigned version)1320         PredicateInfo(unsigned version) {
1321             if (version <= 303) setVersion303();
1322         }
1323 
1324         //!
1325         //! \brief      Destructor of PredicateInfo class.
1326         //!
~PredicateInfo()1327         ~PredicateInfo() {
1328             for (AttributeInfo *s : attribute_info) delete s;
1329         }
1330 
1331         //!
1332         //! \brief      Returns the integer value of the NameIndex field.
1333         //! \details    NameIndex field is at index 0 in the internal
1334         //!             array of Fields.
1335         //! \retval     An integer.
1336         //!
getNameIndex()1337         uint32_t getNameIndex() {
1338             return (uint32_t)fields[0].number32;
1339         }
1340 
1341         //!
1342         //! \brief      Sets the integer value of the NameIndex field.
1343         //! \details    NameIndex field is at index 0 in the internal
1344         //!             array of Fields.
1345         //! \param      [in] value.
1346         //!             Integer be assigned.
1347         //!
setNameIndex(uint32_t value)1348         void setNameIndex(uint32_t value) {
1349             fields[0].number32 = value;
1350         }
1351 
1352         //!
1353         //! \brief      Returns the integer value of the NumElements field.
1354         //! \details    NumElements field is at index 1 in the internal
1355         //!             array of Fields.
1356         //! \retval     An integer.
1357         //!
getNumElements()1358         uint16_t getNumElements() {
1359             return (uint16_t)fields[1].number16;
1360         }
1361 
1362         //!
1363         //! \brief      Sets the integer value of the NumElements field.
1364         //! \details    NumElements field is at index 1 in the internal
1365         //!             array of Fields.
1366         //! \param      [in] value.
1367         //!             Integer be assigned.
1368         //!
setNumElements(uint16_t value)1369         void setNumElements(uint16_t value) {
1370             fields[1].number16 = value;
1371         }
1372 
1373         //!
1374         //! \brief      Returns the integer value of the AttributeCount field.
1375         //! \details    AttributeCount field is at index 2 in the internal
1376         //!             array of Fields.
1377         //! \retval     An integer.
1378         //!
getAttributeCount()1379         uint8_t getAttributeCount() {
1380             return (uint8_t)fields[2].number8;
1381         }
1382 
1383         //!
1384         //! \brief      Sets the integer value of the AttributeCount field.
1385         //! \details    AttributeCount field is at index 2 in the internal
1386         //!             array of Fields.
1387         //! \param      [in] value.
1388         //!             Integer be assigned.
1389         //!
setAttributeCount(uint8_t value)1390         void setAttributeCount(uint8_t value) {
1391             fields[2].number8 = value;
1392         }
1393 
1394         //!
1395         //! \brief      Returns the reference to the vector of AttributeInfo objects.
1396         //! \details    PredicateInfo has a vector of AttributeInfo objects
1397         //!             that represents another entity within the vISA object format.
1398         //! \retval     Reference to the vector of AttributeInfo*.
1399         //!
getAttributeInfo()1400         std::vector<AttributeInfo*> &getAttributeInfo() {
1401             return attribute_info;
1402         }
1403 
1404         //!
1405         //! \brief      Parses one PredicateInfo object from ISA file.
1406         //! \details    Reads and parses all the fields of the PredicateInfo object
1407         //!             from the file buffer and returns the pointer immediately
1408         //!             after all this data.
1409         //!             If this class contains internal structs, their Parse
1410         //!             functions are called when corresponding.
1411         //! \param      [in] p.
1412         //!             Pointer to file buffer to start reading.
1413         //! \param      [in] end.
1414         //!             Pointer to end of file buffer.
1415         //! \param      [in] m.
1416         //!             Pointer ISAfile object.
1417         //! \retval     Pointer to file buffe after parsing one PredicateInfo object.
1418         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)1419         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
1420             unsigned i = 0, count = 0;
1421             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1422                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
1423                 if (!p) return m->setError("bad offset/size for PredicateInfo's field", i);
1424                 i++;
1425             }
1426             // AttributeInfo
1427             count = fields[fields[i].countField].number32;
1428             attribute_info.resize(count);
1429             for (unsigned j = 0; j < count; j++) {
1430                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
1431                 p = r->parse(p, end, m);
1432                 if (!p) {
1433                     delete r;
1434                     return 0;
1435                 }
1436                 attribute_info[j] = r;
1437             }
1438             i++;
1439             return p;
1440         }
1441 
1442         //!
1443         //! \brief      Adds all the PredicateInfo's fields to a buffer.
1444         //! \details    Every field from this class is added to a buffer
1445         //!             in order to be written into an ISA file afterwards
1446         //!             If this class contains other internal structus, their addToBuffer
1447         //!             functions are called when corresponding.
1448         //! \param      [out] buffer.
1449         //!             The buffer where the fields data will be added.
1450         //! \param      [in] m.
1451         //!             Pointer to ISAfile object.
1452         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)1453         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
1454             unsigned i = 0;
1455             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1456                 m->addToBuffer(fields[i], buffer);
1457                 i++;
1458             }
1459             // AttributeInfo
1460             for (AttributeInfo *r : attribute_info) {
1461                 r->addToBuffer(buffer, m);
1462             }
1463             i++;
1464         }
1465 
1466         //!
1467         //! \brief      Makes the changes needed to support 303 version's PredicateInfo.
1468         //! \details    This function is called when the current ISA file has the 303 version.
1469         //!             Initially all the objects are created with last version's format, so
1470         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
1471         //!             of fields can be needed.
1472         //!
setVersion303()1473         void setVersion303() {
1474             fields[0] = Datatype::TWO;
1475         }
1476     };
1477 
1478     //!
1479     //! \brief      RelocationInfo Class.
1480     //! \details    This class represents the RelocationInfo from vISA Object Format.
1481     //!             Provides getters, setters for its fields and structs as well as
1482     //!             functions to read/write it from/to file.
1483     //!
1484     class RelocationInfo {
1485     public:
1486         std::array<Field, 2> fields = std::array<Field, 2>
1487         {
1488             Field(Datatype::TWO), // symbolic_index
1489                 Field(Datatype::TWO) // resolved_index
1490         };
1491 
1492         //!
1493         //! \brief      Constructor of RelocationInfo class.
1494         //! \param      [in] version.
1495         //!             Version of current ISA file.
1496         //!
RelocationInfo(unsigned version)1497         RelocationInfo(unsigned version) {}
1498 
1499         //!
1500         //! \brief      Constructor of RelocationInfo class.
1501         //!
RelocationInfo()1502         RelocationInfo() {}
1503 
1504         //!
1505         //! \brief      Copy Constructor of RelocationInfo class.
1506         //! \param      [in] other.
1507         //!             Reference to object to copy..
1508         //!
RelocationInfo(const RelocationInfo & other)1509         RelocationInfo(const RelocationInfo& other) {
1510             fields = other.fields;
1511         }
1512 
1513         //!
1514         //! \brief      Assignment operator.
1515         //! \param      [in] other.
1516         //!             Reference to object to copy..
1517         //!
1518         RelocationInfo& operator= (const RelocationInfo& other) {
1519             if (this != &other) {
1520                 fields = other.fields;
1521             }
1522             return *this;
1523         }
1524 
1525         //!
1526         //! \brief      Destructor of RelocationInfo class.
1527         //!
~RelocationInfo()1528         ~RelocationInfo() {
1529         }
1530 
1531         //!
1532         //! \brief      Returns the integer value of the SymbolicIndex field.
1533         //! \details    SymbolicIndex field is at index 0 in the internal
1534         //!             array of Fields.
1535         //! \retval     An integer.
1536         //!
getSymbolicIndex()1537         uint16_t getSymbolicIndex() {
1538             return (uint16_t)fields[0].number16;
1539         }
1540 
1541         //!
1542         //! \brief      Sets the integer value of the SymbolicIndex field.
1543         //! \details    SymbolicIndex field is at index 0 in the internal
1544         //!             array of Fields.
1545         //! \param      [in] value.
1546         //!             Integer be assigned.
1547         //!
setSymbolicIndex(uint16_t value)1548         void setSymbolicIndex(uint16_t value) {
1549             fields[0].number16 = value;
1550         }
1551 
1552         //!
1553         //! \brief      Returns the integer value of the ResolvedIndex field.
1554         //! \details    ResolvedIndex field is at index 1 in the internal
1555         //!             array of Fields.
1556         //! \retval     An integer.
1557         //!
getResolvedIndex()1558         uint16_t getResolvedIndex() {
1559             return (uint16_t)fields[1].number16;
1560         }
1561 
1562         //!
1563         //! \brief      Sets the integer value of the ResolvedIndex field.
1564         //! \details    ResolvedIndex field is at index 1 in the internal
1565         //!             array of Fields.
1566         //! \param      [in] value.
1567         //!             Integer be assigned.
1568         //!
setResolvedIndex(uint16_t value)1569         void setResolvedIndex(uint16_t value) {
1570             fields[1].number16 = value;
1571         }
1572 
1573         //!
1574         //! \brief      Parses one RelocationInfo object from ISA file.
1575         //! \details    Reads and parses all the fields of the RelocationInfo object
1576         //!             from the file buffer and returns the pointer immediately
1577         //!             after all this data.
1578         //!             If this class contains internal structs, their Parse
1579         //!             functions are called when corresponding.
1580         //! \param      [in] p.
1581         //!             Pointer to file buffer to start reading.
1582         //! \param      [in] end.
1583         //!             Pointer to end of file buffer.
1584         //! \param      [in] m.
1585         //!             Pointer ISAfile object.
1586         //! \retval     Pointer to file buffe after parsing one RelocationInfo object.
1587         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)1588         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
1589             unsigned i = 0;
1590             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1591                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
1592                 if (!p) return m->setError("bad offset/size for RelocationInfo's field", i);
1593                 i++;
1594             }
1595             return p;
1596         }
1597 
1598         //!
1599         //! \brief      Adds all the RelocationInfo's fields to a buffer.
1600         //! \details    Every field from this class is added to a buffer
1601         //!             in order to be written into an ISA file afterwards
1602         //!             If this class contains other internal structus, their addToBuffer
1603         //!             functions are called when corresponding.
1604         //! \param      [out] buffer.
1605         //!             The buffer where the fields data will be added.
1606         //! \param      [in] m.
1607         //!             Pointer to ISAfile object.
1608         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)1609         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
1610             unsigned i = 0;
1611             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1612                 m->addToBuffer(fields[i], buffer);
1613                 i++;
1614             }
1615         }
1616 
1617     };
1618 
1619     //!
1620     //! \brief      AddressInfo Class.
1621     //! \details    This class represents the AddressInfo from vISA Object Format.
1622     //!             Provides getters, setters for its fields and structs as well as
1623     //!             functions to read/write it from/to file.
1624     //!
1625     class AddressInfo {
1626     public:
1627         std::array<Field, 4> fields = std::array<Field, 4>
1628         {
1629             Field(Datatype::FOUR), // name_index
1630                 Field(Datatype::TWO), // num_elements
1631                 Field(Datatype::ONE), // attribute_count
1632                 Field(Datatype::STRUCT, 2), // attribute_info
1633         };
1634         std::vector<AttributeInfo*> attribute_info;
1635 
1636         //!
1637         //! \brief      Constructor of AddressInfo class.
1638         //! \param      [in] version.
1639         //!             Version of current ISA file.
1640         //!
AddressInfo(unsigned version)1641         AddressInfo(unsigned version) {
1642             if (version <= 303) setVersion303();
1643         }
1644 
1645         //!
1646         //! \brief      Destructor of AddressInfo class.
1647         //!
~AddressInfo()1648         ~AddressInfo() {
1649             for (AttributeInfo *s : attribute_info) delete s;
1650         }
1651 
1652         //!
1653         //! \brief      Returns the integer value of the NameIndex field.
1654         //! \details    NameIndex field is at index 0 in the internal
1655         //!             array of Fields.
1656         //! \retval     An integer.
1657         //!
getNameIndex()1658         uint32_t getNameIndex() {
1659             return (uint32_t)fields[0].number32;
1660         }
1661 
1662         //!
1663         //! \brief      Sets the integer value of the NameIndex field.
1664         //! \details    NameIndex field is at index 0 in the internal
1665         //!             array of Fields.
1666         //! \param      [in] value.
1667         //!             Integer be assigned.
1668         //!
setNameIndex(uint32_t value)1669         void setNameIndex(uint32_t value) {
1670             fields[0].number32 = value;
1671         }
1672 
1673         //!
1674         //! \brief      Returns the integer value of the NumElements field.
1675         //! \details    NumElements field is at index 1 in the internal
1676         //!             array of Fields.
1677         //! \retval     An integer.
1678         //!
getNumElements()1679         uint16_t getNumElements() {
1680             return (uint16_t)fields[1].number16;
1681         }
1682 
1683         //!
1684         //! \brief      Sets the integer value of the NumElements field.
1685         //! \details    NumElements field is at index 1 in the internal
1686         //!             array of Fields.
1687         //! \param      [in] value.
1688         //!             Integer be assigned.
1689         //!
setNumElements(uint16_t value)1690         void setNumElements(uint16_t value) {
1691             fields[1].number16 = value;
1692         }
1693 
1694         //!
1695         //! \brief      Returns the integer value of the AttributeCount field.
1696         //! \details    AttributeCount field is at index 2 in the internal
1697         //!             array of Fields.
1698         //! \retval     An integer.
1699         //!
getAttributeCount()1700         uint8_t getAttributeCount() {
1701             return (uint8_t)fields[2].number8;
1702         }
1703 
1704         //!
1705         //! \brief      Sets the integer value of the AttributeCount field.
1706         //! \details    AttributeCount field is at index 2 in the internal
1707         //!             array of Fields.
1708         //! \param      [in] value.
1709         //!             Integer be assigned.
1710         //!
setAttributeCount(uint8_t value)1711         void setAttributeCount(uint8_t value) {
1712             fields[2].number8 = value;
1713         }
1714 
1715         //!
1716         //! \brief      Returns the reference to the vector of AttributeInfo objects.
1717         //! \details    AddressInfo has a vector of AttributeInfo objects
1718         //!             that represents another entity within the vISA object format.
1719         //! \retval     Reference to the vector of AttributeInfo*.
1720         //!
getAttributeInfo()1721         std::vector<AttributeInfo*> &getAttributeInfo() {
1722             return attribute_info;
1723         }
1724 
1725         //!
1726         //! \brief      Parses one AddressInfo object from ISA file.
1727         //! \details    Reads and parses all the fields of the AddressInfo object
1728         //!             from the file buffer and returns the pointer immediately
1729         //!             after all this data.
1730         //!             If this class contains internal structs, their Parse
1731         //!             functions are called when corresponding.
1732         //! \param      [in] p.
1733         //!             Pointer to file buffer to start reading.
1734         //! \param      [in] end.
1735         //!             Pointer to end of file buffer.
1736         //! \param      [in] m.
1737         //!             Pointer ISAfile object.
1738         //! \retval     Pointer to file buffe after parsing one AddressInfo object.
1739         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)1740         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
1741             unsigned i = 0, count = 0;
1742             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1743                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
1744                 if (!p) return m->setError("bad offset/size for AddressInfo's field", i);
1745                 i++;
1746             }
1747             // AttributeInfo
1748             count = fields[fields[i].countField].number32;
1749             attribute_info.resize(count);
1750             for (unsigned j = 0; j < count; j++) {
1751                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
1752                 p = r->parse(p, end, m);
1753                 if (!p) {
1754                     delete r;
1755                     return 0;
1756                 }
1757                 attribute_info[j] = r;
1758             }
1759             i++;
1760             return p;
1761         }
1762 
1763         //!
1764         //! \brief      Adds all the AddressInfo's fields to a buffer.
1765         //! \details    Every field from this class is added to a buffer
1766         //!             in order to be written into an ISA file afterwards
1767         //!             If this class contains other internal structus, their addToBuffer
1768         //!             functions are called when corresponding.
1769         //! \param      [out] buffer.
1770         //!             The buffer where the fields data will be added.
1771         //! \param      [in] m.
1772         //!             Pointer to ISAfile object.
1773         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)1774         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
1775             unsigned i = 0;
1776             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
1777                 m->addToBuffer(fields[i], buffer);
1778                 i++;
1779             }
1780             // AttributeInfo
1781             for (AttributeInfo *r : attribute_info) {
1782                 r->addToBuffer(buffer, m);
1783             }
1784             i++;
1785         }
1786 
1787         //!
1788         //! \brief      Makes the changes needed to support 303 version's AddressInfo.
1789         //! \details    This function is called when the current ISA file has the 303 version.
1790         //!             Initially all the objects are created with last version's format, so
1791         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
1792         //!             of fields can be needed.
1793         //!
setVersion303()1794         void setVersion303() {
1795             fields[0] = Datatype::TWO;
1796         }
1797     };
1798 
1799     //!
1800     //! \brief      Variable Class.
1801     //! \details    This class represents the Variable from vISA Object Format.
1802     //!             Provides getters, setters for its fields and structs as well as
1803     //!             functions to read/write it from/to file.
1804     //!
1805     class Variable {
1806     public:
1807         std::array<Field, 8> fields = std::array<Field, 8>
1808         {
1809             Field(Datatype::FOUR), // name_index
1810                 Field(Datatype::ONE), // bit_properties
1811                 Field(Datatype::TWO), // num_elements
1812                 Field(Datatype::FOUR), // alias_index
1813                 Field(Datatype::TWO), // alias_offset
1814                 Field(Datatype::ONE), // alias_scope_specifier
1815                 Field(Datatype::ONE), // attribute_count
1816                 Field(Datatype::STRUCT, 6), // attribute_info
1817         };
1818         std::vector<AttributeInfo*> attribute_info;
1819 
1820         //!
1821         //! \brief      Constructor of Variable class.
1822         //! \param      [in] version.
1823         //!             Version of current ISA file.
1824         //!
Variable(unsigned version)1825         Variable(unsigned version) {
1826             if (version <= 303) setVersion303();
1827         }
1828 
1829         //!
1830         //! \brief      Destructor of Variable class.
1831         //!
~Variable()1832         ~Variable() {
1833             for (AttributeInfo *s : attribute_info) delete s;
1834         }
1835 
1836         //!
1837         //! \brief      Returns the integer value of the NameIndex field.
1838         //! \details    NameIndex field is at index 0 in the internal
1839         //!             array of Fields.
1840         //! \retval     An integer.
1841         //!
getNameIndex()1842         uint32_t getNameIndex() {
1843             return (uint32_t)fields[0].number32;
1844         }
1845 
1846         //!
1847         //! \brief      Sets the integer value of the NameIndex field.
1848         //! \details    NameIndex field is at index 0 in the internal
1849         //!             array of Fields.
1850         //! \param      [in] value.
1851         //!             Integer be assigned.
1852         //!
setNameIndex(uint32_t value)1853         void setNameIndex(uint32_t value) {
1854             fields[0].number32 = value;
1855         }
1856 
1857         //!
1858         //! \brief      Returns the integer value of the BitProperties field.
1859         //! \details    BitProperties field is at index 1 in the internal
1860         //!             array of Fields.
1861         //! \retval     An integer.
1862         //!
getBitProperties()1863         uint8_t getBitProperties() {
1864             return (uint8_t)fields[1].number8;
1865         }
1866 
1867         //!
1868         //! \brief      Sets the integer value of the BitProperties field.
1869         //! \details    BitProperties field is at index 1 in the internal
1870         //!             array of Fields.
1871         //! \param      [in] value.
1872         //!             Integer be assigned.
1873         //!
setBitProperties(uint8_t value)1874         void setBitProperties(uint8_t value) {
1875             fields[1].number8 = value;
1876         }
1877 
1878         //!
1879         //! \brief      Returns the integer value of the NumElements field.
1880         //! \details    NumElements field is at index 2 in the internal
1881         //!             array of Fields.
1882         //! \retval     An integer.
1883         //!
getNumElements()1884         uint16_t getNumElements() {
1885             return (uint16_t)fields[2].number16;
1886         }
1887 
1888         //!
1889         //! \brief      Sets the integer value of the NumElements field.
1890         //! \details    NumElements field is at index 2 in the internal
1891         //!             array of Fields.
1892         //! \param      [in] value.
1893         //!             Integer be assigned.
1894         //!
setNumElements(uint16_t value)1895         void setNumElements(uint16_t value) {
1896             fields[2].number16 = value;
1897         }
1898 
1899         //!
1900         //! \brief      Returns the integer value of the AliasIndex field.
1901         //! \details    AliasIndex field is at index 3 in the internal
1902         //!             array of Fields.
1903         //! \retval     An integer.
1904         //!
getAliasIndex()1905         uint32_t getAliasIndex() {
1906             return (uint32_t)fields[3].number32;
1907         }
1908 
1909         //!
1910         //! \brief      Sets the integer value of the AliasIndex field.
1911         //! \details    AliasIndex field is at index 3 in the internal
1912         //!             array of Fields.
1913         //! \param      [in] value.
1914         //!             Integer be assigned.
1915         //!
setAliasIndex(uint32_t value)1916         void setAliasIndex(uint32_t value) {
1917             fields[3].number32 = value;
1918         }
1919 
1920         //!
1921         //! \brief      Returns the integer value of the AliasOffset field.
1922         //! \details    AliasOffset field is at index 4 in the internal
1923         //!             array of Fields.
1924         //! \retval     An integer.
1925         //!
getAliasOffset()1926         uint16_t getAliasOffset() {
1927             return (uint16_t)fields[4].number16;
1928         }
1929 
1930         //!
1931         //! \brief      Sets the integer value of the AliasOffset field.
1932         //! \details    AliasOffset field is at index 4 in the internal
1933         //!             array of Fields.
1934         //! \param      [in] value.
1935         //!             Integer be assigned.
1936         //!
setAliasOffset(uint16_t value)1937         void setAliasOffset(uint16_t value) {
1938             fields[4].number16 = value;
1939         }
1940 
1941         //!
1942         //! \brief      Returns the integer value of the AliasScopeSpecifier field.
1943         //! \details    AliasScopeSpecifier field is at index 5 in the internal
1944         //!             array of Fields.
1945         //! \retval     An integer.
1946         //!
getAliasScopeSpecifier()1947         uint8_t getAliasScopeSpecifier() {
1948             return (uint8_t)fields[5].number8;
1949         }
1950 
1951         //!
1952         //! \brief      Sets the integer value of the AliasScopeSpecifier field.
1953         //! \details    AliasScopeSpecifier field is at index 5 in the internal
1954         //!             array of Fields.
1955         //! \param      [in] value.
1956         //!             Integer be assigned.
1957         //!
setAliasScopeSpecifier(uint8_t value)1958         void setAliasScopeSpecifier(uint8_t value) {
1959             fields[5].number8 = value;
1960         }
1961 
1962         //!
1963         //! \brief      Returns the integer value of the AttributeCount field.
1964         //! \details    AttributeCount field is at index 6 in the internal
1965         //!             array of Fields.
1966         //! \retval     An integer.
1967         //!
getAttributeCount()1968         uint8_t getAttributeCount() {
1969             return (uint8_t)fields[6].number8;
1970         }
1971 
1972         //!
1973         //! \brief      Sets the integer value of the AttributeCount field.
1974         //! \details    AttributeCount field is at index 6 in the internal
1975         //!             array of Fields.
1976         //! \param      [in] value.
1977         //!             Integer be assigned.
1978         //!
setAttributeCount(uint8_t value)1979         void setAttributeCount(uint8_t value) {
1980             fields[6].number8 = value;
1981         }
1982 
1983         //!
1984         //! \brief      Returns the reference to the vector of AttributeInfo objects.
1985         //! \details    Variable has a vector of AttributeInfo objects
1986         //!             that represents another entity within the vISA object format.
1987         //! \retval     Reference to the vector of AttributeInfo*.
1988         //!
getAttributeInfo()1989         std::vector<AttributeInfo*> &getAttributeInfo() {
1990             return attribute_info;
1991         }
1992 
1993         //!
1994         //! \brief      Parses one Variable object from ISA file.
1995         //! \details    Reads and parses all the fields of the Variable object
1996         //!             from the file buffer and returns the pointer immediately
1997         //!             after all this data.
1998         //!             If this class contains internal structs, their Parse
1999         //!             functions are called when corresponding.
2000         //! \param      [in] p.
2001         //!             Pointer to file buffer to start reading.
2002         //! \param      [in] end.
2003         //!             Pointer to end of file buffer.
2004         //! \param      [in] m.
2005         //!             Pointer ISAfile object.
2006         //! \retval     Pointer to file buffe after parsing one Variable object.
2007         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)2008         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
2009             unsigned i = 0, count = 0;
2010             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2011                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
2012                 if (!p) return m->setError("bad offset/size for Variable's field", i);
2013                 i++;
2014             }
2015             // AttributeInfo
2016             count = fields[fields[i].countField].number32;
2017             attribute_info.resize(count);
2018             for (unsigned j = 0; j < count; j++) {
2019                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
2020                 p = r->parse(p, end, m);
2021                 if (!p) {
2022                     delete r;
2023                     return 0;
2024                 }
2025                 attribute_info[j] = r;
2026             }
2027             i++;
2028             return p;
2029         }
2030 
2031         //!
2032         //! \brief      Adds all the Variable's fields to a buffer.
2033         //! \details    Every field from this class is added to a buffer
2034         //!             in order to be written into an ISA file afterwards
2035         //!             If this class contains other internal structus, their addToBuffer
2036         //!             functions are called when corresponding.
2037         //! \param      [out] buffer.
2038         //!             The buffer where the fields data will be added.
2039         //! \param      [in] m.
2040         //!             Pointer to ISAfile object.
2041         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)2042         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
2043             unsigned i = 0;
2044             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2045                 m->addToBuffer(fields[i], buffer);
2046                 i++;
2047             }
2048             // AttributeInfo
2049             for (AttributeInfo *r : attribute_info) {
2050                 r->addToBuffer(buffer, m);
2051             }
2052             i++;
2053         }
2054 
2055         //!
2056         //! \brief      Makes the changes needed to support 303 version's Variable.
2057         //! \details    This function is called when the current ISA file has the 303 version.
2058         //!             Initially all the objects are created with last version's format, so
2059         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
2060         //!             of fields can be needed.
2061         //!
setVersion303()2062         void setVersion303() {
2063             fields[0] = Datatype::TWO;
2064             fields[3] = Datatype::TWO;
2065         }
2066     };
2067 
2068     //!
2069     //! \brief      StringPool Class.
2070     //! \details    This class represents the StringPool from vISA Object Format.
2071     //!             Provides getters, setters for its fields and structs as well as
2072     //!             functions to read/write it from/to file.
2073     //!
2074     class StringPool {
2075     public:
2076         std::array<Field, 1> fields = std::array<Field, 1>
2077         {
2078             Field(Datatype::VARCHAR_POOL) // string
2079         };
2080 
2081         //!
2082         //! \brief      Constructor of StringPool class.
2083         //! \param      [in] version.
2084         //!             Version of current ISA file.
2085         //!
StringPool(unsigned version)2086         StringPool(unsigned version) {}
2087 
2088         //!
2089         //! \brief      Copy Constructor of StringPool class.
2090         //! \param      [in] other.
2091         //!             Reference to object to copy..
2092         //!
StringPool(const StringPool & other)2093         StringPool(const StringPool& other) {
2094             fields = other.fields;
2095         }
2096 
2097         //!
2098         //! \brief      Assignment operator.
2099         //! \param      [in] other.
2100         //!             Reference to object to copy..
2101         //!
2102         StringPool& operator= (const StringPool& other) {
2103             if (this != &other) {
2104                 fields = other.fields;
2105             }
2106             return *this;
2107         }
2108 
2109         //!
2110         //! \brief      Destructor of StringPool class.
2111         //!
~StringPool()2112         ~StringPool() {
2113         }
2114 
2115         //!
2116         //! \brief      Returns the string value of the String field.
2117         //! \details    String field is at index 0 in the internal
2118         //!             array of Fields.
2119         //! \retval     A pointer to the string (const char*).
2120         //!
getString()2121         const char * getString() {
2122             return fields[0].varchar;
2123         }
2124 
2125         //!
2126         //! \brief      Sets the string value of the String field.
2127         //! \details    String field is at index 0 in the internal
2128         //!             array of Fields.
2129         //! \param      [in] value.
2130         //!             Pointer to string (char*) to be assigned.
2131         //!
setString(char * value)2132         void setString(char * value) {
2133             fields[0].varchar = value;
2134         }
2135 
2136         //!
2137         //! \brief      Parses one StringPool object from ISA file.
2138         //! \details    Reads and parses all the fields of the StringPool object
2139         //!             from the file buffer and returns the pointer immediately
2140         //!             after all this data.
2141         //!             If this class contains internal structs, their Parse
2142         //!             functions are called when corresponding.
2143         //! \param      [in] p.
2144         //!             Pointer to file buffer to start reading.
2145         //! \param      [in] end.
2146         //!             Pointer to end of file buffer.
2147         //! \param      [in] m.
2148         //!             Pointer ISAfile object.
2149         //! \retval     Pointer to file buffe after parsing one StringPool object.
2150         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)2151         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
2152             unsigned i = 0;
2153             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2154                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
2155                 if (!p) return m->setError("bad offset/size for StringPool's field", i);
2156                 i++;
2157             }
2158             return p;
2159         }
2160 
2161         //!
2162         //! \brief      Adds all the StringPool's fields to a buffer.
2163         //! \details    Every field from this class is added to a buffer
2164         //!             in order to be written into an ISA file afterwards
2165         //!             If this class contains other internal structus, their addToBuffer
2166         //!             functions are called when corresponding.
2167         //! \param      [out] buffer.
2168         //!             The buffer where the fields data will be added.
2169         //! \param      [in] m.
2170         //!             Pointer to ISAfile object.
2171         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)2172         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
2173             unsigned i = 0;
2174             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2175                 m->addToBuffer(fields[i], buffer);
2176                 i++;
2177             }
2178         }
2179 
2180     };
2181 
2182     //!
2183     //! \brief      GenBinary Class.
2184     //! \details    This class represents the GenBinary from vISA Object Format.
2185     //!             Provides getters, setters for its fields and structs as well as
2186     //!             functions to read/write it from/to file.
2187     //!
2188     class GenBinary {
2189     public:
2190         std::array<Field, 3> fields = std::array<Field, 3>
2191         {
2192             Field(Datatype::ONE), // gen_platform
2193                 Field(Datatype::FOUR), // binary_offset
2194                 Field(Datatype::FOUR) // binary_size
2195         };
2196 
2197         //!
2198         //! \brief      Constructor of GenBinary class.
2199         //! \param      [in] version.
2200         //!             Version of current ISA file.
2201         //!
GenBinary(unsigned version)2202         GenBinary(unsigned version) {}
2203 
2204         //!
2205         //! \brief      Constructor of GenBinary class.
2206         //!
GenBinary()2207         GenBinary() {}
2208 
2209         //!
2210         //! \brief      Copy Constructor of GenBinary class.
2211         //! \param      [in] other.
2212         //!             Reference to object to copy..
2213         //!
GenBinary(const GenBinary & other)2214         GenBinary(const GenBinary& other) {
2215             fields = other.fields;
2216         }
2217 
2218         //!
2219         //! \brief      Assignment operator.
2220         //! \param      [in] other.
2221         //!             Reference to object to copy..
2222         //!
2223         GenBinary& operator= (const GenBinary& other) {
2224             if (this != &other) {
2225                 fields = other.fields;
2226             }
2227             return *this;
2228         }
2229 
2230         //!
2231         //! \brief      Destructor of GenBinary class.
2232         //!
~GenBinary()2233         ~GenBinary() {
2234         }
2235 
2236         //!
2237         //! \brief      Returns the integer value of the GenPlatform field.
2238         //! \details    GenPlatform field is at index 0 in the internal
2239         //!             array of Fields.
2240         //! \retval     An integer.
2241         //!
getGenPlatform()2242         uint8_t getGenPlatform() {
2243             return (uint8_t)fields[0].number8;
2244         }
2245 
2246         //!
2247         //! \brief      Sets the integer value of the GenPlatform field.
2248         //! \details    GenPlatform field is at index 0 in the internal
2249         //!             array of Fields.
2250         //! \param      [in] value.
2251         //!             Integer be assigned.
2252         //!
setGenPlatform(uint8_t value)2253         void setGenPlatform(uint8_t value) {
2254             fields[0].number8 = value;
2255         }
2256 
2257         //!
2258         //! \brief      Returns the integer value of the BinaryOffset field.
2259         //! \details    BinaryOffset field is at index 1 in the internal
2260         //!             array of Fields.
2261         //! \retval     An integer.
2262         //!
getBinaryOffset()2263         uint32_t getBinaryOffset() {
2264             return (uint32_t)fields[1].number32;
2265         }
2266 
2267         //!
2268         //! \brief      Sets the integer value of the BinaryOffset field.
2269         //! \details    BinaryOffset field is at index 1 in the internal
2270         //!             array of Fields.
2271         //! \param      [in] value.
2272         //!             Integer be assigned.
2273         //!
setBinaryOffset(uint32_t value)2274         void setBinaryOffset(uint32_t value) {
2275             fields[1].number32 = value;
2276         }
2277 
2278         //!
2279         //! \brief      Returns the integer value of the BinarySize field.
2280         //! \details    BinarySize field is at index 2 in the internal
2281         //!             array of Fields.
2282         //! \retval     An integer.
2283         //!
getBinarySize()2284         uint32_t getBinarySize() {
2285             return (uint32_t)fields[2].number32;
2286         }
2287 
2288         //!
2289         //! \brief      Sets the integer value of the BinarySize field.
2290         //! \details    BinarySize field is at index 2 in the internal
2291         //!             array of Fields.
2292         //! \param      [in] value.
2293         //!             Integer be assigned.
2294         //!
setBinarySize(uint32_t value)2295         void setBinarySize(uint32_t value) {
2296             fields[2].number32 = value;
2297         }
2298 
2299         //!
2300         //! \brief      Parses one GenBinary object from ISA file.
2301         //! \details    Reads and parses all the fields of the GenBinary object
2302         //!             from the file buffer and returns the pointer immediately
2303         //!             after all this data.
2304         //!             If this class contains internal structs, their Parse
2305         //!             functions are called when corresponding.
2306         //! \param      [in] p.
2307         //!             Pointer to file buffer to start reading.
2308         //! \param      [in] end.
2309         //!             Pointer to end of file buffer.
2310         //! \param      [in] m.
2311         //!             Pointer ISAfile object.
2312         //! \retval     Pointer to file buffe after parsing one GenBinary object.
2313         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)2314         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
2315             unsigned i = 0;
2316             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2317                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
2318                 if (!p) return m->setError("bad offset/size for GenBinary's field", i);
2319                 i++;
2320             }
2321             return p;
2322         }
2323 
2324         //!
2325         //! \brief      Adds all the GenBinary's fields to a buffer.
2326         //! \details    Every field from this class is added to a buffer
2327         //!             in order to be written into an ISA file afterwards
2328         //!             If this class contains other internal structus, their addToBuffer
2329         //!             functions are called when corresponding.
2330         //! \param      [out] buffer.
2331         //!             The buffer where the fields data will be added.
2332         //! \param      [in] m.
2333         //!             Pointer to ISAfile object.
2334         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)2335         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
2336             unsigned i = 0;
2337             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2338                 m->addToBuffer(fields[i], buffer);
2339                 i++;
2340             }
2341         }
2342 
2343     };
2344 
2345     //!
2346     //! \brief      Function Class.
2347     //! \details    This class represents the Function from vISA Object Format.
2348     //!             Provides getters, setters for its fields and structs as well as
2349     //!             functions to read/write it from/to file.
2350     //!
2351     class Function {
2352     public:
2353         std::array<Field, 9> fields = std::array<Field, 9>
2354         {
2355             Field(Datatype::ONE), // linkage
2356                 Field(Datatype::TWO), // name_len
2357                 Field(Datatype::VARCHAR, 1), // name
2358                 Field(Datatype::FOUR), // offset
2359                 Field(Datatype::FOUR), // size
2360                 Field(Datatype::TWO), // num_syms_variable
2361                 Field(Datatype::STRUCT, 5), // variable_reloc_symtab
2362                 Field(Datatype::TWO), // num_syms_function
2363                 Field(Datatype::STRUCT, 7), // function_reloc_symtab
2364         };
2365         std::vector<RelocationInfo*> variable_reloc_symtab;
2366         std::vector<RelocationInfo*> function_reloc_symtab;
2367 
2368         //!
2369         //! \brief      Constructor of Function class.
2370         //! \param      [in] version.
2371         //!             Version of current ISA file.
2372         //!
Function(unsigned version)2373         Function(unsigned version) {
2374             if (version <= 306) setVersion306();
2375         }
2376 
2377         //!
2378         //! \brief      Constructor of Function class.
2379         //!
Function()2380         Function() {}
2381 
2382         //!
2383         //! \brief      Copy Constructor of Function class.
2384         //! \param      [in] other.
2385         //!             Reference to object to copy..
2386         //!
Function(const Function & other)2387         Function(const Function& other) {
2388             fields = other.fields;
2389             for (RelocationInfo *r : other.variable_reloc_symtab) {
2390                 RelocationInfo *s = new RelocationInfo();
2391                 *s = *r;
2392                 variable_reloc_symtab.push_back(s);
2393             }
2394             for (RelocationInfo *r : other.function_reloc_symtab) {
2395                 RelocationInfo *s = new RelocationInfo();
2396                 *s = *r;
2397                 function_reloc_symtab.push_back(s);
2398             }
2399         }
2400 
2401         //!
2402         //! \brief      Assignment operator.
2403         //! \param      [in] other.
2404         //!             Reference to object to copy..
2405         //!
2406         Function& operator= (const Function& other) {
2407             if (this != &other) {
2408                 fields = other.fields;
2409                 for (RelocationInfo *r : variable_reloc_symtab)
2410                     delete r;
2411                 for (RelocationInfo *r : other.variable_reloc_symtab) {
2412                     RelocationInfo *s = new RelocationInfo();
2413                     *s = *r;
2414                     variable_reloc_symtab.push_back(s);
2415                 }
2416                 for (RelocationInfo *r : function_reloc_symtab)
2417                     delete r;
2418                 for (RelocationInfo *r : other.function_reloc_symtab) {
2419                     RelocationInfo *s = new RelocationInfo();
2420                     *s = *r;
2421                     function_reloc_symtab.push_back(s);
2422                 }
2423             }
2424             return *this;
2425         }
2426 
2427         //!
2428         //! \brief      Destructor of Function class.
2429         //!
~Function()2430         ~Function() {
2431             for (RelocationInfo *s : variable_reloc_symtab) delete s;
2432             for (RelocationInfo *s : function_reloc_symtab) delete s;
2433         }
2434 
2435         //!
2436         //! \brief      Returns the integer value of the Linkage field.
2437         //! \details    Linkage field is at index 0 in the internal
2438         //!             array of Fields.
2439         //! \retval     An integer.
2440         //!
getLinkage()2441         uint8_t getLinkage() {
2442             return (uint8_t)fields[0].number8;
2443         }
2444 
2445         //!
2446         //! \brief      Sets the integer value of the Linkage field.
2447         //! \details    Linkage field is at index 0 in the internal
2448         //!             array of Fields.
2449         //! \param      [in] value.
2450         //!             Integer be assigned.
2451         //!
setLinkage(uint8_t value)2452         void setLinkage(uint8_t value) {
2453             fields[0].number8 = value;
2454         }
2455 
2456         //!
2457         //! \brief      Returns the integer value of the NameLen field.
2458         //! \details    NameLen field is at index 1 in the internal
2459         //!             array of Fields for version <= 306
2460         //! \retval     An integer.
2461         //!
getNameLen_Ver306()2462         uint8_t getNameLen_Ver306() {
2463             return (uint8_t)fields[1].number8;
2464         }
2465 
2466         //!
2467         //! \brief      Returns the integer value of the NameLen field.
2468         //! \details    NameLen field is at index 1 in the internal
2469         //!             array of Fields
2470         //! \retval     An integer.
2471         //!
getNameLen()2472         uint16_t getNameLen() {
2473             return (uint16_t)fields[1].number16;
2474         }
2475 
2476         //!
2477         //! \brief      Sets the integer value of the NameLen field.
2478         //! \details    NameLen field is at index 1 in the internal
2479         //!             array of Fields for version <= 306
2480         //! \param      [in] value.
2481         //!             Integer be assigned.
2482         //!
setNameLen_Ver306(uint8_t value)2483         void setNameLen_Ver306(uint8_t value) {
2484             fields[1].number8 = value;
2485         }
2486 
2487         //!
2488         //! \brief      Sets the integer value of the NameLen field.
2489         //! \details    NameLen field is at index 1 in the internal
2490         //!             array of Fields.
2491         //! \param      [in] value.
2492         //!             Integer be assigned.
2493         //!
setNameLen(uint16_t value)2494         void setNameLen(uint16_t value)
2495         {
2496             fields[1].number16 = value;
2497         }
2498 
2499         //!
2500         //! \brief      Returns the string value of the Name field.
2501         //! \details    Name field is at index 2 in the internal
2502         //!             array of Fields.
2503         //! \retval     A pointer to the string (const char*).
2504         //!
getName()2505         const char * getName() {
2506             return fields[2].varchar;
2507         }
2508 
2509         //!
2510         //! \brief      Sets the string value of the Name field.
2511         //! \details    Name field is at index 2 in the internal
2512         //!             array of Fields.
2513         //! \param      [in] value.
2514         //!             Pointer to string (char*) to be assigned.
2515         //!
setName(char * value)2516         void setName(char * value) {
2517             fields[2].varchar = value;
2518         }
2519 
2520         //!
2521         //! \brief      Returns the integer value of the Offset field.
2522         //! \details    Offset field is at index 3 in the internal
2523         //!             array of Fields.
2524         //! \retval     An integer.
2525         //!
getOffset()2526         uint32_t getOffset() {
2527             return (uint32_t)fields[3].number32;
2528         }
2529 
2530         //!
2531         //! \brief      Sets the integer value of the Offset field.
2532         //! \details    Offset field is at index 3 in the internal
2533         //!             array of Fields.
2534         //! \param      [in] value.
2535         //!             Integer be assigned.
2536         //!
setOffset(uint32_t value)2537         void setOffset(uint32_t value) {
2538             fields[3].number32 = value;
2539         }
2540 
2541         //!
2542         //! \brief      Returns the integer value of the Size field.
2543         //! \details    Size field is at index 4 in the internal
2544         //!             array of Fields.
2545         //! \retval     An integer.
2546         //!
getSize()2547         uint32_t getSize() {
2548             return (uint32_t)fields[4].number32;
2549         }
2550 
2551         //!
2552         //! \brief      Sets the integer value of the Size field.
2553         //! \details    Size field is at index 4 in the internal
2554         //!             array of Fields.
2555         //! \param      [in] value.
2556         //!             Integer be assigned.
2557         //!
setSize(uint32_t value)2558         void setSize(uint32_t value) {
2559             fields[4].number32 = value;
2560         }
2561 
2562         //!
2563         //! \brief      Returns the integer value of the NumSymsVariable field.
2564         //! \details    NumSymsVariable field is at index 5 in the internal
2565         //!             array of Fields.
2566         //! \retval     An integer.
2567         //!
getNumSymsVariable()2568         uint16_t getNumSymsVariable() {
2569             return (uint16_t)fields[5].number16;
2570         }
2571 
2572         //!
2573         //! \brief      Sets the integer value of the NumSymsVariable field.
2574         //! \details    NumSymsVariable field is at index 5 in the internal
2575         //!             array of Fields.
2576         //! \param      [in] value.
2577         //!             Integer be assigned.
2578         //!
setNumSymsVariable(uint16_t value)2579         void setNumSymsVariable(uint16_t value) {
2580             fields[5].number16 = value;
2581         }
2582 
2583         //!
2584         //! \brief      Returns the reference to the vector of RelocationInfo objects.
2585         //! \details    Function has a vector of RelocationInfo objects
2586         //!             that represents another entity within the vISA object format.
2587         //! \retval     Reference to the vector of RelocationInfo*.
2588         //!
getVariableRelocSymtab()2589         std::vector<RelocationInfo*> &getVariableRelocSymtab() {
2590             return variable_reloc_symtab;
2591         }
2592 
2593         //!
2594         //! \brief      Returns the integer value of the NumSymsFunction field.
2595         //! \details    NumSymsFunction field is at index 7 in the internal
2596         //!             array of Fields.
2597         //! \retval     An integer.
2598         //!
getNumSymsFunction()2599         uint16_t getNumSymsFunction() {
2600             return (uint16_t)fields[7].number16;
2601         }
2602 
2603         //!
2604         //! \brief      Sets the integer value of the NumSymsFunction field.
2605         //! \details    NumSymsFunction field is at index 7 in the internal
2606         //!             array of Fields.
2607         //! \param      [in] value.
2608         //!             Integer be assigned.
2609         //!
setNumSymsFunction(uint16_t value)2610         void setNumSymsFunction(uint16_t value) {
2611             fields[7].number16 = value;
2612         }
2613 
2614         //!
2615         //! \brief      Returns the reference to the vector of RelocationInfo objects.
2616         //! \details    Function has a vector of RelocationInfo objects
2617         //!             that represents another entity within the vISA object format.
2618         //! \retval     Reference to the vector of RelocationInfo*.
2619         //!
getFunctionRelocSymtab()2620         std::vector<RelocationInfo*> &getFunctionRelocSymtab() {
2621             return function_reloc_symtab;
2622         }
2623 
2624         //!
2625         //! \brief      Parses one Function object from ISA file.
2626         //! \details    Reads and parses all the fields of the Function object
2627         //!             from the file buffer and returns the pointer immediately
2628         //!             after all this data.
2629         //!             If this class contains internal structs, their Parse
2630         //!             functions are called when corresponding.
2631         //! \param      [in] p.
2632         //!             Pointer to file buffer to start reading.
2633         //! \param      [in] end.
2634         //!             Pointer to end of file buffer.
2635         //! \param      [in] m.
2636         //!             Pointer ISAfile object.
2637         //! \retval     Pointer to file buffe after parsing one Function object.
2638         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)2639         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
2640             unsigned i = 0, count = 0;
2641             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2642                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
2643                 if (!p) return m->setError("bad offset/size for Function's field", i);
2644                 i++;
2645             }
2646             // RelocationInfo
2647             count = fields[fields[i].countField].number32;
2648             variable_reloc_symtab.resize(count);
2649             for (unsigned j = 0; j < count; j++) {
2650                 RelocationInfo *r = new RelocationInfo(m->getCurrentVISAVersion());
2651                 p = r->parse(p, end, m);
2652                 if (!p) {
2653                     delete r;
2654                     return 0;
2655                 }
2656                 variable_reloc_symtab[j] = r;
2657             }
2658             i++;
2659             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2660                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
2661                 if (!p) return m->setError("bad offset/size for Function's field", i);
2662                 i++;
2663             }
2664             // RelocationInfo
2665             count = fields[fields[i].countField].number32;
2666             function_reloc_symtab.resize(count);
2667             for (unsigned j = 0; j < count; j++) {
2668                 RelocationInfo *r = new RelocationInfo(m->getCurrentVISAVersion());
2669                 p = r->parse(p, end, m);
2670                 if (!p) {
2671                     delete r;
2672                     return 0;
2673                 }
2674                 function_reloc_symtab[j] = r;
2675             }
2676             i++;
2677             return p;
2678         }
2679 
2680         //!
2681         //! \brief      Adds all the Function's fields to a buffer.
2682         //! \details    Every field from this class is added to a buffer
2683         //!             in order to be written into an ISA file afterwards
2684         //!             If this class contains other internal structus, their addToBuffer
2685         //!             functions are called when corresponding.
2686         //! \param      [out] buffer.
2687         //!             The buffer where the fields data will be added.
2688         //! \param      [in] m.
2689         //!             Pointer to ISAfile object.
2690         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)2691         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
2692             unsigned i = 0;
2693             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2694                 m->addToBuffer(fields[i], buffer);
2695                 i++;
2696             }
2697             // RelocationInfo
2698             for (RelocationInfo *r : variable_reloc_symtab) {
2699                 r->addToBuffer(buffer, m);
2700             }
2701             i++;
2702             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2703                 m->addToBuffer(fields[i], buffer);
2704                 i++;
2705             }
2706             // RelocationInfo
2707             for (RelocationInfo *r : function_reloc_symtab) {
2708                 r->addToBuffer(buffer, m);
2709             }
2710             i++;
2711         }
2712 
2713                 //!
2714         //! \brief      Makes the changes needed to support 306 version's Function.
2715         //! \details    This function is called when the current ISA file has the 306 version.
2716         //!             Initially all the objects are created with last version's format, so
2717         //!             in order to suppport newer versions, changes of datatypes and insertion/removal
2718         //!             of fields can be needed.
2719         //!
setVersion306()2720         void setVersion306()
2721         {
2722             fields[1] = Datatype::ONE;
2723         }
2724 
2725     };
2726 
2727     //!
2728     //! \brief      GlobalVariable Class.
2729     //! \details    This class represents the GlobalVariable from vISA Object Format.
2730     //!             Provides getters, setters for its fields and structs as well as
2731     //!             functions to read/write it from/to file.
2732     //!
2733     class GlobalVariable {
2734     public:
2735         std::array<Field, 7> fields = std::array<Field, 7>
2736         {
2737             Field(Datatype::ONE), // linkage
2738                 Field(Datatype::TWO), // name_len
2739                 Field(Datatype::VARCHAR, 1), // name
2740                 Field(Datatype::ONE), // bit_properties
2741                 Field(Datatype::TWO), // num_elements
2742                 Field(Datatype::ONE), // attribute_count
2743                 Field(Datatype::STRUCT, 5), // attribute_info
2744         };
2745         std::vector<AttributeInfo*> attribute_info;
2746 
2747         //!
2748         //! \brief      Constructor of GlobalVariable class.
2749         //! \param      [in] version.
2750         //!             Version of current ISA file.
2751         //!
GlobalVariable(unsigned version)2752         GlobalVariable(unsigned version) {}
2753 
2754         //!
2755         //! \brief      Constructor of GlobalVariable class.
2756         //!
GlobalVariable()2757         GlobalVariable() {}
2758 
2759         //!
2760         //! \brief      Copy Constructor of GlobalVariable class.
2761         //! \param      [in] other.
2762         //!             Reference to object to copy..
2763         //!
GlobalVariable(const GlobalVariable & other)2764         GlobalVariable(const GlobalVariable& other) {
2765             fields = other.fields;
2766             for (AttributeInfo *r : other.attribute_info) {
2767                 AttributeInfo *s = new AttributeInfo();
2768                 *s = *r;
2769                 attribute_info.push_back(s);
2770             }
2771         }
2772 
2773         //!
2774         //! \brief      Assignment operator.
2775         //! \param      [in] other.
2776         //!             Reference to object to copy..
2777         //!
2778         GlobalVariable& operator= (const GlobalVariable& other) {
2779             if (this != &other) {
2780                 fields = other.fields;
2781                 for (AttributeInfo *r : attribute_info)
2782                     delete r;
2783                 for (AttributeInfo *r : other.attribute_info) {
2784                     AttributeInfo *s = new AttributeInfo();
2785                     *s = *r;
2786                     attribute_info.push_back(s);
2787                 }
2788             }
2789             return *this;
2790         }
2791 
2792         //!
2793         //! \brief      Destructor of GlobalVariable class.
2794         //!
~GlobalVariable()2795         ~GlobalVariable() {
2796             for (AttributeInfo *s : attribute_info) delete s;
2797         }
2798 
2799         //!
2800         //! \brief      Returns the integer value of the Linkage field.
2801         //! \details    Linkage field is at index 0 in the internal
2802         //!             array of Fields.
2803         //! \retval     An integer.
2804         //!
getLinkage()2805         uint8_t getLinkage() {
2806             return (uint8_t)fields[0].number8;
2807         }
2808 
2809         //!
2810         //! \brief      Sets the integer value of the Linkage field.
2811         //! \details    Linkage field is at index 0 in the internal
2812         //!             array of Fields.
2813         //! \param      [in] value.
2814         //!             Integer be assigned.
2815         //!
setLinkage(uint8_t value)2816         void setLinkage(uint8_t value) {
2817             fields[0].number8 = value;
2818         }
2819 
2820         //!
2821         //! \brief      Returns the integer value of the NameLen field.
2822         //! \details    NameLen field is at index 1 in the internal
2823         //!             array of Fields.
2824         //! \retval     An integer.
2825         //!
getNameLen()2826         uint16_t getNameLen() {
2827             return (uint16_t)fields[1].number16;
2828         }
2829 
2830         //!
2831         //! \brief      Sets the integer value of the NameLen field.
2832         //! \details    NameLen field is at index 1 in the internal
2833         //!             array of Fields.
2834         //! \param      [in] value.
2835         //!             Integer be assigned.
2836         //!
setNameLen(uint16_t value)2837         void setNameLen(uint16_t value) {
2838             fields[1].number16 = value;
2839         }
2840 
2841         //!
2842         //! \brief      Returns the string value of the Name field.
2843         //! \details    Name field is at index 2 in the internal
2844         //!             array of Fields.
2845         //! \retval     A pointer to the string (const char*).
2846         //!
getName()2847         const char * getName() {
2848             return fields[2].varchar;
2849         }
2850 
2851         //!
2852         //! \brief      Sets the string value of the Name field.
2853         //! \details    Name field is at index 2 in the internal
2854         //!             array of Fields.
2855         //! \param      [in] value.
2856         //!             Pointer to string (char*) to be assigned.
2857         //!
setName(char * value)2858         void setName(char * value) {
2859             fields[2].varchar = value;
2860         }
2861 
2862         //!
2863         //! \brief      Returns the integer value of the BitProperties field.
2864         //! \details    BitProperties field is at index 3 in the internal
2865         //!             array of Fields.
2866         //! \retval     An integer.
2867         //!
getBitProperties()2868         uint8_t getBitProperties() {
2869             return (uint8_t)fields[3].number8;
2870         }
2871 
2872         //!
2873         //! \brief      Sets the integer value of the BitProperties field.
2874         //! \details    BitProperties field is at index 3 in the internal
2875         //!             array of Fields.
2876         //! \param      [in] value.
2877         //!             Integer be assigned.
2878         //!
setBitProperties(uint8_t value)2879         void setBitProperties(uint8_t value) {
2880             fields[3].number8 = value;
2881         }
2882 
2883         //!
2884         //! \brief      Returns the integer value of the NumElements field.
2885         //! \details    NumElements field is at index 4 in the internal
2886         //!             array of Fields.
2887         //! \retval     An integer.
2888         //!
getNumElements()2889         uint16_t getNumElements() {
2890             return (uint16_t)fields[4].number16;
2891         }
2892 
2893         //!
2894         //! \brief      Sets the integer value of the NumElements field.
2895         //! \details    NumElements field is at index 4 in the internal
2896         //!             array of Fields.
2897         //! \param      [in] value.
2898         //!             Integer be assigned.
2899         //!
setNumElements(uint16_t value)2900         void setNumElements(uint16_t value) {
2901             fields[4].number16 = value;
2902         }
2903 
2904         //!
2905         //! \brief      Returns the integer value of the AttributeCount field.
2906         //! \details    AttributeCount field is at index 5 in the internal
2907         //!             array of Fields.
2908         //! \retval     An integer.
2909         //!
getAttributeCount()2910         uint8_t getAttributeCount() {
2911             return (uint8_t)fields[5].number8;
2912         }
2913 
2914         //!
2915         //! \brief      Sets the integer value of the AttributeCount field.
2916         //! \details    AttributeCount field is at index 5 in the internal
2917         //!             array of Fields.
2918         //! \param      [in] value.
2919         //!             Integer be assigned.
2920         //!
setAttributeCount(uint8_t value)2921         void setAttributeCount(uint8_t value) {
2922             fields[5].number8 = value;
2923         }
2924 
2925         //!
2926         //! \brief      Returns the reference to the vector of AttributeInfo objects.
2927         //! \details    GlobalVariable has a vector of AttributeInfo objects
2928         //!             that represents another entity within the vISA object format.
2929         //! \retval     Reference to the vector of AttributeInfo*.
2930         //!
getAttributeInfo()2931         std::vector<AttributeInfo*> &getAttributeInfo() {
2932             return attribute_info;
2933         }
2934 
2935         //!
2936         //! \brief      Parses one GlobalVariable object from ISA file.
2937         //! \details    Reads and parses all the fields of the GlobalVariable object
2938         //!             from the file buffer and returns the pointer immediately
2939         //!             after all this data.
2940         //!             If this class contains internal structs, their Parse
2941         //!             functions are called when corresponding.
2942         //! \param      [in] p.
2943         //!             Pointer to file buffer to start reading.
2944         //! \param      [in] end.
2945         //!             Pointer to end of file buffer.
2946         //! \param      [in] m.
2947         //!             Pointer ISAfile object.
2948         //! \retval     Pointer to file buffe after parsing one GlobalVariable object.
2949         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)2950         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
2951             unsigned i = 0, count = 0;
2952             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2953                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
2954                 if (!p) return m->setError("bad offset/size for GlobalVariable's field", i);
2955                 i++;
2956             }
2957             // AttributeInfo
2958             count = fields[fields[i].countField].number32;
2959             attribute_info.resize(count);
2960             for (unsigned j = 0; j < count; j++) {
2961                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
2962                 p = r->parse(p, end, m);
2963                 if (!p) {
2964                     delete r;
2965                     return 0;
2966                 }
2967                 attribute_info[j] = r;
2968             }
2969             i++;
2970             return p;
2971         }
2972 
2973         //!
2974         //! \brief      Adds all the GlobalVariable's fields to a buffer.
2975         //! \details    Every field from this class is added to a buffer
2976         //!             in order to be written into an ISA file afterwards
2977         //!             If this class contains other internal structus, their addToBuffer
2978         //!             functions are called when corresponding.
2979         //! \param      [out] buffer.
2980         //!             The buffer where the fields data will be added.
2981         //! \param      [in] m.
2982         //!             Pointer to ISAfile object.
2983         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)2984         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
2985             unsigned i = 0;
2986             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
2987                 m->addToBuffer(fields[i], buffer);
2988                 i++;
2989             }
2990             // AttributeInfo
2991             for (AttributeInfo *r : attribute_info) {
2992                 r->addToBuffer(buffer, m);
2993             }
2994             i++;
2995         }
2996 
2997     };
2998 
2999     //!
3000     //! \brief      FunctionBody Class.
3001     //! \details    This class represents the FunctionBody from vISA Object Format.
3002     //!             Provides getters, setters for its fields and structs as well as
3003     //!             functions to read/write it from/to file.
3004     //!
3005     class FunctionBody {
3006     public:
3007         std::array<Field, 24> fields = std::array<Field, 24>
3008         {
3009             Field(Datatype::FOUR), // string_count
3010                 Field(Datatype::STRUCT, 0), // string_pool
3011                 Field(Datatype::FOUR), // name_index
3012                 Field(Datatype::FOUR), // variable_count
3013                 Field(Datatype::STRUCT, 3), // var_info
3014                 Field(Datatype::TWO), // address_count
3015                 Field(Datatype::STRUCT, 5), // address_info
3016                 Field(Datatype::TWO), // predicate_count
3017                 Field(Datatype::STRUCT, 7), // predicate_info
3018                 Field(Datatype::TWO), // label_count
3019                 Field(Datatype::STRUCT, 9), // label_info
3020                 Field(Datatype::ONE), // sampler_count
3021                 Field(Datatype::STRUCT, 11), // sampler_info
3022                 Field(Datatype::ONE), // surface_count
3023                 Field(Datatype::STRUCT, 13), // surface_info
3024                 Field(Datatype::ONE), // vme_count
3025                 Field(Datatype::STRUCT, 15), // vme_info
3026                 Field(Datatype::FOUR), // size
3027                 Field(Datatype::FOUR), // entry
3028                 Field(Datatype::ONE), // input_size
3029                 Field(Datatype::ONE), // return_value_size
3030                 Field(Datatype::TWO), // attribute_count
3031                 Field(Datatype::STRUCT, 21), // attribute_info
3032                 Field(Datatype::GDATA, 17) // instructions
3033         };
3034         std::vector<StringPool*> string_pool;
3035         std::vector<Variable*> var_info;
3036         std::vector<AddressInfo*> address_info;
3037         std::vector<PredicateInfo*> predicate_info;
3038         std::vector<LabelInfo*> label_info;
3039         std::vector<SamplerInfo*> sampler_info;
3040         std::vector<SurfaceInfo*> surface_info;
3041         std::vector<VmeInfo*> vme_info;
3042         std::vector<AttributeInfo*> attribute_info;
3043 
3044         //!
3045         //! \brief      Constructor of FunctionBody class.
3046         //! \param      [in] version.
3047         //!             Version of current ISA file.
3048         //!
FunctionBody(unsigned version)3049         FunctionBody(unsigned version) {
3050             if (version <= 303) setVersion303();
3051         }
3052 
3053         //!
3054         //! \brief      Destructor of FunctionBody class.
3055         //!
~FunctionBody()3056         ~FunctionBody() {
3057             for (StringPool *s : string_pool) delete s;
3058             for (Variable *s : var_info) delete s;
3059             for (AddressInfo *s : address_info) delete s;
3060             for (PredicateInfo *s : predicate_info) delete s;
3061             for (LabelInfo *s : label_info) delete s;
3062             for (SamplerInfo *s : sampler_info) delete s;
3063             for (SurfaceInfo *s : surface_info) delete s;
3064             for (VmeInfo *s : vme_info) delete s;
3065             for (AttributeInfo *s : attribute_info) delete s;
3066         }
3067 
3068         //!
3069         //! \brief      Returns the integer value of the StringCount field.
3070         //! \details    StringCount field is at index 0 in the internal
3071         //!             array of Fields.
3072         //! \retval     An integer.
3073         //!
getStringCount()3074         uint32_t getStringCount() {
3075             return (uint32_t)fields[0].number32;
3076         }
3077 
3078         //!
3079         //! \brief      Sets the integer value of the StringCount field.
3080         //! \details    StringCount field is at index 0 in the internal
3081         //!             array of Fields.
3082         //! \param      [in] value.
3083         //!             Integer be assigned.
3084         //!
setStringCount(uint32_t value)3085         void setStringCount(uint32_t value) {
3086             fields[0].number32 = value;
3087         }
3088 
3089         //!
3090         //! \brief      Returns the reference to the vector of StringPool objects.
3091         //! \details    FunctionBody has a vector of StringPool objects
3092         //!             that represents another entity within the vISA object format.
3093         //! \retval     Reference to the vector of StringPool*.
3094         //!
getStringPool()3095         std::vector<StringPool*> &getStringPool() {
3096             return string_pool;
3097         }
3098 
3099         //!
3100         //! \brief      Returns the integer value of the NameIndex field.
3101         //! \details    NameIndex field is at index 2 in the internal
3102         //!             array of Fields.
3103         //! \retval     An integer.
3104         //!
getNameIndex()3105         uint32_t getNameIndex() {
3106             return (uint32_t)fields[2].number32;
3107         }
3108 
3109         //!
3110         //! \brief      Sets the integer value of the NameIndex field.
3111         //! \details    NameIndex field is at index 2 in the internal
3112         //!             array of Fields.
3113         //! \param      [in] value.
3114         //!             Integer be assigned.
3115         //!
setNameIndex(uint32_t value)3116         void setNameIndex(uint32_t value) {
3117             fields[2].number32 = value;
3118         }
3119 
3120         //!
3121         //! \brief      Returns the integer value of the VariableCount field.
3122         //! \details    VariableCount field is at index 3 in the internal
3123         //!             array of Fields.
3124         //! \retval     An integer.
3125         //!
getVariableCount()3126         uint32_t getVariableCount() {
3127             return (uint32_t)fields[3].number32;
3128         }
3129 
3130         //!
3131         //! \brief      Sets the integer value of the VariableCount field.
3132         //! \details    VariableCount field is at index 3 in the internal
3133         //!             array of Fields.
3134         //! \param      [in] value.
3135         //!             Integer be assigned.
3136         //!
setVariableCount(uint32_t value)3137         void setVariableCount(uint32_t value) {
3138             fields[3].number32 = value;
3139         }
3140 
3141         //!
3142         //! \brief      Returns the reference to the vector of Variable objects.
3143         //! \details    FunctionBody has a vector of Variable objects
3144         //!             that represents another entity within the vISA object format.
3145         //! \retval     Reference to the vector of Variable*.
3146         //!
getVarInfo()3147         std::vector<Variable*> &getVarInfo() {
3148             return var_info;
3149         }
3150 
3151         //!
3152         //! \brief      Returns the integer value of the AddressCount field.
3153         //! \details    AddressCount field is at index 5 in the internal
3154         //!             array of Fields.
3155         //! \retval     An integer.
3156         //!
getAddressCount()3157         uint16_t getAddressCount() {
3158             return (uint16_t)fields[5].number16;
3159         }
3160 
3161         //!
3162         //! \brief      Sets the integer value of the AddressCount field.
3163         //! \details    AddressCount field is at index 5 in the internal
3164         //!             array of Fields.
3165         //! \param      [in] value.
3166         //!             Integer be assigned.
3167         //!
setAddressCount(uint16_t value)3168         void setAddressCount(uint16_t value) {
3169             fields[5].number16 = value;
3170         }
3171 
3172         //!
3173         //! \brief      Returns the reference to the vector of AddressInfo objects.
3174         //! \details    FunctionBody has a vector of AddressInfo objects
3175         //!             that represents another entity within the vISA object format.
3176         //! \retval     Reference to the vector of AddressInfo*.
3177         //!
getAddressInfo()3178         std::vector<AddressInfo*> &getAddressInfo() {
3179             return address_info;
3180         }
3181 
3182         //!
3183         //! \brief      Returns the integer value of the PredicateCount field.
3184         //! \details    PredicateCount field is at index 7 in the internal
3185         //!             array of Fields.
3186         //! \retval     An integer.
3187         //!
getPredicateCount()3188         uint16_t getPredicateCount() {
3189             return (uint16_t)fields[7].number16;
3190         }
3191 
3192         //!
3193         //! \brief      Sets the integer value of the PredicateCount field.
3194         //! \details    PredicateCount field is at index 7 in the internal
3195         //!             array of Fields.
3196         //! \param      [in] value.
3197         //!             Integer be assigned.
3198         //!
setPredicateCount(uint16_t value)3199         void setPredicateCount(uint16_t value) {
3200             fields[7].number16 = value;
3201         }
3202 
3203         //!
3204         //! \brief      Returns the reference to the vector of PredicateInfo objects.
3205         //! \details    FunctionBody has a vector of PredicateInfo objects
3206         //!             that represents another entity within the vISA object format.
3207         //! \retval     Reference to the vector of PredicateInfo*.
3208         //!
getPredicateInfo()3209         std::vector<PredicateInfo*> &getPredicateInfo() {
3210             return predicate_info;
3211         }
3212 
3213         //!
3214         //! \brief      Returns the integer value of the LabelCount field.
3215         //! \details    LabelCount field is at index 9 in the internal
3216         //!             array of Fields.
3217         //! \retval     An integer.
3218         //!
getLabelCount()3219         uint16_t getLabelCount() {
3220             return (uint16_t)fields[9].number16;
3221         }
3222 
3223         //!
3224         //! \brief      Sets the integer value of the LabelCount field.
3225         //! \details    LabelCount field is at index 9 in the internal
3226         //!             array of Fields.
3227         //! \param      [in] value.
3228         //!             Integer be assigned.
3229         //!
setLabelCount(uint16_t value)3230         void setLabelCount(uint16_t value) {
3231             fields[9].number16 = value;
3232         }
3233 
3234         //!
3235         //! \brief      Returns the reference to the vector of LabelInfo objects.
3236         //! \details    FunctionBody has a vector of LabelInfo objects
3237         //!             that represents another entity within the vISA object format.
3238         //! \retval     Reference to the vector of LabelInfo*.
3239         //!
getLabelInfo()3240         std::vector<LabelInfo*> &getLabelInfo() {
3241             return label_info;
3242         }
3243 
3244         //!
3245         //! \brief      Returns the integer value of the SamplerCount field.
3246         //! \details    SamplerCount field is at index 11 in the internal
3247         //!             array of Fields.
3248         //! \retval     An integer.
3249         //!
getSamplerCount()3250         uint8_t getSamplerCount() {
3251             return (uint8_t)fields[11].number8;
3252         }
3253 
3254         //!
3255         //! \brief      Sets the integer value of the SamplerCount field.
3256         //! \details    SamplerCount field is at index 11 in the internal
3257         //!             array of Fields.
3258         //! \param      [in] value.
3259         //!             Integer be assigned.
3260         //!
setSamplerCount(uint8_t value)3261         void setSamplerCount(uint8_t value) {
3262             fields[11].number8 = value;
3263         }
3264 
3265         //!
3266         //! \brief      Returns the reference to the vector of SamplerInfo objects.
3267         //! \details    FunctionBody has a vector of SamplerInfo objects
3268         //!             that represents another entity within the vISA object format.
3269         //! \retval     Reference to the vector of SamplerInfo*.
3270         //!
getSamplerInfo()3271         std::vector<SamplerInfo*> &getSamplerInfo() {
3272             return sampler_info;
3273         }
3274 
3275         //!
3276         //! \brief      Returns the integer value of the SurfaceCount field.
3277         //! \details    SurfaceCount field is at index 13 in the internal
3278         //!             array of Fields.
3279         //! \retval     An integer.
3280         //!
getSurfaceCount()3281         uint8_t getSurfaceCount() {
3282             return (uint8_t)fields[13].number8;
3283         }
3284 
3285         //!
3286         //! \brief      Sets the integer value of the SurfaceCount field.
3287         //! \details    SurfaceCount field is at index 13 in the internal
3288         //!             array of Fields.
3289         //! \param      [in] value.
3290         //!             Integer be assigned.
3291         //!
setSurfaceCount(uint8_t value)3292         void setSurfaceCount(uint8_t value) {
3293             fields[13].number8 = value;
3294         }
3295 
3296         //!
3297         //! \brief      Returns the reference to the vector of SurfaceInfo objects.
3298         //! \details    FunctionBody has a vector of SurfaceInfo objects
3299         //!             that represents another entity within the vISA object format.
3300         //! \retval     Reference to the vector of SurfaceInfo*.
3301         //!
getSurfaceInfo()3302         std::vector<SurfaceInfo*> &getSurfaceInfo() {
3303             return surface_info;
3304         }
3305 
3306         //!
3307         //! \brief      Returns the integer value of the VmeCount field.
3308         //! \details    VmeCount field is at index 15 in the internal
3309         //!             array of Fields.
3310         //! \retval     An integer.
3311         //!
getVmeCount()3312         uint8_t getVmeCount() {
3313             return (uint8_t)fields[15].number8;
3314         }
3315 
3316         //!
3317         //! \brief      Sets the integer value of the VmeCount field.
3318         //! \details    VmeCount field is at index 15 in the internal
3319         //!             array of Fields.
3320         //! \param      [in] value.
3321         //!             Integer be assigned.
3322         //!
setVmeCount(uint8_t value)3323         void setVmeCount(uint8_t value) {
3324             fields[15].number8 = value;
3325         }
3326 
3327         //!
3328         //! \brief      Returns the reference to the vector of VmeInfo objects.
3329         //! \details    FunctionBody has a vector of VmeInfo objects
3330         //!             that represents another entity within the vISA object format.
3331         //! \retval     Reference to the vector of VmeInfo*.
3332         //!
getVmeInfo()3333         std::vector<VmeInfo*> &getVmeInfo() {
3334             return vme_info;
3335         }
3336 
3337         //!
3338         //! \brief      Returns the integer value of the Size field.
3339         //! \details    Size field is at index 17 in the internal
3340         //!             array of Fields.
3341         //! \retval     An integer.
3342         //!
getSize()3343         uint32_t getSize() {
3344             return (uint32_t)fields[17].number32;
3345         }
3346 
3347         //!
3348         //! \brief      Sets the integer value of the Size field.
3349         //! \details    Size field is at index 17 in the internal
3350         //!             array of Fields.
3351         //! \param      [in] value.
3352         //!             Integer be assigned.
3353         //!
setSize(uint32_t value)3354         void setSize(uint32_t value) {
3355             fields[17].number32 = value;
3356         }
3357 
3358         //!
3359         //! \brief      Returns the integer value of the Entry field.
3360         //! \details    Entry field is at index 18 in the internal
3361         //!             array of Fields.
3362         //! \retval     An integer.
3363         //!
getEntry()3364         uint32_t getEntry() {
3365             return (uint32_t)fields[18].number32;
3366         }
3367 
3368         //!
3369         //! \brief      Sets the integer value of the Entry field.
3370         //! \details    Entry field is at index 18 in the internal
3371         //!             array of Fields.
3372         //! \param      [in] value.
3373         //!             Integer be assigned.
3374         //!
setEntry(uint32_t value)3375         void setEntry(uint32_t value) {
3376             fields[18].number32 = value;
3377         }
3378 
3379         //!
3380         //! \brief      Returns the integer value of the InputSize field.
3381         //! \details    InputSize field is at index 19 in the internal
3382         //!             array of Fields.
3383         //! \retval     An integer.
3384         //!
getInputSize()3385         uint8_t getInputSize() {
3386             return (uint8_t)fields[19].number8;
3387         }
3388 
3389         //!
3390         //! \brief      Sets the integer value of the InputSize field.
3391         //! \details    InputSize field is at index 19 in the internal
3392         //!             array of Fields.
3393         //! \param      [in] value.
3394         //!             Integer be assigned.
3395         //!
setInputSize(uint8_t value)3396         void setInputSize(uint8_t value) {
3397             fields[19].number8 = value;
3398         }
3399 
3400         //!
3401         //! \brief      Returns the integer value of the ReturnValueSize field.
3402         //! \details    ReturnValueSize field is at index 20 in the internal
3403         //!             array of Fields.
3404         //! \retval     An integer.
3405         //!
getReturnValueSize()3406         uint8_t getReturnValueSize() {
3407             return (uint8_t)fields[20].number8;
3408         }
3409 
3410         //!
3411         //! \brief      Sets the integer value of the ReturnValueSize field.
3412         //! \details    ReturnValueSize field is at index 20 in the internal
3413         //!             array of Fields.
3414         //! \param      [in] value.
3415         //!             Integer be assigned.
3416         //!
setReturnValueSize(uint8_t value)3417         void setReturnValueSize(uint8_t value) {
3418             fields[20].number8 = value;
3419         }
3420 
3421         //!
3422         //! \brief      Returns the integer value of the AttributeCount field.
3423         //! \details    AttributeCount field is at index 21 in the internal
3424         //!             array of Fields.
3425         //! \retval     An integer.
3426         //!
getAttributeCount()3427         uint16_t getAttributeCount() {
3428             return (uint16_t)fields[21].number16;
3429         }
3430 
3431         //!
3432         //! \brief      Sets the integer value of the AttributeCount field.
3433         //! \details    AttributeCount field is at index 21 in the internal
3434         //!             array of Fields.
3435         //! \param      [in] value.
3436         //!             Integer be assigned.
3437         //!
setAttributeCount(uint16_t value)3438         void setAttributeCount(uint16_t value) {
3439             fields[21].number16 = value;
3440         }
3441 
3442         //!
3443         //! \brief      Returns the reference to the vector of AttributeInfo objects.
3444         //! \details    FunctionBody has a vector of AttributeInfo objects
3445         //!             that represents another entity within the vISA object format.
3446         //! \retval     Reference to the vector of AttributeInfo*.
3447         //!
getAttributeInfo()3448         std::vector<AttributeInfo*> &getAttributeInfo() {
3449             return attribute_info;
3450         }
3451 
3452         //!
3453         //! \brief      Returns the pointer to buffer data from Instructions field.
3454         //! \details    Instructions field is at index 23 in the internal
3455         //!             array of Fields.
3456         //! \retval     A pointer to buffer data (const uint8_t*).
3457         //!
getInstructions()3458         const uint8_t* getInstructions() {
3459             return fields[23].gdata;
3460         }
3461 
3462         //!
3463         //! \brief      Sets the pointer to buffer data of the Instructions field.
3464         //! \details    Instructions field is at index 23 in the internal
3465         //!             array of Fields.
3466         //! \param      [in] value.
3467         //!             Pointer to buffer data (uint8_t*) to be assigned.
3468         //!
setInstructions(uint8_t * value)3469         void setInstructions(uint8_t * value) {
3470             fields[23].gdata = value;
3471         }
3472 
3473         //!
3474         //! \brief      Parses one FunctionBody object from ISA file.
3475         //! \details    Reads and parses all the fields of the FunctionBody object
3476         //!             from the file buffer and returns the pointer immediately
3477         //!             after all this data.
3478         //!             If this class contains internal structs, their Parse
3479         //!             functions are called when corresponding.
3480         //! \param      [in] p.
3481         //!             Pointer to file buffer to start reading.
3482         //! \param      [in] end.
3483         //!             Pointer to end of file buffer.
3484         //! \param      [in] m.
3485         //!             Pointer ISAfile object.
3486         //! \retval     Pointer to file buffe after parsing one FunctionBody object.
3487         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)3488         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
3489             unsigned i = 0, count = 0;
3490             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3491                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3492                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3493                 i++;
3494             }
3495             // StringPool
3496             count = fields[fields[i].countField].number32;
3497             string_pool.resize(count);
3498             for (unsigned j = 0; j < count; j++) {
3499                 StringPool *r = new StringPool(m->getCurrentVISAVersion());
3500                 p = r->parse(p, end, m);
3501                 if (!p) {
3502                     delete r;
3503                     return 0;
3504                 }
3505                 string_pool[j] = r;
3506             }
3507             i++;
3508             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3509                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3510                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3511                 i++;
3512             }
3513             // Variable
3514             count = fields[fields[i].countField].number32;
3515             var_info.resize(count);
3516             for (unsigned j = 0; j < count; j++) {
3517                 Variable *r = new Variable(m->getCurrentVISAVersion());
3518                 p = r->parse(p, end, m);
3519                 if (!p) {
3520                     delete r;
3521                     return 0;
3522                 }
3523                 var_info[j] = r;
3524             }
3525             i++;
3526             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3527                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3528                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3529                 i++;
3530             }
3531             // AddressInfo
3532             count = fields[fields[i].countField].number32;
3533             address_info.resize(count);
3534             for (unsigned j = 0; j < count; j++) {
3535                 AddressInfo *r = new AddressInfo(m->getCurrentVISAVersion());
3536                 p = r->parse(p, end, m);
3537                 if (!p) {
3538                     delete r;
3539                     return 0;
3540                 }
3541                 address_info[j] = r;
3542             }
3543             i++;
3544             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3545                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3546                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3547                 i++;
3548             }
3549             // PredicateInfo
3550             count = fields[fields[i].countField].number32;
3551             predicate_info.resize(count);
3552             for (unsigned j = 0; j < count; j++) {
3553                 PredicateInfo *r = new PredicateInfo(m->getCurrentVISAVersion());
3554                 p = r->parse(p, end, m);
3555                 if (!p) {
3556                     delete r;
3557                     return 0;
3558                 }
3559                 predicate_info[j] = r;
3560             }
3561             i++;
3562             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3563                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3564                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3565                 i++;
3566             }
3567             // LabelInfo
3568             count = fields[fields[i].countField].number32;
3569             label_info.resize(count);
3570             for (unsigned j = 0; j < count; j++) {
3571                 LabelInfo *r = new LabelInfo(m->getCurrentVISAVersion());
3572                 p = r->parse(p, end, m);
3573                 if (!p) {
3574                     delete r;
3575                     return 0;
3576                 }
3577                 label_info[j] = r;
3578             }
3579             i++;
3580             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3581                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3582                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3583                 i++;
3584             }
3585             // SamplerInfo
3586             count = fields[fields[i].countField].number32;
3587             sampler_info.resize(count);
3588             for (unsigned j = 0; j < count; j++) {
3589                 SamplerInfo *r = new SamplerInfo(m->getCurrentVISAVersion());
3590                 p = r->parse(p, end, m);
3591                 if (!p) {
3592                     delete r;
3593                     return 0;
3594                 }
3595                 sampler_info[j] = r;
3596             }
3597             i++;
3598             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3599                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3600                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3601                 i++;
3602             }
3603             // SurfaceInfo
3604             count = fields[fields[i].countField].number32;
3605             surface_info.resize(count);
3606             for (unsigned j = 0; j < count; j++) {
3607                 SurfaceInfo *r = new SurfaceInfo(m->getCurrentVISAVersion());
3608                 p = r->parse(p, end, m);
3609                 if (!p) {
3610                     delete r;
3611                     return 0;
3612                 }
3613                 surface_info[j] = r;
3614             }
3615             i++;
3616             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3617                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3618                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3619                 i++;
3620             }
3621             // VmeInfo
3622             count = fields[fields[i].countField].number32;
3623             vme_info.resize(count);
3624             for (unsigned j = 0; j < count; j++) {
3625                 VmeInfo *r = new VmeInfo(m->getCurrentVISAVersion());
3626                 p = r->parse(p, end, m);
3627                 if (!p) {
3628                     delete r;
3629                     return 0;
3630                 }
3631                 vme_info[j] = r;
3632             }
3633             i++;
3634             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3635                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3636                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3637                 i++;
3638             }
3639             // AttributeInfo
3640             count = fields[fields[i].countField].number32;
3641             attribute_info.resize(count);
3642             for (unsigned j = 0; j < count; j++) {
3643                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
3644                 p = r->parse(p, end, m);
3645                 if (!p) {
3646                     delete r;
3647                     return 0;
3648                 }
3649                 attribute_info[j] = r;
3650             }
3651             i++;
3652             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3653                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
3654                 if (!p) return m->setError("bad offset/size for FunctionBody's field", i);
3655                 i++;
3656             }
3657             return p;
3658         }
3659 
3660         //!
3661         //! \brief      Adds all the FunctionBody's fields to a buffer.
3662         //! \details    Every field from this class is added to a buffer
3663         //!             in order to be written into an ISA file afterwards
3664         //!             If this class contains other internal structus, their addToBuffer
3665         //!             functions are called when corresponding.
3666         //! \param      [out] buffer.
3667         //!             The buffer where the fields data will be added.
3668         //! \param      [in] m.
3669         //!             Pointer to ISAfile object.
3670         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)3671         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
3672             unsigned i = 0;
3673             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3674                 m->addToBuffer(fields[i], buffer);
3675                 i++;
3676             }
3677             // StringPool
3678             for (StringPool *r : string_pool) {
3679                 r->addToBuffer(buffer, m);
3680             }
3681             i++;
3682             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3683                 m->addToBuffer(fields[i], buffer);
3684                 i++;
3685             }
3686             // Variable
3687             for (Variable *r : var_info) {
3688                 r->addToBuffer(buffer, m);
3689             }
3690             i++;
3691             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3692                 m->addToBuffer(fields[i], buffer);
3693                 i++;
3694             }
3695             // AddressInfo
3696             for (AddressInfo *r : address_info) {
3697                 r->addToBuffer(buffer, m);
3698             }
3699             i++;
3700             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3701                 m->addToBuffer(fields[i], buffer);
3702                 i++;
3703             }
3704             // PredicateInfo
3705             for (PredicateInfo *r : predicate_info) {
3706                 r->addToBuffer(buffer, m);
3707             }
3708             i++;
3709             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3710                 m->addToBuffer(fields[i], buffer);
3711                 i++;
3712             }
3713             // LabelInfo
3714             for (LabelInfo *r : label_info) {
3715                 r->addToBuffer(buffer, m);
3716             }
3717             i++;
3718             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3719                 m->addToBuffer(fields[i], buffer);
3720                 i++;
3721             }
3722             // SamplerInfo
3723             for (SamplerInfo *r : sampler_info) {
3724                 r->addToBuffer(buffer, m);
3725             }
3726             i++;
3727             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3728                 m->addToBuffer(fields[i], buffer);
3729                 i++;
3730             }
3731             // SurfaceInfo
3732             for (SurfaceInfo *r : surface_info) {
3733                 r->addToBuffer(buffer, m);
3734             }
3735             i++;
3736             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3737                 m->addToBuffer(fields[i], buffer);
3738                 i++;
3739             }
3740             // VmeInfo
3741             for (VmeInfo *r : vme_info) {
3742                 r->addToBuffer(buffer, m);
3743             }
3744             i++;
3745             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3746                 m->addToBuffer(fields[i], buffer);
3747                 i++;
3748             }
3749             // AttributeInfo
3750             for (AttributeInfo *r : attribute_info) {
3751                 r->addToBuffer(buffer, m);
3752             }
3753             i++;
3754             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
3755                 m->addToBuffer(fields[i], buffer);
3756                 i++;
3757             }
3758         }
3759 
3760         //!
3761         //! \brief      Makes the changes needed to support 303 version's FunctionBody.
3762         //! \details    This function is called when the current ISA file has the 303 version.
3763         //!             Initially all the objects are created with last version's format, so
3764         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
3765         //!             of fields can be needed.
3766         //!
setVersion303()3767         void setVersion303() {
3768             fields[0] = Datatype::TWO;
3769             fields[2] = Datatype::TWO;
3770             fields[3] = Datatype::TWO;
3771         }
3772     };
3773 
3774     //!
3775     //! \brief      KernelBody Class.
3776     //! \details    This class represents the KernelBody from vISA Object Format.
3777     //!             Provides getters, setters for its fields and structs as well as
3778     //!             functions to read/write it from/to file.
3779     //!
3780     class KernelBody {
3781     public:
3782         std::array<Field, 24> fields = std::array<Field, 24>
3783         {
3784             Field(Datatype::FOUR), // string_count
3785                 Field(Datatype::STRUCT, 0), // string_pool
3786                 Field(Datatype::FOUR), // name_index
3787                 Field(Datatype::FOUR), // variable_count
3788                 Field(Datatype::STRUCT, 3), // var_info
3789                 Field(Datatype::TWO), // address_count
3790                 Field(Datatype::STRUCT, 5), // address_info
3791                 Field(Datatype::TWO), // predicate_count
3792                 Field(Datatype::STRUCT, 7), // predicate_info
3793                 Field(Datatype::TWO), // label_count
3794                 Field(Datatype::STRUCT, 9), // label_info
3795                 Field(Datatype::ONE), // sampler_count
3796                 Field(Datatype::STRUCT, 11), // sampler_info
3797                 Field(Datatype::ONE), // surface_count
3798                 Field(Datatype::STRUCT, 13), // surface_info
3799                 Field(Datatype::ONE), // vme_count
3800                 Field(Datatype::STRUCT, 15), // vme_info
3801                 Field(Datatype::FOUR), // num_inputs
3802                 Field(Datatype::STRUCT, 17), // input_info
3803                 Field(Datatype::FOUR), // size
3804                 Field(Datatype::FOUR), // entry
3805                 Field(Datatype::TWO), // attribute_count
3806                 Field(Datatype::STRUCT, 21), // attribute_info
3807                 Field(Datatype::GDATA, 19) // instructions
3808         };
3809         std::vector<StringPool*> string_pool;
3810         std::vector<Variable*> var_info;
3811         std::vector<AddressInfo*> address_info;
3812         std::vector<PredicateInfo*> predicate_info;
3813         std::vector<LabelInfo*> label_info;
3814         std::vector<SamplerInfo*> sampler_info;
3815         std::vector<SurfaceInfo*> surface_info;
3816         std::vector<VmeInfo*> vme_info;
3817         std::vector<InputInfo*> input_info;
3818         std::vector<AttributeInfo*> attribute_info;
3819 
3820         //!
3821         //! \brief      Constructor of KernelBody class.
3822         //! \param      [in] version.
3823         //!             Version of current ISA file.
3824         //!
KernelBody(unsigned version)3825         KernelBody(unsigned version) {
3826             if (version <= 304) setVersion304();
3827             if (version <= 303) setVersion303();
3828         }
3829 
3830         //!
3831         //! \brief      Destructor of KernelBody class.
3832         //!
~KernelBody()3833         ~KernelBody() {
3834             for (StringPool *s : string_pool) delete s;
3835             for (Variable *s : var_info) delete s;
3836             for (AddressInfo *s : address_info) delete s;
3837             for (PredicateInfo *s : predicate_info) delete s;
3838             for (LabelInfo *s : label_info) delete s;
3839             for (SamplerInfo *s : sampler_info) delete s;
3840             for (SurfaceInfo *s : surface_info) delete s;
3841             for (VmeInfo *s : vme_info) delete s;
3842             for (InputInfo *s : input_info) delete s;
3843             for (AttributeInfo *s : attribute_info) delete s;
3844         }
3845 
3846         //!
3847         //! \brief      Returns the integer value of the StringCount field.
3848         //! \details    StringCount field is at index 0 in the internal
3849         //!             array of Fields.
3850         //! \retval     An integer.
3851         //!
getStringCount()3852         uint32_t getStringCount() {
3853             return (uint32_t)fields[0].number32;
3854         }
3855 
3856         //!
3857         //! \brief      Sets the integer value of the StringCount field.
3858         //! \details    StringCount field is at index 0 in the internal
3859         //!             array of Fields.
3860         //! \param      [in] value.
3861         //!             Integer be assigned.
3862         //!
setStringCount(uint32_t value)3863         void setStringCount(uint32_t value) {
3864             fields[0].number32 = value;
3865         }
3866 
3867         //!
3868         //! \brief      Returns the reference to the vector of StringPool objects.
3869         //! \details    KernelBody has a vector of StringPool objects
3870         //!             that represents another entity within the vISA object format.
3871         //! \retval     Reference to the vector of StringPool*.
3872         //!
getStringPool()3873         std::vector<StringPool*> &getStringPool() {
3874             return string_pool;
3875         }
3876 
3877         //!
3878         //! \brief      Returns the integer value of the NameIndex field.
3879         //! \details    NameIndex field is at index 2 in the internal
3880         //!             array of Fields.
3881         //! \retval     An integer.
3882         //!
getNameIndex()3883         uint32_t getNameIndex() {
3884             return (uint32_t)fields[2].number32;
3885         }
3886 
3887         //!
3888         //! \brief      Sets the integer value of the NameIndex field.
3889         //! \details    NameIndex field is at index 2 in the internal
3890         //!             array of Fields.
3891         //! \param      [in] value.
3892         //!             Integer be assigned.
3893         //!
setNameIndex(uint32_t value)3894         void setNameIndex(uint32_t value) {
3895             fields[2].number32 = value;
3896         }
3897 
3898         //!
3899         //! \brief      Returns the integer value of the VariableCount field.
3900         //! \details    VariableCount field is at index 3 in the internal
3901         //!             array of Fields.
3902         //! \retval     An integer.
3903         //!
getVariableCount()3904         uint32_t getVariableCount() {
3905             return (uint32_t)fields[3].number32;
3906         }
3907 
3908         //!
3909         //! \brief      Sets the integer value of the VariableCount field.
3910         //! \details    VariableCount field is at index 3 in the internal
3911         //!             array of Fields.
3912         //! \param      [in] value.
3913         //!             Integer be assigned.
3914         //!
setVariableCount(uint32_t value)3915         void setVariableCount(uint32_t value) {
3916             fields[3].number32 = value;
3917         }
3918 
3919         //!
3920         //! \brief      Returns the reference to the vector of Variable objects.
3921         //! \details    KernelBody has a vector of Variable objects
3922         //!             that represents another entity within the vISA object format.
3923         //! \retval     Reference to the vector of Variable*.
3924         //!
getVarInfo()3925         std::vector<Variable*> &getVarInfo() {
3926             return var_info;
3927         }
3928 
3929         //!
3930         //! \brief      Returns the integer value of the AddressCount field.
3931         //! \details    AddressCount field is at index 5 in the internal
3932         //!             array of Fields.
3933         //! \retval     An integer.
3934         //!
getAddressCount()3935         uint16_t getAddressCount() {
3936             return (uint16_t)fields[5].number16;
3937         }
3938 
3939         //!
3940         //! \brief      Sets the integer value of the AddressCount field.
3941         //! \details    AddressCount field is at index 5 in the internal
3942         //!             array of Fields.
3943         //! \param      [in] value.
3944         //!             Integer be assigned.
3945         //!
setAddressCount(uint16_t value)3946         void setAddressCount(uint16_t value) {
3947             fields[5].number16 = value;
3948         }
3949 
3950         //!
3951         //! \brief      Returns the reference to the vector of AddressInfo objects.
3952         //! \details    KernelBody has a vector of AddressInfo objects
3953         //!             that represents another entity within the vISA object format.
3954         //! \retval     Reference to the vector of AddressInfo*.
3955         //!
getAddressInfo()3956         std::vector<AddressInfo*> &getAddressInfo() {
3957             return address_info;
3958         }
3959 
3960         //!
3961         //! \brief      Returns the integer value of the PredicateCount field.
3962         //! \details    PredicateCount field is at index 7 in the internal
3963         //!             array of Fields.
3964         //! \retval     An integer.
3965         //!
getPredicateCount()3966         uint16_t getPredicateCount() {
3967             return (uint16_t)fields[7].number16;
3968         }
3969 
3970         //!
3971         //! \brief      Sets the integer value of the PredicateCount field.
3972         //! \details    PredicateCount field is at index 7 in the internal
3973         //!             array of Fields.
3974         //! \param      [in] value.
3975         //!             Integer be assigned.
3976         //!
setPredicateCount(uint16_t value)3977         void setPredicateCount(uint16_t value) {
3978             fields[7].number16 = value;
3979         }
3980 
3981         //!
3982         //! \brief      Returns the reference to the vector of PredicateInfo objects.
3983         //! \details    KernelBody has a vector of PredicateInfo objects
3984         //!             that represents another entity within the vISA object format.
3985         //! \retval     Reference to the vector of PredicateInfo*.
3986         //!
getPredicateInfo()3987         std::vector<PredicateInfo*> &getPredicateInfo() {
3988             return predicate_info;
3989         }
3990 
3991         //!
3992         //! \brief      Returns the integer value of the LabelCount field.
3993         //! \details    LabelCount field is at index 9 in the internal
3994         //!             array of Fields.
3995         //! \retval     An integer.
3996         //!
getLabelCount()3997         uint16_t getLabelCount() {
3998             return (uint16_t)fields[9].number16;
3999         }
4000 
4001         //!
4002         //! \brief      Sets the integer value of the LabelCount field.
4003         //! \details    LabelCount field is at index 9 in the internal
4004         //!             array of Fields.
4005         //! \param      [in] value.
4006         //!             Integer be assigned.
4007         //!
setLabelCount(uint16_t value)4008         void setLabelCount(uint16_t value) {
4009             fields[9].number16 = value;
4010         }
4011 
4012         //!
4013         //! \brief      Returns the reference to the vector of LabelInfo objects.
4014         //! \details    KernelBody has a vector of LabelInfo objects
4015         //!             that represents another entity within the vISA object format.
4016         //! \retval     Reference to the vector of LabelInfo*.
4017         //!
getLabelInfo()4018         std::vector<LabelInfo*> &getLabelInfo() {
4019             return label_info;
4020         }
4021 
4022         //!
4023         //! \brief      Returns the integer value of the SamplerCount field.
4024         //! \details    SamplerCount field is at index 11 in the internal
4025         //!             array of Fields.
4026         //! \retval     An integer.
4027         //!
getSamplerCount()4028         uint8_t getSamplerCount() {
4029             return (uint8_t)fields[11].number8;
4030         }
4031 
4032         //!
4033         //! \brief      Sets the integer value of the SamplerCount field.
4034         //! \details    SamplerCount field is at index 11 in the internal
4035         //!             array of Fields.
4036         //! \param      [in] value.
4037         //!             Integer be assigned.
4038         //!
setSamplerCount(uint8_t value)4039         void setSamplerCount(uint8_t value) {
4040             fields[11].number8 = value;
4041         }
4042 
4043         //!
4044         //! \brief      Returns the reference to the vector of SamplerInfo objects.
4045         //! \details    KernelBody has a vector of SamplerInfo objects
4046         //!             that represents another entity within the vISA object format.
4047         //! \retval     Reference to the vector of SamplerInfo*.
4048         //!
getSamplerInfo()4049         std::vector<SamplerInfo*> &getSamplerInfo() {
4050             return sampler_info;
4051         }
4052 
4053         //!
4054         //! \brief      Returns the integer value of the SurfaceCount field.
4055         //! \details    SurfaceCount field is at index 13 in the internal
4056         //!             array of Fields.
4057         //! \retval     An integer.
4058         //!
getSurfaceCount()4059         uint8_t getSurfaceCount() {
4060             return (uint8_t)fields[13].number8;
4061         }
4062 
4063         //!
4064         //! \brief      Sets the integer value of the SurfaceCount field.
4065         //! \details    SurfaceCount field is at index 13 in the internal
4066         //!             array of Fields.
4067         //! \param      [in] value.
4068         //!             Integer be assigned.
4069         //!
setSurfaceCount(uint8_t value)4070         void setSurfaceCount(uint8_t value) {
4071             fields[13].number8 = value;
4072         }
4073 
4074         //!
4075         //! \brief      Returns the reference to the vector of SurfaceInfo objects.
4076         //! \details    KernelBody has a vector of SurfaceInfo objects
4077         //!             that represents another entity within the vISA object format.
4078         //! \retval     Reference to the vector of SurfaceInfo*.
4079         //!
getSurfaceInfo()4080         std::vector<SurfaceInfo*> &getSurfaceInfo() {
4081             return surface_info;
4082         }
4083 
4084         //!
4085         //! \brief      Returns the integer value of the VmeCount field.
4086         //! \details    VmeCount field is at index 15 in the internal
4087         //!             array of Fields.
4088         //! \retval     An integer.
4089         //!
getVmeCount()4090         uint8_t getVmeCount() {
4091             return (uint8_t)fields[15].number8;
4092         }
4093 
4094         //!
4095         //! \brief      Sets the integer value of the VmeCount field.
4096         //! \details    VmeCount field is at index 15 in the internal
4097         //!             array of Fields.
4098         //! \param      [in] value.
4099         //!             Integer be assigned.
4100         //!
setVmeCount(uint8_t value)4101         void setVmeCount(uint8_t value) {
4102             fields[15].number8 = value;
4103         }
4104 
4105         //!
4106         //! \brief      Returns the reference to the vector of VmeInfo objects.
4107         //! \details    KernelBody has a vector of VmeInfo objects
4108         //!             that represents another entity within the vISA object format.
4109         //! \retval     Reference to the vector of VmeInfo*.
4110         //!
getVmeInfo()4111         std::vector<VmeInfo*> &getVmeInfo() {
4112             return vme_info;
4113         }
4114 
4115         //!
4116         //! \brief      Returns the integer value of the NumInputs field.
4117         //! \details    NumInputs field is at index 17 in the internal
4118         //!             array of Fields.
4119         //! \retval     An integer.
4120         //!
getNumInputs()4121         uint32_t getNumInputs() {
4122             return (uint32_t)fields[17].number32;
4123         }
4124 
4125         //!
4126         //! \brief      Sets the integer value of the NumInputs field.
4127         //! \details    NumInputs field is at index 17 in the internal
4128         //!             array of Fields.
4129         //! \param      [in] value.
4130         //!             Integer be assigned.
4131         //!
setNumInputs(uint32_t value)4132         void setNumInputs(uint32_t value) {
4133             fields[17].number32 = value;
4134         }
4135 
4136         //!
4137         //! \brief      Returns the reference to the vector of InputInfo objects.
4138         //! \details    KernelBody has a vector of InputInfo objects
4139         //!             that represents another entity within the vISA object format.
4140         //! \retval     Reference to the vector of InputInfo*.
4141         //!
getInputInfo()4142         std::vector<InputInfo*> &getInputInfo() {
4143             return input_info;
4144         }
4145 
4146         //!
4147         //! \brief      Returns the integer value of the Size field.
4148         //! \details    Size field is at index 19 in the internal
4149         //!             array of Fields.
4150         //! \retval     An integer.
4151         //!
getSize()4152         uint32_t getSize() {
4153             return (uint32_t)fields[19].number32;
4154         }
4155 
4156         //!
4157         //! \brief      Sets the integer value of the Size field.
4158         //! \details    Size field is at index 19 in the internal
4159         //!             array of Fields.
4160         //! \param      [in] value.
4161         //!             Integer be assigned.
4162         //!
setSize(uint32_t value)4163         void setSize(uint32_t value) {
4164             fields[19].number32 = value;
4165         }
4166 
4167         //!
4168         //! \brief      Returns the integer value of the Entry field.
4169         //! \details    Entry field is at index 20 in the internal
4170         //!             array of Fields.
4171         //! \retval     An integer.
4172         //!
getEntry()4173         uint32_t getEntry() {
4174             return (uint32_t)fields[20].number32;
4175         }
4176 
4177         //!
4178         //! \brief      Sets the integer value of the Entry field.
4179         //! \details    Entry field is at index 20 in the internal
4180         //!             array of Fields.
4181         //! \param      [in] value.
4182         //!             Integer be assigned.
4183         //!
setEntry(uint32_t value)4184         void setEntry(uint32_t value) {
4185             fields[20].number32 = value;
4186         }
4187 
4188         //!
4189         //! \brief      Returns the integer value of the AttributeCount field.
4190         //! \details    AttributeCount field is at index 21 in the internal
4191         //!             array of Fields.
4192         //! \retval     An integer.
4193         //!
getAttributeCount()4194         uint16_t getAttributeCount() {
4195             return (uint16_t)fields[21].number16;
4196         }
4197 
4198         //!
4199         //! \brief      Sets the integer value of the AttributeCount field.
4200         //! \details    AttributeCount field is at index 21 in the internal
4201         //!             array of Fields.
4202         //! \param      [in] value.
4203         //!             Integer be assigned.
4204         //!
setAttributeCount(uint16_t value)4205         void setAttributeCount(uint16_t value) {
4206             fields[21].number16 = value;
4207         }
4208 
4209         //!
4210         //! \brief      Returns the reference to the vector of AttributeInfo objects.
4211         //! \details    KernelBody has a vector of AttributeInfo objects
4212         //!             that represents another entity within the vISA object format.
4213         //! \retval     Reference to the vector of AttributeInfo*.
4214         //!
getAttributeInfo()4215         std::vector<AttributeInfo*> &getAttributeInfo() {
4216             return attribute_info;
4217         }
4218 
4219         //!
4220         //! \brief      Returns the pointer to buffer data from Instructions field.
4221         //! \details    Instructions field is at index 23 in the internal
4222         //!             array of Fields.
4223         //! \retval     A pointer to buffer data (const uint8_t*).
4224         //!
getInstructions()4225         const uint8_t* getInstructions() {
4226             return fields[23].gdata;
4227         }
4228 
4229         //!
4230         //! \brief      Sets the pointer to buffer data of the Instructions field.
4231         //! \details    Instructions field is at index 23 in the internal
4232         //!             array of Fields.
4233         //! \param      [in] value.
4234         //!             Pointer to buffer data (uint8_t*) to be assigned.
4235         //!
setInstructions(uint8_t * value)4236         void setInstructions(uint8_t * value) {
4237             fields[23].gdata = value;
4238         }
4239 
4240         //!
4241         //! \brief      Parses one KernelBody object from ISA file.
4242         //! \details    Reads and parses all the fields of the KernelBody object
4243         //!             from the file buffer and returns the pointer immediately
4244         //!             after all this data.
4245         //!             If this class contains internal structs, their Parse
4246         //!             functions are called when corresponding.
4247         //! \param      [in] p.
4248         //!             Pointer to file buffer to start reading.
4249         //! \param      [in] end.
4250         //!             Pointer to end of file buffer.
4251         //! \param      [in] m.
4252         //!             Pointer ISAfile object.
4253         //! \retval     Pointer to file buffe after parsing one KernelBody object.
4254         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)4255         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
4256             unsigned i = 0, count = 0;
4257             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4258                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4259                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4260                 i++;
4261             }
4262             // StringPool
4263             count = fields[fields[i].countField].number32;
4264             string_pool.resize(count);
4265             for (unsigned j = 0; j < count; j++) {
4266                 StringPool *r = new StringPool(m->getCurrentVISAVersion());
4267                 p = r->parse(p, end, m);
4268                 if (!p) {
4269                     delete r;
4270                     return 0;
4271                 }
4272                 string_pool[j] = r;
4273             }
4274             i++;
4275             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4276                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4277                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4278                 i++;
4279             }
4280             // Variable
4281             count = fields[fields[i].countField].number32;
4282             var_info.resize(count);
4283             for (unsigned j = 0; j < count; j++) {
4284                 Variable *r = new Variable(m->getCurrentVISAVersion());
4285                 p = r->parse(p, end, m);
4286                 if (!p) {
4287                     delete r;
4288                     return 0;
4289                 }
4290                 var_info[j] = r;
4291             }
4292             i++;
4293             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4294                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4295                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4296                 i++;
4297             }
4298             // AddressInfo
4299             count = fields[fields[i].countField].number32;
4300             address_info.resize(count);
4301             for (unsigned j = 0; j < count; j++) {
4302                 AddressInfo *r = new AddressInfo(m->getCurrentVISAVersion());
4303                 p = r->parse(p, end, m);
4304                 if (!p) {
4305                     delete r;
4306                     return 0;
4307                 }
4308                 address_info[j] = r;
4309             }
4310             i++;
4311             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4312                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4313                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4314                 i++;
4315             }
4316             // PredicateInfo
4317             count = fields[fields[i].countField].number32;
4318             predicate_info.resize(count);
4319             for (unsigned j = 0; j < count; j++) {
4320                 PredicateInfo *r = new PredicateInfo(m->getCurrentVISAVersion());
4321                 p = r->parse(p, end, m);
4322                 if (!p) {
4323                     delete r;
4324                     return 0;
4325                 }
4326                 predicate_info[j] = r;
4327             }
4328             i++;
4329             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4330                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4331                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4332                 i++;
4333             }
4334             // LabelInfo
4335             count = fields[fields[i].countField].number32;
4336             label_info.resize(count);
4337             for (unsigned j = 0; j < count; j++) {
4338                 LabelInfo *r = new LabelInfo(m->getCurrentVISAVersion());
4339                 p = r->parse(p, end, m);
4340                 if (!p) {
4341                     delete r;
4342                     return 0;
4343                 }
4344                 label_info[j] = r;
4345             }
4346             i++;
4347             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4348                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4349                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4350                 i++;
4351             }
4352             // SamplerInfo
4353             count = fields[fields[i].countField].number32;
4354             sampler_info.resize(count);
4355             for (unsigned j = 0; j < count; j++) {
4356                 SamplerInfo *r = new SamplerInfo(m->getCurrentVISAVersion());
4357                 p = r->parse(p, end, m);
4358                 if (!p) {
4359                     delete r;
4360                     return 0;
4361                 }
4362                 sampler_info[j] = r;
4363             }
4364             i++;
4365             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4366                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4367                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4368                 i++;
4369             }
4370             // SurfaceInfo
4371             count = fields[fields[i].countField].number32;
4372             surface_info.resize(count);
4373             for (unsigned j = 0; j < count; j++) {
4374                 SurfaceInfo *r = new SurfaceInfo(m->getCurrentVISAVersion());
4375                 p = r->parse(p, end, m);
4376                 if (!p) {
4377                     delete r;
4378                     return 0;
4379                 }
4380                 surface_info[j] = r;
4381             }
4382             i++;
4383             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4384                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4385                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4386                 i++;
4387             }
4388             // VmeInfo
4389             count = fields[fields[i].countField].number32;
4390             vme_info.resize(count);
4391             for (unsigned j = 0; j < count; j++) {
4392                 VmeInfo *r = new VmeInfo(m->getCurrentVISAVersion());
4393                 p = r->parse(p, end, m);
4394                 if (!p) {
4395                     delete r;
4396                     return 0;
4397                 }
4398                 vme_info[j] = r;
4399             }
4400             i++;
4401             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4402                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4403                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4404                 i++;
4405             }
4406             // InputInfo
4407             count = fields[fields[i].countField].number32;
4408             input_info.resize(count);
4409             for (unsigned j = 0; j < count; j++) {
4410                 InputInfo *r = new InputInfo(m->getCurrentVISAVersion());
4411                 p = r->parse(p, end, m);
4412                 if (!p) {
4413                     delete r;
4414                     return 0;
4415                 }
4416                 input_info[j] = r;
4417             }
4418             i++;
4419             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4420                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4421                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4422                 i++;
4423             }
4424             // AttributeInfo
4425             count = fields[fields[i].countField].number32;
4426             attribute_info.resize(count);
4427             for (unsigned j = 0; j < count; j++) {
4428                 AttributeInfo *r = new AttributeInfo(m->getCurrentVISAVersion());
4429                 p = r->parse(p, end, m);
4430                 if (!p) {
4431                     delete r;
4432                     return 0;
4433                 }
4434                 attribute_info[j] = r;
4435             }
4436             i++;
4437             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4438                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4439                 if (!p) return m->setError("bad offset/size for KernelBody's field", i);
4440                 i++;
4441             }
4442             return p;
4443         }
4444 
4445         //!
4446         //! \brief      Adds all the KernelBody's fields to a buffer.
4447         //! \details    Every field from this class is added to a buffer
4448         //!             in order to be written into an ISA file afterwards
4449         //!             If this class contains other internal structus, their addToBuffer
4450         //!             functions are called when corresponding.
4451         //! \param      [out] buffer.
4452         //!             The buffer where the fields data will be added.
4453         //! \param      [in] m.
4454         //!             Pointer to ISAfile object.
4455         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)4456         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
4457             unsigned i = 0;
4458             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4459                 m->addToBuffer(fields[i], buffer);
4460                 i++;
4461             }
4462             // StringPool
4463             for (StringPool *r : string_pool) {
4464                 r->addToBuffer(buffer, m);
4465             }
4466             i++;
4467             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4468                 m->addToBuffer(fields[i], buffer);
4469                 i++;
4470             }
4471             // Variable
4472             for (Variable *r : var_info) {
4473                 r->addToBuffer(buffer, m);
4474             }
4475             i++;
4476             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4477                 m->addToBuffer(fields[i], buffer);
4478                 i++;
4479             }
4480             // AddressInfo
4481             for (AddressInfo *r : address_info) {
4482                 r->addToBuffer(buffer, m);
4483             }
4484             i++;
4485             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4486                 m->addToBuffer(fields[i], buffer);
4487                 i++;
4488             }
4489             // PredicateInfo
4490             for (PredicateInfo *r : predicate_info) {
4491                 r->addToBuffer(buffer, m);
4492             }
4493             i++;
4494             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4495                 m->addToBuffer(fields[i], buffer);
4496                 i++;
4497             }
4498             // LabelInfo
4499             for (LabelInfo *r : label_info) {
4500                 r->addToBuffer(buffer, m);
4501             }
4502             i++;
4503             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4504                 m->addToBuffer(fields[i], buffer);
4505                 i++;
4506             }
4507             // SamplerInfo
4508             for (SamplerInfo *r : sampler_info) {
4509                 r->addToBuffer(buffer, m);
4510             }
4511             i++;
4512             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4513                 m->addToBuffer(fields[i], buffer);
4514                 i++;
4515             }
4516             // SurfaceInfo
4517             for (SurfaceInfo *r : surface_info) {
4518                 r->addToBuffer(buffer, m);
4519             }
4520             i++;
4521             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4522                 m->addToBuffer(fields[i], buffer);
4523                 i++;
4524             }
4525             // VmeInfo
4526             for (VmeInfo *r : vme_info) {
4527                 r->addToBuffer(buffer, m);
4528             }
4529             i++;
4530             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4531                 m->addToBuffer(fields[i], buffer);
4532                 i++;
4533             }
4534             // InputInfo
4535             for (InputInfo *r : input_info) {
4536                 r->addToBuffer(buffer, m);
4537             }
4538             i++;
4539             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4540                 m->addToBuffer(fields[i], buffer);
4541                 i++;
4542             }
4543             // AttributeInfo
4544             for (AttributeInfo *r : attribute_info) {
4545                 r->addToBuffer(buffer, m);
4546             }
4547             i++;
4548             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4549                 m->addToBuffer(fields[i], buffer);
4550                 i++;
4551             }
4552         }
4553 
4554         //!
4555         //! \brief      Makes the changes needed to support 303 version's KernelBody.
4556         //! \details    This function is called when the current ISA file has the 303 version.
4557         //!             Initially all the objects are created with last version's format, so
4558         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
4559         //!             of fields can be needed.
4560         //!
setVersion303()4561         void setVersion303() {
4562             fields[0] = Datatype::TWO;
4563             fields[2] = Datatype::TWO;
4564             fields[3] = Datatype::TWO;
4565         }
4566 
4567         //!
4568         //! \brief      Makes the changes needed to support 304 version's KernelBody.
4569         //! \details    This function is called when the current ISA file has the 304 version.
4570         //!             Initially all the objects are created with last version's format, so
4571         //!             in order to suppport previous versions, changes of datatypes and insertion/removal
4572         //!             of fields can be needed.
4573         //!
setVersion304()4574         void setVersion304() {
4575             fields[17] = Datatype::ONE;
4576         }
4577     };
4578 
4579     //!
4580     //! \brief      Kernel Class.
4581     //! \details    This class represents the Kernel from vISA Object Format.
4582     //!             Provides getters, setters for its fields and structs as well as
4583     //!             functions to read/write it from/to file.
4584     //!
4585     class Kernel {
4586     public:
4587         std::array<Field, 11> fields = std::array<Field, 11>
4588         {
4589             Field(Datatype::TWO), // name_len
4590                 Field(Datatype::VARCHAR, 0), // name
4591                 Field(Datatype::FOUR), // offset
4592                 Field(Datatype::FOUR), // size
4593                 Field(Datatype::FOUR), // input_offset
4594                 Field(Datatype::TWO), // num_syms_variable
4595                 Field(Datatype::STRUCT, 5), // variable_reloc_symtab
4596                 Field(Datatype::TWO), // num_syms_function
4597                 Field(Datatype::STRUCT, 7), // function_reloc_symtab
4598                 Field(Datatype::ONE), // num_gen_binaries
4599                 Field(Datatype::STRUCT, 9), // gen_binary_info
4600         };
4601         std::vector<RelocationInfo*> variable_reloc_symtab;
4602         std::vector<RelocationInfo*> function_reloc_symtab;
4603         std::vector<GenBinary*> gen_binary_info;
4604 
4605         //!
4606         //! \brief      Constructor of Kernel class.
4607         //! \param      [in] version.
4608         //!             Version of current ISA file.
4609         //!
Kernel(unsigned version)4610         Kernel(unsigned version) {
4611             if (version <= 306) setVersion306();
4612         }
4613 
4614         //!
4615         //! \brief      Constructor of Kernel class.
4616         //!
Kernel()4617         Kernel() {}
4618 
4619         //!
4620         //! \brief      Copy Constructor of Kernel class.
4621         //! \param      [in] other.
4622         //!             Reference to object to copy..
4623         //!
Kernel(const Kernel & other)4624         Kernel(const Kernel& other) {
4625             fields = other.fields;
4626             for (RelocationInfo *r : other.variable_reloc_symtab) {
4627                 RelocationInfo *s = new RelocationInfo();
4628                 *s = *r;
4629                 variable_reloc_symtab.push_back(s);
4630             }
4631             for (RelocationInfo *r : other.function_reloc_symtab) {
4632                 RelocationInfo *s = new RelocationInfo();
4633                 *s = *r;
4634                 function_reloc_symtab.push_back(s);
4635             }
4636             for (GenBinary *r : other.gen_binary_info) {
4637                 GenBinary *s = new GenBinary();
4638                 *s = *r;
4639                 gen_binary_info.push_back(s);
4640             }
4641         }
4642 
4643         //!
4644         //! \brief      Assignment operator.
4645         //! \param      [in] other.
4646         //!             Reference to object to copy..
4647         //!
4648         Kernel& operator= (const Kernel& other) {
4649             if (this != &other) {
4650                 fields = other.fields;
4651                 for (RelocationInfo *r : variable_reloc_symtab)
4652                     delete r;
4653                 for (RelocationInfo *r : other.variable_reloc_symtab) {
4654                     RelocationInfo *s = new RelocationInfo();
4655                     *s = *r;
4656                     variable_reloc_symtab.push_back(s);
4657                 }
4658                 for (RelocationInfo *r : function_reloc_symtab)
4659                     delete r;
4660                 for (RelocationInfo *r : other.function_reloc_symtab) {
4661                     RelocationInfo *s = new RelocationInfo();
4662                     *s = *r;
4663                     function_reloc_symtab.push_back(s);
4664                 }
4665                 for (GenBinary *r : gen_binary_info)
4666                     delete r;
4667                 for (GenBinary *r : other.gen_binary_info) {
4668                     GenBinary *s = new GenBinary();
4669                     *s = *r;
4670                     gen_binary_info.push_back(s);
4671                 }
4672             }
4673             return *this;
4674         }
4675 
4676         //!
4677         //! \brief      Destructor of Kernel class.
4678         //!
~Kernel()4679         ~Kernel() {
4680             for (RelocationInfo *s : variable_reloc_symtab) delete s;
4681             for (RelocationInfo *s : function_reloc_symtab) delete s;
4682             for (GenBinary *s : gen_binary_info) delete s;
4683         }
4684 
4685         //!
4686         //! \brief      Returns the integer value of the NameLen field.
4687         //! \details    NameLen field is at index 0 in the internal
4688         //!             array of Fields for vesrion <= 306
4689         //! \retval     An integer.
4690         //!
getNameLen_Ver306()4691         uint8_t getNameLen_Ver306() {
4692             return (uint8_t)fields[0].number8;
4693         }
4694 
4695         //!
4696         //! \brief      Returns the integer value of the NameLen field.
4697         //! \details    NameLen field is at index 0 in the internal
4698         //!             array of Fields.
4699         //! \retval     An integer.
4700         //!
getNameLen()4701         uint16_t getNameLen()
4702         {
4703             return (uint16_t)fields[0].number16;
4704         }
4705 
4706         //!
4707         //! \brief      Sets the integer value of the NameLen field.
4708         //! \details    NameLen field is at index 0 in the internal
4709         //!             array of Fields for version <= 306
4710         //! \param      [in] value.
4711         //!             Integer be assigned.
4712         //!
setNameLen_Ver306(uint8_t value)4713         void setNameLen_Ver306(uint8_t value) {
4714             fields[0].number8 = value;
4715         }
4716 
4717         //!
4718         //! \brief      Sets the integer value of the NameLen field.
4719         //! \details    NameLen field is at index 0 in the internal
4720         //!             array of Fields.
4721         //! \param      [in] value.
4722         //!             Integer be assigned.
4723         //!
setNameLen(uint16_t value)4724         void setNameLen(uint16_t value)
4725         {
4726             fields[0].number16 = value;
4727         }
4728 
4729         //!
4730         //! \brief      Returns the string value of the Name field.
4731         //! \details    Name field is at index 1 in the internal
4732         //!             array of Fields.
4733         //! \retval     A pointer to the string (const char*).
4734         //!
getName()4735         const char * getName() {
4736             return fields[1].varchar;
4737         }
4738 
4739         //!
4740         //! \brief      Sets the string value of the Name field.
4741         //! \details    Name field is at index 1 in the internal
4742         //!             array of Fields.
4743         //! \param      [in] value.
4744         //!             Pointer to string (char*) to be assigned.
4745         //!
setName(char * value)4746         void setName(char * value) {
4747             fields[1].varchar = value;
4748         }
4749 
4750         //!
4751         //! \brief      Returns the integer value of the Offset field.
4752         //! \details    Offset field is at index 2 in the internal
4753         //!             array of Fields.
4754         //! \retval     An integer.
4755         //!
getOffset()4756         uint32_t getOffset() {
4757             return (uint32_t)fields[2].number32;
4758         }
4759 
4760         //!
4761         //! \brief      Sets the integer value of the Offset field.
4762         //! \details    Offset field is at index 2 in the internal
4763         //!             array of Fields.
4764         //! \param      [in] value.
4765         //!             Integer be assigned.
4766         //!
setOffset(uint32_t value)4767         void setOffset(uint32_t value) {
4768             fields[2].number32 = value;
4769         }
4770 
4771         //!
4772         //! \brief      Returns the integer value of the Size field.
4773         //! \details    Size field is at index 3 in the internal
4774         //!             array of Fields.
4775         //! \retval     An integer.
4776         //!
getSize()4777         uint32_t getSize() {
4778             return (uint32_t)fields[3].number32;
4779         }
4780 
4781         //!
4782         //! \brief      Sets the integer value of the Size field.
4783         //! \details    Size field is at index 3 in the internal
4784         //!             array of Fields.
4785         //! \param      [in] value.
4786         //!             Integer be assigned.
4787         //!
setSize(uint32_t value)4788         void setSize(uint32_t value) {
4789             fields[3].number32 = value;
4790         }
4791 
4792         //!
4793         //! \brief      Returns the integer value of the InputOffset field.
4794         //! \details    InputOffset field is at index 4 in the internal
4795         //!             array of Fields.
4796         //! \retval     An integer.
4797         //!
getInputOffset()4798         uint32_t getInputOffset() {
4799             return (uint32_t)fields[4].number32;
4800         }
4801 
4802         //!
4803         //! \brief      Sets the integer value of the InputOffset field.
4804         //! \details    InputOffset field is at index 4 in the internal
4805         //!             array of Fields.
4806         //! \param      [in] value.
4807         //!             Integer be assigned.
4808         //!
setInputOffset(uint32_t value)4809         void setInputOffset(uint32_t value) {
4810             fields[4].number32 = value;
4811         }
4812 
4813         //!
4814         //! \brief      Returns the integer value of the NumSymsVariable field.
4815         //! \details    NumSymsVariable field is at index 5 in the internal
4816         //!             array of Fields.
4817         //! \retval     An integer.
4818         //!
getNumSymsVariable()4819         uint16_t getNumSymsVariable() {
4820             return (uint16_t)fields[5].number16;
4821         }
4822 
4823         //!
4824         //! \brief      Sets the integer value of the NumSymsVariable field.
4825         //! \details    NumSymsVariable field is at index 5 in the internal
4826         //!             array of Fields.
4827         //! \param      [in] value.
4828         //!             Integer be assigned.
4829         //!
setNumSymsVariable(uint16_t value)4830         void setNumSymsVariable(uint16_t value) {
4831             fields[5].number16 = value;
4832         }
4833 
4834         //!
4835         //! \brief      Returns the reference to the vector of RelocationInfo objects.
4836         //! \details    Kernel has a vector of RelocationInfo objects
4837         //!             that represents another entity within the vISA object format.
4838         //! \retval     Reference to the vector of RelocationInfo*.
4839         //!
getVariableRelocSymtab()4840         std::vector<RelocationInfo*> &getVariableRelocSymtab() {
4841             return variable_reloc_symtab;
4842         }
4843 
4844         //!
4845         //! \brief      Returns the integer value of the NumSymsFunction field.
4846         //! \details    NumSymsFunction field is at index 7 in the internal
4847         //!             array of Fields.
4848         //! \retval     An integer.
4849         //!
getNumSymsFunction()4850         uint16_t getNumSymsFunction() {
4851             return (uint16_t)fields[7].number16;
4852         }
4853 
4854         //!
4855         //! \brief      Sets the integer value of the NumSymsFunction field.
4856         //! \details    NumSymsFunction field is at index 7 in the internal
4857         //!             array of Fields.
4858         //! \param      [in] value.
4859         //!             Integer be assigned.
4860         //!
setNumSymsFunction(uint16_t value)4861         void setNumSymsFunction(uint16_t value) {
4862             fields[7].number16 = value;
4863         }
4864 
4865         //!
4866         //! \brief      Returns the reference to the vector of RelocationInfo objects.
4867         //! \details    Kernel has a vector of RelocationInfo objects
4868         //!             that represents another entity within the vISA object format.
4869         //! \retval     Reference to the vector of RelocationInfo*.
4870         //!
getFunctionRelocSymtab()4871         std::vector<RelocationInfo*> &getFunctionRelocSymtab() {
4872             return function_reloc_symtab;
4873         }
4874 
4875         //!
4876         //! \brief      Returns the integer value of the NumGenBinaries field.
4877         //! \details    NumGenBinaries field is at index 9 in the internal
4878         //!             array of Fields.
4879         //! \retval     An integer.
4880         //!
getNumGenBinaries()4881         uint8_t getNumGenBinaries() {
4882             return (uint8_t)fields[9].number8;
4883         }
4884 
4885         //!
4886         //! \brief      Sets the integer value of the NumGenBinaries field.
4887         //! \details    NumGenBinaries field is at index 9 in the internal
4888         //!             array of Fields.
4889         //! \param      [in] value.
4890         //!             Integer be assigned.
4891         //!
setNumGenBinaries(uint8_t value)4892         void setNumGenBinaries(uint8_t value) {
4893             fields[9].number8 = value;
4894         }
4895 
4896         //!
4897         //! \brief      Returns the reference to the vector of GenBinary objects.
4898         //! \details    Kernel has a vector of GenBinary objects
4899         //!             that represents another entity within the vISA object format.
4900         //! \retval     Reference to the vector of GenBinary*.
4901         //!
getGenBinaryInfo()4902         std::vector<GenBinary*> &getGenBinaryInfo() {
4903             return gen_binary_info;
4904         }
4905 
4906         //!
4907         //! \brief      Parses one Kernel object from ISA file.
4908         //! \details    Reads and parses all the fields of the Kernel object
4909         //!             from the file buffer and returns the pointer immediately
4910         //!             after all this data.
4911         //!             If this class contains internal structs, their Parse
4912         //!             functions are called when corresponding.
4913         //! \param      [in] p.
4914         //!             Pointer to file buffer to start reading.
4915         //! \param      [in] end.
4916         //!             Pointer to end of file buffer.
4917         //! \param      [in] m.
4918         //!             Pointer ISAfile object.
4919         //! \retval     Pointer to file buffe after parsing one Kernel object.
4920         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)4921         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
4922             unsigned i = 0, count = 0;
4923             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4924                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4925                 if (!p) return m->setError("bad offset/size for Kernel's field", i);
4926                 i++;
4927             }
4928             // RelocationInfo
4929             count = fields[fields[i].countField].number32;
4930             variable_reloc_symtab.resize(count);
4931             for (unsigned j = 0; j < count; j++) {
4932                 RelocationInfo *r = new RelocationInfo(m->getCurrentVISAVersion());
4933                 p = r->parse(p, end, m);
4934                 if (!p) {
4935                     delete r;
4936                     return 0;
4937                 }
4938                 variable_reloc_symtab[j] = r;
4939             }
4940             i++;
4941             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4942                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4943                 if (!p) return m->setError("bad offset/size for Kernel's field", i);
4944                 i++;
4945             }
4946             // RelocationInfo
4947             count = fields[fields[i].countField].number32;
4948             function_reloc_symtab.resize(count);
4949             for (unsigned j = 0; j < count; j++) {
4950                 RelocationInfo *r = new RelocationInfo(m->getCurrentVISAVersion());
4951                 p = r->parse(p, end, m);
4952                 if (!p) {
4953                     delete r;
4954                     return 0;
4955                 }
4956                 function_reloc_symtab[j] = r;
4957             }
4958             i++;
4959             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4960                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
4961                 if (!p) return m->setError("bad offset/size for Kernel's field", i);
4962                 i++;
4963             }
4964             // GenBinary
4965             count = fields[fields[i].countField].number32;
4966             gen_binary_info.resize(count);
4967             for (unsigned j = 0; j < count; j++) {
4968                 GenBinary *r = new GenBinary(m->getCurrentVISAVersion());
4969                 p = r->parse(p, end, m);
4970                 if (!p) {
4971                     delete r;
4972                     return 0;
4973                 }
4974                 gen_binary_info[j] = r;
4975             }
4976             i++;
4977             return p;
4978         }
4979 
4980         //!
4981         //! \brief      Adds all the Kernel's fields to a buffer.
4982         //! \details    Every field from this class is added to a buffer
4983         //!             in order to be written into an ISA file afterwards
4984         //!             If this class contains other internal structus, their addToBuffer
4985         //!             functions are called when corresponding.
4986         //! \param      [out] buffer.
4987         //!             The buffer where the fields data will be added.
4988         //! \param      [in] m.
4989         //!             Pointer to ISAfile object.
4990         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)4991         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
4992             unsigned i = 0;
4993             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
4994                 m->addToBuffer(fields[i], buffer);
4995                 i++;
4996             }
4997             // RelocationInfo
4998             for (RelocationInfo *r : variable_reloc_symtab) {
4999                 r->addToBuffer(buffer, m);
5000             }
5001             i++;
5002             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
5003                 m->addToBuffer(fields[i], buffer);
5004                 i++;
5005             }
5006             // RelocationInfo
5007             for (RelocationInfo *r : function_reloc_symtab) {
5008                 r->addToBuffer(buffer, m);
5009             }
5010             i++;
5011             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
5012                 m->addToBuffer(fields[i], buffer);
5013                 i++;
5014             }
5015             // GenBinary
5016             for (GenBinary *r : gen_binary_info) {
5017                 r->addToBuffer(buffer, m);
5018             }
5019             i++;
5020         }
5021 
5022         //!
5023         //! \brief      Makes the changes needed to support 306 version's Kernel.
5024         //! \details    This function is called when the current ISA file has the 306 version.
5025         //!             Initially all the objects are created with last version's format, so
5026         //!             in order to suppport newer versions, changes of datatypes and insertion/removal
5027         //!             of fields can be needed.
5028         //!
setVersion306()5029         void setVersion306()
5030         {
5031             fields[0] = Datatype::ONE;
5032         }
5033 
5034     };
5035 
5036     //!
5037     //! \brief      Header Class.
5038     //! \details    This class represents the Header from vISA Object Format.
5039     //!             Provides getters, setters for its fields and structs as well as
5040     //!             functions to read/write it from/to file.
5041     //!
5042     class Header {
5043     public:
5044         std::array<Field, 9> fields = std::array<Field, 9>
5045         {
5046             Field(Datatype::FOUR), // magic_number
5047                 Field(Datatype::ONE), // major_version
5048                 Field(Datatype::ONE), // minor_version
5049                 Field(Datatype::TWO), // num_kernels
5050                 Field(Datatype::STRUCT, 3), // kernel_info
5051                 Field(Datatype::TWO), // num_variables
5052                 Field(Datatype::STRUCT, 5), // file_scope_var_info
5053                 Field(Datatype::TWO), // num_functions
5054                 Field(Datatype::STRUCT, 7), // function_info
5055         };
5056         std::vector<Kernel*> kernel_info;
5057         std::vector<GlobalVariable*> file_scope_var_info;
5058         std::vector<Function*> function_info;
5059 
5060         //!
5061         //! \brief      Constructor of Header class.
5062         //! \param      [in] version.
5063         //!             Version of current ISA file.
5064         //!
Header(unsigned version)5065         Header(unsigned version) {}
5066 
5067         //!
5068         //! \brief      Copy Constructor of Header class.
5069         //! \param      [in] other.
5070         //!             Reference to object to copy..
5071         //!
Header(const Header & other)5072         Header(const Header& other) {
5073             fields = other.fields;
5074             for (Kernel *r : other.kernel_info) {
5075                 Kernel *s = new Kernel();
5076                 *s = *r;
5077                 kernel_info.push_back(s);
5078             }
5079             for (GlobalVariable *r : other.file_scope_var_info) {
5080                 GlobalVariable *s = new GlobalVariable();
5081                 *s = *r;
5082                 file_scope_var_info.push_back(s);
5083             }
5084             for (Function *r : other.function_info) {
5085                 Function *s = new Function();
5086                 *s = *r;
5087                 function_info.push_back(s);
5088             }
5089         }
5090 
5091         //!
5092         //! \brief      Assignment operator.
5093         //! \param      [in] other.
5094         //!             Reference to object to copy..
5095         //!
5096         Header& operator= (const Header& other) {
5097             if (this != &other) {
5098                 fields = other.fields;
5099                 for (Kernel *r : kernel_info)
5100                     delete r;
5101                 for (Kernel *r : other.kernel_info) {
5102                     Kernel *s = new Kernel();
5103                     *s = *r;
5104                     kernel_info.push_back(s);
5105                 }
5106                 for (GlobalVariable *r : file_scope_var_info)
5107                     delete r;
5108                 for (GlobalVariable *r : other.file_scope_var_info) {
5109                     GlobalVariable *s = new GlobalVariable();
5110                     *s = *r;
5111                     file_scope_var_info.push_back(s);
5112                 }
5113                 for (Function *r : function_info)
5114                     delete r;
5115                 for (Function *r : other.function_info) {
5116                     Function *s = new Function();
5117                     *s = *r;
5118                     function_info.push_back(s);
5119                 }
5120             }
5121             return *this;
5122         }
5123 
5124         //!
5125         //! \brief      Destructor of Header class.
5126         //!
~Header()5127         ~Header() {
5128             for (Kernel *s : kernel_info) delete s;
5129             for (GlobalVariable *s : file_scope_var_info) delete s;
5130             for (Function *s : function_info) delete s;
5131         }
5132 
5133         //!
5134         //! \brief      Returns the integer value of the MagicNumber field.
5135         //! \details    MagicNumber field is at index 0 in the internal
5136         //!             array of Fields.
5137         //! \retval     An integer.
5138         //!
getMagicNumber()5139         uint32_t getMagicNumber() {
5140             return (uint32_t)fields[0].number32;
5141         }
5142 
5143         //!
5144         //! \brief      Sets the integer value of the MagicNumber field.
5145         //! \details    MagicNumber field is at index 0 in the internal
5146         //!             array of Fields.
5147         //! \param      [in] value.
5148         //!             Integer be assigned.
5149         //!
setMagicNumber(uint32_t value)5150         void setMagicNumber(uint32_t value) {
5151             fields[0].number32 = value;
5152         }
5153 
5154         //!
5155         //! \brief      Returns the integer value of the MajorVersion field.
5156         //! \details    MajorVersion field is at index 1 in the internal
5157         //!             array of Fields.
5158         //! \retval     An integer.
5159         //!
getMajorVersion()5160         uint8_t getMajorVersion() {
5161             return (uint8_t)fields[1].number8;
5162         }
5163 
5164         //!
5165         //! \brief      Sets the integer value of the MajorVersion field.
5166         //! \details    MajorVersion field is at index 1 in the internal
5167         //!             array of Fields.
5168         //! \param      [in] value.
5169         //!             Integer be assigned.
5170         //!
setMajorVersion(uint8_t value)5171         void setMajorVersion(uint8_t value) {
5172             fields[1].number8 = value;
5173         }
5174 
5175         //!
5176         //! \brief      Returns the integer value of the MinorVersion field.
5177         //! \details    MinorVersion field is at index 2 in the internal
5178         //!             array of Fields.
5179         //! \retval     An integer.
5180         //!
getMinorVersion()5181         uint8_t getMinorVersion() {
5182             return (uint8_t)fields[2].number8;
5183         }
5184 
5185         //!
5186         //! \brief      Sets the integer value of the MinorVersion field.
5187         //! \details    MinorVersion field is at index 2 in the internal
5188         //!             array of Fields.
5189         //! \param      [in] value.
5190         //!             Integer be assigned.
5191         //!
setMinorVersion(uint8_t value)5192         void setMinorVersion(uint8_t value) {
5193             fields[2].number8 = value;
5194         }
5195 
5196         //!
5197         //! \brief      Returns the integer value of the NumKernels field.
5198         //! \details    NumKernels field is at index 3 in the internal
5199         //!             array of Fields.
5200         //! \retval     An integer.
5201         //!
getNumKernels()5202         uint16_t getNumKernels() {
5203             return (uint16_t)fields[3].number16;
5204         }
5205 
5206         //!
5207         //! \brief      Sets the integer value of the NumKernels field.
5208         //! \details    NumKernels field is at index 3 in the internal
5209         //!             array of Fields.
5210         //! \param      [in] value.
5211         //!             Integer be assigned.
5212         //!
setNumKernels(uint16_t value)5213         void setNumKernels(uint16_t value) {
5214             fields[3].number16 = value;
5215         }
5216 
5217         //!
5218         //! \brief      Returns the reference to the vector of Kernel objects.
5219         //! \details    Header has a vector of Kernel objects
5220         //!             that represents another entity within the vISA object format.
5221         //! \retval     Reference to the vector of Kernel*.
5222         //!
getKernelInfo()5223         std::vector<Kernel*> &getKernelInfo() {
5224             return kernel_info;
5225         }
5226 
5227         //!
5228         //! \brief      Returns the integer value of the NumVariables field.
5229         //! \details    NumVariables field is at index 5 in the internal
5230         //!             array of Fields.
5231         //! \retval     An integer.
5232         //!
getNumVariables()5233         uint16_t getNumVariables() {
5234             return (uint16_t)fields[5].number16;
5235         }
5236 
5237         //!
5238         //! \brief      Sets the integer value of the NumVariables field.
5239         //! \details    NumVariables field is at index 5 in the internal
5240         //!             array of Fields.
5241         //! \param      [in] value.
5242         //!             Integer be assigned.
5243         //!
setNumVariables(uint16_t value)5244         void setNumVariables(uint16_t value) {
5245             fields[5].number16 = value;
5246         }
5247 
5248         //!
5249         //! \brief      Returns the reference to the vector of GlobalVariable objects.
5250         //! \details    Header has a vector of GlobalVariable objects
5251         //!             that represents another entity within the vISA object format.
5252         //! \retval     Reference to the vector of GlobalVariable*.
5253         //!
getFileScopeVarInfo()5254         std::vector<GlobalVariable*> &getFileScopeVarInfo() {
5255             return file_scope_var_info;
5256         }
5257 
5258         //!
5259         //! \brief      Returns the integer value of the NumFunctions field.
5260         //! \details    NumFunctions field is at index 7 in the internal
5261         //!             array of Fields.
5262         //! \retval     An integer.
5263         //!
getNumFunctions()5264         uint16_t getNumFunctions() {
5265             return (uint16_t)fields[7].number16;
5266         }
5267 
5268         //!
5269         //! \brief      Sets the integer value of the NumFunctions field.
5270         //! \details    NumFunctions field is at index 7 in the internal
5271         //!             array of Fields.
5272         //! \param      [in] value.
5273         //!             Integer be assigned.
5274         //!
setNumFunctions(uint16_t value)5275         void setNumFunctions(uint16_t value) {
5276             fields[7].number16 = value;
5277         }
5278 
5279         //!
5280         //! \brief      Returns the reference to the vector of Function objects.
5281         //! \details    Header has a vector of Function objects
5282         //!             that represents another entity within the vISA object format.
5283         //! \retval     Reference to the vector of Function*.
5284         //!
getFunctionInfo()5285         std::vector<Function*> &getFunctionInfo() {
5286             return function_info;
5287         }
5288 
5289         //!
5290         //! \brief      Parses one Header object from ISA file.
5291         //! \details    Reads and parses all the fields of the Header object
5292         //!             from the file buffer and returns the pointer immediately
5293         //!             after all this data.
5294         //!             If this class contains internal structs, their Parse
5295         //!             functions are called when corresponding.
5296         //! \param      [in] p.
5297         //!             Pointer to file buffer to start reading.
5298         //! \param      [in] end.
5299         //!             Pointer to end of file buffer.
5300         //! \param      [in] m.
5301         //!             Pointer ISAfile object.
5302         //! \retval     Pointer to file buffe after parsing one Header object.
5303         //!
parse(const uint8_t * p,const uint8_t * end,ISAfile * m)5304         const uint8_t* parse(const uint8_t *p, const uint8_t *end, ISAfile *m) {
5305             unsigned i = 0, count = 0;
5306             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
5307                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
5308                 if (!p) return m->setError("bad offset/size for Header's field", i);
5309                 i++;
5310             }
5311             m->setCurrentVISAVersion(getMajorVersion() * 100 + getMinorVersion());
5312             // Kernel
5313             count = fields[fields[i].countField].number32;
5314             kernel_info.resize(count);
5315             for (unsigned j = 0; j < count; j++) {
5316                 Kernel *r = new Kernel(m->getCurrentVISAVersion());
5317                 p = r->parse(p, end, m);
5318                 if (!p) {
5319                     delete r;
5320                     return 0;
5321                 }
5322                 kernel_info[j] = r;
5323             }
5324             i++;
5325             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
5326                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
5327                 if (!p) return m->setError("bad offset/size for Header's field", i);
5328                 i++;
5329             }
5330             // GlobalVariable
5331             count = fields[fields[i].countField].number32;
5332             file_scope_var_info.resize(count);
5333             for (unsigned j = 0; j < count; j++) {
5334                 GlobalVariable *r = new GlobalVariable(m->getCurrentVISAVersion());
5335                 p = r->parse(p, end, m);
5336                 if (!p) {
5337                     delete r;
5338                     return 0;
5339                 }
5340                 file_scope_var_info[j] = r;
5341             }
5342             i++;
5343             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
5344                 p = m->readField(p, end, fields[i], fields[fields[i].countField].number32);
5345                 if (!p) return m->setError("bad offset/size for Header's field", i);
5346                 i++;
5347             }
5348             // Function
5349             count = fields[fields[i].countField].number32;
5350             function_info.resize(count);
5351             for (unsigned j = 0; j < count; j++) {
5352                 Function *r = new Function(m->getCurrentVISAVersion());
5353                 p = r->parse(p, end, m);
5354                 if (!p) {
5355                     delete r;
5356                     return 0;
5357                 }
5358                 function_info[j] = r;
5359             }
5360             i++;
5361             return p;
5362         }
5363 
5364         //!
5365         //! \brief      Adds all the Header's fields to a buffer.
5366         //! \details    Every field from this class is added to a buffer
5367         //!             in order to be written into an ISA file afterwards
5368         //!             If this class contains other internal structus, their addToBuffer
5369         //!             functions are called when corresponding.
5370         //! \param      [out] buffer.
5371         //!             The buffer where the fields data will be added.
5372         //! \param      [in] m.
5373         //!             Pointer to ISAfile object.
5374         //!
addToBuffer(std::vector<char> & buffer,ISAfile * m)5375         void addToBuffer(std::vector<char> &buffer, ISAfile *m) {
5376             unsigned i = 0;
5377             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
5378                 m->addToBuffer(fields[i], buffer);
5379                 i++;
5380             }
5381             // Kernel
5382             for (Kernel *r : kernel_info) {
5383                 r->addToBuffer(buffer, m);
5384             }
5385             i++;
5386             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
5387                 m->addToBuffer(fields[i], buffer);
5388                 i++;
5389             }
5390             // GlobalVariable
5391             for (GlobalVariable *r : file_scope_var_info) {
5392                 r->addToBuffer(buffer, m);
5393             }
5394             i++;
5395             while (i < fields.size() && fields[i].type != Datatype::STRUCT) {
5396                 m->addToBuffer(fields[i], buffer);
5397                 i++;
5398             }
5399             // Function
5400             for (Function *r : function_info) {
5401                 r->addToBuffer(buffer, m);
5402             }
5403             i++;
5404         }
5405 
5406     };
5407 
5408 };
5409 
5410 #endif //VISA_H
5411