Skip to content

Commit

Permalink
i#3544 core, part 3: Add RISC-V opcode and instr macros
Browse files Browse the repository at this point in the history
Add minimal opcode, operand and instruction generation macro definitions
to enable the rest of the code to compile.

NOTE:
  This code is not validated and mostly contains stubs as the main point
  was to achieve compilation and estimate the effort required for the
  port. Some of the trivial logic has been implemented though.

Issue: DynamoRIO#3544

Signed-off-by: Stanislaw Kardach <[email protected]>
  • Loading branch information
semihalf-kardach-stanislaw committed Jul 12, 2022
1 parent 620fe03 commit 99fd8a5
Show file tree
Hide file tree
Showing 9 changed files with 1,064 additions and 5 deletions.
2 changes: 2 additions & 0 deletions core/ir/dr_ir_opcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
# include "dr_ir_opcodes_aarch64.h"
#elif defined(ARM)
# include "dr_ir_opcodes_arm.h"
#elif defined(RISCV64)
# include "dr_ir_opcodes_riscv64.h"
#endif

#endif /* _DR_IR_OPCODES_H_ */
2 changes: 2 additions & 0 deletions core/ir/instr_create_shared_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
# include "dr_ir_macros_aarch64.h"
# elif defined(ARM)
# include "dr_ir_macros_arm.h"
# elif defined(RISCV64)
# include "dr_ir_macros_riscv64.h"
# endif
# include "dr_ir_opnd.h"
# include "dr_ir_instr.h"
Expand Down
26 changes: 24 additions & 2 deletions core/ir/instr_inline_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,24 @@ opnd_is_far_rel_addr(opnd_t opnd)
{
return false;
}
# endif
# elif defined(RISCV64)
# define OPND_IS_REL_ADDR(op) ((op).kind == REL_ADDR_kind)
# define opnd_is_rel_addr OPND_IS_REL_ADDR

INSTR_INLINE
bool
opnd_is_near_rel_addr(opnd_t opnd)
{
return opnd_is_rel_addr(opnd);
}

INSTR_INLINE
bool
opnd_is_far_rel_addr(opnd_t opnd)
{
return false;
}
# endif /* RISCV64 */
# endif /* X64 || ARM */

/* opnd_t constructors */
Expand Down Expand Up @@ -271,6 +288,11 @@ opnd_create_pc(app_pc pc)
"opnd_get_flags called on non-reg non-base-disp non-immed-int opnd")( \
opnd) \
.aux.flags)
# elif defined(RISCV64)
# define OPND_GET_FLAGS(opnd) \
(CLIENT_ASSERT_( \
opnd_is_reg(opnd) || opnd_is_base_disp(opnd) || opnd_is_immed_int(opnd), \
"opnd_get_flags called on non-reg non-base-disp non-immed-int opnd") 0)
# endif
# define opnd_get_flags OPND_GET_FLAGS

