Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
JerryYouxin authored Sep 20, 2023
2 parents 2f93cb4 + bbd4ffa commit 2058488
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 69 deletions.
26 changes: 21 additions & 5 deletions clients/drcachesim/tracer/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,9 @@ output_buffer(void *drcontext, per_thread_t *data, byte *buf_base, byte *buf_ptr
size_t header_size)
{
byte *pipe_start = buf_base;
byte *pipe_end = pipe_start;
if (!op_offline.get_value()) {
byte *post_header = buf_base + header_size;
byte *last_ok_to_split_ref = nullptr;
// Pipe split headers are just the tid.
header_size = instru->sizeof_entry();
for (byte *mem_ref = post_header; mem_ref < buf_ptr;
Expand All @@ -743,7 +743,6 @@ output_buffer(void *drcontext, per_thread_t *data, byte *buf_base, byte *buf_ptr
// it or one instr after.
if (is_ok_to_split_before(instru->get_entry_type(mem_ref),
instru->get_entry_size(mem_ref))) {
pipe_end = mem_ref;
// We check the end of this entry + the max # of delay entries to
// avoid splitting an instr from its subsequent bundle entry.
// An alternative is to have the reader use per-thread state.
Expand All @@ -752,8 +751,23 @@ output_buffer(void *drcontext, per_thread_t *data, byte *buf_base, byte *buf_ptr
DR_ASSERT(is_ok_to_split_before(
instru->get_entry_type(pipe_start + header_size),
instru->get_entry_size(pipe_start + header_size)));
pipe_start = atomic_pipe_write(drcontext, pipe_start, pipe_end,
get_local_window(data));
// Check if we went over the edge waiting for enough entries to
// write. If we did, we simply write till the last ok-to-split ref.
if (mem_ref - pipe_start > ipc_pipe.get_atomic_write_size()) {
DR_ASSERT_MSG(
last_ok_to_split_ref != nullptr,
"Found too many entries without an ok-to-split point");
pipe_start =
atomic_pipe_write(drcontext, pipe_start, last_ok_to_split_ref,
get_local_window(data));
last_ok_to_split_ref = mem_ref;
} else {
pipe_start = atomic_pipe_write(drcontext, pipe_start, mem_ref,
get_local_window(data));
last_ok_to_split_ref = nullptr;
}
} else {
last_ok_to_split_ref = mem_ref;
}
}
}
Expand All @@ -767,7 +781,9 @@ output_buffer(void *drcontext, per_thread_t *data, byte *buf_base, byte *buf_ptr
DR_ASSERT(
is_ok_to_split_before(instru->get_entry_type(pipe_start + header_size),
instru->get_entry_size(pipe_start + header_size)));
pipe_start = atomic_pipe_write(drcontext, pipe_start, pipe_end,
DR_ASSERT_MSG(last_ok_to_split_ref != nullptr,
"Found too many entries without an ok-to-split point");
pipe_start = atomic_pipe_write(drcontext, pipe_start, last_ok_to_split_ref,
get_local_window(data));
}
if ((buf_ptr - pipe_start) > (ssize_t)buf_hdr_slots_size) {
Expand Down
2 changes: 1 addition & 1 deletion core/arch/arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -3893,7 +3893,7 @@ get_time()
bool
is_ibl_routine_type(dcontext_t *dcontext, cache_pc target, ibl_branch_type_t branch_type)
{
ibl_type_t ibl_type;
ibl_type_t ibl_type = { 0 };
DEBUG_DECLARE(bool is_ibl =)
get_ibl_routine_type_ex(dcontext, target, &ibl_type _IF_X86_64(NULL));
ASSERT(is_ibl);
Expand Down
9 changes: 6 additions & 3 deletions core/fragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,14 @@ frag_flags_from_isa_mode(dr_isa_mode_t mode)
}

/* to save space size field is a ushort => maximum fragment size */
#ifndef AARCH64
enum { MAX_FRAGMENT_SIZE = USHRT_MAX };
#else
#ifdef AARCH64
/* On AArch64, TBNZ/TBZ has a range of +/- 32 KiB. */
enum { MAX_FRAGMENT_SIZE = 0x8000 };
#elif defined(RISCV64)
/* On RISCV64, direct branch has a range of +/- 4 KiB. */
enum { MAX_FRAGMENT_SIZE = 0x1000 };
#else
enum { MAX_FRAGMENT_SIZE = USHRT_MAX };
#endif

/* fragment structure used for basic blocks and traces
Expand Down
2 changes: 1 addition & 1 deletion core/ir/opnd_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1930,7 +1930,7 @@ enum {
FAR_PC_kind, /* a segment is specified as a selector value */
FAR_INSTR_kind, /* a segment is specified as a selector value */
# if defined(X64) || defined(ARM)
REL_ADDR_kind, /* pc-relative address: ARM or 64-bit X86 only */
REL_ADDR_kind, /* pc-relative address: ARM/RISCV64/64-bit X86 only */
# endif
# ifdef X64
ABS_ADDR_kind, /* 64-bit absolute address: x64 only */
Expand Down
8 changes: 5 additions & 3 deletions core/ir/riscv64/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,9 @@ decode_u_immpc_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or
int idx, instr_t *out)
{
int32_t uimm = GET_FIELD(inst, 31, 12);
opnd_t opnd = opnd_create_pc(orig_pc + (uimm << 12));
/* OPSZ_0 is used here to indicate that this is not a real memory access instruction.
*/
opnd_t opnd = opnd_create_rel_addr(orig_pc + (uimm << 12), OPSZ_0);
instr_set_src(out, idx, opnd);
return true;
}
Expand Down Expand Up @@ -1937,8 +1939,8 @@ encode_u_immpc_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out, decode_inf
{
opnd_t opnd = instr_get_src(instr, idx);
uint32_t imm;
if (opnd.kind == PC_kind)
imm = opnd_get_pc(opnd) - pc;
if (opnd.kind == REL_ADDR_kind)
imm = (app_pc)opnd_get_addr(opnd) - pc;
else if (opnd.kind == INSTR_kind)
imm = (byte *)opnd_get_instr(opnd)->offset - (byte *)instr->offset;
else
Expand Down
135 changes: 84 additions & 51 deletions core/ir/riscv64/instr.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,58 @@ instr_get_isa_mode(instr_t *instr)
int
instr_length_arch(dcontext_t *dcontext, instr_t *instr)
{
/* FIXME i#3544: Compressed Instructions ISA extension has a shorter instruction
* length. */
return RISCV64_INSTR_SIZE;
int opcode = instr_get_opcode(instr);
switch (opcode) {
case OP_LABEL: return 0;
case OP_c_flwsp:
case OP_c_fswsp:
case OP_c_flw:
case OP_c_fsw:
case OP_c_jal:
case OP_c_ldsp:
case OP_c_sdsp:
case OP_c_ld:
case OP_c_sd:
case OP_c_addiw:
case OP_c_addw:
case OP_c_subw:
case OP_c_lwsp:
case OP_c_fldsp:
case OP_c_swsp:
case OP_c_fsdsp:
case OP_c_lw:
case OP_c_fld:
case OP_c_sw:
case OP_c_fsd:
case OP_c_j:
case OP_c_jr:
case OP_c_jalr:
case OP_c_beqz:
case OP_c_bnez:
case OP_c_li:
case OP_c_lui:
case OP_c_addi:
case OP_c_addi16sp:
case OP_c_addi4spn:
case OP_c_slli:
case OP_c_srli:
case OP_c_srai:
case OP_c_andi:
case OP_c_mv:
case OP_c_add:
case OP_c_and:
case OP_c_or:
case OP_c_xor:
case OP_c_sub:
case OP_c_nop:
case OP_c_ebreak: return RISCV64_INSTR_COMPRESSED_SIZE;
default: return RISCV64_INSTR_SIZE;
}
}

bool
opc_is_not_a_real_memory_load(int opc)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return opc == OP_auipc;
}

Expand Down Expand Up @@ -120,46 +162,40 @@ bool
instr_is_call_arch(instr_t *instr)
{
int opc = instr_get_opcode(instr);
return (opc == OP_jal || opc == OP_jalr || opc == OP_c_j || opc == OP_c_jal ||
opc == OP_c_jr || opc == OP_c_jalr);
return ((opc == OP_jal || opc == OP_jalr || opc == OP_c_jal || opc == OP_c_jalr) &&
opnd_get_reg(instr_get_dst(instr, 0)) != DR_REG_ZERO);
}

bool
instr_is_call_direct(instr_t *instr)
{
/* FIXME i#3544: Check if valid */
int opc = instr_get_opcode(instr);
return (opc == OP_jal);
return ((opc == OP_jal || opc == OP_c_jal) &&
opnd_get_reg(instr_get_dst(instr, 0)) != DR_REG_ZERO);
}

bool
instr_is_near_call_direct(instr_t *instr)
{
/* FIXME i#3544: Check if valid */
int opc = instr_get_opcode(instr);
return (opc == OP_jal);
return instr_is_call_direct(instr);
}

bool
instr_is_call_indirect(instr_t *instr)
{
/* FIXME i#3544: Check if valid */
int opc = instr_get_opcode(instr);
return (opc == OP_jalr);
return ((opc == OP_jalr || opc == OP_c_jalr) &&
opnd_get_reg(instr_get_dst(instr, 0)) != DR_REG_ZERO);
}

bool
instr_is_return(instr_t *instr)
{
/* FIXME i#3544: Check if valid */
int opc = instr_get_opcode(instr);
if (instr_num_srcs(instr) < 1 || instr_num_dsts(instr) < 1)
return false;
opnd_t rd = instr_get_dst(instr, 0);
opnd_t rs = instr_get_src(instr, 0);
return (opc == OP_jalr && opnd_get_reg(rd) == DR_REG_X0 &&
opnd_is_memory_reference(rs) && opnd_get_base(rs) == DR_REG_X1 &&
opnd_get_disp(rs) == 0);
return ((opc == OP_c_jr || opc == OP_jalr) &&
opnd_get_reg(instr_get_dst(instr, 0)) == DR_REG_X0 &&
opnd_get_reg(instr_get_src(instr, 0)) == DR_REG_RA &&
opnd_get_immed_int(instr_get_src(instr, 1)) == 0);
}

bool
Expand All @@ -173,28 +209,22 @@ instr_is_cbr_arch(instr_t *instr)
bool
instr_is_mbr_arch(instr_t *instr)
{
int opc = instr->opcode; /* caller ensures opcode is valid */
switch (opc) {
case OP_jalr:
case OP_c_jalr:
case OP_c_jr: return true;
default: return false;
}
int opc = instr_get_opcode(instr);
return (opc == OP_jalr || opc == OP_c_jr || opc == OP_c_jalr);
}

bool
instr_is_far_cti(instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
}

bool
instr_is_ubr_arch(instr_t *instr)
{
int opc = instr_get_opcode(instr);
return opc == OP_jal || opc == OP_jalr;
return ((opc == OP_jal || opc == OP_c_j) &&
opnd_get_reg(instr_get_dst(instr, 0)) == DR_REG_ZERO);
}

bool
Expand All @@ -206,8 +236,9 @@ instr_is_near_ubr(instr_t *instr)
bool
instr_is_cti_short(instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
/* The branch with smallest reach is direct branch, with range +/- 4 KiB.
* We have restricted MAX_FRAGMENT_SIZE on RISCV64 accordingly.
*/
return false;
}

Expand All @@ -226,56 +257,60 @@ instr_is_cti_short_rewrite(instr_t *instr, byte *pc)
bool
instr_is_interrupt(instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
int opc = instr_get_opcode(instr);
return (opc == OP_ecall);
}

bool
instr_is_syscall(instr_t *instr)
{
/* FIXME i#3544: Check if valid */
int opc = instr_get_opcode(instr);
return (opc == OP_ecall);
}

bool
instr_is_mov_constant(instr_t *instr, ptr_int_t *value)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
uint opc = instr_get_opcode(instr);

if (opc == OP_addi || opc == OP_addiw || opc == OP_c_addi || opc == OP_c_addiw ||
opc == OP_c_addi4spn || opc == OP_c_addi16sp) {
opnd_t op1 = instr_get_src(instr, 0);
opnd_t op2 = instr_get_src(instr, 1);
if (opnd_is_reg(op1) && opnd_get_reg(op1) == DR_REG_X0) {
*value = opnd_get_immed_int(op2);
return true;
}
}
return false;
}

bool
instr_is_prefetch(instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
switch (instr_get_opcode(instr)) {
case OP_prefetch_i:
case OP_prefetch_r:
case OP_prefetch_w: return true;
default: return false;
}
}

bool
instr_is_string_op(instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
}

bool
instr_is_rep_string_op(instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
}

bool
instr_saves_float_pc(instr_t *instr)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
}

Expand Down Expand Up @@ -334,8 +369,6 @@ instr_predicate_writes_eflags(dr_pred_type_t pred)
bool
instr_predicate_is_cond(dr_pred_type_t pred)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion core/unix/os.c
Original file line number Diff line number Diff line change
Expand Up @@ -10503,7 +10503,7 @@ wait_for_event(event_t e, int timeout_ms)
#ifdef DEBUG
dcontext_t *dcontext = get_thread_private_dcontext();
#endif
uint64 start_time, cur_time;
uint64 start_time = 0, cur_time = 0;
if (timeout_ms > 0)
start_time = query_time_millis();
/* Use a user-space event on Linux, a kernel event on Windows. */
Expand Down
6 changes: 3 additions & 3 deletions suite/tests/api/ir_riscv64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1115,15 +1115,15 @@ test_jump_and_branch(void *dc)
/* Not printing disassembly for jal and branch instructions below, see comment of
* test_instr_encoding_jal_or_branch(). */
instr = INSTR_CREATE_auipc(dc, opnd_create_reg(DR_REG_A0),
opnd_create_pc(pc + (3 << 12)));
OPND_CREATE_ABSMEM(pc + (3 << 12), OPSZ_0));
test_instr_encoding_auipc(dc, OP_auipc, pc, instr);

instr = INSTR_CREATE_auipc(dc, opnd_create_reg(DR_REG_A0),
opnd_create_pc(pc - (3 << 12)));
OPND_CREATE_ABSMEM(pc + (3 << 12), OPSZ_0));
test_instr_encoding_auipc(dc, OP_auipc, pc, instr);

instr = INSTR_CREATE_auipc(dc, opnd_create_reg(DR_REG_A0),
opnd_create_pc(pc + (3 << 12)));
OPND_CREATE_ABSMEM(pc + (3 << 12), OPSZ_0));
/* This is expected to fail since we are using an unaligned PC (i.e. target_pc -
* instr_encode_pc has non-zero lower 12 bits). */
test_instr_encoding_failure(dc, OP_auipc, pc + 4, instr);
Expand Down
Loading

0 comments on commit 2058488

Please sign in to comment.