mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 06:40:11 +01:00
freedreno: slurp in rnn
Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6070>
This commit is contained in:
parent
b721d336da
commit
7c0bd8429f
13 changed files with 3055 additions and 0 deletions
|
|
@ -28,6 +28,13 @@ subdir('fdl')
|
|||
subdir('perfcntrs')
|
||||
subdir('computerator')
|
||||
|
||||
dep_libxml2 = dependency('libxml-2.0', required: false)
|
||||
|
||||
# Everything that depends on rnn requires (indirectly) libxml2:
|
||||
if dep_libxml2.found()
|
||||
subdir('rnn')
|
||||
endif
|
||||
|
||||
if with_tools.contains('drm-shim')
|
||||
subdir('drm-shim')
|
||||
endif
|
||||
|
|
|
|||
38
src/freedreno/rnn/aprintf.c
Normal file
38
src/freedreno/rnn/aprintf.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2011 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
char *aprintf(const char *format, ...) {
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
size_t sz = vsnprintf(0, 0, format, va);
|
||||
va_end(va);
|
||||
char *res = malloc(sz + 1);
|
||||
va_start(va, format);
|
||||
vsnprintf(res, sz + 1, format, va);
|
||||
va_end(va);
|
||||
return res;
|
||||
}
|
||||
61
src/freedreno/rnn/colors.c
Normal file
61
src/freedreno/rnn/colors.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "colors.h"
|
||||
|
||||
const struct envy_colors envy_null_colors = {
|
||||
.reset = "",
|
||||
.iname = "",
|
||||
.rname = "",
|
||||
.mod = "",
|
||||
.sym = "",
|
||||
.reg = "",
|
||||
.regsp = "",
|
||||
.num = "",
|
||||
.mem = "",
|
||||
.btarg = "",
|
||||
.ctarg = "",
|
||||
.bctarg = "",
|
||||
.eval = "",
|
||||
.comm = "",
|
||||
.err = "",
|
||||
};
|
||||
|
||||
const struct envy_colors envy_def_colors = {
|
||||
.reset = "\x1b[0m",
|
||||
.iname = "\x1b[0;32m",
|
||||
.rname = "\x1b[0;32m",
|
||||
.mod = "\x1b[0;36m",
|
||||
.sym = "\x1b[0;36m",
|
||||
.reg = "\x1b[0;31m",
|
||||
.regsp = "\x1b[0;35m",
|
||||
.num = "\x1b[0;33m",
|
||||
.mem = "\x1b[0;35m",
|
||||
.btarg = "\x1b[0;35m",
|
||||
.ctarg = "\x1b[0;1;37m",
|
||||
.bctarg = "\x1b[0;1;35m",
|
||||
.eval = "\x1b[0;35m",
|
||||
.comm = "\x1b[0;34m",
|
||||
.err = "\x1b[0;1;31m",
|
||||
};
|
||||
49
src/freedreno/rnn/colors.h
Normal file
49
src/freedreno/rnn/colors.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef COLORS_H
|
||||
#define COLORS_H
|
||||
|
||||
struct envy_colors {
|
||||
const char *reset;
|
||||
const char *iname; /* instruction name */
|
||||
const char *rname; /* register or bitfield name */
|
||||
const char *mod; /* instruction modifier */
|
||||
const char *sym; /* auxiliary char like { , + */
|
||||
const char *reg; /* ISA register */
|
||||
const char *regsp; /* special ISA register */
|
||||
const char *num; /* immediate number */
|
||||
const char *mem; /* memory reference */
|
||||
const char *btarg; /* branch target */
|
||||
const char *ctarg; /* call target */
|
||||
const char *bctarg; /* branch and call target */
|
||||
const char *eval; /* enum value */
|
||||
const char *comm; /* comment */
|
||||
const char *err; /* error */
|
||||
};
|
||||
|
||||
extern const struct envy_colors envy_null_colors;
|
||||
extern const struct envy_colors envy_def_colors;
|
||||
|
||||
#endif
|
||||
501
src/freedreno/rnn/headergen2.c
Normal file
501
src/freedreno/rnn/headergen2.c
Normal file
|
|
@ -0,0 +1,501 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Rob Clark <robdclark@gmail.com>
|
||||
* Copyright (C) 2010-2011 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* Copyright (C) 2010 Luca Barbieri <luca@luca-barbieri.com>
|
||||
* Copyright (C) 2010 Marcin Slusarz <marcin.slusarz@gmail.com>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* modified version of headergen which uses enums and inline fxns for
|
||||
* type safety.. based on original headergen
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "rnn.h"
|
||||
#include "util.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct rnndelem **elems = NULL;
|
||||
int elemsnum = 0;
|
||||
int elemsmax = 0;
|
||||
|
||||
char **offsetfns = NULL;
|
||||
int offsetfnsnum = 0;
|
||||
int offsetfnsmax = 0;
|
||||
|
||||
int startcol = 64;
|
||||
|
||||
struct fout {
|
||||
char *name;
|
||||
FILE *file;
|
||||
char *guard;
|
||||
};
|
||||
|
||||
struct fout *fouts = 0;
|
||||
int foutsnum = 0;
|
||||
int foutsmax = 0;
|
||||
|
||||
static bool no_asserts = false;
|
||||
|
||||
static void seekcol (FILE *f, int src, int dst) {
|
||||
if (dst <= src)
|
||||
fprintf (f, "\t");
|
||||
else {
|
||||
int n = dst/8 - src/8;
|
||||
if (n) {
|
||||
while (n--)
|
||||
fprintf (f, "\t");
|
||||
n = dst&7;
|
||||
} else
|
||||
n = dst-src;
|
||||
while (n--)
|
||||
fprintf (f, " ");
|
||||
}
|
||||
}
|
||||
|
||||
static FILE *findfout (char *file) {
|
||||
int i;
|
||||
for (i = 0; i < foutsnum; i++)
|
||||
if (!strcmp(fouts[i].name, file))
|
||||
break;
|
||||
if (i == foutsnum) {
|
||||
fprintf (stderr, "AIII, didn't open file %s.\n", file);
|
||||
exit(1);
|
||||
}
|
||||
return fouts[i].file;
|
||||
}
|
||||
|
||||
static void printdef (char *name, char *suf, int type, uint64_t val, char *file) {
|
||||
FILE *dst = findfout(file);
|
||||
int len;
|
||||
if (suf)
|
||||
fprintf (dst, "#define %s__%s%n", name, suf, &len);
|
||||
else
|
||||
fprintf (dst, "#define %s%n", name, &len);
|
||||
if (type == 0 && val > 0xffffffffull)
|
||||
seekcol (dst, len, startcol-8);
|
||||
else
|
||||
seekcol (dst, len, startcol);
|
||||
switch (type) {
|
||||
case 0:
|
||||
if (val > 0xffffffffull)
|
||||
fprintf (dst, "0x%016"PRIx64"ULL\n", val);
|
||||
else
|
||||
fprintf (dst, "0x%08"PRIx64"\n", val);
|
||||
break;
|
||||
case 1:
|
||||
fprintf (dst, "%"PRIu64"\n", val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printvalue (struct rnnvalue *val, int shift) {
|
||||
if (val->varinfo.dead)
|
||||
return;
|
||||
if (val->valvalid)
|
||||
printdef (val->fullname, 0, 0, val->value << shift, val->file);
|
||||
}
|
||||
|
||||
static void printbitfield (struct rnnbitfield *bf, int shift);
|
||||
|
||||
static void printtypeinfo (struct rnntypeinfo *ti, struct rnnbitfield *bf,
|
||||
char *prefix, char *file) {
|
||||
FILE *dst = findfout(file);
|
||||
enum rnnttype intype = ti->type;
|
||||
char *typename = NULL;
|
||||
uint32_t mask = typeinfo_mask(ti);
|
||||
uint32_t width = 1 + ti->high - ti->low;
|
||||
|
||||
/* for fixed point, input type (arg to fxn) is float: */
|
||||
if ((ti->type == RNN_TTYPE_FIXED) || (ti->type == RNN_TTYPE_UFIXED))
|
||||
intype = RNN_TTYPE_FLOAT;
|
||||
|
||||
/* for toplevel register (ie. not bitfield), only generate accessor
|
||||
* fxn for special cases (float, shr, min/max, etc):
|
||||
*/
|
||||
if (bf || ti->shr || ti->minvalid || ti->maxvalid || ti->alignvalid ||
|
||||
ti->radixvalid || (intype == RNN_TTYPE_FLOAT)) {
|
||||
switch (intype) {
|
||||
case RNN_TTYPE_HEX:
|
||||
case RNN_TTYPE_UINT:
|
||||
case RNN_TTYPE_A3XX_REGID:
|
||||
typename = "uint32_t";
|
||||
break;
|
||||
case RNN_TTYPE_INT:
|
||||
typename = "int32_t";
|
||||
break;
|
||||
case RNN_TTYPE_FLOAT:
|
||||
typename = "float";
|
||||
break;
|
||||
case RNN_TTYPE_ENUM:
|
||||
asprintf(&typename, "enum %s", ti->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* for boolean, just generate a #define flag.. rather than inline fxn */
|
||||
if (bf && (intype == RNN_TTYPE_BOOLEAN)) {
|
||||
printdef(bf->fullname, 0, 0, mask, file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typename) {
|
||||
printdef(prefix, "MASK", 0, mask, file);
|
||||
printdef(prefix, "SHIFT", 1, ti->low, file);
|
||||
|
||||
fprintf(dst, "static inline uint32_t %s(%s val)\n", prefix, typename);
|
||||
fprintf(dst, "{\n");
|
||||
|
||||
if ((ti->minvalid || ti->maxvalid || ti->alignvalid) && !no_asserts) {
|
||||
fprintf(dst, "\tassert(1");
|
||||
if (ti->minvalid)
|
||||
fprintf(dst, " && (val >= %lu)", ti->min);
|
||||
if (ti->maxvalid)
|
||||
fprintf(dst, " && (val <= %lu)", ti->max);
|
||||
if (ti->alignvalid)
|
||||
fprintf(dst, " && !(val %% %lu)", ti->align);
|
||||
fprintf(dst, ");\n");
|
||||
}
|
||||
|
||||
if (ti->shr && !no_asserts) {
|
||||
fprintf(dst, "\tassert(!(val & 0x%x));\n", (1 << ti->shr) - 1);
|
||||
}
|
||||
|
||||
fprintf(dst, "\treturn ((");
|
||||
|
||||
if (ti->type == RNN_TTYPE_FIXED) {
|
||||
fprintf(dst, "((int32_t)(val * %d.0))", (1 << ti->radix));
|
||||
} else if (ti->type == RNN_TTYPE_UFIXED) {
|
||||
fprintf(dst, "((uint32_t)(val * %d.0))", (1 << ti->radix));
|
||||
} else if (ti->type == RNN_TTYPE_FLOAT) {
|
||||
if (width == 32)
|
||||
fprintf(dst, "fui(val)");
|
||||
else if (width == 16)
|
||||
fprintf(dst, "util_float_to_half(val)");
|
||||
else
|
||||
assert(!"invalid float size");
|
||||
} else {
|
||||
fprintf(dst, "val");
|
||||
}
|
||||
|
||||
if (ti->shr)
|
||||
fprintf(dst, " >> %d", ti->shr);
|
||||
|
||||
fprintf(dst, ") << %s__SHIFT) & %s__MASK;\n", prefix, prefix);
|
||||
fprintf(dst, "}\n");
|
||||
|
||||
if (intype == RNN_TTYPE_ENUM)
|
||||
free(typename);
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < ti->valsnum; i++)
|
||||
printvalue(ti->vals[i], ti->low);
|
||||
for (i = 0; i < ti->bitfieldsnum; i++)
|
||||
printbitfield(ti->bitfields[i], ti->low);
|
||||
}
|
||||
|
||||
static void printbitfield (struct rnnbitfield *bf, int shift) {
|
||||
if (bf->varinfo.dead)
|
||||
return;
|
||||
printtypeinfo (&bf->typeinfo, bf, bf->fullname, bf->file);
|
||||
}
|
||||
|
||||
static void printdelem (struct rnndelem *elem, uint64_t offset) {
|
||||
int use_offset_fxn;
|
||||
char *offsetfn = NULL;
|
||||
|
||||
if (elem->varinfo.dead)
|
||||
return;
|
||||
|
||||
use_offset_fxn = elem->offsets || elem->doffset || elem->doffsets;
|
||||
assert((!!elem->offsets + !!elem->doffset + !!elem->doffsets) <= 1);
|
||||
|
||||
if (use_offset_fxn)
|
||||
asprintf(&offsetfn, "__offset_%s", elem->name);
|
||||
|
||||
if (elem->length != 1) {
|
||||
ADDARRAY(elems, elem);
|
||||
ADDARRAY(offsetfns, offsetfn);
|
||||
}
|
||||
|
||||
if (elem->name) {
|
||||
char *regname;
|
||||
asprintf(®name, "REG_%s", elem->fullname);
|
||||
if (elemsnum) {
|
||||
int len;
|
||||
FILE *dst = findfout(elem->file);
|
||||
int i;
|
||||
|
||||
if (use_offset_fxn) {
|
||||
fprintf(dst, "static inline uint32_t %s(", offsetfn);
|
||||
if (elem->index)
|
||||
fprintf(dst, "enum %s", elem->index->name);
|
||||
else
|
||||
fprintf(dst, "uint32_t");
|
||||
fprintf(dst, " idx)\n");
|
||||
fprintf(dst, "{\n");
|
||||
if (elem->doffset) {
|
||||
fprintf(dst, "\treturn (%s) + (%#" PRIx64 "*idx);\n", elem->doffset, elem->stride);
|
||||
} else {
|
||||
int valuesnum = elem->doffsets ? elem->doffsetsnum : elem->offsetsnum;
|
||||
|
||||
fprintf(dst, "\tswitch (idx) {\n");
|
||||
for (i = 0; i < valuesnum; i++) {
|
||||
struct rnnvalue *val = NULL;
|
||||
fprintf(dst, "\t\tcase ");
|
||||
if (elem->index) {
|
||||
int j;
|
||||
for (j = 0; j < elem->index->valsnum; j++) {
|
||||
if (elem->index->vals[j]->value == i) {
|
||||
val = elem->index->vals[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (val) {
|
||||
fprintf(dst, "%s", val->name);
|
||||
} else {
|
||||
fprintf(dst, "%d", i);
|
||||
}
|
||||
if (elem->offsets) {
|
||||
fprintf(dst, ": return 0x%08lx;\n", elem->offsets[i]);
|
||||
} else {
|
||||
fprintf(dst, ": return (%s);\n", elem->doffsets[i]);
|
||||
}
|
||||
}
|
||||
fprintf(dst, "\t\tdefault: return INVALID_IDX(idx);\n");
|
||||
fprintf(dst, "\t}\n");
|
||||
}
|
||||
fprintf(dst, "}\n");
|
||||
}
|
||||
fprintf (dst, "static inline uint32_t %s(", regname);
|
||||
for (i = 0; i < elemsnum; i++) {
|
||||
if (i)
|
||||
fprintf(dst, ", ");
|
||||
if (elems[i]->index)
|
||||
fprintf(dst, "enum %s ", elems[i]->index->name);
|
||||
else
|
||||
fprintf(dst, "uint32_t ");
|
||||
fprintf (dst, "i%d%n", i, &len);
|
||||
}
|
||||
fprintf (dst, ") { return ");
|
||||
fprintf (dst, "0x%08"PRIx64"", offset + elem->offset);
|
||||
for (i = 0; i < elemsnum; i++) {
|
||||
if (offsetfns[i])
|
||||
fprintf(dst, " + %s(i%d)", offsetfns[i], i);
|
||||
else
|
||||
fprintf (dst, " + %#" PRIx64 "*i%d", elems[i]->stride, i);
|
||||
}
|
||||
fprintf (dst, "; }\n");
|
||||
} else
|
||||
printdef (regname, 0, 0, offset + elem->offset, elem->file);
|
||||
|
||||
free(regname);
|
||||
/*
|
||||
if (elem->stride)
|
||||
printdef (elem->fullname, "ESIZE", 0, elem->stride, elem->file);
|
||||
if (elem->length != 1)
|
||||
printdef (elem->fullname, "LEN", 0, elem->length, elem->file);
|
||||
*/
|
||||
printtypeinfo (&elem->typeinfo, NULL, elem->fullname, elem->file);
|
||||
}
|
||||
fprintf (findfout(elem->file), "\n");
|
||||
int j;
|
||||
for (j = 0; j < elem->subelemsnum; j++) {
|
||||
printdelem(elem->subelems[j], offset + elem->offset);
|
||||
}
|
||||
if (elem->length != 1) {
|
||||
elemsnum--;
|
||||
offsetfnsnum--;
|
||||
}
|
||||
free(offsetfn);
|
||||
}
|
||||
|
||||
static void print_file_info_(FILE *dst, struct stat* sb, struct tm* tm)
|
||||
{
|
||||
char timestr[64];
|
||||
strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm);
|
||||
fprintf(dst, "(%7Lu bytes, from %s)\n", (unsigned long long)sb->st_size, timestr);
|
||||
}
|
||||
|
||||
static void print_file_info(FILE *dst, const char* file)
|
||||
{
|
||||
struct stat sb;
|
||||
struct tm tm;
|
||||
stat(file, &sb);
|
||||
gmtime_r(&sb.st_mtime, &tm);
|
||||
print_file_info_(dst, &sb, &tm);
|
||||
}
|
||||
|
||||
static void printhead(struct fout f, struct rnndb *db) {
|
||||
int i, j;
|
||||
struct stat sb;
|
||||
struct tm tm;
|
||||
stat(f.name, &sb);
|
||||
gmtime_r(&sb.st_mtime, &tm);
|
||||
fprintf (f.file, "#ifndef %s\n", f.guard);
|
||||
fprintf (f.file, "#define %s\n", f.guard);
|
||||
fprintf (f.file, "\n");
|
||||
fprintf(f.file,
|
||||
"/* Autogenerated file, DO NOT EDIT manually!\n"
|
||||
"\n"
|
||||
"This file was generated by the rules-ng-ng headergen tool in this git repository:\n"
|
||||
"http://github.com/freedreno/envytools/\n"
|
||||
"git clone https://github.com/freedreno/envytools.git\n"
|
||||
"\n"
|
||||
"The rules-ng-ng source files this header was generated from are:\n");
|
||||
unsigned maxlen = 0;
|
||||
for(i = 0; i < db->filesnum; ++i) {
|
||||
unsigned len = strlen(db->files[i]);
|
||||
if(len > maxlen)
|
||||
maxlen = len;
|
||||
}
|
||||
for(i = 0; i < db->filesnum; ++i) {
|
||||
unsigned len = strlen(db->files[i]);
|
||||
fprintf(f.file, "- %s%*s ", db->files[i], maxlen - len, "");
|
||||
print_file_info(f.file, db->files[i]);
|
||||
}
|
||||
fprintf(f.file,
|
||||
"\n"
|
||||
"Copyright (C) ");
|
||||
if(db->copyright.firstyear && db->copyright.firstyear < (1900 + tm.tm_year))
|
||||
fprintf(f.file, "%u-", db->copyright.firstyear);
|
||||
fprintf(f.file, "%u", 1900 + tm.tm_year);
|
||||
if(db->copyright.authorsnum) {
|
||||
fprintf(f.file, " by the following authors:");
|
||||
for(i = 0; i < db->copyright.authorsnum; ++i) {
|
||||
fprintf(f.file, "\n- ");
|
||||
if(db->copyright.authors[i]->name)
|
||||
fprintf(f.file, "%s", db->copyright.authors[i]->name);
|
||||
if(db->copyright.authors[i]->email)
|
||||
fprintf(f.file, " <%s>", db->copyright.authors[i]->email);
|
||||
if(db->copyright.authors[i]->nicknamesnum) {
|
||||
for(j = 0; j < db->copyright.authors[i]->nicknamesnum; ++j) {
|
||||
fprintf(f.file, "%s%s", (j ? ", " : " ("), db->copyright.authors[i]->nicknames[j]);
|
||||
}
|
||||
fprintf(f.file, ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(f.file, "\n");
|
||||
if(db->copyright.license)
|
||||
fprintf(f.file, "\n%s\n", db->copyright.license);
|
||||
fprintf(f.file, "*/\n\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *file;
|
||||
struct rnndb *db;
|
||||
int i, j;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage:\n\theadergen database-file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((argc >= 3) && !strcmp(argv[1], "--no-asserts")) {
|
||||
no_asserts = true;
|
||||
file = argv[2];
|
||||
} else {
|
||||
file = argv[1];
|
||||
}
|
||||
|
||||
rnn_init();
|
||||
db = rnn_newdb();
|
||||
rnn_parsefile (db, file);
|
||||
rnn_prepdb (db);
|
||||
for(i = 0; i < db->filesnum; ++i) {
|
||||
char *dstname = malloc(strlen(db->files[i]) + 3);
|
||||
char *pretty;
|
||||
strcpy(dstname, db->files[i]);
|
||||
strcat(dstname, ".h");
|
||||
struct fout f = { db->files[i], fopen(dstname, "w") };
|
||||
if (!f.file) {
|
||||
perror(dstname);
|
||||
exit(1);
|
||||
}
|
||||
free(dstname);
|
||||
pretty = strrchr(f.name, '/');
|
||||
if (pretty)
|
||||
pretty += 1;
|
||||
else
|
||||
pretty = f.name;
|
||||
f.guard = strdup(pretty);
|
||||
for (j = 0; j < strlen(f.guard); j++)
|
||||
if (isalnum(f.guard[j]))
|
||||
f.guard[j] = toupper(f.guard[j]);
|
||||
else
|
||||
f.guard[j] = '_';
|
||||
ADDARRAY(fouts, f);
|
||||
printhead(f, db);
|
||||
}
|
||||
|
||||
for (i = 0; i < db->enumsnum; i++) {
|
||||
FILE *dst = NULL;
|
||||
int j;
|
||||
for (j = 0; j < db->enums[i]->valsnum; j++) {
|
||||
if (!dst) {
|
||||
dst = findfout(db->enums[i]->vals[j]->file);
|
||||
fprintf(dst, "enum %s {\n", db->enums[i]->name);
|
||||
}
|
||||
if (0xffff0000 & db->enums[i]->vals[j]->value)
|
||||
fprintf(dst, "\t%s = 0x%08lx,\n", db->enums[i]->vals[j]->name,
|
||||
db->enums[i]->vals[j]->value);
|
||||
else
|
||||
fprintf(dst, "\t%s = %lu,\n", db->enums[i]->vals[j]->name,
|
||||
db->enums[i]->vals[j]->value);
|
||||
}
|
||||
if (dst) {
|
||||
fprintf(dst, "};\n\n");
|
||||
}
|
||||
}
|
||||
for (i = 0; i < db->bitsetsnum; i++) {
|
||||
if (db->bitsets[i]->isinline)
|
||||
continue;
|
||||
int j;
|
||||
for (j = 0; j < db->bitsets[i]->bitfieldsnum; j++)
|
||||
printbitfield (db->bitsets[i]->bitfields[j], 0);
|
||||
}
|
||||
for (i = 0; i < db->domainsnum; i++) {
|
||||
if (db->domains[i]->size)
|
||||
printdef (db->domains[i]->fullname, "SIZE", 0, db->domains[i]->size, db->domains[i]->file);
|
||||
int j;
|
||||
for (j = 0; j < db->domains[i]->subelemsnum; j++) {
|
||||
printdelem(db->domains[i]->subelems[j], 0);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < foutsnum; ++i) {
|
||||
fprintf (fouts[i].file, "\n#endif /* %s */\n", fouts[i].guard);
|
||||
}
|
||||
return db->estatus;
|
||||
}
|
||||
59
src/freedreno/rnn/meson.build
Normal file
59
src/freedreno/rnn/meson.build
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Copyright © 2020 Google, Inc
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
libfreedreno_rnn_files = files(
|
||||
'aprintf.c',
|
||||
'colors.c',
|
||||
'colors.h',
|
||||
'path.c',
|
||||
'rnn.c',
|
||||
'rnn.h',
|
||||
'rnndec.c',
|
||||
'rnndec.h',
|
||||
'rnn_path.h',
|
||||
'util.h',
|
||||
)
|
||||
|
||||
libfreedreno_rnn = static_library(
|
||||
'freedreno_rnn',
|
||||
libfreedreno_rnn_files,
|
||||
include_directories: [],
|
||||
c_args : [
|
||||
no_override_init_args,
|
||||
'-DSOURCE_DIR="' + meson.source_root() + '"',
|
||||
# TODO how do we get install prefix??
|
||||
'-DINSTALL_DIR=""',
|
||||
],
|
||||
gnu_symbol_visibility: 'hidden',
|
||||
dependencies: [ dep_libxml2 ],
|
||||
build_by_default: false,
|
||||
)
|
||||
|
||||
headergen2 = executable(
|
||||
'headergen2',
|
||||
'headergen2.c',
|
||||
include_directories: [],
|
||||
c_args : [no_override_init_args],
|
||||
gnu_symbol_visibility: 'hidden',
|
||||
dependencies: [],
|
||||
link_with: libfreedreno_rnn,
|
||||
build_by_default: with_tools.contains('freedreno'),
|
||||
install: false
|
||||
)
|
||||
59
src/freedreno/rnn/path.c
Normal file
59
src/freedreno/rnn/path.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
#include <string.h>
|
||||
|
||||
FILE *find_in_path(const char *name, const char *path, char **pfullname) {
|
||||
if (!path)
|
||||
return 0;
|
||||
while (path) {
|
||||
const char *npath = strchr(path, ':');
|
||||
size_t plen;
|
||||
if (npath) {
|
||||
plen = npath - path;
|
||||
npath++;
|
||||
} else {
|
||||
plen = strlen(path);
|
||||
}
|
||||
if (plen) {
|
||||
char *fullname = malloc(strlen(name) + plen + 2);
|
||||
strncpy(fullname, path, plen);
|
||||
fullname[plen] = '/';
|
||||
fullname[plen+1] = 0;
|
||||
strcat(fullname, name);
|
||||
FILE *file = fopen(fullname, "r");
|
||||
if (file) {
|
||||
if (pfullname)
|
||||
*pfullname = fullname;
|
||||
else
|
||||
free(fullname);
|
||||
return file;
|
||||
}
|
||||
free(fullname);
|
||||
}
|
||||
path = npath;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
1332
src/freedreno/rnn/rnn.c
Normal file
1332
src/freedreno/rnn/rnn.c
Normal file
File diff suppressed because it is too large
Load diff
243
src/freedreno/rnn/rnn.h
Normal file
243
src/freedreno/rnn/rnn.h
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* Copyright (C) 2010 Luca Barbieri <luca@luca-barbieri.com>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef RNN_H
|
||||
#define RNN_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct rnnauthor {
|
||||
char* name;
|
||||
char* email;
|
||||
char* contributions;
|
||||
char* license;
|
||||
char** nicknames;
|
||||
int nicknamesnum;
|
||||
int nicknamesmax;
|
||||
};
|
||||
|
||||
struct rnncopyright {
|
||||
unsigned firstyear;
|
||||
char* license;
|
||||
struct rnnauthor **authors;
|
||||
int authorsnum;
|
||||
int authorsmax;
|
||||
};
|
||||
|
||||
struct rnndb {
|
||||
struct rnncopyright copyright;
|
||||
struct rnnenum **enums;
|
||||
int enumsnum;
|
||||
int enumsmax;
|
||||
struct rnnbitset **bitsets;
|
||||
int bitsetsnum;
|
||||
int bitsetsmax;
|
||||
struct rnndomain **domains;
|
||||
int domainsnum;
|
||||
int domainsmax;
|
||||
struct rnngroup **groups;
|
||||
int groupsnum;
|
||||
int groupsmax;
|
||||
struct rnnspectype **spectypes;
|
||||
int spectypesnum;
|
||||
int spectypesmax;
|
||||
char **files;
|
||||
int filesnum;
|
||||
int filesmax;
|
||||
int estatus;
|
||||
};
|
||||
|
||||
struct rnnvarset {
|
||||
struct rnnenum *venum;
|
||||
int *variants;
|
||||
};
|
||||
|
||||
struct rnnvarinfo {
|
||||
char *prefixstr;
|
||||
char *varsetstr;
|
||||
char *variantsstr;
|
||||
int dead;
|
||||
struct rnnenum *prefenum;
|
||||
char *prefix;
|
||||
struct rnnvarset **varsets;
|
||||
int varsetsnum;
|
||||
int varsetsmax;
|
||||
};
|
||||
|
||||
struct rnnenum {
|
||||
char *name;
|
||||
int bare;
|
||||
int isinline;
|
||||
struct rnnvarinfo varinfo;
|
||||
struct rnnvalue **vals;
|
||||
int valsnum;
|
||||
int valsmax;
|
||||
char *fullname;
|
||||
int prepared;
|
||||
char *file;
|
||||
};
|
||||
|
||||
struct rnnvalue {
|
||||
char *name;
|
||||
int valvalid;
|
||||
uint64_t value;
|
||||
struct rnnvarinfo varinfo;
|
||||
char *fullname;
|
||||
char *file;
|
||||
};
|
||||
|
||||
struct rnntypeinfo {
|
||||
char *name;
|
||||
enum rnnttype {
|
||||
RNN_TTYPE_INVALID,
|
||||
RNN_TTYPE_INLINE_ENUM,
|
||||
RNN_TTYPE_INLINE_BITSET,
|
||||
RNN_TTYPE_ENUM,
|
||||
RNN_TTYPE_BITSET,
|
||||
RNN_TTYPE_SPECTYPE,
|
||||
RNN_TTYPE_HEX,
|
||||
RNN_TTYPE_INT,
|
||||
RNN_TTYPE_UINT,
|
||||
RNN_TTYPE_FLOAT,
|
||||
RNN_TTYPE_BOOLEAN,
|
||||
RNN_TTYPE_FIXED,
|
||||
RNN_TTYPE_UFIXED,
|
||||
RNN_TTYPE_A3XX_REGID,
|
||||
} type;
|
||||
struct rnnenum *eenum;
|
||||
struct rnnbitset *ebitset;
|
||||
struct rnnspectype *spectype;
|
||||
struct rnnbitfield **bitfields;
|
||||
int bitfieldsnum;
|
||||
int bitfieldsmax;
|
||||
struct rnnvalue **vals;
|
||||
int valsnum;
|
||||
int valsmax;
|
||||
int shr, low, high;
|
||||
uint64_t min, max, align, radix;
|
||||
int addvariant;
|
||||
int minvalid, maxvalid, alignvalid, radixvalid;
|
||||
};
|
||||
|
||||
static inline uint64_t typeinfo_mask(struct rnntypeinfo *ti)
|
||||
{
|
||||
if (ti->high == 63)
|
||||
return -(1ULL << ti->low);
|
||||
else
|
||||
return (1ULL << (ti->high + 1)) - (1ULL << ti->low);
|
||||
}
|
||||
|
||||
struct rnnbitset {
|
||||
char *name;
|
||||
int bare;
|
||||
int isinline;
|
||||
struct rnnvarinfo varinfo;
|
||||
struct rnnbitfield **bitfields;
|
||||
int bitfieldsnum;
|
||||
int bitfieldsmax;
|
||||
char *fullname;
|
||||
char *file;
|
||||
};
|
||||
|
||||
struct rnnbitfield {
|
||||
char *name;
|
||||
struct rnnvarinfo varinfo;
|
||||
struct rnntypeinfo typeinfo;
|
||||
char *fullname;
|
||||
char *file;
|
||||
};
|
||||
|
||||
struct rnndomain {
|
||||
char *name;
|
||||
int bare;
|
||||
int width;
|
||||
uint64_t size;
|
||||
int sizevalid;
|
||||
struct rnnvarinfo varinfo;
|
||||
struct rnndelem **subelems;
|
||||
int subelemsnum;
|
||||
int subelemsmax;
|
||||
char *fullname;
|
||||
char *file;
|
||||
};
|
||||
|
||||
struct rnngroup {
|
||||
char *name;
|
||||
struct rnndelem **subelems;
|
||||
int subelemsnum;
|
||||
int subelemsmax;
|
||||
};
|
||||
|
||||
struct rnndelem {
|
||||
enum rnnetype {
|
||||
RNN_ETYPE_REG,
|
||||
RNN_ETYPE_ARRAY,
|
||||
RNN_ETYPE_STRIPE,
|
||||
RNN_ETYPE_USE_GROUP,
|
||||
} type;
|
||||
char *name;
|
||||
int width;
|
||||
enum rnnaccess {
|
||||
RNN_ACCESS_R,
|
||||
RNN_ACCESS_W,
|
||||
RNN_ACCESS_RW,
|
||||
} access;
|
||||
uint64_t offset;
|
||||
uint64_t *offsets; /* for "array" with irregular offsets */
|
||||
int offsetsnum;
|
||||
int offsetsmax;
|
||||
char *doffset;
|
||||
char **doffsets;
|
||||
int doffsetsnum;
|
||||
int doffsetsmax;
|
||||
uint64_t length;
|
||||
uint64_t stride;
|
||||
struct rnndelem **subelems;
|
||||
int subelemsnum;
|
||||
int subelemsmax;
|
||||
struct rnnvarinfo varinfo;
|
||||
struct rnntypeinfo typeinfo;
|
||||
struct rnnenum *index; /* for arrays, for symbolic idx values */
|
||||
char *fullname;
|
||||
char *file;
|
||||
};
|
||||
|
||||
struct rnnspectype {
|
||||
char *name;
|
||||
struct rnntypeinfo typeinfo;
|
||||
char *file;
|
||||
};
|
||||
|
||||
void rnn_init(void);
|
||||
struct rnndb *rnn_newdb(void);
|
||||
void rnn_parsefile (struct rnndb *db, char *file);
|
||||
void rnn_prepdb (struct rnndb *db);
|
||||
struct rnnenum *rnn_findenum (struct rnndb *db, const char *name);
|
||||
struct rnnbitset *rnn_findbitset (struct rnndb *db, const char *name);
|
||||
struct rnndomain *rnn_finddomain (struct rnndb *db, const char *name);
|
||||
struct rnnspectype *rnn_findspectype (struct rnndb *db, const char *name);
|
||||
|
||||
#endif
|
||||
1
src/freedreno/rnn/rnn_path.h
Normal file
1
src/freedreno/rnn/rnn_path.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#define RNN_DEF_PATH SOURCE_DIR "/src/freedreno/registers:" INSTALL_DIR "share/mesa/freedreno/registers"
|
||||
531
src/freedreno/rnn/rnndec.c
Normal file
531
src/freedreno/rnn/rnndec.c
Normal file
|
|
@ -0,0 +1,531 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2011 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* Copyright (C) 2010 Francisco Jerez <currojerez@riseup.net>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE // for asprintf
|
||||
#include "rnndec.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include "util.h"
|
||||
|
||||
struct rnndeccontext *rnndec_newcontext(struct rnndb *db) {
|
||||
struct rnndeccontext *res = calloc (sizeof *res, 1);
|
||||
res->db = db;
|
||||
res->colors = &envy_null_colors;
|
||||
return res;
|
||||
}
|
||||
|
||||
int rnndec_varadd(struct rnndeccontext *ctx, char *varset, char *variant) {
|
||||
struct rnnenum *en = rnn_findenum(ctx->db, varset);
|
||||
if (!en) {
|
||||
fprintf (stderr, "Enum %s doesn't exist in database!\n", varset);
|
||||
return 0;
|
||||
}
|
||||
int i, j;
|
||||
for (i = 0; i < en->valsnum; i++)
|
||||
if (!strcasecmp(en->vals[i]->name, variant)) {
|
||||
struct rnndecvariant *ci = calloc (sizeof *ci, 1);
|
||||
ci->en = en;
|
||||
ci->variant = i;
|
||||
ADDARRAY(ctx->vars, ci);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (i == en->valsnum) {
|
||||
fprintf (stderr, "Variant %s doesn't exist in enum %s!\n", variant, varset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < ctx->varsnum; j++) {
|
||||
if (ctx->vars[j]->en == en) {
|
||||
ctx->vars[j]->variant = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ctx->varsnum) {
|
||||
struct rnndecvariant *ci = calloc (sizeof *ci, 1);
|
||||
ci->en = en;
|
||||
ci->variant = i;
|
||||
ADDARRAY(ctx->vars, ci);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rnndec_varmatch(struct rnndeccontext *ctx, struct rnnvarinfo *vi) {
|
||||
if (vi->dead)
|
||||
return 0;
|
||||
int i;
|
||||
for (i = 0; i < vi->varsetsnum; i++) {
|
||||
int j;
|
||||
for (j = 0; j < ctx->varsnum; j++)
|
||||
if (vi->varsets[i]->venum == ctx->vars[j]->en)
|
||||
break;
|
||||
if (j == ctx->varsnum) {
|
||||
fprintf (stderr, "I don't know which %s variant to use!\n", vi->varsets[i]->venum->name);
|
||||
} else {
|
||||
if (!vi->varsets[i]->variants[ctx->vars[j]->variant])
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* see https://en.wikipedia.org/wiki/Half-precision_floating-point_format */
|
||||
static uint32_t float16i(uint16_t val)
|
||||
{
|
||||
uint32_t sign = ((uint32_t)(val & 0x8000)) << 16;
|
||||
uint32_t frac = val & 0x3ff;
|
||||
int32_t expn = (val >> 10) & 0x1f;
|
||||
|
||||
if (expn == 0) {
|
||||
if (frac) {
|
||||
/* denormalized number: */
|
||||
int shift = __builtin_clz(frac) - 21;
|
||||
frac <<= shift;
|
||||
expn = -shift;
|
||||
} else {
|
||||
/* +/- zero: */
|
||||
return sign;
|
||||
}
|
||||
} else if (expn == 0x1f) {
|
||||
/* Inf/NaN: */
|
||||
return sign | 0x7f800000 | (frac << 13);
|
||||
}
|
||||
|
||||
return sign | ((expn + 127 - 15) << 23) | (frac << 13);
|
||||
}
|
||||
static float float16(uint16_t val)
|
||||
{
|
||||
union { uint32_t i; float f; } u;
|
||||
u.i = float16i(val);
|
||||
return u.f;
|
||||
}
|
||||
|
||||
static const char *rnndec_decode_enum_val(struct rnndeccontext *ctx,
|
||||
struct rnnvalue **vals, int valsnum, uint64_t value)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < valsnum; i++)
|
||||
if (rnndec_varmatch(ctx, &vals[i]->varinfo) &&
|
||||
vals[i]->valvalid && vals[i]->value == value)
|
||||
return vals[i]->name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *rnndec_decode_enum(struct rnndeccontext *ctx, const char *enumname, uint64_t enumval)
|
||||
{
|
||||
struct rnnenum *en = rnn_findenum (ctx->db, enumname);
|
||||
if (en) {
|
||||
int i;
|
||||
for (i = 0; i < en->valsnum; i++)
|
||||
if (en->vals[i]->valvalid && en->vals[i]->value == enumval)
|
||||
return en->vals[i]->name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The name UNK%u is used as a placeholder for bitfields that exist but
|
||||
* have an unknown function.
|
||||
*/
|
||||
static int is_unknown(const char *name)
|
||||
{
|
||||
unsigned u;
|
||||
return sscanf(name, "UNK%u", &u) == 1;
|
||||
}
|
||||
|
||||
char *rnndec_decodeval(struct rnndeccontext *ctx, struct rnntypeinfo *ti, uint64_t value) {
|
||||
int width = ti->high - ti->low + 1;
|
||||
char *res = 0;
|
||||
int i;
|
||||
struct rnnvalue **vals;
|
||||
int valsnum;
|
||||
struct rnnbitfield **bitfields;
|
||||
int bitfieldsnum;
|
||||
char *tmp;
|
||||
uint64_t mask, value_orig;
|
||||
if (!ti)
|
||||
goto failhex;
|
||||
value_orig = value;
|
||||
value = (value & typeinfo_mask(ti)) >> ti->low;
|
||||
value <<= ti->shr;
|
||||
|
||||
switch (ti->type) {
|
||||
case RNN_TTYPE_ENUM:
|
||||
vals = ti->eenum->vals;
|
||||
valsnum = ti->eenum->valsnum;
|
||||
goto doenum;
|
||||
case RNN_TTYPE_INLINE_ENUM:
|
||||
vals = ti->vals;
|
||||
valsnum = ti->valsnum;
|
||||
goto doenum;
|
||||
doenum:
|
||||
tmp = rnndec_decode_enum_val(ctx, vals, valsnum, value);
|
||||
if (tmp) {
|
||||
asprintf (&res, "%s%s%s", ctx->colors->eval, tmp, ctx->colors->reset);
|
||||
if (ti->addvariant) {
|
||||
rnndec_varadd(ctx, ti->eenum->name, tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
goto failhex;
|
||||
case RNN_TTYPE_BITSET:
|
||||
bitfields = ti->ebitset->bitfields;
|
||||
bitfieldsnum = ti->ebitset->bitfieldsnum;
|
||||
goto dobitset;
|
||||
case RNN_TTYPE_INLINE_BITSET:
|
||||
bitfields = ti->bitfields;
|
||||
bitfieldsnum = ti->bitfieldsnum;
|
||||
goto dobitset;
|
||||
dobitset:
|
||||
mask = 0;
|
||||
for (i = 0; i < bitfieldsnum; i++) {
|
||||
if (!rnndec_varmatch(ctx, &bitfields[i]->varinfo))
|
||||
continue;
|
||||
uint64_t type_mask = typeinfo_mask(&bitfields[i]->typeinfo);
|
||||
if (((value & type_mask) == 0) && is_unknown(bitfields[i]->name))
|
||||
continue;
|
||||
mask |= type_mask;
|
||||
if (bitfields[i]->typeinfo.type == RNN_TTYPE_BOOLEAN) {
|
||||
const char *color = is_unknown(bitfields[i]->name) ?
|
||||
ctx->colors->err : ctx->colors->mod;
|
||||
if (value & type_mask) {
|
||||
if (!res)
|
||||
asprintf (&res, "%s%s%s", color, bitfields[i]->name, ctx->colors->reset);
|
||||
else {
|
||||
asprintf (&tmp, "%s | %s%s%s", res, color, bitfields[i]->name, ctx->colors->reset);
|
||||
free(res);
|
||||
res = tmp;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
char *subval;
|
||||
if (is_unknown(bitfields[i]->name) && (bitfields[i]->typeinfo.type != RNN_TTYPE_A3XX_REGID)) {
|
||||
uint64_t field_val = value & type_mask;
|
||||
field_val = (field_val & typeinfo_mask(&bitfields[i]->typeinfo)) >> bitfields[i]->typeinfo.low;
|
||||
field_val <<= bitfields[i]->typeinfo.shr;
|
||||
asprintf (&subval, "%s%#"PRIx64"%s", ctx->colors->err, field_val, ctx->colors->reset);
|
||||
} else {
|
||||
subval = rnndec_decodeval(ctx, &bitfields[i]->typeinfo, value & type_mask);
|
||||
}
|
||||
if (!res)
|
||||
asprintf (&res, "%s%s%s = %s", ctx->colors->rname, bitfields[i]->name, ctx->colors->reset, subval);
|
||||
else {
|
||||
asprintf (&tmp, "%s | %s%s%s = %s", res, ctx->colors->rname, bitfields[i]->name, ctx->colors->reset, subval);
|
||||
free(res);
|
||||
res = tmp;
|
||||
}
|
||||
free(subval);
|
||||
}
|
||||
if (value & ~mask) {
|
||||
if (!res)
|
||||
asprintf (&res, "%s%#"PRIx64"%s", ctx->colors->err, value & ~mask, ctx->colors->reset);
|
||||
else {
|
||||
asprintf (&tmp, "%s | %s%#"PRIx64"%s", res, ctx->colors->err, value & ~mask, ctx->colors->reset);
|
||||
free(res);
|
||||
res = tmp;
|
||||
}
|
||||
}
|
||||
if (!res)
|
||||
asprintf (&res, "%s0%s", ctx->colors->num, ctx->colors->reset);
|
||||
asprintf (&tmp, "{ %s }", res);
|
||||
free(res);
|
||||
return tmp;
|
||||
case RNN_TTYPE_SPECTYPE:
|
||||
return rnndec_decodeval(ctx, &ti->spectype->typeinfo, value);
|
||||
case RNN_TTYPE_HEX:
|
||||
asprintf (&res, "%s%#"PRIx64"%s", ctx->colors->num, value, ctx->colors->reset);
|
||||
break;
|
||||
case RNN_TTYPE_FIXED:
|
||||
if (value & UINT64_C(1) << (width-1)) {
|
||||
asprintf (&res, "%s-%lf%s", ctx->colors->num,
|
||||
((double)((UINT64_C(1) << width) - value)) / ((double)(1 << ti->radix)),
|
||||
ctx->colors->reset);
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case RNN_TTYPE_UFIXED:
|
||||
asprintf (&res, "%s%lf%s", ctx->colors->num,
|
||||
((double)value) / ((double)(1LL << ti->radix)),
|
||||
ctx->colors->reset);
|
||||
break;
|
||||
case RNN_TTYPE_A3XX_REGID:
|
||||
asprintf (&res, "%sr%"PRIu64".%c%s", ctx->colors->num, (value >> 2), "xyzw"[value & 0x3], ctx->colors->reset);
|
||||
break;
|
||||
case RNN_TTYPE_UINT:
|
||||
asprintf (&res, "%s%"PRIu64"%s", ctx->colors->num, value, ctx->colors->reset);
|
||||
break;
|
||||
case RNN_TTYPE_INT:
|
||||
if (value & UINT64_C(1) << (width-1))
|
||||
asprintf (&res, "%s-%"PRIi64"%s", ctx->colors->num, (UINT64_C(1) << width) - value, ctx->colors->reset);
|
||||
else
|
||||
asprintf (&res, "%s%"PRIi64"%s", ctx->colors->num, value, ctx->colors->reset);
|
||||
break;
|
||||
case RNN_TTYPE_BOOLEAN:
|
||||
if (value == 0) {
|
||||
asprintf (&res, "%sFALSE%s", ctx->colors->eval, ctx->colors->reset);
|
||||
} else if (value == 1) {
|
||||
asprintf (&res, "%sTRUE%s", ctx->colors->eval, ctx->colors->reset);
|
||||
}
|
||||
break;
|
||||
case RNN_TTYPE_FLOAT: {
|
||||
union { uint64_t i; float f; double d; } val;
|
||||
val.i = value;
|
||||
if (width == 64)
|
||||
asprintf(&res, "%s%f%s", ctx->colors->num,
|
||||
val.d, ctx->colors->reset);
|
||||
else if (width == 32)
|
||||
asprintf(&res, "%s%f%s", ctx->colors->num,
|
||||
val.f, ctx->colors->reset);
|
||||
else if (width == 16)
|
||||
asprintf(&res, "%s%f%s", ctx->colors->num,
|
||||
float16(value), ctx->colors->reset);
|
||||
else
|
||||
goto failhex;
|
||||
|
||||
break;
|
||||
}
|
||||
failhex:
|
||||
default:
|
||||
asprintf (&res, "%s%#"PRIx64"%s", ctx->colors->num, value, ctx->colors->reset);
|
||||
break;
|
||||
}
|
||||
if (value_orig & ~typeinfo_mask(ti)) {
|
||||
asprintf (&tmp, "%s | %s%#"PRIx64"%s", res, ctx->colors->err, value_orig & ~typeinfo_mask(ti), ctx->colors->reset);
|
||||
free(res);
|
||||
res = tmp;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static char *appendidx (struct rnndeccontext *ctx, char *name, uint64_t idx, struct rnnenum *index) {
|
||||
char *res, *index_name = NULL;
|
||||
|
||||
if (index)
|
||||
index_name = rnndec_decode_enum_val(ctx, index->vals, index->valsnum, idx);
|
||||
|
||||
if (index_name)
|
||||
asprintf (&res, "%s[%s%s%s]", name, ctx->colors->eval, index_name, ctx->colors->reset);
|
||||
else
|
||||
asprintf (&res, "%s[%s%#"PRIx64"%s]", name, ctx->colors->num, idx, ctx->colors->reset);
|
||||
|
||||
free (name);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* This could probably be made to work for stripes too.. */
|
||||
static int get_array_idx_offset(struct rnndelem *elem, uint64_t addr, uint64_t *idx, uint64_t *offset)
|
||||
{
|
||||
if (elem->offsets) {
|
||||
int i;
|
||||
for (i = 0; i < elem->offsetsnum; i++) {
|
||||
uint64_t o = elem->offsets[i];
|
||||
if ((o <= addr) && (addr < (o + elem->stride))) {
|
||||
*idx = i;
|
||||
*offset = addr - o;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
if (addr < elem->offset)
|
||||
return -1;
|
||||
|
||||
*idx = (addr - elem->offset) / elem->stride;
|
||||
*offset = (addr - elem->offset) % elem->stride;
|
||||
|
||||
if (elem->length && (*idx >= elem->length))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct rnndecaddrinfo *trymatch (struct rnndeccontext *ctx, struct rnndelem **elems, int elemsnum, uint64_t addr, int write, int dwidth, uint64_t *indices, int indicesnum) {
|
||||
struct rnndecaddrinfo *res;
|
||||
int i, j;
|
||||
for (i = 0; i < elemsnum; i++) {
|
||||
if (!rnndec_varmatch(ctx, &elems[i]->varinfo))
|
||||
continue;
|
||||
uint64_t offset, idx;
|
||||
char *tmp, *name;
|
||||
switch (elems[i]->type) {
|
||||
case RNN_ETYPE_REG:
|
||||
if (addr < elems[i]->offset)
|
||||
break;
|
||||
if (elems[i]->stride) {
|
||||
idx = (addr-elems[i]->offset)/elems[i]->stride;
|
||||
offset = (addr-elems[i]->offset)%elems[i]->stride;
|
||||
} else {
|
||||
idx = 0;
|
||||
offset = addr-elems[i]->offset;
|
||||
}
|
||||
if (offset >= elems[i]->width/dwidth)
|
||||
break;
|
||||
if (elems[i]->length && idx >= elems[i]->length)
|
||||
break;
|
||||
res = calloc (sizeof *res, 1);
|
||||
res->typeinfo = &elems[i]->typeinfo;
|
||||
res->width = elems[i]->width;
|
||||
asprintf (&res->name, "%s%s%s", ctx->colors->rname, elems[i]->name, ctx->colors->reset);
|
||||
for (j = 0; j < indicesnum; j++)
|
||||
res->name = appendidx(ctx, res->name, indices[j], NULL);
|
||||
if (elems[i]->length != 1)
|
||||
res->name = appendidx(ctx, res->name, idx, elems[i]->index);
|
||||
if (offset) {
|
||||
asprintf (&tmp, "%s+%s%#"PRIx64"%s", res->name, ctx->colors->err, offset, ctx->colors->reset);
|
||||
free(res->name);
|
||||
res->name = tmp;
|
||||
}
|
||||
return res;
|
||||
case RNN_ETYPE_STRIPE:
|
||||
for (idx = 0; idx < elems[i]->length || !elems[i]->length; idx++) {
|
||||
if (addr < elems[i]->offset + elems[i]->stride * idx)
|
||||
break;
|
||||
offset = addr - (elems[i]->offset + elems[i]->stride * idx);
|
||||
int extraidx = (elems[i]->length != 1);
|
||||
int nindnum = (elems[i]->name ? 0 : indicesnum + extraidx);
|
||||
uint64_t nind[nindnum];
|
||||
if (!elems[i]->name) {
|
||||
for (j = 0; j < indicesnum; j++)
|
||||
nind[j] = indices[j];
|
||||
if (extraidx)
|
||||
nind[indicesnum] = idx;
|
||||
}
|
||||
res = trymatch (ctx, elems[i]->subelems, elems[i]->subelemsnum, offset, write, dwidth, nind, nindnum);
|
||||
if (!res)
|
||||
continue;
|
||||
if (!elems[i]->name)
|
||||
return res;
|
||||
asprintf (&name, "%s%s%s", ctx->colors->rname, elems[i]->name, ctx->colors->reset);
|
||||
for (j = 0; j < indicesnum; j++)
|
||||
name = appendidx(ctx, name, indices[j], NULL);
|
||||
if (elems[i]->length != 1)
|
||||
name = appendidx(ctx, name, idx, elems[i]->index);
|
||||
asprintf (&tmp, "%s.%s", name, res->name);
|
||||
free(name);
|
||||
free(res->name);
|
||||
res->name = tmp;
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
case RNN_ETYPE_ARRAY:
|
||||
if (get_array_idx_offset(elems[i], addr, &idx, &offset))
|
||||
break;
|
||||
asprintf (&name, "%s%s%s", ctx->colors->rname, elems[i]->name, ctx->colors->reset);
|
||||
for (j = 0; j < indicesnum; j++)
|
||||
name = appendidx(ctx, name, indices[j], NULL);
|
||||
if (elems[i]->length != 1)
|
||||
name = appendidx(ctx, name, idx, elems[i]->index);
|
||||
if ((res = trymatch (ctx, elems[i]->subelems, elems[i]->subelemsnum, offset, write, dwidth, 0, 0))) {
|
||||
asprintf (&tmp, "%s.%s", name, res->name);
|
||||
free(name);
|
||||
free(res->name);
|
||||
res->name = tmp;
|
||||
return res;
|
||||
}
|
||||
res = calloc (sizeof *res, 1);
|
||||
asprintf (&tmp, "%s+%s%#"PRIx64"%s", name, ctx->colors->err, offset, ctx->colors->reset);
|
||||
free(name);
|
||||
res->name = tmp;
|
||||
return res;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rnndec_checkaddr(struct rnndeccontext *ctx, struct rnndomain *domain, uint64_t addr, int write) {
|
||||
struct rnndecaddrinfo *res = trymatch(ctx, domain->subelems, domain->subelemsnum, addr, write, domain->width, 0, 0);
|
||||
if (res) {
|
||||
free(res->name);
|
||||
free(res);
|
||||
}
|
||||
return res != NULL;
|
||||
}
|
||||
|
||||
struct rnndecaddrinfo *rnndec_decodeaddr(struct rnndeccontext *ctx, struct rnndomain *domain, uint64_t addr, int write) {
|
||||
struct rnndecaddrinfo *res = trymatch(ctx, domain->subelems, domain->subelemsnum, addr, write, domain->width, 0, 0);
|
||||
if (res)
|
||||
return res;
|
||||
res = calloc (sizeof *res, 1);
|
||||
asprintf (&res->name, "%s%#"PRIx64"%s", ctx->colors->err, addr, ctx->colors->reset);
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint64_t tryreg(struct rnndeccontext *ctx, struct rnndelem **elems, int elemsnum,
|
||||
int dwidth, const char *name)
|
||||
{
|
||||
int i;
|
||||
const char *suffix = strchr(name, '[');
|
||||
unsigned n = suffix ? (suffix - name) : strlen(name);
|
||||
|
||||
const char *child = NULL;
|
||||
unsigned idx = 0;
|
||||
|
||||
if (suffix) {
|
||||
const char *tmp = strchr(suffix, ']');
|
||||
idx = strtol(suffix+1, NULL, 0);
|
||||
child = tmp+2;
|
||||
}
|
||||
|
||||
for (i = 0; i < elemsnum; i++) {
|
||||
struct rnndelem *elem = elems[i];
|
||||
if (!rnndec_varmatch(ctx, &elem->varinfo))
|
||||
continue;
|
||||
int match = (strlen(elem->name) == n) && !strncmp(elem->name, name, n);
|
||||
switch (elem->type) {
|
||||
case RNN_ETYPE_REG:
|
||||
if (match) {
|
||||
assert(!suffix);
|
||||
return elem->offset;
|
||||
}
|
||||
break;
|
||||
case RNN_ETYPE_STRIPE:
|
||||
assert(0); // TODO
|
||||
break;
|
||||
case RNN_ETYPE_ARRAY:
|
||||
if (match) {
|
||||
assert(suffix);
|
||||
return elem->offset + (idx * elem->stride) +
|
||||
tryreg(ctx, elem->subelems, elem->subelemsnum, dwidth, child);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t rnndec_decodereg(struct rnndeccontext *ctx, struct rnndomain *domain, const char *name)
|
||||
{
|
||||
return tryreg(ctx, domain->subelems, domain->subelemsnum, domain->width, name);
|
||||
}
|
||||
59
src/freedreno/rnn/rnndec.h
Normal file
59
src/freedreno/rnn/rnndec.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef RNNDEC_H
|
||||
#define RNNDEC_H
|
||||
|
||||
#include "rnn.h"
|
||||
#include "colors.h"
|
||||
|
||||
struct rnndecvariant {
|
||||
struct rnnenum *en;
|
||||
int variant;
|
||||
};
|
||||
|
||||
struct rnndeccontext {
|
||||
struct rnndb *db;
|
||||
struct rnndecvariant **vars;
|
||||
int varsnum;
|
||||
int varsmax;
|
||||
const struct envy_colors *colors;
|
||||
};
|
||||
|
||||
struct rnndecaddrinfo {
|
||||
struct rnntypeinfo *typeinfo;
|
||||
int width;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct rnndeccontext *rnndec_newcontext(struct rnndb *db);
|
||||
int rnndec_varadd(struct rnndeccontext *ctx, char *varset, char *variant);
|
||||
int rnndec_varmatch(struct rnndeccontext *ctx, struct rnnvarinfo *vi);
|
||||
char *rnndec_decode_enum(struct rnndeccontext *ctx, const char *enumname, uint64_t enumval);
|
||||
char *rnndec_decodeval(struct rnndeccontext *ctx, struct rnntypeinfo *ti, uint64_t value);
|
||||
int rnndec_checkaddr(struct rnndeccontext *ctx, struct rnndomain *domain, uint64_t addr, int write);
|
||||
struct rnndecaddrinfo *rnndec_decodeaddr(struct rnndeccontext *ctx, struct rnndomain *domain, uint64_t addr, int write);
|
||||
uint64_t rnndec_decodereg(struct rnndeccontext *ctx, struct rnndomain *domain, const char *name);
|
||||
|
||||
#endif
|
||||
115
src/freedreno/rnn/util.h
Normal file
115
src/freedreno/rnn/util.h
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2011 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
* Copyright (C) 2010 Francisco Jerez <currojerez@riseup.net>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define ADDARRAY(a, e) \
|
||||
do { \
|
||||
if ((a ## num) >= (a ## max)) { \
|
||||
if (!(a ## max)) \
|
||||
(a ## max) = 16; \
|
||||
else \
|
||||
(a ## max) *= 2; \
|
||||
(a) = realloc((a), (a ## max)*sizeof(*(a))); \
|
||||
} \
|
||||
(a)[(a ## num)++] = (e); \
|
||||
} while(0)
|
||||
|
||||
#define FINDARRAY(a, tmp, pred) \
|
||||
({ \
|
||||
int __i; \
|
||||
\
|
||||
for (__i = 0; __i < (a ## num); __i++) { \
|
||||
tmp = (a)[__i]; \
|
||||
if (pred) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
tmp = ((pred) ? tmp : NULL); \
|
||||
})
|
||||
|
||||
/* ceil(log2(x)) */
|
||||
static inline int clog2(uint64_t x) {
|
||||
if (!x)
|
||||
return x;
|
||||
int r = 0;
|
||||
while (x - 1 > (1ull << r) - 1)
|
||||
r++;
|
||||
return r;
|
||||
}
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof (a) / sizeof *(a))
|
||||
|
||||
#define min(a,b) \
|
||||
({ \
|
||||
typeof (a) _a = (a); \
|
||||
typeof (b) _b = (b); \
|
||||
_a < _b ? _a : _b; \
|
||||
})
|
||||
|
||||
#define max(a,b) \
|
||||
({ \
|
||||
typeof (a) _a = (a); \
|
||||
typeof (b) _b = (b); \
|
||||
_a > _b ? _a : _b; \
|
||||
})
|
||||
|
||||
#define CEILDIV(a, b) (((a) + (b) - 1)/(b))
|
||||
|
||||
#define extr(a, b, c) ((uint64_t)(a) << (64 - (b) - (c)) >> (64 - (c)))
|
||||
#define extrs(a, b, c) ((int64_t)(a) << (64 - (b) - (c)) >> (64 - (c)))
|
||||
#define sext(a, b) extrs(a, 0, b+1)
|
||||
#define bflmask(a) ((2ull << ((a)-1)) - 1)
|
||||
#define insrt(a, b, c, d) ((a) = ((a) & ~(bflmask(c) << (b))) | ((d) & bflmask(c)) << (b))
|
||||
|
||||
struct envy_loc {
|
||||
int lstart;
|
||||
int cstart;
|
||||
int lend;
|
||||
int cend;
|
||||
const char *file;
|
||||
};
|
||||
|
||||
#define LOC_FORMAT(loc, str) "%s:%d.%d-%d.%d: " str, (loc).file, (loc).lstart, (loc).cstart, (loc).lend, (loc).cend
|
||||
|
||||
uint32_t elf_hash(const char *str);
|
||||
|
||||
FILE *find_in_path(const char *name, const char *path, char **pfullname);
|
||||
|
||||
struct astr {
|
||||
char *str;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
void print_escaped_astr(FILE *out, struct astr *astr);
|
||||
|
||||
char *aprintf(const char *format, ...);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue