[Mesa-dev] [PATCH 20/23] intel/eu: Rework opcode description tables to allow efficient look-up by either HW or IR opcode.

Francisco Jerez currojerez at riseup.net
Tue Jun 12 02:26:12 UTC 2018


This rewrites the current opcode description tables as a more compact
flat data structure.  The purpose is to allow efficient constant-time
look-up by either HW or IR opcode, which will allow us to drop the
hard-coded correspondence between HW and IR opcodes -- See the next
commits for the rationale.

brw_eu.c is now built as C++ source so we can take advantage of
pointers to member in order to make the look-up function work
regardless of the opcode_desc member used as look-up key.
---
 src/intel/Makefile.sources                  |   2 +-
 src/intel/Makefile.tools.am                 |   4 +
 src/intel/compiler/{brw_eu.c => brw_eu.cpp} | 414 ++++++++++------------------
 src/intel/compiler/brw_eu.h                 |  43 +--
 src/intel/compiler/brw_eu_defines.h         |   4 +-
 src/intel/compiler/meson.build              |   2 +-
 6 files changed, 170 insertions(+), 299 deletions(-)
 rename src/intel/compiler/{brw_eu.c => brw_eu.cpp} (57%)

diff --git a/src/intel/Makefile.sources b/src/intel/Makefile.sources
index f22e727553f..33fdf4a26c7 100644
--- a/src/intel/Makefile.sources
+++ b/src/intel/Makefile.sources
@@ -43,7 +43,7 @@ COMPILER_FILES = \
 	compiler/brw_disasm.c \
 	compiler/brw_disasm_info.c \
 	compiler/brw_disasm_info.h \
-	compiler/brw_eu.c \
+	compiler/brw_eu.cpp \
 	compiler/brw_eu_compact.c \
 	compiler/brw_eu_defines.h \
 	compiler/brw_eu_emit.c \
diff --git a/src/intel/Makefile.tools.am b/src/intel/Makefile.tools.am
index b00cc8cc2cb..4f2027cdfd6 100644
--- a/src/intel/Makefile.tools.am
+++ b/src/intel/Makefile.tools.am
@@ -27,6 +27,8 @@ tools_aubinator_SOURCES = \
 	tools/aubinator.c \
 	tools/intel_aub.h
 
+nodist_EXTRA_tools_aubinator_SOURCES = dummy.cpp
+
 tools_aubinator_CFLAGS = \
 	$(AM_CFLAGS) \
 	$(ZLIB_CFLAGS)
@@ -47,6 +49,8 @@ tools_aubinator_LDADD = \
 tools_aubinator_error_decode_SOURCES = \
 	tools/aubinator_error_decode.c
 
+nodist_EXTRA_tools_aubinator_error_decode_SOURCES = dummy.cpp
+
 tools_aubinator_error_decode_LDADD = \
 	common/libintel_common.la \
 	compiler/libintel_compiler.la \
