Bring in logging functionality for debug builds based on that from rv32esim

main
John Zacarias Jekel 2 years ago
parent ae67f4b7b1
commit 7154b55707
  1. 4
      CMakeLists.txt
  2. 1
      include/libvsemu.h
  3. 29
      src/libvsemu/logging.c
  4. 27
      src/libvsemu/logging.h
  5. 5
      src/libvsemu/memory.c
  6. 6
      src/libvsemu/registers.h
  7. 9
      src/libvsemu/state_lifetime.c
  8. 5
      src/libvsemu/tick.c

@ -19,14 +19,14 @@ endif()
set(CMAKE_C_FLAGS "-I include -Wall -Wextra -g3")
#set(CMAKE_C_FLAGS "-I include -Wall -Wextra -g3 -mno-sse2")
set(CMAKE_C_FLAGS_DEBUG "-O0")
set(CMAKE_C_FLAGS_RELEASE "-Ofast -flto=auto -fuse-linker-plugin -floop-nest-optimize -fipa-pta -fno-semantic-interposition -fdevirtualize-at-ltrans -fno-plt -fstdarg-opt -frename-registers -fweb -ftree-vectorize")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -Ofast -flto=auto -fuse-linker-plugin -floop-nest-optimize -fipa-pta -fno-semantic-interposition -fdevirtualize-at-ltrans -fno-plt -fstdarg-opt -frename-registers -fweb -ftree-vectorize")
#vsemu Library Targets
#set(RV32ESIM_UNSAFE 0)#Speed boost; may cause out of bounds/etc problems if programs executing on the simulator go out-of-bounds/etc
#set(RV32ESIM_DISABLE_LOGGING 0)#Speed boost (avoid checking if enabled, allows compiler to optimize some things more, etc)
#set(RV32ESIM_C 0)#Support compressed extension
set(VSEMU_SOURCES src/libvsemu/state_lifetime.c src/libvsemu/tick.c src/libvsemu/decode.c src/libvsemu/execute.c src/libvsemu/memory.c src/libvsemu/version.c src/libvsemu/common.h src/libvsemu/registers.h include/libvsemu.h src/libvsemu/libvsemu.version)
set(VSEMU_SOURCES src/libvsemu/state_lifetime.c src/libvsemu/logging.c src/libvsemu/logging.h src/libvsemu/tick.c src/libvsemu/decode.c src/libvsemu/execute.c src/libvsemu/memory.c src/libvsemu/version.c src/libvsemu/common.h src/libvsemu/registers.h include/libvsemu.h src/libvsemu/libvsemu.version)
if (CMAKE_C_BYTE_ORDER STREQUAL LITTLE_ENDIAN)
set(IS_LITTLE_ENDIAN 1)

