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-string-plus-int',
|
||||||
'-Wno-tautological-type-limit-compare',
|
'-Wno-tautological-type-limit-compare',
|
||||||
'-Wno-typedef-redefinition',
|
'-Wno-typedef-redefinition',
|
||||||
|
'-Wno-unused-function',
|
||||||
]
|
]
|
||||||
|
|
||||||
if host_os != 'darwin'
|
if host_os != 'darwin'
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
static void cr16c_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) {
|
static void cr16c_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) {
|
||||||
info->mach = bfd_arch_cr16c;
|
info->mach = bfd_arch_cr16c;
|
||||||
info->endian = BFD_ENDIAN_LITTLE;
|
info->endian = BFD_ENDIAN_LITTLE;
|
||||||
|
info->print_insn = cr16c_print_insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cr16c_cpu_realizefn(DeviceState *dev, Error **errp)
|
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',
|
'cpu.c',
|
||||||
'helper.c',
|
'helper.c',
|
||||||
'translate.c',
|
'translate.c',
|
||||||
|
'disas.c',
|
||||||
))
|
))
|
||||||
|
|
||||||
cr16c_system_ss = ss.source_set()
|
cr16c_system_ss = ss.source_set()
|
||||||
|
|
|
||||||
|
|
@ -1465,6 +1465,13 @@ static bool trans_STOR_rrp(DisasContext *ctx, arg_STOR_rrp *a) {
|
||||||
return true;
|
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) {
|
static bool trans_STOR_abs(DisasContext *ctx, arg_STOR_abs *a) {
|
||||||
int32_t addr = a->addr;
|
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
|
// See Table 5-7, footnote f, which applies for abs20
|
||||||
|
|
||||||
if (a->remap) {
|
if (a->remap) {
|
||||||
addr = addr > 0xEFFFF ? addr | 0xF00000 : addr;
|
addr = abs20_remap(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_combine_rp(a->rs, a->width);
|
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.
|
// third [imm -> dest] format of the instruction.
|
||||||
// See Table 5-4, footnote e, which applies for abs20
|
// See Table 5-4, footnote e, which applies for abs20
|
||||||
if (a->remap) {
|
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]);
|
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