diff --git a/src/intel/compiler/brw_eu.c b/src/intel/compiler/brw_eu.cpp
similarity index 57%
rename from src/intel/compiler/brw_eu.c
rename to src/intel/compiler/brw_eu.cpp
index 80f05240b42..37375005daa 100644
--- a/src/intel/compiler/brw_eu.c
+++ b/src/intel/compiler/brw_eu.cpp
@@ -406,263 +406,87 @@ enum gen {
 #define GEN_GE(gen) (~GEN_LT(gen))
 #define GEN_LE(gen) (GEN_LT(gen) | (gen))
 
-static const struct opcode_desc opcode_10_descs[] = {
-   { .name = "dim",   .nsrc = 1, .ndst = 1, .gens = GEN75 },
-   { .name = "smov",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN8) },
-};
-
-static const struct opcode_desc opcode_35_descs[] = {
-   { .name = "iff",   .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
-   { .name = "brc",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN7) },
-};
-
-static const struct opcode_desc opcode_38_descs[] = {
-   { .name = "do",    .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
-   { .name = "case",  .nsrc = 0, .ndst = 0, .gens = GEN6 },
-};
-
-static const struct opcode_desc opcode_44_descs[] = {
-   { .name = "msave", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
-   { .name = "call",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN6) },
-};
-
-static const struct opcode_desc opcode_45_descs[] = {
-   { .name = "mrest", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
-   { .name = "ret",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN6) },
-};
-
-static const struct opcode_desc opcode_46_descs[] = {
-   { .name = "push",  .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
-   { .name = "fork",  .nsrc = 0, .ndst = 0, .gens = GEN6 },
-   { .name = "goto",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN8) },
-};
-
-static const struct opcode_desc opcode_descs[128] = {
-   [BRW_OPCODE_ILLEGAL] = {
-      .name = "illegal", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_MOV] = {
-      .name = "mov",     .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_SEL] = {
-      .name = "sel",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_MOVI] = {
-      .name = "movi",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN45),
-   },
-   [BRW_OPCODE_NOT] = {
-      .name = "not",     .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_AND] = {
-      .name = "and",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_OR] = {
-      .name = "or",      .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_XOR] = {
-      .name = "xor",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_SHR] = {
-      .name = "shr",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_SHL] = {
-      .name = "shl",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [10] = {
-      .table = opcode_10_descs, .size = ARRAY_SIZE(opcode_10_descs),
-   },
-   /* Reserved - 11 */
-   [BRW_OPCODE_ASR] = {
-      .name = "asr",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   /* Reserved - 13-15 */
-   [BRW_OPCODE_CMP] = {
-      .name = "cmp",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_CMPN] = {
-      .name = "cmpn",    .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_CSEL] = {
-      .name = "csel",    .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN8),
-   },
-   [BRW_OPCODE_F32TO16] = {
-      .name = "f32to16", .nsrc = 1, .ndst = 1, .gens = GEN7 | GEN75,
-   },
-   [BRW_OPCODE_F16TO32] = {
-      .name = "f16to32", .nsrc = 1, .ndst = 1, .gens = GEN7 | GEN75,
-   },
-   /* Reserved - 21-22 */
-   [BRW_OPCODE_BFREV] = {
-      .name = "bfrev",   .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_BFE] = {
-      .name = "bfe",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_BFI1] = {
-      .name = "bfi1",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_BFI2] = {
-      .name = "bfi2",    .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   /* Reserved - 27-31 */
-   [BRW_OPCODE_JMPI] = {
-      .name = "jmpi",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [33] = {
-      .name = "brd",     .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_IF] = {
-      .name = "if",      .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [35] = {
-      .table = opcode_35_descs, .size = ARRAY_SIZE(opcode_35_descs),
-   },
-   [BRW_OPCODE_ELSE] = {
-      .name = "else",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_ENDIF] = {
-      .name = "endif",   .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [38] = {
-      .table = opcode_38_descs, .size = ARRAY_SIZE(opcode_38_descs),
-   },
-   [BRW_OPCODE_WHILE] = {
-      .name = "while",   .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_BREAK] = {
-      .name = "break",   .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_CONTINUE] = {
-      .name = "cont",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_HALT] = {
-      .name = "halt",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
-   [43] = {
-      .name = "calla",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN75),
-   },
-   [44] = {
-      .table = opcode_44_descs, .size = ARRAY_SIZE(opcode_44_descs),
-   },
-   [45] = {
-      .table = opcode_45_descs, .size = ARRAY_SIZE(opcode_45_descs),
-   },
-   [46] = {
-      .table = opcode_46_descs, .size = ARRAY_SIZE(opcode_46_descs),
-   },
-   [47] = {
-      .name = "pop",     .nsrc = 2, .ndst = 0, .gens = GEN_LE(GEN5),
-   },
-   [BRW_OPCODE_WAIT] = {
-      .name = "wait",    .nsrc = 1, .ndst = 0, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_SEND] = {
-      .name = "send",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_SENDC] = {
-      .name = "sendc",   .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_SENDS] = {
-      .name = "sends",   .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN9),
-   },
-   [BRW_OPCODE_SENDSC] = {
-      .name = "sendsc",  .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN9),
-   },
-   /* Reserved 53-55 */
-   [BRW_OPCODE_MATH] = {
-      .name = "math",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN6),
-   },
-   /* Reserved 57-63 */
-   [BRW_OPCODE_ADD] = {
-      .name = "add",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_MUL] = {
-      .name = "mul",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_AVG] = {
-      .name = "avg",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_FRC] = {
-      .name = "frc",     .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_RNDU] = {
-      .name = "rndu",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_RNDD] = {
-      .name = "rndd",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_RNDE] = {
-      .name = "rnde",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_RNDZ] = {
-      .name = "rndz",    .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_MAC] = {
-      .name = "mac",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_MACH] = {
-      .name = "mach",    .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_LZD] = {
-      .name = "lzd",     .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_FBH] = {
-      .name = "fbh",     .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_FBL] = {
-      .name = "fbl",     .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_CBIT] = {
-      .name = "cbit",    .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_ADDC] = {
-      .name = "addc",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_SUBB] = {
-      .name = "subb",    .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
-   },
-   [BRW_OPCODE_SAD2] = {
-      .name = "sad2",    .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_SADA2] = {
-      .name = "sada2",   .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   /* Reserved 82-83 */
-   [BRW_OPCODE_DP4] = {
-      .name = "dp4",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_DPH] = {
-      .name = "dph",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_DP3] = {
-      .name = "dp3",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   [BRW_OPCODE_DP2] = {
-      .name = "dp2",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
-   },
-   /* Reserved 88 */
-   [BRW_OPCODE_LINE] = {
-      .name = "line",    .nsrc = 2, .ndst = 1, .gens = GEN_LE(GEN10),
-   },
-   [BRW_OPCODE_PLN] = {
-      .name = "pln",     .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN45) & GEN_LE(GEN10),
-   },
-   [BRW_OPCODE_MAD] = {
-      .name = "mad",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6),
-   },
-   [BRW_OPCODE_LRP] = {
-      .name = "lrp",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6) & GEN_LE(GEN10),
-   },
-   [93] = {
-      .name = "madm",    .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN8),
-   },
-   /* Reserved 94-124 */
-   [BRW_OPCODE_NENOP] = {
-      .name = "nenop",   .nsrc = 0, .ndst = 0, .gens = GEN45,
-   },
-   [BRW_OPCODE_NOP] = {
-      .name = "nop",     .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
-   },
+static const struct opcode_desc opcode_descs[] = {
+   /* IR,                 HW,  name,      nsrc, ndst, gens */
+   { BRW_OPCODE_ILLEGAL,  0,   "illegal", 0,    0,    GEN_ALL },
+   { BRW_OPCODE_MOV,      1,   "mov",     1,    1,    GEN_ALL },
+   { BRW_OPCODE_SEL,      2,   "sel",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_MOVI,     3,   "movi",    2,    1,    GEN_GE(GEN45) },
+   { BRW_OPCODE_NOT,      4,   "not",     1,    1,    GEN_ALL },
+   { BRW_OPCODE_AND,      5,   "and",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_OR,       6,   "or",      2,    1,    GEN_ALL },
+   { BRW_OPCODE_XOR,      7,   "xor",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_SHR,      8,   "shr",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_SHL,      9,   "shl",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_DIM,      10,  "dim",     1,    1,    GEN75 },
+   { BRW_OPCODE_SMOV,     10,  "smov",    0,    0,    GEN_GE(GEN8) },
+   { BRW_OPCODE_ASR,      12,  "asr",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_CMP,      16,  "cmp",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_CMPN,     17,  "cmpn",    2,    1,    GEN_ALL },
+   { BRW_OPCODE_CSEL,     18,  "csel",    3,    1,    GEN_GE(GEN8) },
+   { BRW_OPCODE_F32TO16,  19,  "f32to16", 1,    1,    GEN7 | GEN75 },
+   { BRW_OPCODE_F16TO32,  20,  "f16to32", 1,    1,    GEN7 | GEN75 },
+   { BRW_OPCODE_BFREV,    23,  "bfrev",   1,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_BFE,      24,  "bfe",     3,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_BFI1,     25,  "bfi1",    2,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_BFI2,     26,  "bfi2",    3,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_JMPI,     32,  "jmpi",    0,    0,    GEN_ALL },
+   { BRW_OPCODE_BRD,      33,  "brd",     0,    0,    GEN_GE(GEN7) },
+   { BRW_OPCODE_IF,       34,  "if",      0,    0,    GEN_ALL },
+   { BRW_OPCODE_IFF,      35,  "iff",     0,    0,    GEN_LE(GEN5) },
+   { BRW_OPCODE_BRC,      35,  "brc",     0,    0,    GEN_GE(GEN7) },
+   { BRW_OPCODE_ELSE,     36,  "else",    0,    0,    GEN_ALL },
+   { BRW_OPCODE_ENDIF,    37,  "endif",   0,    0,    GEN_ALL },
+   { BRW_OPCODE_DO,       38,  "do",      0,    0,    GEN_LE(GEN5) },
+   { BRW_OPCODE_CASE,     38,  "case",    0,    0,    GEN6 },
+   { BRW_OPCODE_WHILE,    39,  "while",   0,    0,    GEN_ALL },
+   { BRW_OPCODE_BREAK,    40,  "break",   0,    0,    GEN_ALL },
+   { BRW_OPCODE_CONTINUE, 41,  "cont",    0,    0,    GEN_ALL },
+   { BRW_OPCODE_HALT,     42,  "halt",    0,    0,    GEN_ALL },
+   { BRW_OPCODE_CALLA,    43,  "calla",   0,    0,    GEN_GE(GEN75) },
+   { BRW_OPCODE_MSAVE,    44,  "msave",   0,    0,    GEN_LE(GEN5) },
+   { BRW_OPCODE_CALL,     44,  "call",    0,    0,    GEN_GE(GEN6) },
+   { BRW_OPCODE_MREST,    45,  "mrest",   0,    0,    GEN_LE(GEN5) },
+   { BRW_OPCODE_RET,      45,  "ret",     0,    0,    GEN_GE(GEN6) },
+   { BRW_OPCODE_PUSH,     46,  "push",    0,    0,    GEN_LE(GEN5) },
+   { BRW_OPCODE_FORK,     46,  "fork",    0,    0,    GEN6 },
+   { BRW_OPCODE_GOTO,     46,  "goto",    0,    0,    GEN_GE(GEN8) },
+   { BRW_OPCODE_POP,      47,  "pop",     2,    0,    GEN_LE(GEN5) },
+   { BRW_OPCODE_WAIT,     48,  "wait",    1,    0,    GEN_ALL },
+   { BRW_OPCODE_SEND,     49,  "send",    1,    1,    GEN_ALL },
+   { BRW_OPCODE_SENDC,    50,  "sendc",   1,    1,    GEN_ALL },
+   { BRW_OPCODE_SENDS,    51,  "sends",   2,    1,    GEN_GE(GEN9) },
+   { BRW_OPCODE_SENDSC,   52,  "sendsc",  2,    1,    GEN_GE(GEN9) },
+   { BRW_OPCODE_MATH,     56,  "math",    2,    1,    GEN_GE(GEN6) },
+   { BRW_OPCODE_ADD,      64,  "add",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_MUL,      65,  "mul",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_AVG,      66,  "avg",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_FRC,      67,  "frc",     1,    1,    GEN_ALL },
+   { BRW_OPCODE_RNDU,     68,  "rndu",    1,    1,    GEN_ALL },
+   { BRW_OPCODE_RNDD,     69,  "rndd",    1,    1,    GEN_ALL },
+   { BRW_OPCODE_RNDE,     70,  "rnde",    1,    1,    GEN_ALL },
+   { BRW_OPCODE_RNDZ,     71,  "rndz",    1,    1,    GEN_ALL },
+   { BRW_OPCODE_MAC,      72,  "mac",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_MACH,     73,  "mach",    2,    1,    GEN_ALL },
+   { BRW_OPCODE_LZD,      74,  "lzd",     1,    1,    GEN_ALL },
+   { BRW_OPCODE_FBH,      75,  "fbh",     1,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_FBL,      76,  "fbl",     1,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_CBIT,     77,  "cbit",    1,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_ADDC,     78,  "addc",    2,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_SUBB,     79,  "subb",    2,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_SAD2,     80,  "sad2",    2,    1,    GEN_ALL },
+   { BRW_OPCODE_SADA2,    81,  "sada2",   2,    1,    GEN_ALL },
+   { BRW_OPCODE_DP4,      84,  "dp4",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_DPH,      85,  "dph",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_DP3,      86,  "dp3",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_DP2,      87,  "dp2",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_LINE,     89,  "line",    2,    1,    GEN_LE(GEN10) },
+   { BRW_OPCODE_PLN,      90,  "pln",     2,    1,    GEN_GE(GEN45) & GEN_LE(GEN10) },
+   { BRW_OPCODE_MAD,      91,  "mad",     3,    1,    GEN_GE(GEN6) },
+   { BRW_OPCODE_LRP,      92,  "lrp",     3,    1,    GEN_GE(GEN6) & GEN_LE(GEN10) },
+   { BRW_OPCODE_MADM,     93,  "madm",    3,    1,    GEN_GE(GEN8) },
+   { BRW_OPCODE_NENOP,    125, "nenop",   0,    0,    GEN45 },
+   { BRW_OPCODE_NOP,      126, "nop",     0,    0,    GEN_ALL },
 };
 
 static enum gen
@@ -682,27 +506,67 @@ gen_from_devinfo(const struct gen_device_info *devinfo)
    }
 }
 