@ -47,6 +47,7 @@ typedef struct vsemu_registers_t {
typedef struct vsemu_state_t {
bool valid;
uint64_t tick_num;
vsemu_buttons_t buttons;

@ -0,0 +1,29 @@
/* logging.h
* By: John Jekel
*
* Logging facilities for VSEMU
*/
/* Includes */
#include "logging.h"
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
/* Function Implementations */
//TODO colour
void vsemu_log_func(uint64_t tick_num, uint8_t indent, const char* restrict str, ...) {
fprintf(stderr, "@Tick=%lu>\t", tick_num);
while (indent--)
fputc('\t', stderr);
va_list list;
assert(str);
va_start(list, str);
vfprintf(stderr, str, list);
va_end(list);
putc('\n', stderr);
}

@ -0,0 +1,27 @@
/* logging.h
* By: John Jekel
*
* Logging facilities for VSEMU
*/
#ifndef LOGGING_H
#define LOGGING_H
/* Includes */
#include <stdarg.h>
#include <stdint.h>
/* Constants And Defines */
#ifdef NDEBUG
#define vsemu_log(...) ((void)0)
#else
#define vsemu_log(...) do {vsemu_log_func(state->tick_num, __VA_ARGS__);} while (0)
#endif
/* Function/Class Declarations */
void vsemu_log_func(uint64_t inst_num, uint8_t indent, const char* restrict str, ...);
#endif//LOGGING_H

@ -17,6 +17,7 @@
#include "common.h"
#include "registers.h"
#include "logging.h"
/* Types */
@ -41,7 +42,9 @@ bool vsemu_fetch(const vsemu_state_t* state, fetched_inst_t* fetched_inst) {
assert(state->mem_raw);
uint8_t* mem_as_bytes = (uint8_t*)(state->mem_raw);
size_t pc_byte = r(PC, state->reg) * 2;
size_t pc_byte = REG(PC);
vsemu_log(1, "Fetch from PC=%x", pc_byte);
if (pc_byte < (MEMORY_SIZE_BYTES - 1)) {//Need to fetch at least 2 bytes
fetched_inst->wg[0] = (mem_as_bytes[pc_byte + 1] << 8) | mem_as_bytes[pc_byte];
if (pc_byte < (MEMORY_SIZE_BYTES - 3))//We can fetch another 2 bytes (decode will decide if they are actually useful)

@ -21,10 +21,14 @@
typedef enum {SP = 0, R1 = 1, R2 = 2, R3 = 3, R4 = 4, BP = 5, SR = 6, PC = 7, N_FLAG, Z_FLAG, S_FLAG, C_FLAG, DS, CS, MR} register_name_t;
/* Constants And Defines */
#define REG(register_name) vsemu_reg_access_func(register_name, state->reg)
/* Function Implementations */
//Normally it is bad to pass structs by value, but since this is always inlined, it should make optimizations easier for the compiler
inline __attribute__((always_inline)) uint_fast32_t r(register_name_t name, vsemu_registers_t register_struct) {
inline __attribute__((always_inline)) uint_fast32_t vsemu_reg_access_func(register_name_t name, vsemu_registers_t register_struct) {
switch (name) {
case SP: return register_struct.sp;
case R1: return register_struct.r[0];

@ -19,6 +19,7 @@
#include "libvsemu.h"
#include "common.h"
#include "logging.h"
/* Types */
@ -50,8 +51,10 @@ bool vsemu_reset(vsemu_state_t* state) {//Cheaper than freeing and re-initing; r
return false;
memset(state->mem_raw, 0, MEMORY_SIZE_BYTES);
state->tick_num = 0;
//TODO clear other things (set PC to reset vector + 0x7)
vsemu_log(0, "Reset completed.");
return true;
}
@ -63,6 +66,8 @@ bool vsemu_load_rom_mem(vsemu_state_t* state, uint_fast32_t size, const void* ro
return false;
memcpy(state->mem_raw, rom_image, size);
vsemu_log(0, "Rom image loaded sucessfully from memory");
return true;
}
@ -81,6 +86,8 @@ bool vsemu_load_rom_file(vsemu_state_t* state, const char* rom_path) {
bool success = ferror(rom_file) == 0;
fclose(rom_file);
vsemu_log(0, "Rom image \"%s\" loaded sucessfully", rom_path);
return success;
}
@ -89,6 +96,8 @@ bool vsemu_free_state(vsemu_state_t* state) {
return false;
free(state->mem_raw);
vsemu_log(0, "VSEMU state freed");
return true;
}

@ -13,6 +13,7 @@
#include "libvsemu.h"
#include "common.h"
#include "logging.h"
/* Types */
@ -29,6 +30,9 @@
/* Function Implementations */
vsemu_return_code_t vsemu_tick(vsemu_state_t* state) {
state->tick_num++;
vsemu_log(0, "Tick began");
fetched_inst_t fetched_inst;
decoded_inst_t decoded_inst;
@ -38,7 +42,6 @@ vsemu_return_code_t vsemu_tick(vsemu_state_t* state) {
return VSEMU_RET_FAIL;
if (!vsemu_execute(state, &decoded_inst))
return VSEMU_RET_FAIL;
return VSEMU_RET_OK;
}