wip! broken disas, doesnt build right now
This commit is contained in:
parent
848cef2def
commit
010f44408a
5 changed files with 160 additions and 2 deletions
|
|
@ -755,6 +755,7 @@ warn_flags = [
|
|||
'-Wno-string-plus-int',
|
||||
'-Wno-tautological-type-limit-compare',
|
||||
'-Wno-typedef-redefinition',
|
||||
'-Wno-unused-function',
|
||||
]
|
||||
|
||||
if host_os != 'darwin'
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
static void cr16c_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) {
|
||||
info->mach = bfd_arch_cr16c;
|
||||
info->endian = BFD_ENDIAN_LITTLE;
|
||||
info->print_insn = cr16c_print_insn;
|
||||
}
|
||||
|
||||
static void cr16c_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
|
|
|
|||
148
target/cr16c/disas.c
Normal file
148
target/cr16c/disas.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* CR16C disassembler, adapted from the AVR one
|
||||
*
|
||||
* Copyright (c) 2025 fridtjof <fridtjof@das-labor.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
|
||||
// TODO
|
||||
typedef struct {
|
||||
disassemble_info *info;
|
||||
uint16_t next_word;
|
||||
bool next_word_used;
|
||||
} DisasContext;
|
||||
|
||||
static uint64_t decode_load_bytes(DisasContext *ctx, uint64_t insn, int i, int n) {
|
||||
for(; i < n; i+=2) {
|
||||
insn |= (uint64_t)translator_lduw(ctx->env, &ctx->base, ctx->base.pc_next) << (48 - i * 8);
|
||||
ctx->base.pc_next += 2;
|
||||
}
|
||||
if (i == n)
|
||||
return insn;
|
||||
else {
|
||||
gen_helper_raise_illegal_instruction(tcg_env);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int16_t u4_load_s16(DisasContext *ctx, int val) {
|
||||
if (val == 0x9) {
|
||||
return -1;
|
||||
}
|
||||
else if (val == 0xB) {
|
||||
int16_t val_ld = cpu_ldsw_le_data(ctx->env, ctx->base.pc_next);
|
||||
ctx->base.pc_next += 2;
|
||||
return val_ld;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint16_t load_u16(DisasContext *ctx) {
|
||||
ctx->next_word_used = 1;
|
||||
uint16_t imm = cpu_lduw_code(ctx->env, ctx->base.pc_next);
|
||||
ctx->base.pc_next += 2;
|
||||
return imm;
|
||||
}
|
||||
|
||||
static uint8_t get_disp4(DisasContext *ctx, uint8_t disp) {
|
||||
return disp << 1;
|
||||
}
|
||||
|
||||
static int32_t disp8_get_dest(DisasContext* ctx, int32_t disp) {
|
||||
int32_t dest = ctx->base.pc_next - 2;
|
||||
if (disp == 0xFFFFFF80) {
|
||||
dest += cpu_ldsw_le_data(ctx->env, ctx->base.pc_next);
|
||||
ctx->base.pc_next += 2;
|
||||
}
|
||||
else {
|
||||
dest += disp << 1;
|
||||
}
|
||||
return dest;
|
||||
};
|
||||
|
||||
static uint32_t reloc_abs20(DisasContext *ctx, uint32_t addr) {
|
||||
if (addr > 0xEFFFF) {
|
||||
addr |= 0xF00000;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* Include the auto-generated decoder. */
|
||||
static bool decode_insn(DisasContext *ctx, uint16_t insn);
|
||||
#include "decode-insn.c.inc"
|
||||
|
||||
#define output(mnemonic, format, ...) \
|
||||
(pctx->info->fprintf_func(pctx->info->stream, "%-9s " format, \
|
||||
mnemonic, ##__VA_ARGS__))
|
||||
|
||||
int cr16c_print_insn(bfd_vma addr, disassemble_info *info)
|
||||
{
|
||||
DisasContext ctx = { info };
|
||||
DisasContext *pctx = &ctx;
|
||||
bfd_byte buffer[4];
|
||||
uint16_t insn;
|
||||
int status;
|
||||
|
||||
status = info->read_memory_func(addr, buffer, 2, info);
|
||||
if (status != 0) {
|
||||
info->memory_error_func(status, addr, info);
|
||||
return -1;
|
||||
}
|
||||
insn = bfd_getl16(buffer);
|
||||
(void)insn;
|
||||
|
||||
status = info->read_memory_func(addr + 2, buffer + 2, 2, info);
|
||||
if (status == 0) {
|
||||
ctx.next_word = bfd_getl16(buffer + 2);
|
||||
}
|
||||
|
||||
//if (!decode_insn(&ctx, insn)) {
|
||||
output(".db", "0x%02x, 0x%02x", buffer[0], buffer[1]);
|
||||
//}
|
||||
|
||||
if (!ctx.next_word_used) {
|
||||
return 2;
|
||||
} else if (status == 0) {
|
||||
return 4;
|
||||
}
|
||||
info->memory_error_func(status, addr + 2, info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define INSN(opcode, format, ...) \
|
||||
static bool trans_##opcode(DisasContext *pctx, arg_##opcode * a) \
|
||||
{ \
|
||||
output(#opcode, format, ##__VA_ARGS__); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
#define INSN_MNEMONIC(opcode, mnemonic, format, ...) \
|
||||
static bool trans_##opcode(DisasContext *pctx, arg_##opcode * a) \
|
||||
{ \
|
||||
output(mnemonic, format, ##__VA_ARGS__); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
static const char width[] = {
|
||||
'x', 'B', 'W', 'x', 'D'
|
||||
};
|
||||
|
||||
INSN(MOV_imm, "%c, 0x%x, r%d", width[a->width], a->imm, a->rd)
|
||||
INSN(MOV_reg, "%c r%d, r%d", width[a->width], a->rs, a->rd)
|
||||
INSN(MOVD_reg, "r%d, r%d", a->rs, a->rd)
|
||||
|
|
@ -8,6 +8,7 @@ cr16c_ss.add(files(
|
|||
'cpu.c',
|
||||
'helper.c',
|
||||
'translate.c',
|
||||
'disas.c',
|
||||
))
|
||||
|
||||
cr16c_system_ss = ss.source_set()
|
||||
|
|
|
|||
|
|
@ -1465,6 +1465,13 @@ static bool trans_STOR_rrp(DisasContext *ctx, arg_STOR_rrp *a) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO this should already be in reloc_abs20. see how to replace this in the decoder
|
||||
static int abs20_remap(int addr) {
|
||||
if (addr > 0xEFFFF)
|
||||
return addr | 0xF00000;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static bool trans_STOR_abs(DisasContext *ctx, arg_STOR_abs *a) {
|
||||
int32_t addr = a->addr;
|
||||
|
||||
|
|
@ -1473,7 +1480,7 @@ static bool trans_STOR_abs(DisasContext *ctx, arg_STOR_abs *a) {
|
|||
// See Table 5-7, footnote f, which applies for abs20
|
||||
|
||||
if (a->remap) {
|
||||
addr = addr > 0xEFFFF ? addr | 0xF00000 : addr;
|
||||
addr = abs20_remap(addr);
|
||||
}
|
||||
|
||||
gen_combine_rp(a->rs, a->width);
|
||||
|
|
@ -1498,7 +1505,7 @@ static bool trans_STOR_abs_imm(DisasContext *ctx, arg_STOR_abs_imm *a) {
|
|||
// third [imm -> dest] format of the instruction.
|
||||
// See Table 5-4, footnote e, which applies for abs20
|
||||
if (a->remap) {
|
||||
addr = addr > 0xEFFFF ? addr | 0xF00000 : addr;
|
||||
addr = abs20_remap(addr);
|
||||
}
|
||||
|
||||
tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), tcg_constant_i32(addr), 0, unsigned_op_by_width[a->width]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue