diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-03-31 23:10:44 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-03-31 23:10:44 +0300 |
| commit | ab276c733ce9dc80983e5c8ae5c530e1477cf990 (patch) | |
| tree | ef5da32c91d27da7a53a26e8d501f0ea616558c8 /tdump/src | |
| parent | a152fbd956cc9cb9c05a233abe004ba3d12767a0 (diff) | |
| download | tri-ab276c733ce9dc80983e5c8ae5c530e1477cf990.tar.gz tri-ab276c733ce9dc80983e5c8ae5c530e1477cf990.zip | |
implement more meta instructions
+ Also have a working draft of ABI names for registers, matches qbt
currently but should probably codify somewhere
Diffstat (limited to 'tdump/src')
| -rw-r--r-- | tdump/src/disassembler.c | 271 |
1 files changed, 191 insertions, 80 deletions
diff --git a/tdump/src/disassembler.c b/tdump/src/disassembler.c index 63c8d9d..e9383ca 100644 --- a/tdump/src/disassembler.c +++ b/tdump/src/disassembler.c @@ -12,86 +12,86 @@ static const char *get_gpr(tri_t x) { switch (x) { case X0: return "x0"; - case X1: return "x1"; - case X2: return "x2"; - case X3: return "x3"; - case X4: return "x4"; - case X5: return "x5"; - case X6: return "x6"; - case X7: return "x7"; - case X8: return "x8"; - case X9: return "x9"; - case X10: return "x10"; - case X11: return "x11"; - case X12: return "x12"; - case X13: return "x13"; - case X14: return "x14"; - case X15: return "x15"; - case X16: return "x16"; - case X17: return "x17"; - case X18: return "x18"; - case X19: return "x19"; - case X20: return "x20"; - case X21: return "x21"; - case X22: return "x22"; - case X23: return "x23"; - case X24: return "x24"; - case X25: return "x25"; - case X26: return "x26"; - case X27: return "x27"; - case X28: return "x28"; - case X29: return "x29"; - case X30: return "x30"; - case X31: return "x31"; - case X32: return "x32"; - case X33: return "x33"; - case X34: return "x34"; - case X35: return "x35"; - case X36: return "x36"; - case X37: return "x37"; - case X38: return "x38"; - case X39: return "x39"; - case X40: return "x40"; - case X41: return "x41"; - case X42: return "x42"; - case X43: return "x43"; - case X44: return "x44"; - case X45: return "x45"; - case X46: return "x46"; - case X47: return "x47"; - case X48: return "x48"; - case X49: return "x49"; - case X50: return "x50"; - case X51: return "x51"; - case X52: return "x52"; - case X53: return "x53"; - case X54: return "x54"; - case X55: return "x55"; - case X56: return "x56"; - case X57: return "x57"; - case X58: return "x58"; - case X59: return "x59"; - case X60: return "x60"; - case X61: return "x61"; - case X62: return "x62"; - case X63: return "x63"; - case X64: return "x64"; - case X65: return "x65"; - case X66: return "x66"; - case X67: return "x67"; - case X68: return "x68"; - case X69: return "x69"; - case X70: return "x70"; - case X71: return "x71"; - case X72: return "x72"; - case X73: return "x73"; - case X74: return "x74"; - case X75: return "x75"; - case X76: return "x76"; - case X77: return "x77"; - case X78: return "x78"; - case X79: return "x79"; - case X80: return "x80"; + case X1: return "sp"; + case X2: return "fp"; + case X3: return "gp"; + case X4: return "a0"; + case X5: return "a1"; + case X6: return "a2"; + case X7: return "a3"; + case X8: return "a4"; + case X9: return "a5"; + case X10: return "a6"; + case X11: return "t0"; + case X12: return "t1"; + case X13: return "t2"; + case X14: return "t3"; + case X15: return "t4"; + case X16: return "t5"; + case X17: return "t6"; + case X18: return "s0"; + case X19: return "s1"; + case X20: return "s2"; + case X21: return "s3"; + case X22: return "s4"; + case X23: return "s5"; + case X24: return "s6"; + case X25: return "tp"; + case X26: return "ra"; + case X27: return "a7"; + case X28: return "a8"; + case X29: return "a9"; + case X30: return "a10"; + case X31: return "a11"; + case X32: return "a12"; + case X33: return "a13"; + case X34: return "a14"; + case X35: return "a15"; + case X36: return "a16"; + case X37: return "a17"; + case X38: return "a18"; + case X39: return "a19"; + case X40: return "a20"; + case X41: return "a21"; + case X42: return "a22"; + case X43: return "a23"; + case X44: return "a24"; + case X45: return "t7"; + case X46: return "t8"; + case X47: return "t9"; + case X48: return "t10"; + case X49: return "t11"; + case X50: return "t12"; + case X51: return "t13"; + case X52: return "t14"; + case X53: return "t15"; + case X54: return "t16"; + case X55: return "t17"; + case X56: return "t18"; + case X57: return "t19"; + case X58: return "t20"; + case X59: return "t21"; + case X60: return "t22"; + case X61: return "t23"; + case X62: return "t24"; + case X63: return "s7"; + case X64: return "s8"; + case X65: return "s9"; + case X66: return "s10"; + case X67: return "s11"; + case X68: return "s12"; + case X69: return "s13"; + case X70: return "s14"; + case X71: return "s15"; + case X72: return "s16"; + case X73: return "s17"; + case X74: return "s18"; + case X75: return "s19"; + case X76: return "s20"; + case X77: return "s21"; + case X78: return "s22"; + case X79: return "s23"; + case X80: return "s24"; default: return "ill"; } } @@ -161,6 +161,26 @@ static void disasm_store(struct disasm_ctx *ctx, tri_t i) ctx->pc, width, get_gpr(rs1), imm, get_gpr(rs2)); } +static void disasm_load(struct disasm_ctx *ctx, tri_t i) +{ + tri_t rd, fn0, rs1, imm9; + parse_i(i, &rd, &fn0, &rs1, &imm9); + + int w = tri_get_trit(fn0, 4); + char *width = NULL; + switch (w) { + case 0: width = "t"; break; + case 1: width = "w"; break; + default: width = "ill"; break; + } + + char imm[256]; + size_t l = tri_fmt_default(imm, 256, imm9); + imm[l] = '\0'; + printf(DEFAULT_PREFIX "ld %s, %s, %s(%s)\n", + ctx->pc, width, get_gpr(rd), imm, get_gpr(rs1)); +} + static void disasm_op_imm(struct disasm_ctx *ctx, tri_t i) { tri_t rd, fn0, rs1, imm9; @@ -182,6 +202,92 @@ static void disasm_op_imm(struct disasm_ctx *ctx, tri_t i) } } +static void disasm_op(struct disasm_ctx *ctx, tri_t i) +{ + tri_t rd, fn0, rs1, rs2, fn5; + parse_r(i, &rd, &fn0, &rs1, &rs2, &fn5); + + switch (fn5) { + case 0: + switch (fn0) { + case OP_ADD: + printf(DEFAULT_PREFIX "add %s, %s, %s\n", + ctx->pc, + get_gpr(rd), + get_gpr(rs1), + get_gpr(rs2)); + break; + + case OP_SUB: + printf(DEFAULT_PREFIX "sub %s, %s, %s\n", + ctx->pc, + get_gpr(rd), + get_gpr(rs1), + get_gpr(rs2)); + break; + + default: + printf(DEFAULT_PREFIX "unknown/unimp op\n", + ctx->pc); + } + break; + + default: printf(DEFAULT_PREFIX "unknown/unimp op metaclass\n", + ctx->pc); + } +} + +static void disasm_jalr(struct disasm_ctx *ctx, tri_t i) +{ + tri_t rd, fn0, rs1, imm9; + parse_i(i, &rd, &fn0, &rs1, &imm9); + + char imm[256]; + size_t l = tri_fmt_default(imm, 256, imm9); + imm[l] = '\0'; + + switch (fn0) { + case 0: + printf(DEFAULT_PREFIX "jalr %s, %s(%s)\n", + ctx->pc, get_gpr(rd), imm, get_gpr(rs1)); + break; + default: printf(DEFAULT_PREFIX "unknown/unimp jalr\n", ctx->pc); + } +} + +static void disasm_branch(struct disasm_ctx *ctx, tri_t i) +{ + tri_t imm4, fn0, rs1, rs2, imm5; + parse_s(i, &imm4, &fn0, &rs1, &rs2, &imm5); + + tri_t imm9 = tri_sl(imm4, 5) | imm5; + + char imm[256]; + size_t l = tri_fmt_default(imm, 256, imm9); + imm[l] = '\0'; + + switch (fn0) { + case BRANCH_BLT: + printf(DEFAULT_PREFIX "blt %s, %s, %s\n", + ctx->pc, get_gpr(rs1), get_gpr(rs2), imm); + break; + default: printf(DEFAULT_PREFIX "unknown/unimp branch\n", ctx->pc); + } +} + +static void disasm_auipc(struct disasm_ctx *ctx, tri_t i) +{ + tri_t rd, imm18; + parse_u(i, &rd, &imm18); + + char imm[256]; + size_t l = tri_fmt_default(imm, 256, imm18); + imm[l] = '\0'; + + printf(DEFAULT_PREFIX "auipc %s, %s\n", + ctx->pc, get_gpr(rd), imm); +} + static tri_t read1(struct disasm_ctx *ctx, size_t off) { tri_t t = (tri_t)ctx->buf[off]; @@ -208,8 +314,13 @@ int disassemble(const char *file) switch (parse_opcode(i)) { case OPCODE_LUI: disasm_lui(&ctx, i); break; case OPCODE_STORE: disasm_store(&ctx, i); break; + case OPCODE_LOAD: disasm_load(&ctx, i); break; //case OPCODE_SYSTEM: disasm_system(&ctx, i); break; case OPCODE_OP_IMM: disasm_op_imm(&ctx, i); break; + case OPCODE_OP: disasm_op(&ctx, i); break; + case OPCODE_JALR: disasm_jalr(&ctx, i); break; + case OPCODE_BRANCH: disasm_branch(&ctx, i); break; + case OPCODE_AUIPC: disasm_auipc(&ctx, i); break; default: printf(DEFAULT_PREFIX "unimp/illegal\n", ctx.pc); break; |
