[Libre-soc-bugs] [Bug 979] Implement C-based Power ISA decoder compiler

bugzilla-daemon at libre-soc.org bugzilla-daemon at libre-soc.org
Wed Sep 6 20:18:43 BST 2023


https://bugs.libre-soc.org/show_bug.cgi?id=979

--- Comment #30 from Dmitry Selyutin <ghostmansd at gmail.com> ---
Hi folks! Good news, I've already implemented a very trivial generated library
based on visitors. This library is intended to keep both assembler and
disassembler; the code looks like this (obviously the code is truncated):


$ cat svp64.h
enum svp64_state {
    SVP64_SUCCESS,
    SVP64_ERROR_LOOKUP,
    SVP64_ERROR_OPERAND_0,
    SVP64_ERROR_OPERAND_1,
    SVP64_ERROR_OPERAND_2,
    SVP64_ERROR_OPERAND_3,
    SVP64_ERROR_OPERAND_4,
    SVP64_ERROR_OPERAND_5,
    SVP64_ERROR_OPERAND_6,
    SVP64_ERROR_OPERAND_7,
};

struct svp64_opcode {
    uint32_t value;
    uint32_t mask;
};

struct svp64_record {
    struct svp64_opcode opcode;
    uint8_t operands[8];
    char name[16];
};

struct svp64_ctx {
    struct svp64_record const *record;
    int64_t operands[8];
};

enum svp64_state
svp64_disassemble(struct svp64_ctx *ctx, uint32_t insn);

struct svp64_record const *
svp64_lookup_insn(uint32_t insn);


$ cat svp64-dis-gen.c
static inline enum svp64_state
svp64_disassemble_operand(struct svp64_ctx *ctx, uint32_t insn, size_t id) {
    int64_t value;

    switch (ctx->record->operands[id]) {
    case 0x02: /* RA */
        value = (int64_t)(
            /* 11 */ (((insn >> UINT64_C(20)) & UINT64_C(1)) << UINT64_C(4)) |
            /* 12 */ (((insn >> UINT64_C(19)) & UINT64_C(1)) << UINT64_C(3)) |
            /* 13 */ (((insn >> UINT64_C(18)) & UINT64_C(1)) << UINT64_C(2)) |
            /* 14 */ (((insn >> UINT64_C(17)) & UINT64_C(1)) << UINT64_C(1)) |
            /* 15 */ (((insn >> UINT64_C(16)) & UINT64_C(1)) << UINT64_C(0)) |
            UINT64_C(0)
        );
        break;

    case 0x03: /* SI */
        value = (int64_t)(
            (
                (
                    /* 16 */ (((insn >> UINT64_C(15)) & UINT64_C(1)) <<
UINT64_C(15)) |
                    /* 17 */ (((insn >> UINT64_C(14)) & UINT64_C(1)) <<
UINT64_C(14)) |
                    /* 18 */ (((insn >> UINT64_C(13)) & UINT64_C(1)) <<
UINT64_C(13)) |
                    /* 19 */ (((insn >> UINT64_C(12)) & UINT64_C(1)) <<
UINT64_C(12)) |
                    /* 20 */ (((insn >> UINT64_C(11)) & UINT64_C(1)) <<
UINT64_C(11)) |
                    /* 21 */ (((insn >> UINT64_C(10)) & UINT64_C(1)) <<
UINT64_C(10)) |
                    /* 22 */ (((insn >> UINT64_C(9)) & UINT64_C(1)) <<
UINT64_C(9)) |
                    /* 23 */ (((insn >> UINT64_C(8)) & UINT64_C(1)) <<
UINT64_C(8)) |
                    /* 24 */ (((insn >> UINT64_C(7)) & UINT64_C(1)) <<
UINT64_C(7)) |
                    /* 25 */ (((insn >> UINT64_C(6)) & UINT64_C(1)) <<
UINT64_C(6)) |
                    /* 26 */ (((insn >> UINT64_C(5)) & UINT64_C(1)) <<
UINT64_C(5)) |
                    /* 27 */ (((insn >> UINT64_C(4)) & UINT64_C(1)) <<
UINT64_C(4)) |
                    /* 28 */ (((insn >> UINT64_C(3)) & UINT64_C(1)) <<
UINT64_C(3)) |
                    /* 29 */ (((insn >> UINT64_C(2)) & UINT64_C(1)) <<
UINT64_C(2)) |
                    /* 30 */ (((insn >> UINT64_C(1)) & UINT64_C(1)) <<
UINT64_C(1)) |
                    /* 31 */ (((insn >> UINT64_C(0)) & UINT64_C(1)) <<
UINT64_C(0)) |
                    UINT64_C(0)
                )
                ^
                (UINT64_C(1) << (UINT64_C(16) - 1))
            )
            -
            (UINT64_C(1) << (UINT64_C(16) - 1))
        );
        break;

    case 0x04: /* RS, RT */
        value = (int64_t)(
            /* 6  */ (((insn >> UINT64_C(25)) & UINT64_C(1)) << UINT64_C(4)) |
            /* 7  */ (((insn >> UINT64_C(24)) & UINT64_C(1)) << UINT64_C(3)) |
            /* 8  */ (((insn >> UINT64_C(23)) & UINT64_C(1)) << UINT64_C(2)) |
            /* 9  */ (((insn >> UINT64_C(22)) & UINT64_C(1)) << UINT64_C(1)) |
            /* 10 */ (((insn >> UINT64_C(21)) & UINT64_C(1)) << UINT64_C(0)) |
            UINT64_C(0)
        );
        break;

    case 0x05: /* RB */
        value = (int64_t)(
            /* 16 */ (((insn >> UINT64_C(15)) & UINT64_C(1)) << UINT64_C(4)) |
            /* 17 */ (((insn >> UINT64_C(14)) & UINT64_C(1)) << UINT64_C(3)) |
            /* 18 */ (((insn >> UINT64_C(13)) & UINT64_C(1)) << UINT64_C(2)) |
            /* 19 */ (((insn >> UINT64_C(12)) & UINT64_C(1)) << UINT64_C(1)) |
            /* 20 */ (((insn >> UINT64_C(11)) & UINT64_C(1)) << UINT64_C(0)) |
            UINT64_C(0)
        );
        break;
    }


$ cat svp64-opc-gen.c
    [29] = {
        .name = "addi",
        .opcode = {
            .value = UINT64_C(0x0000000038000000),
            .mask = UINT64_C(0x00000000fc000000),
        },
        .operands = {
            [0] = UINT8_C(0x04), /* RT */
            [1] = UINT8_C(0x02), /* RA */
            [2] = UINT8_C(0x03), /* SI */
            [3] = UINT8_C(0x00), /* NIL */
        },
    },
    [232] = {
        /*
         * OE=0 [21]
         * Rc=0 [31]
         */
        .name = "add",
        .opcode = {
            .value = UINT64_C(0x000000007c000214),
            .mask = UINT64_C(0x00000000fc0007ff),
        },
        .operands = {
            [0] = UINT8_C(0x04), /* RT */
            [1] = UINT8_C(0x02), /* RA */
            [2] = UINT8_C(0x05), /* RB */
            [3] = UINT8_C(0x00), /* NIL */
        },
    },

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the libre-soc-bugs mailing list