nouveau/mme: Add initial Fermi definition

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
Mary
2023-01-05 23:43:00 +01:00
committed by Marge Bot
parent 5971c0967a
commit 663258be5e
5 changed files with 713 additions and 6 deletions
+41 -6
View File
@@ -18,12 +18,12 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
mme_isa_depend_files = [
mme_tu104_isa_depend_files = [
'mme_tu104.xml',
isaspec_py_deps
]
mme_isa = custom_target(
mme_tu104_isa = custom_target(
'mme_isa',
input: ['mme_tu104.xml'],
output: ['mme_tu104_isa.c', 'mme_tu104_isa.h'],
@@ -31,21 +31,50 @@ mme_isa = custom_target(
prog_isaspec_decode, '--xml', '@INPUT@',
'--out-c', '@OUTPUT0@', '--out-h', '@OUTPUT1@',
],
depend_files: mme_isa_depend_files,
depend_files: mme_tu104_isa_depend_files,
)
mme_encode_h = custom_target(
mme_tu104_encode_h = custom_target(
'mme-tu104-encode.h',
input: ['mme_tu104.xml'],
output: 'mme_tu104_encode.h',
command: [
prog_isaspec_encode, '--xml', '@INPUT@', '--out-h', '@OUTPUT@'
],
depend_files: mme_isa_depend_files,
depend_files: mme_tu104_isa_depend_files,
)
mme_fermi_isa_depend_files = [
'mme_fermi.xml',
isaspec_py_deps
]
mme_fermi_isa = custom_target(
'mme_fermi_isa',
input: ['mme_fermi.xml'],
output: ['mme_fermi_isa.c', 'mme_fermi_isa.h'],
command: [
prog_isaspec_decode, '--xml', '@INPUT@',
'--out-c', '@OUTPUT0@', '--out-h', '@OUTPUT1@',
],
depend_files: mme_fermi_isa_depend_files,
)
mme_fermi_encode_h = custom_target(
'mme-fermi-encode.h',
input: ['mme_fermi.xml'],
output: 'mme_fermi_encode.h',
command: [
prog_isaspec_encode, '--xml', '@INPUT@', '--out-h', '@OUTPUT@'
],
depend_files: mme_fermi_isa_depend_files,
)
libnouveau_mme_files = files(
'mme_builder.h',
'mme_fermi.c',
'mme_fermi.h',
'mme_fermi_dump.c',
'mme_tu104.c',
'mme_tu104.h',
'mme_tu104_builder.c',
@@ -56,7 +85,13 @@ libnouveau_mme_files = files(
_libnouveau_mme = static_library(
'nouveau_mme',
[libnouveau_mme_files, mme_isa, mme_encode_h],
[
libnouveau_mme_files,
mme_fermi_isa,
mme_fermi_encode_h,
mme_tu104_isa,
mme_tu104_encode_h,
],
include_directories : [inc_include, inc_src],
gnu_symbol_visibility : 'hidden',
dependencies : [
+281
View File
@@ -0,0 +1,281 @@
#include "mme_fermi.h"
#include "mme_fermi_encode.h"
#include "util/u_math.h"
#define OP_TO_STR(OP) [MME_FERMI_OP_##OP] = #OP
static const char *op_to_str[] = {
OP_TO_STR(ALU_REG),
OP_TO_STR(ADD_IMM),
OP_TO_STR(MERGE),
OP_TO_STR(BFE_LSL_IMM),
OP_TO_STR(BFE_LSL_REG),
OP_TO_STR(STATE),
OP_TO_STR(UNK6),
OP_TO_STR(BRANCH),
};
#undef OP_TO_STR
const char *
mme_fermi_op_to_str(enum mme_fermi_op op)
{
assert(op < ARRAY_SIZE(op_to_str));
return op_to_str[op];
}
#define ALU_OP_TO_STR(OP) [MME_FERMI_ALU_OP_##OP] = #OP
static const char *alu_op_to_str[] = {
ALU_OP_TO_STR(ADD),
ALU_OP_TO_STR(ADDC),
ALU_OP_TO_STR(SUB),
ALU_OP_TO_STR(SUBB),
ALU_OP_TO_STR(RESERVED4),
ALU_OP_TO_STR(RESERVED5),
ALU_OP_TO_STR(RESERVED6),
ALU_OP_TO_STR(RESERVED7),
ALU_OP_TO_STR(XOR),
ALU_OP_TO_STR(OR),
ALU_OP_TO_STR(AND),
ALU_OP_TO_STR(AND_NOT),
ALU_OP_TO_STR(NAND),
ALU_OP_TO_STR(RESERVED13),
ALU_OP_TO_STR(RESERVED14),
ALU_OP_TO_STR(RESERVED15),
ALU_OP_TO_STR(RESERVED16),
ALU_OP_TO_STR(RESERVED17),
ALU_OP_TO_STR(RESERVED18),
ALU_OP_TO_STR(RESERVED19),
ALU_OP_TO_STR(RESERVED20),
ALU_OP_TO_STR(RESERVED21),
ALU_OP_TO_STR(RESERVED22),
ALU_OP_TO_STR(RESERVED23),
ALU_OP_TO_STR(RESERVED24),
ALU_OP_TO_STR(RESERVED25),
ALU_OP_TO_STR(RESERVED26),
ALU_OP_TO_STR(RESERVED27),
ALU_OP_TO_STR(RESERVED28),
ALU_OP_TO_STR(RESERVED29),
ALU_OP_TO_STR(RESERVED30),
ALU_OP_TO_STR(RESERVED31),
};
#undef ALU_OP_TO_STR
const char *
mme_fermi_alu_op_to_str(enum mme_fermi_alu_op op)
{
assert(op < ARRAY_SIZE(alu_op_to_str));
return alu_op_to_str[op];
}
#define ASSIGN_OP_TO_STR(OP) [MME_FERMI_ASSIGN_OP_##OP] = #OP
static const char *assign_op_to_str[] = {
ASSIGN_OP_TO_STR(LOAD),
ASSIGN_OP_TO_STR(MOVE),
ASSIGN_OP_TO_STR(MOVE_SET_MADDR),
ASSIGN_OP_TO_STR(LOAD_EMIT),
ASSIGN_OP_TO_STR(MOVE_EMIT),
ASSIGN_OP_TO_STR(LOAD_SET_MADDR),
ASSIGN_OP_TO_STR(MOVE_SET_MADDR_LOAD_EMIT),
ASSIGN_OP_TO_STR(MOVE_SET_MADDR_LOAD_EMIT_HIGH),
};
#undef ASSIGN_OP_TO_STR
const char *
mme_fermi_assign_op_to_str(enum mme_fermi_assign_op op)
{
assert(op < ARRAY_SIZE(assign_op_to_str));
return assign_op_to_str[op];
}
void mme_fermi_encode(uint32_t *out, uint32_t inst_count,
const struct mme_fermi_inst *insts)
{
for (uint32_t i = 0; i < inst_count; i++) {
bitmask_t enc = encode__instruction(NULL, NULL, insts[i]);
out[i] = enc.bitset[0];
}
}
static uint64_t
unpack_field(bitmask_t bitmask, unsigned low, unsigned high, bool is_signed)
{
bitmask_t field, mask;
assert(high >= low);
BITSET_ZERO(mask.bitset);
BITSET_SET_RANGE(mask.bitset, 0, high - low);
BITSET_COPY(field.bitset, bitmask.bitset);
BITSET_SHR(field.bitset, low);
BITSET_AND(field.bitset, field.bitset, mask.bitset);
uint64_t data = bitmask_to_uint64_t(field);
if (is_signed)
data = util_sign_extend(data, high - low + 1);
return data;
}
void mme_fermi_decode(struct mme_fermi_inst *insts,
const uint32_t *in, uint32_t inst_count)
{
for (uint32_t i = 0; i < inst_count; i++) {
bitmask_t enc = { .bitset = { in[i] }};
insts[i].op = unpack_field(enc, 0, 3, false);
insts[i].end_next = unpack_field(enc, 7, 7, false);
insts[i].dst = unpack_field(enc, 8, 10, false);
if (insts[i].op != MME_FERMI_OP_BRANCH) {
insts[i].assign_op = unpack_field(enc, 4, 6, false);
}
if (insts[i].op == MME_FERMI_OP_ALU_REG) {
insts[i].src[0] = unpack_field(enc, 11, 13, false);
insts[i].src[1] = unpack_field(enc, 14, 16, false);
insts[i].alu_op = unpack_field(enc, 17, 21, false);
} else if (insts[i].op == MME_FERMI_OP_ADD_IMM ||
insts[i].op == MME_FERMI_OP_STATE) {
insts[i].src[0] = unpack_field(enc, 11, 13, false);
insts[i].imm = unpack_field(enc, 14, 31, false);
} else if (insts[i].op == MME_FERMI_OP_MERGE ||
insts[i].op == MME_FERMI_OP_BFE_LSL_IMM ||
insts[i].op == MME_FERMI_OP_BFE_LSL_REG) {
insts[i].src[0] = unpack_field(enc, 11, 13, false);
insts[i].src[1] = unpack_field(enc, 14, 16, false);
insts[i].bitfield.src_bit = unpack_field(enc, 17, 21, false);
insts[i].bitfield.size = unpack_field(enc, 22, 26, false);
insts[i].bitfield.dst_bit = unpack_field(enc, 27, 31, false);
} else if (insts[i].op == MME_FERMI_OP_BRANCH) {
insts[i].branch.not_zero = unpack_field(enc, 4, 4, false);
insts[i].branch.no_delay = unpack_field(enc, 5, 5, false);
insts[i].src[0] = unpack_field(enc, 11, 13, false);
insts[i].imm = unpack_field(enc, 14, 31, false);
}
}
}
static void
print_indent(FILE *fp, unsigned depth)
{
for (unsigned i = 0; i < depth; i++)
fprintf(fp, " ");
}
static void
print_reg(FILE *fp, enum mme_fermi_reg reg)
{
if (reg == MME_FERMI_REG_ZERO) {
fprintf(fp, " $zero");
} else {
fprintf(fp, " $r%u", (unsigned)reg);
}
}
static void
print_imm(FILE *fp, const struct mme_fermi_inst *inst)
{
int32_t imm = util_mask_sign_extend(inst->imm, 18);
fprintf(fp, " %d /* 0x%04x */", (int)imm, (unsigned)imm);
}
void
mme_fermi_print_inst(FILE *fp, unsigned indent,
const struct mme_fermi_inst *inst)
{
print_indent(fp, indent);
switch (inst->op) {
case MME_FERMI_OP_ALU_REG:
fprintf(fp, "%s", mme_fermi_alu_op_to_str(inst->alu_op));
print_reg(fp, inst->src[0]);
print_reg(fp, inst->src[1]);
if (inst->alu_op == MME_FERMI_ALU_OP_ADDC) {
fprintf(fp, " $carry");
} else if (inst->alu_op == MME_FERMI_ALU_OP_SUBB) {
fprintf(fp, " $borrow");
}
break;
case MME_FERMI_OP_ADD_IMM:
case MME_FERMI_OP_STATE:
fprintf(fp, "%s", mme_fermi_op_to_str(inst->op));
print_reg(fp, inst->src[0]);
print_imm(fp, inst);
break;
case MME_FERMI_OP_MERGE:
uint32_t src_bit = inst->bitfield.src_bit;
uint32_t size = inst->bitfield.size;
uint32_t dst_bit = inst->bitfield.dst_bit;
fprintf(fp, "%s", mme_fermi_op_to_str(inst->op));
print_reg(fp, inst->src[0]);
print_reg(fp, inst->src[1]);
fprintf(fp, " (%u, %u, %u)", src_bit, size, dst_bit);
break;
case MME_FERMI_OP_BFE_LSL_IMM:
fprintf(fp, "%s", mme_fermi_op_to_str(inst->op));
print_reg(fp, inst->src[0]);
print_reg(fp, inst->src[1]);
fprintf(fp, " (%u, %u)", inst->bitfield.dst_bit,
inst->bitfield.size);
break;
case MME_FERMI_OP_BFE_LSL_REG:
fprintf(fp, "%s", mme_fermi_op_to_str(inst->op));
print_reg(fp, inst->src[0]);
print_reg(fp, inst->src[1]);
fprintf(fp, " (%u, %u)", inst->bitfield.src_bit,
inst->bitfield.size);
break;
case MME_FERMI_OP_BRANCH:
if (inst->branch.not_zero) {
fprintf(fp, "BNZ");
} else {
fprintf(fp, "BZ");
}
print_reg(fp, inst->src[0]);
print_imm(fp, inst);
if (inst->branch.no_delay) {
fprintf(fp, " NO_DELAY");
}
break;
default:
fprintf(fp, "%s", mme_fermi_op_to_str(inst->op));
break;
}
if (inst->op != MME_FERMI_OP_BRANCH) {
fprintf(fp, "\n");
print_indent(fp, indent);
fprintf(fp, "%s", mme_fermi_assign_op_to_str(inst->assign_op));
print_reg(fp, inst->dst);
if (inst->assign_op != MME_FERMI_ASSIGN_OP_LOAD) {
fprintf(fp, " $scratch");
}
}
if (inst->end_next) {
fprintf(fp, "\n");
print_indent(fp, indent);
fprintf(fp, "END_NEXT");
}
fprintf(fp, "\n");
}
void
mme_fermi_print(FILE *fp, const struct mme_fermi_inst *insts,
uint32_t inst_count)
{
for (uint32_t i = 0; i < inst_count; i++) {
fprintf(fp, "%u:\n", i);
mme_fermi_print_inst(fp, 1, &insts[i]);
}
}
+148
View File
@@ -0,0 +1,148 @@
#ifndef MME_FERMI_H
#define MME_FERMI_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "util/macros.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MME_FERMI_DRAM_COUNT 0xc00
#define MME_FERMI_SCRATCH_COUNT 128
enum PACKED mme_fermi_reg {
MME_FERMI_REG_ZERO,
MME_FERMI_REG_R1,
MME_FERMI_REG_R2,
MME_FERMI_REG_R3,
MME_FERMI_REG_R4,
MME_FERMI_REG_R5,
MME_FERMI_REG_R6,
MME_FERMI_REG_R7,
};
enum PACKED mme_fermi_op {
MME_FERMI_OP_ALU_REG,
MME_FERMI_OP_ADD_IMM,
MME_FERMI_OP_MERGE,
MME_FERMI_OP_BFE_LSL_IMM,
MME_FERMI_OP_BFE_LSL_REG,
MME_FERMI_OP_STATE,
MME_FERMI_OP_UNK6,
MME_FERMI_OP_BRANCH,
};
const char *mme_fermi_op_to_str(enum mme_fermi_op op);
enum PACKED mme_fermi_alu_op {
MME_FERMI_ALU_OP_ADD,
MME_FERMI_ALU_OP_ADDC,
MME_FERMI_ALU_OP_SUB,
MME_FERMI_ALU_OP_SUBB,
MME_FERMI_ALU_OP_RESERVED4,
MME_FERMI_ALU_OP_RESERVED5,
MME_FERMI_ALU_OP_RESERVED6,
MME_FERMI_ALU_OP_RESERVED7,
MME_FERMI_ALU_OP_XOR,
MME_FERMI_ALU_OP_OR,
MME_FERMI_ALU_OP_AND,
MME_FERMI_ALU_OP_AND_NOT,
MME_FERMI_ALU_OP_NAND,
MME_FERMI_ALU_OP_RESERVED13,
MME_FERMI_ALU_OP_RESERVED14,
MME_FERMI_ALU_OP_RESERVED15,
MME_FERMI_ALU_OP_RESERVED16,
MME_FERMI_ALU_OP_RESERVED17,
MME_FERMI_ALU_OP_RESERVED18,
MME_FERMI_ALU_OP_RESERVED19,
MME_FERMI_ALU_OP_RESERVED20,
MME_FERMI_ALU_OP_RESERVED21,
MME_FERMI_ALU_OP_RESERVED22,
MME_FERMI_ALU_OP_RESERVED23,
MME_FERMI_ALU_OP_RESERVED24,
MME_FERMI_ALU_OP_RESERVED25,
MME_FERMI_ALU_OP_RESERVED26,
MME_FERMI_ALU_OP_RESERVED27,
MME_FERMI_ALU_OP_RESERVED28,
MME_FERMI_ALU_OP_RESERVED29,
MME_FERMI_ALU_OP_RESERVED30,
MME_FERMI_ALU_OP_RESERVED31,
};
const char *mme_fermi_alu_op_to_str(enum mme_fermi_alu_op op);
enum PACKED mme_fermi_assign_op {
MME_FERMI_ASSIGN_OP_LOAD,
MME_FERMI_ASSIGN_OP_MOVE,
MME_FERMI_ASSIGN_OP_MOVE_SET_MADDR,
MME_FERMI_ASSIGN_OP_LOAD_EMIT,
MME_FERMI_ASSIGN_OP_MOVE_EMIT,
MME_FERMI_ASSIGN_OP_LOAD_SET_MADDR,
MME_FERMI_ASSIGN_OP_MOVE_SET_MADDR_LOAD_EMIT,
MME_FERMI_ASSIGN_OP_MOVE_SET_MADDR_LOAD_EMIT_HIGH,
};
const char *mme_fermi_assign_op_to_str(enum mme_fermi_assign_op op);
struct mme_fermi_bitfield {
uint8_t src_bit;
uint8_t size;
uint8_t dst_bit;
};
struct mme_fermi_branch {
bool not_zero;
bool no_delay;
};
struct mme_fermi_inst {
bool end_next;
enum mme_fermi_assign_op assign_op;
enum mme_fermi_op op;
enum mme_fermi_reg dst;
enum mme_fermi_reg src[2];
int32_t imm;
union {
enum mme_fermi_alu_op alu_op;
struct mme_fermi_bitfield bitfield;
struct mme_fermi_branch branch;
};
};
#define MME_FERMI_INST_DEFAULTS \
.end_next = false, \
.assign_op = MME_FERMI_ASSIGN_OP_MOVE, \
.op = MME_FERMI_OP_ALU_REG, \
.dst = MME_FERMI_REG_ZERO, \
.src = { \
MME_FERMI_REG_ZERO, \
MME_FERMI_REG_ZERO \
}, \
.imm = 0, \
.alu_op = MME_FERMI_ALU_OP_ADD, \
void mme_fermi_print_inst(FILE *fp, unsigned indent,
const struct mme_fermi_inst *inst);
void mme_fermi_print(FILE *fp, const struct mme_fermi_inst *insts,
uint32_t inst_count);
void mme_fermi_encode(uint32_t *out, uint32_t inst_count,
const struct mme_fermi_inst *insts);
void mme_fermi_decode(struct mme_fermi_inst *insts,
const uint32_t *in, uint32_t inst_count);
void mme_fermi_dump(FILE *fp, uint32_t *encoded, size_t encoded_size);
#ifdef __cplusplus
}
#endif
#endif /* MME_FERMI_H */
+219
View File
@@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2022 marysaka <mary@mary.zone>
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.
-->
<isa>
<enum name="#reg">
<value val="0" display="zero"/>
<value val="1" display="r1"/>
<value val="2" display="r2"/>
<value val="3" display="r3"/>
<value val="4" display="r4"/>
<value val="5" display="r5"/>
<value val="6" display="r6"/>
<value val="7" display="r7"/>
</enum>
<enum name="#op">
<value val="0" display="ALU_REG"/>
<value val="1" display="ADD_IMM"/>
<value val="2" display="MERGE"/>
<value val="3" display="BFE_LSL_IMM"/>
<value val="4" display="BFE_LSL_REG"/>
<value val="5" display="STATE"/>
<!-- TODO: There seems to be something here (no fault is generated) -->
<value val="6" display="UNK6"/>
<value val="7" display="BRANCH"/>
</enum>
<enum name="#alu-op">
<value val="0" display="ADD"/>
<value val="1" display="ADDC"/>
<value val="2" display="SUB"/>
<value val="3" display="SUBB"/>
<!-- value val="4" display="reserved4"/ -->
<!-- value val="5" display="reserved5"/ -->
<!-- value val="6" display="reserved6"/ -->
<!-- value val="7" display="reserved7"/ -->
<value val="8" display="XOR"/>
<value val="9" display="OR"/>
<value val="10" display="AND"/>
<value val="11" display="AND_NOT"/>
<value val="12" display="NAND"/>
<!-- value val="13" display="reserved13"/ -->
<!-- value val="14" display="reserved14"/ -->
<!-- value val="15" display="reserved15"/ -->
<!-- value val="16" display="reserved16"/ -->
<!-- value val="17" display="reserved17"/ -->
<!-- value val="18" display="reserved18"/ -->
<!-- value val="19" display="reserved19"/ -->
<!-- value val="20" display="reserved20"/ -->
<!-- value val="21" display="reserved21"/ -->
<!-- value val="22" display="reserved22"/ -->
<!-- value val="23" display="reserved23"/ -->
<!-- value val="24" display="reserved24"/ -->
<!-- value val="25" display="reserved25"/ -->
<!-- value val="26" display="reserved26"/ -->
<!-- value val="27" display="reserved27"/ -->
<!-- value val="28" display="reserved28"/ -->
<!-- value val="29" display="reserved29"/ -->
<!-- value val="30" display="reserved30"/ -->
<!-- value val="31" display="reserved31"/ -->
</enum>
<enum name="#assign-op">
<value val="0" display="LOAD"/>
<value val="1" display="MOVE"/>
<value val="2" display="MOVE_SET_MADDR"/>
<value val="3" display="LOAD_EMIT"/>
<value val="4" display="MOVE_EMIT"/>
<value val="5" display="LOAD_SET_MADDR"/>
<value val="6" display="MOVE_SET_MADDR_LOAD_EMIT"/>
<value val="7" display="MOVE_SET_MADDR_LOAD_EMIT_HIGH"/>
</enum>
<bitset name="#alu-instruction" size="18">
<display>
{NAME} {ASSIGN_OP} {ALU_OP} {DST} {SRC0} {SRC1}
</display>
<field name="ASSIGN_OP" low="0" high="2" type="#assign-op"/>
<pattern low="3" high="3">x</pattern>
<field name="DST" low="4" high="6" type="#reg"/>
<field name="SRC0" low="7" high="9" type="#reg"/>
<field name="SRC1" low="10" high="12" type="#reg"/>
<field name="ALU_OP" low="13" high="17" type="#alu-op"/>
<encode type="struct mme_fermi_inst">
<map name="ASSIGN_OP">src.assign_op</map>
<map name="ALU_OP">src.alu_op</map>
<map name="DST">src.dst</map>
<map name="SRC0">src.src[0]</map>
<map name="SRC1">src.src[1]</map>
</encode>
</bitset>
<bitset name="#src0-imm-encoding" size="28">
<display>
{NAME} {ASSIGN_OP} {DST} {SRC0} {IMM}
</display>
<field name="ASSIGN_OP" low="0" high="2" type="#assign-op"/>
<pattern low="3" high="3">x</pattern>
<field name="DST" low="4" high="6" type="#reg"/>
<field name="SRC0" low="7" high="9" type="#reg"/>
<field name="IMM" low="10" high="27" type="int"/>
<encode type="struct mme_fermi_inst">
<map name="ASSIGN_OP">src.assign_op</map>
<map name="DST">src.dst</map>
<map name="SRC0">src.src[0]</map>
<map name="IMM">src.imm</map>
</encode>
</bitset>
<bitset name="#bf-encoding" size="28">
<display>
{NAME} {ASSIGN_OP} {DST} {SRC0} {SRC1} {BF_SRC_BIT} {BF_SIZE} {BF_DST_BIT}
</display>
<field name="ASSIGN_OP" low="0" high="2" type="#assign-op"/>
<pattern low="3" high="3">x</pattern>
<field name="DST" low="4" high="6" type="#reg"/>
<field name="SRC0" low="7" high="9" type="#reg"/>
<field name="SRC1" low="10" high="12" type="#reg"/>
<field name="BF_SRC_BIT" low="13" high="17" type="uint"/>
<field name="BF_SIZE" low="18" high="22" type="uint"/>
<field name="BF_DST_BIT" low="23" high="27" type="uint"/>
<encode type="struct mme_fermi_inst">
<map name="ASSIGN_OP">src.assign_op</map>
<map name="DST">src.dst</map>
<map name="SRC0">src.src[0]</map>
<map name="SRC1">src.src[1]</map>
<map name="BF_SRC_BIT">src.bitfield.src_bit</map>
<map name="BF_SIZE">src.bitfield.size</map>
<map name="BF_DST_BIT">src.bitfield.dst_bit</map>
</encode>
</bitset>
<bitset name="#branch-encoding" size="28">
<display>
{NO_DELAY} B{NOT_ZERO} {SRC0} {IMM}
</display>
<field name="NOT_ZERO" pos="0" type="bool" display="Z"/>
<field name="NO_DELAY" pos="1" type="bool" display="NO_DELAY"/>
<pattern low="2" high="6">xxxxx</pattern>
<field name="SRC0" low="7" high="9" type="#reg"/>
<field name="IMM" low="10" high="27" type="int"/>
<encode type="struct mme_fermi_inst">
<map name="NOT_ZERO">src.branch.not_zero</map>
<map name="NO_DELAY">src.branch.no_delay</map>
<map name="SRC0">src.src[0]</map>
<map name="IMM">src.imm</map>
</encode>
</bitset>
<bitset name="#instruction" size="32">
<doc>
Encoding of a NVIDIA Fermi Macro Method instruction. All instructions are 32b.
</doc>
<display>
{END_NEXT} {OP} {ALU_OP_ENCODING} {SRC0_IMM_ENCODING} {BF_ENCODING} {BRANCH_ENCODING}
</display>
<field name="OP" low="0" high="3" type="#op"/>
<pattern low="4" high="6">xxx</pattern>
<field name="END_NEXT" pos="7" type="bool" display="(end-next)"/>
<pattern low="8" high="31">xxxxxxxxxxxxxxxxxxxxxxxx</pattern>
<override>
<expr>{OP} == 0</expr>
<field name="ALU_OP_ENCODING" low="4" high="21" type="#alu-instruction" />
</override>
<override>
<expr>{OP} == 1 || {OP} == 5</expr>
<field name="SRC0_IMM_ENCODING" low="4" high="31" type="#src0-imm-encoding" />
</override>
<override>
<expr>{OP} == 2 || {OP} == 3 || {OP} == 4</expr>
<field name="BF_ENCODING" low="4" high="31" type="#bf-encoding" />
</override>
<override>
<expr>{OP} == 7</expr>
<field name="BRANCH_ENCODING" low="4" high="31" type="#branch-encoding" />
</override>
<encode type="struct mme_fermi_inst">
<map name="END_NEXT">src.end_next</map>
<map name="OP">src.op</map>
<map name="ALU_OP_ENCODING">src</map>
<map name="SRC0_IMM_ENCODING">src</map>
<map name="BF_ENCODING">src</map>
<map name="BRANCH_ENCODING">src</map>
</encode>
</bitset>
</isa>
+24
View File
@@ -0,0 +1,24 @@
#include "mme_fermi.h"
#include "mme_fermi_isa.h"
#include "isa.h"
#include <stdlib.h>
static void
disasm_instr_cb(void *d, unsigned n, void *instr)
{
fprintf(d, "%3d[%08x]", n, *(uint32_t *)instr);
}
void
mme_fermi_dump(FILE *fp, uint32_t *encoded, size_t encoded_size)
{
const struct isa_decode_options opts = {
.show_errors = true,
.branch_labels = true,
.cbdata = fp,
.pre_instr_cb = disasm_instr_cb,
};
isa_disasm(encoded, encoded_size, fp, &opts);
}