Skip to content

Commit

Permalink
Apply editorial changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jserv committed Mar 2, 2024
1 parent 7ebe625 commit acb06dc
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 78 deletions.
13 changes: 7 additions & 6 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ static bool has_loops = false;
#include "rv32_template.c"
#undef RVOP

/* multiple lui */
/* multiple LUI */
static bool do_fuse1(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
{
cycle += ir->imm2;
Expand Down Expand Up @@ -1050,12 +1050,13 @@ static block_t *block_find_or_translate(riscv_t *rv)
#if RV32_HAS(JIT)
static bool runtime_profiler(riscv_t *rv, block_t *block)
{
/* Based on our observation, a high percentage of true hotspots involve high
* using frequency, loops or backward jumps. Therefore, we believe our
* profiler can use three indices to detect hotspots */
uint32_t freq = cache_freq(rv->block_cache, block->pc_start);
/* to profile the block after chaining, the block should be executed first
/* Based on our observations, a significant number of true hotspots are
* characterized by high usage frequency, including loops or backward
* jumps. Consequently, we posit that our profiler could effectively
* identify hotspots using three key indicators.
*/
uint32_t freq = cache_freq(rv->block_cache, block->pc_start);
/* To profile a block after chaining, it must first be executed. */
if (unlikely(freq >= 2 && (block->backward || block->has_loops)))
return true;
/* using frequency exceeds predetermined threshold */
Expand Down
89 changes: 44 additions & 45 deletions src/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,45 +132,45 @@ typedef enum {
AS_SUB = 2,
AS_SUBS = 3,
/* LogicalOpcode */
LOG_AND = 0x00000000U, // 0000_0000_0000_0000_0000_0000_0000_0000
LOG_ORR = 0x20000000U, // 0010_0000_0000_0000_0000_0000_0000_0000
LOG_ORN = 0x20200000U, // 0010_0000_0010_0000_0000_0000_0000_0000
LOG_EOR = 0x40000000U, // 0100_0000_0000_0000_0000_0000_0000_0000
LOG_AND = 0x00000000U, /* 0000_0000_0000_0000_0000_0000_0000_0000 */
LOG_ORR = 0x20000000U, /* 0010_0000_0000_0000_0000_0000_0000_0000 */
LOG_ORN = 0x20200000U, /* 0010_0000_0010_0000_0000_0000_0000_0000 */
LOG_EOR = 0x40000000U, /* 0100_0000_0000_0000_0000_0000_0000_0000 */
/* LoadStoreOpcode */
LS_STRB = 0x00000000U, // 0000_0000_0000_0000_0000_0000_0000_0000
LS_LDRB = 0x00400000U, // 0000_0000_0100_0000_0000_0000_0000_0000
LS_LDRSBW = 0x00c00000U, // 0000_0000_1100_0000_0000_0000_0000_0000
LS_STRH = 0x40000000U, // 0100_0000_0000_0000_0000_0000_0000_0000
LS_LDRH = 0x40400000U, // 0100_0000_0100_0000_0000_0000_0000_0000
LS_LDRSHW = 0x40c00000U, // 0100_0000_1100_0000_0000_0000_0000_0000
LS_STRW = 0x80000000U, // 1000_0000_0000_0000_0000_0000_0000_0000
LS_LDRW = 0x80400000U, // 1000_0000_0100_0000_0000_0000_0000_0000
LS_LDRSW = 0x80800000U, // 1000_0000_1000_0000_0000_0000_0000_0000
LS_STRX = 0xc0000000U, // 1100_0000_0000_0000_0000_0000_0000_0000
LS_LDRX = 0xc0400000U, // 1100_0000_0100_0000_0000_0000_0000_0000
LS_STRB = 0x00000000U, /* 0000_0000_0000_0000_0000_0000_0000_0000 */
LS_LDRB = 0x00400000U, /* 0000_0000_0100_0000_0000_0000_0000_0000 */
LS_LDRSBW = 0x00c00000U, /* 0000_0000_1100_0000_0000_0000_0000_0000 */
LS_STRH = 0x40000000U, /* 0100_0000_0000_0000_0000_0000_0000_0000 */
LS_LDRH = 0x40400000U, /* 0100_0000_0100_0000_0000_0000_0000_0000 */
LS_LDRSHW = 0x40c00000U, /* 0100_0000_1100_0000_0000_0000_0000_0000 */
LS_STRW = 0x80000000U, /* 1000_0000_0000_0000_0000_0000_0000_0000 */
LS_LDRW = 0x80400000U, /* 1000_0000_0100_0000_0000_0000_0000_0000 */
LS_LDRSW = 0x80800000U, /* 1000_0000_1000_0000_0000_0000_0000_0000 */
LS_STRX = 0xc0000000U, /* 1100_0000_0000_0000_0000_0000_0000_0000 */
LS_LDRX = 0xc0400000U, /* 1100_0000_0100_0000_0000_0000_0000_0000 */
/* LoadStorePairOpcode */
LSP_STPX = 0xa9000000U, // 1010_1001_0000_0000_0000_0000_0000_0000
LSP_LDPX = 0xa9400000U, // 1010_1001_0100_0000_0000_0000_0000_0000
LSP_STPX = 0xa9000000U, /* 1010_1001_0000_0000_0000_0000_0000_0000 */
LSP_LDPX = 0xa9400000U, /* 1010_1001_0100_0000_0000_0000_0000_0000 */
/* UnconditionalBranchOpcode */
BR_BR = 0xd61f0000U, // 1101_0110_0001_1111_0000_0000_0000_0000
BR_BLR = 0xd63f0000U, // 1101_0110_0011_1111_0000_0000_0000_0000
BR_RET = 0xd65f0000U, // 1101_0110_0101_1111_0000_0000_0000_0000
BR_BR = 0xd61f0000U, /* 1101_0110_0001_1111_0000_0000_0000_0000 */
BR_BLR = 0xd63f0000U, /* 1101_0110_0011_1111_0000_0000_0000_0000 */
BR_RET = 0xd65f0000U, /* 1101_0110_0101_1111_0000_0000_0000_0000 */
/* UnconditionalBranchImmediateOpcode */
UBR_B = 0x14000000U, // 0001_0100_0000_0000_0000_0000_0000_0000
UBR_B = 0x14000000U, /* 0001_0100_0000_0000_0000_0000_0000_0000 */
/* ConditionalBranchImmediateOpcode */
BR_Bcond = 0x54000000U,
/* DP2Opcode */
DP2_UDIV = 0x1ac00800U, // 0001_1010_1100_0000_0000_1000_0000_0000
DP2_LSLV = 0x1ac02000U, // 0001_1010_1100_0000_0010_0000_0000_0000
DP2_LSRV = 0x1ac02400U, // 0001_1010_1100_0000_0010_0100_0000_0000
DP2_ASRV = 0x1ac02800U, // 0001_1010_1100_0000_0010_1000_0000_0000
DP2_UDIV = 0x1ac00800U, /* 0001_1010_1100_0000_0000_1000_0000_0000 */
DP2_LSLV = 0x1ac02000U, /* 0001_1010_1100_0000_0010_0000_0000_0000 */
DP2_LSRV = 0x1ac02400U, /* 0001_1010_1100_0000_0010_0100_0000_0000 */
DP2_ASRV = 0x1ac02800U, /* 0001_1010_1100_0000_0010_1000_0000_0000 */
/* DP3Opcode */
DP3_MADD = 0x1b000000U, // 0001_1011_0000_0000_0000_0000_0000_0000
DP3_MSUB = 0x1b008000U, // 0001_1011_0000_0000_1000_0000_0000_0000
DP3_MADD = 0x1b000000U, /* 0001_1011_0000_0000_0000_0000_0000_0000 */
DP3_MSUB = 0x1b008000U, /* 0001_1011_0000_0000_1000_0000_0000_0000 */
/* MoveWideOpcode */
MW_MOVN = 0x12800000U, // 0001_0010_1000_0000_0000_0000_0000_0000
MW_MOVZ = 0x52800000U, // 0101_0010_1000_0000_0000_0000_0000_0000
MW_MOVK = 0x72800000U, // 0111_0010_1000_0000_0000_0000_0000_0000
MW_MOVN = 0x12800000U, /* 0001_0010_1000_0000_0000_0000_0000_0000 */
MW_MOVZ = 0x52800000U, /* 0101_0010_1000_0000_0000_0000_0000_0000 */
MW_MOVK = 0x72800000U, /* 0111_0010_1000_0000_0000_0000_0000_0000 */
} a64opcode_t;

enum condition {
Expand Down Expand Up @@ -219,21 +219,21 @@ static int temp_reg = RCX;
#endif
#elif defined(__aarch64__)
/* callee_reg - this must be a multiple of two because of how we save the stack
* later on. */
* later on.
*/
static const int callee_reg[] = {R19, R20, R21, R22, R23, R24, R25, R26};
/* parameter_reg (Caller saved registers) */
static const int parameter_reg[] = {R0, R1, R2, R3, R4};
static int temp_reg = R8;

/* Register assignments:
* Arm64 Usage
* r0 - r4 Function parameters, caller-saved
* r6 - r8 Temp - used for storing calculated value during execution
* r19 - r23 Callee-saved registers
* r24 Temp - used for generating 32-bit immediates
* r25 Temp - used for modulous calculations
/* Register assignments:
* Arm64 Usage
* r0 - r4 Function parameters, caller-saved
* r6 - r8 Temp - used for storing calculated value during execution
* r19 - r23 Callee-saved registers
* r24 Temp - used for generating 32-bit immediates
* r25 Temp - used for modulous calculations
*/

static const int register_map[] = {
R5, R6, R7, R9, R11, R12, R13, R14, R15, R16, R17, R18, R26,
};
Expand Down Expand Up @@ -435,7 +435,8 @@ static inline void emit_movewide_imm(struct jit_state *state,
}

/* Iterate over 16-bit elements of imm, outputting an appropriate move
* instruction. */
* instruction.
*/
bool invert = (count0000 < countffff);
a64opcode_t op = invert ? MW_MOVN : MW_MOVZ;
uint64_t skip_pattern = invert ? 0xffff : 0;
Expand All @@ -453,9 +454,8 @@ static inline void emit_movewide_imm(struct jit_state *state,
}

/* Tidy up for the case imm = 0 or imm == -1. */
if (op != MW_MOVK) {
if (op != MW_MOVK)
emit_a64(state, sz(is64) | op | (0 << 21) | (0 << 5) | rd);
}
}

/* [ARM-A]: C4.1.66: Load/store register (unscaled immediate). */
Expand Down Expand Up @@ -527,7 +527,7 @@ static void update_branch_imm(struct jit_state *state,
memcpy(&insn, state->buf + offset, sizeof(uint32_t));
if ((insn & 0xfe000000U) == 0x54000000U /* Conditional branch immediate. */
|| (insn & 0x7e000000U) ==
0x34000000U) { /* Compare and branch immediate. */
0x34000000U) { /* Compare and branch immediate. */
assert((imm >> 19) == INT64_C(-1) || (imm >> 19) == 0);
insn |= (imm & 0x7ffff) << 5;
} else if ((insn & 0x7c000000U) == 0x14000000U) {
Expand Down Expand Up @@ -1206,9 +1206,8 @@ static int vm_reg[3] = {0};
static void reset_reg()
{
count = 0;
for (int i = 0; i < 32; i++) {
for (int i = 0; i < 32; i++)
reg_table[i] = -1;
}
}

static void store_back(struct jit_state *state)
Expand Down
2 changes: 1 addition & 1 deletion src/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ static map_node_t *map_create_node(void *key,

/* copy over the key and values.
* If the parameter passed in is NULL, make the element blank instead of
* a segfault.
* a segmentation fault.
*/
if (!key)
memset(node->key, 0, ksize);
Expand Down
3 changes: 1 addition & 2 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
* "LICENSE" for information on usage and redistribution of this file.
*/

/*
* C Implementation for C++ std::map using red-black tree.
/* C Implementation for C++ std::map using red-black tree.
*
* Any data type can be stored in a map, just like std::map.
* A map instance requires the specification of two file types:
Expand Down
22 changes: 7 additions & 15 deletions src/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,19 +237,16 @@ typedef struct {
/* vm memory object */
memory_t *mem;

/*
* max memory size is 2^32 - 1 bytes
*
* it is for portable on both 32-bit and 64-bit platforms. In this way,
/* max memory size is 2^32 - 1 bytes.
* It is for portable on both 32-bit and 64-bit platforms. In this way,
* emulator can access any segment of the memory on either platform.
*/
uint32_t mem_size;

/* vm main stack size */
uint32_t stack_size;

/*
* To deal with the RV32 ABI for accessing args list,
/* To deal with the RV32 ABI for accessing args list,
* offset of args data have to be saved.
*
* args_offset_size is the memory size to store the offset
Expand All @@ -259,7 +256,7 @@ typedef struct {
/* arguments of emulation program */
int argc;
char **argv;
/* FIXME: rv32emu cannot access envp yet */
/* FIXME: cannot access envp yet */

/* emulation program exit code */
int exit_code;
Expand All @@ -279,23 +276,18 @@ typedef struct {
/* allow misaligned memory access */
bool allow_misalign;

/*
* run flag, it is the bitwise OR from
/* run flag, it is the bitwise OR from
* RV_RUN_TRACE, RV_RUN_GDBSTUB, and RV_RUN_PROFILE
*/
uint8_t run_flag;

/* profiling output file if RV_RUN_PROFILE is set in run_flag */
char *profile_output_file;

/*
* set by rv_create during initialization
*
/* set by rv_create during initialization.
* use rv_remap_stdstream to overwrite them
*/
int fd_stdin;
int fd_stdout;
int fd_stderr;
int fd_stdin, fd_stdout, fd_stderr;

/* vm file descriptor map: int -> (FILE *) */
map_t fd_map;
Expand Down
5 changes: 3 additions & 2 deletions src/riscv_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ struct riscv_internal {
/* GDB instruction breakpoint */
breakpoint_map_t breakpoint_map;

/* The flag to notify interrupt from GDB client: it should
* be accessed by atomic operation when starting the GDBSTUB. */
/* The flag to notify interrupt from GDB client: it should be accessed by
* atomic operation when starting the GDBSTUB.
*/
bool is_interrupted;
#endif
};
Expand Down
1 change: 1 addition & 0 deletions src/rv32_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ RVOP(
MUST_TAIL return block->ir_head->impl(rv, block->ir_head, cycle, PC); \
}
#endif

/* The indirect jump instruction JALR uses the I-type encoding. The target
* address is obtained by adding the sign-extended 12-bit I-immediate to the
* register rs1, then setting the least-significant bit of the result to zero.
Expand Down
4 changes: 1 addition & 3 deletions src/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,7 @@ void syscall_handler(riscv_t *rv)
break;
}

/*
* save return code
*
/* save return code.
* the application decides the usage of the return code
*/
vm_attr_t *attr = PRIV(rv);
Expand Down
7 changes: 4 additions & 3 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ char *sanitize_path(const char *input)
return NULL;

/* After sanitization, the new path will only be shorter than the original
* one. Thus, we can reuse the space */
* one. Thus, we can reuse the space.
*/
if (n == 0) {
ret[0] = '.';
return ret;
Expand All @@ -93,8 +94,8 @@ char *sanitize_path(const char *input)
* reading from path; r is index of next byte to process -> path[r]
* writing to buf; w is index of next byte to write -> ret[strlen(ret)]
* dotdot is index in buf where .. must stop, either because:
* a) it is the leading slash;
* b) it is a leading ../../.. prefix.
* (a) it is the leading slash;
* (b) it is a leading ../../.. prefix.
*/
size_t w = 0, r = 0;
size_t dotdot = 0;
Expand Down
4 changes: 3 additions & 1 deletion src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ static inline uintptr_t align_up(uintptr_t sz, size_t alignment)
return (((sz + mask) / alignment) * alignment);
}

/* Linux-like List API */

struct list_head {
struct list_head *prev, *next;
};
Expand All @@ -68,7 +70,7 @@ static inline void INIT_LIST_HEAD(struct list_head *head)

static inline bool list_empty(const struct list_head *head)
{
return (head->next == head);
return head->next == head;
}

static inline void list_add(struct list_head *node, struct list_head *head)
Expand Down

1 comment on commit acb06dc

@jserv
Copy link
Contributor Author

@jserv jserv commented on acb06dc Mar 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Benchmark suite Current: acb06dc Previous: 2718a26 Ratio
Dhrystone 1596 Average DMIPS over 10 runs 1759.37 Average DMIPS over 10 runs 1.10
Coremark 1486.308 Average iterations/sec over 10 runs 1517.908 Average iterations/sec over 10 runs 1.02

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.