Expand Down Expand Up @@ -302,7 +324,7 @@ opnd_create_pc(app_pc pc)
opnd_is_rel_addr(opnd)), \
"opnd_get_segment called on invalid opnd type")(opnd) \
.aux.segment)
# elif defined(AARCHXX)
# elif defined(AARCHXX) || defined(RISCV64)
# define OPND_GET_SEGMENT(opnd) DR_REG_NULL
# endif
# define opnd_get_segment OPND_GET_SEGMENT
Expand Down
22 changes: 19 additions & 3 deletions core/ir/instr_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -2656,7 +2656,8 @@ instr_is_cti(instr_t *instr) /* any control-transfer instruction */
int
instr_get_interrupt_number(instr_t *instr)
{
CLIENT_ASSERT(instr_get_opcode(instr) == IF_X86_ELSE(OP_int, OP_svc),
CLIENT_ASSERT(instr_get_opcode(instr) ==
IF_X86_ELSE(OP_int, IF_RISCV64_ELSE(OP_ecall, OP_svc)),
"instr_get_interrupt_number: instr not interrupt");
if (instr_operands_valid(instr)) {
ptr_int_t val = opnd_get_immed_int(instr_get_src(instr, 0));
Expand Down Expand Up @@ -3603,7 +3604,10 @@ instr_raw_is_tls_spill(byte *pc, reg_id_t reg, ushort offs)
/* FIXME i#1551, i#1569: NYI on ARM/AArch64 */
ASSERT_NOT_IMPLEMENTED(false);
return false;
# endif /* X86/ARM */
# elif defined(RISCV64)
ASSERT_NOT_IMPLEMENTED(false);
return false;
# endif /* X86/ARM/RISCV64 */
}

/* this routine may upgrade a level 1 instr */
Expand Down Expand Up @@ -3640,6 +3644,10 @@ instr_check_tls_spill_restore(instr_t *instr, bool *spill, reg_id_t *reg, int *o
# elif defined(AARCHXX)
opnd_is_base_disp(memop) && opnd_get_base(memop) == dr_reg_stolen &&
opnd_get_index(memop) == DR_REG_NULL
# elif defined(RISCV64)
/* FIXME-RISCV: Check if valid. */
opnd_is_base_disp(memop) && opnd_get_base(memop) == DR_REG_TP &&
opnd_get_index(memop) == DR_REG_NULL
# endif
) {
if (reg != NULL)
Expand Down Expand Up @@ -3695,6 +3703,10 @@ instr_is_tls_xcx_spill(instr_t *instr)
/* FIXME i#1551, i#1569: NYI on ARM/AArch64 */
ASSERT_NOT_IMPLEMENTED(false);
return false;
# elif defined(RISCV64)
/* FIXME-RISCV: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return false;
# endif
}

Expand Down Expand Up @@ -3883,7 +3895,11 @@ move_mm_reg_opcode(bool aligned16, bool aligned32)
# elif defined(AARCH64)
ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */
return 0;
# endif /* X86/ARM */
# elif defined(RISCV64)
/* FIXME-RISCV: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
return 0;
# endif /* X86/ARM/RISCV64 */
}

uint
Expand Down
45 changes: 45 additions & 0 deletions core/ir/opnd_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,9 @@ const reg_id_t d_r_regparms[] = {
# ifdef X64
REGPARM_4, REGPARM_5, REGPARM_6, REGPARM_7,
# endif
#elif defined(RISCV64)
REGPARM_0, REGPARM_1, REGPARM_2, REGPARM_3,
REGPARM_4, REGPARM_5, REGPARM_6, REGPARM_7,
#endif
REG_INVALID
};
Expand Down Expand Up @@ -1273,6 +1276,20 @@ opnd_replace_reg(opnd_t *opnd, reg_id_t old_reg, reg_id_t new_reg)
*opnd = opnd_create_far_base_disp_ex(
s, b, i, sc, d, size, opnd_is_disp_encode_zero(*opnd),
opnd_is_disp_force_full(*opnd), opnd_is_disp_short_addr(*opnd));
#elif defined(RISCV64)
/* FIXME-RISCV: RISC-V has no support for base + idx * scale + disp.
* If needed, instructions with this operand should be transformed
* to:
* mul idx, idx, scale # or slli if scale is immediate
* add base, base, idx
* addi base, base, disp
*/
CLIENT_ASSERT(false, "Not implemented");
(void)size;
(void)b;
(void)i;
(void)d;
return false;
#endif
return true;
}
Expand Down Expand Up @@ -1381,6 +1398,19 @@ opnd_replace_reg_resize(opnd_t *opnd, reg_id_t old_reg, reg_id_t new_reg)
*opnd = opnd_create_far_base_disp_ex(
new_s, new_b, new_i, sc, disp, size, opnd_is_disp_encode_zero(*opnd),
opnd_is_disp_force_full(*opnd), opnd_is_disp_short_addr(*opnd));
#elif defined(RISCV64)
/* FIXME-RISCV: RISC-V has no support for base + idx * scale + disp.
* We could support base + disp as long as disp == +/-1MB.
* If needed, instructions with this operand should be transformed
* to:
* mul idx, idx, scale # or slli if scale is immediate
* add base, base, idx
* addi base, base, disp
*/
CLIENT_ASSERT(false, "Not implemented");
(void)disp;
(void)size;
return false;
#endif
return true;
}
Expand Down Expand Up @@ -2161,6 +2191,11 @@ opnd_compute_address_priv(opnd_t opnd, priv_mcontext_t *mc)
break;
default: scaled_index = index_val;
}
#elif defined(RISCV64)
/* FIXME-RISCV: Not implemented */
(void)index;
CLIENT_ASSERT(false, "Not implemented");
return NULL;
#endif
}
return opnd_compute_address_helper(opnd, mc, scaled_index);
Expand Down Expand Up @@ -2200,6 +2235,11 @@ reg_32_to_16(reg_id_t reg)
#elif defined(AARCHXX)
CLIENT_ASSERT(false, "reg_32_to_16 not supported on ARM");
return REG_NULL;
#elif defined(RISCV64)
/* FIXME-RISCV: There is no separate addressing for half registers.
* Semantics are part of the opcode.
*/
return reg;
#endif
}

Expand All @@ -2222,6 +2262,11 @@ reg_32_to_8(reg_id_t reg)
#elif defined(AARCHXX)
CLIENT_ASSERT(false, "reg_32_to_8 not supported on ARM");
return REG_NULL;
#elif defined(RISCV64)
/* FIXME-RISCV: There is no separate addressing for half registers.
* Semantics are part of the opcode.
*/
return reg;
#endif
}

Expand Down
Loading

0 comments on commit 99fd8a5

Please sign in to comment.