-/* Return the matching opcode_desc for the specified opcode number and
- * hardware generation, or NULL if the opcode is not supported by the device.
+/**
+ * Look up the opcode_descs[] entry with \p key member matching \p k which is
+ * supported by the device specified by \p devinfo, or NULL if there is no
+ * matching entry.
+ *
+ * This is implemented by using an index data structure (storage for which is
+ * provided by the caller as \p index_devinfo and \p index_descs) in order to
+ * provide efficient constant-time look-up.
  */
-const struct opcode_desc *
-brw_opcode_desc(const struct gen_device_info *devinfo, enum opcode opcode)
+static const opcode_desc *
+lookup_opcode_desc(gen_device_info *index_devinfo,
+                   const opcode_desc **index_descs,
+                   unsigned index_size,
+                   unsigned opcode_desc::*key,
+                   const gen_device_info *devinfo,
+                   unsigned k)
 {
-   if (opcode >= ARRAY_SIZE(opcode_descs))
-      return NULL;
-
-   enum gen gen = gen_from_devinfo(devinfo);
-   if (opcode_descs[opcode].gens != 0) {
-      if ((opcode_descs[opcode].gens & gen) != 0) {
-         return &opcode_descs[opcode];
-      }
-   } else if (opcode_descs[opcode].table != NULL) {
-      const struct opcode_desc *table = opcode_descs[opcode].table;
-      for (unsigned i = 0; i < opcode_descs[opcode].size; i++) {
-         if ((table[i].gens & gen) != 0) {
-            return &table[i];
+   if (memcmp(index_devinfo, devinfo, sizeof(*devinfo))) {
+      memcpy(index_devinfo, devinfo, sizeof(*devinfo));
+      const gen gen = gen_from_devinfo(devinfo);
+
+      for (unsigned l = 0; l < index_size; l++)
+         index_descs[l] = NULL;
+
+      for (unsigned i = 0; i < ARRAY_SIZE(opcode_descs); i++) {
+         if (opcode_descs[i].gens & gen) {
+            const unsigned l = opcode_descs[i].*key;
+            assert(l < index_size && !index_descs[l]);
+            index_descs[l] = &opcode_descs[i];
          }
       }
    }
-   return NULL;
+
+   if (k < index_size)
+      return index_descs[k];
+   else
+      return NULL;
+}
+
+/**
+ * Return the matching opcode_desc for the specified IR opcode and hardware
+ * generation, or NULL if the opcode is not supported by the device.
+ */
+const struct opcode_desc *
+brw_opcode_desc(const struct gen_device_info *devinfo, enum opcode opcode)
+{
+   static __thread gen_device_info index_devinfo = {};
+   static __thread const opcode_desc *index_descs[NUM_BRW_OPCODES];
+   return lookup_opcode_desc(&index_devinfo, index_descs, ARRAY_SIZE(index_descs),
+                             &opcode_desc::ir, devinfo, opcode);
+}
+
+/**
+ * Return the matching opcode_desc for the specified HW opcode and hardware
+ * generation, or NULL if the opcode is not supported by the device.
+ */
+const struct opcode_desc *
+brw_opcode_desc_from_hw(const struct gen_device_info *devinfo, unsigned hw)
+{
+   static __thread gen_device_info index_devinfo = {};
+   static __thread const opcode_desc *index_descs[128];
+   return lookup_opcode_desc(&index_devinfo, index_descs, ARRAY_SIZE(index_descs),
+                             &opcode_desc::hw, devinfo, hw);
 }
diff --git a/src/intel/compiler/brw_eu.h b/src/intel/compiler/brw_eu.h
index 0fc32ef0750..dcfaffdaa03 100644
--- a/src/intel/compiler/brw_eu.h
+++ b/src/intel/compiler/brw_eu.h
@@ -718,32 +718,33 @@ next_offset(const struct gen_device_info *devinfo, void *store, int offset)
 }
 
 struct opcode_desc {
-   /* The union is an implementation detail used by brw_opcode_desc() to handle
-    * opcodes that have been reused for different instructions across hardware
-    * generations.
-    *
-    * The gens field acts as a tag. If it is non-zero, name points to a string
-    * containing the instruction mnemonic. If it is zero, the table field is
-    * valid and either points to a secondary opcode_desc table with 'size'
-    * elements or is NULL and no such instruction exists for the opcode.
-    */
-   union {
-      struct {
-         char    *name;
-         int      nsrc;
-      };
-      struct {
-         const struct opcode_desc *table;
-         unsigned size;
-      };
-   };
-   int      ndst;
-   int      gens;
+   unsigned ir;
+   unsigned hw;
+   const char *name;
+   int nsrc;
+   int ndst;
+   int gens;
 };
 
 const struct opcode_desc *
 brw_opcode_desc(const struct gen_device_info *devinfo, enum opcode opcode);
 
+const struct opcode_desc *
+brw_opcode_desc_from_hw(const struct gen_device_info *devinfo, unsigned hw);
+
+static inline unsigned
+brw_opcode_encode(const struct gen_device_info *devinfo, enum opcode opcode)
+{
+   return brw_opcode_desc(devinfo, opcode)->hw;
+}
+
+static inline enum opcode
+brw_opcode_decode(const struct gen_device_info *devinfo, unsigned hw)
+{
+   const struct opcode_desc *desc = brw_opcode_desc_from_hw(devinfo, hw);
+   return desc ? (enum opcode)desc->ir : BRW_OPCODE_ILLEGAL;
+}
+
 static inline bool
 is_3src(const struct gen_device_info *devinfo, enum opcode opcode)
 {
diff --git a/src/intel/compiler/brw_eu_defines.h b/src/intel/compiler/brw_eu_defines.h
index a00f84ca681..ff1a3ac2075 100644
--- a/src/intel/compiler/brw_eu_defines.h
+++ b/src/intel/compiler/brw_eu_defines.h
@@ -279,10 +279,12 @@ enum opcode {
    BRW_OPCODE_NOP =	126,
    /* Reserved 127 */
 
+   NUM_BRW_OPCODES = 128,
+
    /* These are compiler backend opcodes that get translated into other
     * instructions.
     */
-   FS_OPCODE_FB_WRITE = 128,
+   FS_OPCODE_FB_WRITE = NUM_BRW_OPCODES,
 
    /**
     * Same as FS_OPCODE_FB_WRITE but expects its arguments separately as
diff --git a/src/intel/compiler/meson.build b/src/intel/compiler/meson.build
index 72b7a6796cb..e11ed64608d 100644
--- a/src/intel/compiler/meson.build
+++ b/src/intel/compiler/meson.build
@@ -36,7 +36,7 @@ libintel_compiler_files = files(
   'brw_disasm.c',
   'brw_disasm_info.c',
   'brw_disasm_info.h',
-  'brw_eu.c',
+  'brw_eu.cpp',
   'brw_eu_compact.c',
   'brw_eu_defines.h',
   'brw_eu_emit.c',
-- 
2.16.1



More information about the mesa-dev mailing list