Skip to content

Commit

Permalink
asd
Browse files Browse the repository at this point in the history
  • Loading branch information
qwe661234 committed Jun 7, 2024
1 parent ec5f65c commit 5dc4496
Showing 1 changed file with 52 additions and 21 deletions.
73 changes: 52 additions & 21 deletions src/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,24 +762,6 @@ static inline void emit_alu64_imm32(struct jit_state *state,
emit_alu64(state, op, src, dst);
emit4(state, imm);
}
#elif defined(__aarch64__)
static void divmod(struct jit_state *state,
uint8_t opcode,
int rd,
int rn,
int rm)
{
bool mod = (opcode & JIT_ALU_OP_MASK) == (JIT_OP_MOD_IMM & JIT_ALU_OP_MASK);
bool is64 = (opcode & JIT_CLS_MASK) == JIT_CLS_ALU64;
int div_dest = mod ? temp_div_reg : rd;

/* Do not need to treet divide by zero as special because the UDIV
* instruction already returns 0 when dividing by zero.
*/
emit_dataproc_2source(state, is64, DP2_UDIV, div_dest, rn, rm);
if (mod)
emit_dataproc_3source(state, is64, DP3_MSUB, rd, rm, div_dest, rn);
}
#endif

static inline void emit_cmp_imm32(struct jit_state *state, int dst, int32_t imm)
Expand Down Expand Up @@ -1035,8 +1017,57 @@ static inline void emit_exit(struct jit_state *state)
#endif
}

/* TODO: muldivmod is incomplete, it does not handle imm or overflow now */
#if RV32_HAS(EXT_M)
#if defined(__aarch64__)
static void emit_conditional_move(struct jit_state *state,
int rd,
int rn,
int rm,
int cond)
{
emit_a64(state, 0x1a800000 | (rm << 16) | (cond << 12) | (rn << 5) | rd);
set_dirty(rd, true);
}

static void divmod(struct jit_state *state,
uint8_t opcode,
int rd,
int rn,
int rm,
bool sign)
{
bool mod = (opcode & JIT_ALU_OP_MASK) == (JIT_OP_MOD_IMM & JIT_ALU_OP_MASK);
bool is64 = (opcode & JIT_CLS_MASK) == JIT_CLS_ALU64;
int div_dest = mod ? temp_div_reg : rd;

if (sign)
emit_cmp_imm32(state, rd, 0x80000000); /* overflow checking */

emit_dataproc_2source(state, is64, DP2_UDIV, div_dest, rn, rm);
if (mod)
emit_dataproc_3source(state, is64, DP3_MSUB, rd, rm, div_dest, rn);

if (sign) {
/* handle overflow */
uint32_t jump_loc = state->offset;
emit_jcc_offset(state, 0x85);
emit_cmp_imm32(state, rm, -1);
if (mod)
emit_load_imm(state, R10, 0);
else
emit_load_imm(state, R10, 0x80000000);
emit_conditional_move(state, rd, R10, rd, COND_EQ);
emit_jump_target_offset(state, JUMP_LOC, state->offset);
}
if (!mod) {
/* handle dividing zero */
emit_cmp_imm32(state, rm, 0);
emit_load_imm(state, temp_reg, -1);
emit_conditional_move(state, rd, temp_reg, rd, COND_EQ);
}
}
#endif

static void muldivmod(struct jit_state *state,
uint8_t opcode,
int src,
Expand Down Expand Up @@ -1190,10 +1221,10 @@ static void muldivmod(struct jit_state *state,
emit_dataproc_3source(state, true, DP3_MADD, dst, dst, src, RZ);
break;
case 0x38:
divmod(state, JIT_OP_DIV_REG, dst, dst, src);
divmod(state, JIT_OP_DIV_REG, dst, dst, src, sign);
break;
case 0x98:
divmod(state, JIT_OP_MOD_REG, dst, dst, src);
divmod(state, JIT_OP_MOD_REG, dst, dst, src, sign);
break;
default:
__UNREACHABLE;
Expand Down

0 comments on commit 5dc4496

Please sign in to comment.