/*
- * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
tcg_gen_andi_tl(new_val, new_val, ~reg_mask);
tcg_gen_andi_tl(tmp, cur_val, reg_mask);
tcg_gen_or_tl(new_val, new_val, tmp);
-
- tcg_temp_free(tmp);
}
}
-static inline void gen_log_predicated_reg_write(int rnum, TCGv val,
- uint32_t slot)
+static TCGv get_result_gpr(DisasContext *ctx, int rnum)
{
- TCGv zero = tcg_constant_tl(0);
- TCGv slot_mask = tcg_temp_new();
-
- tcg_gen_andi_tl(slot_mask, hex_slot_cancelled, 1 << slot);
- tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum], slot_mask, zero,
- val, hex_new_value[rnum]);
- if (HEX_DEBUG) {
- /*
- * Do this so HELPER(debug_commit_end) will know
- *
- * Note that slot_mask indicates the value is not written
- * (i.e., slot was cancelled), so we create a true/false value before
- * or'ing with hex_reg_written[rnum].
- */
- tcg_gen_setcond_tl(TCG_COND_EQ, slot_mask, slot_mask, zero);
- tcg_gen_or_tl(hex_reg_written[rnum], hex_reg_written[rnum], slot_mask);
- }
+ return hex_new_value[rnum];
+}
- tcg_temp_free(slot_mask);
+static TCGv_i64 get_result_gpr_pair(DisasContext *ctx, int rnum)
+{
+ TCGv_i64 result = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(result, hex_new_value[rnum],
+ hex_new_value[rnum + 1]);
+ return result;
}
void gen_log_reg_write(int rnum, TCGv val)
}
}
-static void gen_log_predicated_reg_write_pair(int rnum, TCGv_i64 val,
- uint32_t slot)
-{
- TCGv val32 = tcg_temp_new();
- TCGv zero = tcg_constant_tl(0);
- TCGv slot_mask = tcg_temp_new();
-
- tcg_gen_andi_tl(slot_mask, hex_slot_cancelled, 1 << slot);
- /* Low word */
- tcg_gen_extrl_i64_i32(val32, val);
- tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum],
- slot_mask, zero,
- val32, hex_new_value[rnum]);
- /* High word */
- tcg_gen_extrh_i64_i32(val32, val);
- tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum + 1],
- slot_mask, zero,
- val32, hex_new_value[rnum + 1]);
- if (HEX_DEBUG) {
- /*
- * Do this so HELPER(debug_commit_end) will know
- *
- * Note that slot_mask indicates the value is not written
- * (i.e., slot was cancelled), so we create a true/false value before
- * or'ing with hex_reg_written[rnum].
- */
- tcg_gen_setcond_tl(TCG_COND_EQ, slot_mask, slot_mask, zero);
- tcg_gen_or_tl(hex_reg_written[rnum], hex_reg_written[rnum], slot_mask);
- tcg_gen_or_tl(hex_reg_written[rnum + 1], hex_reg_written[rnum + 1],
- slot_mask);
- }
-
- tcg_temp_free(val32);
- tcg_temp_free(slot_mask);
-}
-
static void gen_log_reg_write_pair(int rnum, TCGv_i64 val)
{
const target_ulong reg_mask_low = reg_immut_masks[rnum];
/* Do this so HELPER(debug_commit_end) will know */
tcg_gen_movi_tl(hex_reg_written[rnum + 1], 1);
}
-
- tcg_temp_free(val32);
}
void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val)
hex_new_pred_value[pnum], base_val);
}
tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << pnum);
-
- tcg_temp_free(base_val);
+ set_bit(pnum, ctx->pregs_written);
}
static inline void gen_read_p3_0(TCGv control_reg)
TCGv p3_0 = tcg_temp_new();
gen_read_p3_0(p3_0);
tcg_gen_concat_i32_i64(dest, p3_0, hex_gpr[reg_num + 1]);
- tcg_temp_free(p3_0);
} else if (reg_num == HEX_REG_PC - 1) {
TCGv pc = tcg_constant_tl(ctx->base.pc_next);
tcg_gen_concat_i32_i64(dest, hex_gpr[reg_num], pc);
tcg_gen_addi_tl(insn_cnt, hex_gpr[HEX_REG_QEMU_INSN_CNT],
ctx->num_insns);
tcg_gen_concat_i32_i64(dest, pkt_cnt, insn_cnt);
- tcg_temp_free(pkt_cnt);
- tcg_temp_free(insn_cnt);
} else if (reg_num == HEX_REG_QEMU_HVX_CNT) {
TCGv hvx_cnt = tcg_temp_new();
tcg_gen_addi_tl(hvx_cnt, hex_gpr[HEX_REG_QEMU_HVX_CNT],
ctx->num_hvx_insns);
tcg_gen_concat_i32_i64(dest, hvx_cnt, hex_gpr[reg_num + 1]);
- tcg_temp_free(hvx_cnt);
} else {
tcg_gen_concat_i32_i64(dest,
hex_gpr[reg_num],
for (int i = 0; i < NUM_PREGS; i++) {
tcg_gen_extract_tl(hex_p8, control_reg, i * 8, 8);
gen_log_pred_write(ctx, i, hex_p8);
- ctx_log_pred_write(ctx, i);
}
- tcg_temp_free(hex_p8);
}
/*
gen_write_p3_0(ctx, val);
} else {
gen_log_reg_write(reg_num, val);
- ctx_log_reg_write(ctx, reg_num);
if (reg_num == HEX_REG_QEMU_PKT_CNT) {
ctx->num_packets = 0;
}
TCGv_i64 val)
{
if (reg_num == HEX_REG_P3_0_ALIASED) {
+ TCGv result = get_result_gpr(ctx, reg_num + 1);
TCGv val32 = tcg_temp_new();
tcg_gen_extrl_i64_i32(val32, val);
gen_write_p3_0(ctx, val32);
tcg_gen_extrh_i64_i32(val32, val);
- gen_log_reg_write(reg_num + 1, val32);
- tcg_temp_free(val32);
- ctx_log_reg_write(ctx, reg_num + 1);
+ tcg_gen_mov_tl(result, val32);
} else {
gen_log_reg_write_pair(reg_num, val);
- ctx_log_reg_write_pair(ctx, reg_num);
if (reg_num == HEX_REG_QEMU_PKT_CNT) {
ctx->num_packets = 0;
ctx->num_insns = 0;
tcg_gen_extract_i64(res64, src, N * 8, 8);
}
tcg_gen_extrl_i64_i32(result, res64);
- tcg_temp_free_i64(res64);
return result;
}
TCGv_i64 src64 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(src64, src);
tcg_gen_deposit_i64(result, result, src64, N * 16, 16);
- tcg_temp_free_i64(src64);
}
void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
TCGv_i64 src64 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(src64, src);
tcg_gen_deposit_i64(result, result, src64, N * 8, 8);
- tcg_temp_free_i64(src64);
}
static inline void gen_load_locked4u(TCGv dest, TCGv vaddr, int mem_index)
ctx->mem_idx, MO_32);
tcg_gen_movcond_tl(TCG_COND_EQ, pred, tmp, hex_llsc_val,
one, zero);
- tcg_temp_free(tmp);
tcg_gen_br(done);
gen_set_label(fail);
tcg_gen_movcond_i64(TCG_COND_EQ, tmp, tmp, hex_llsc_val_i64,
one, zero);
tcg_gen_extrl_i64_i32(pred, tmp);
- tcg_temp_free_i64(tmp);
tcg_gen_br(done);
gen_set_label(fail);
gen_write_new_pc_addr(ctx, dst_pc, cond, pred);
}
+static void gen_cond_jumpr31(DisasContext *ctx, TCGCond cond, TCGv pred)
+{
+ TCGv LSB = tcg_temp_new();
+ tcg_gen_andi_tl(LSB, pred, 1);
+ gen_cond_jumpr(ctx, hex_gpr[HEX_REG_LR], cond, LSB);
+}
+
static void gen_cond_jump(DisasContext *ctx, TCGCond cond, TCGv pred,
int pc_off)
{
TCGv pred = tcg_temp_new();
gen_compare(cond1, pred, arg1, arg2);
gen_log_pred_write(ctx, pnum, pred);
- tcg_temp_free(pred);
} else {
TCGv pred = tcg_temp_new();
tcg_gen_mov_tl(pred, hex_new_pred_value[pnum]);
gen_cond_jump(ctx, cond2, pred, pc_off);
- tcg_temp_free(pred);
}
}
tcg_gen_andi_tl(pred, arg, 1);
gen_8bitsof(pred, pred);
gen_log_pred_write(ctx, pnum, pred);
- tcg_temp_free(pred);
} else {
TCGv pred = tcg_temp_new();
tcg_gen_mov_tl(pred, hex_new_pred_value[pnum]);
gen_cond_jump(ctx, cond, pred, pc_off);
- tcg_temp_free(pred);
}
}
TCGv pred = tcg_temp_new();
tcg_gen_andi_tl(pred, arg, 1);
gen_cond_jump(ctx, cond, pred, pc_off);
- tcg_temp_free(pred);
}
static void gen_jump(DisasContext *ctx, int pc_off)
static void gen_call(DisasContext *ctx, int pc_off)
{
- TCGv next_PC =
- tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes);
- gen_log_reg_write(HEX_REG_LR, next_PC);
+ TCGv lr = get_result_gpr(ctx, HEX_REG_LR);
+ tcg_gen_movi_tl(lr, ctx->next_PC);
gen_write_new_pc_pcrel(ctx, pc_off, TCG_COND_ALWAYS, NULL);
}
+static void gen_callr(DisasContext *ctx, TCGv new_pc)
+{
+ TCGv lr = get_result_gpr(ctx, HEX_REG_LR);
+ tcg_gen_movi_tl(lr, ctx->next_PC);
+ gen_write_new_pc_addr(ctx, new_pc, TCG_COND_ALWAYS, NULL);
+}
+
static void gen_cond_call(DisasContext *ctx, TCGv pred,
TCGCond cond, int pc_off)
{
- TCGv next_PC;
+ TCGv lr = get_result_gpr(ctx, HEX_REG_LR);
TCGv lsb = tcg_temp_new();
TCGLabel *skip = gen_new_label();
tcg_gen_andi_tl(lsb, pred, 1);
gen_write_new_pc_pcrel(ctx, pc_off, cond, lsb);
tcg_gen_brcondi_tl(cond, lsb, 0, skip);
- tcg_temp_free(lsb);
- next_PC =
- tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes);
- gen_log_reg_write(HEX_REG_LR, next_PC);
+ tcg_gen_movi_tl(lr, ctx->next_PC);
+ gen_set_label(skip);
+}
+
+static void gen_cond_callr(DisasContext *ctx,
+ TCGCond cond, TCGv pred, TCGv new_pc)
+{
+ TCGv lsb = tcg_temp_new();
+ TCGLabel *skip = gen_new_label();
+ tcg_gen_andi_tl(lsb, pred, 1);
+ tcg_gen_brcondi_tl(cond, lsb, 0, skip);
+ gen_callr(ctx, new_pc);
+ gen_set_label(skip);
+}
+
+/* frame ^= (int64_t)FRAMEKEY << 32 */
+static void gen_frame_unscramble(TCGv_i64 frame)
+{
+ TCGv_i64 framekey = tcg_temp_new_i64();
+ tcg_gen_extu_i32_i64(framekey, hex_gpr[HEX_REG_FRAMEKEY]);
+ tcg_gen_shli_i64(framekey, framekey, 32);
+ tcg_gen_xor_i64(frame, frame, framekey);
+}
+
+static void gen_load_frame(DisasContext *ctx, TCGv_i64 frame, TCGv EA)
+{
+ Insn *insn = ctx->insn; /* Needed for CHECK_NOSHUF */
+ CHECK_NOSHUF(EA, 8);
+ tcg_gen_qemu_ld64(frame, EA, ctx->mem_idx);
+}
+
+static void gen_return(DisasContext *ctx, TCGv_i64 dst, TCGv src)
+{
+ /*
+ * frame = *src
+ * dst = frame_unscramble(frame)
+ * SP = src + 8
+ * PC = dst.w[1]
+ */
+ TCGv_i64 frame = tcg_temp_new_i64();
+ TCGv r31 = tcg_temp_new();
+ TCGv r29 = get_result_gpr(ctx, HEX_REG_SP);
+
+ gen_load_frame(ctx, frame, src);
+ gen_frame_unscramble(frame);
+ tcg_gen_mov_i64(dst, frame);
+ tcg_gen_addi_tl(r29, src, 8);
+ tcg_gen_extrh_i64_i32(r31, dst);
+ gen_jumpr(ctx, r31);
+}
+
+/* if (pred) dst = dealloc_return(src):raw */
+static void gen_cond_return(DisasContext *ctx, TCGv_i64 dst, TCGv src,
+ TCGv pred, TCGCond cond)
+{
+ TCGv LSB = tcg_temp_new();
+ TCGLabel *skip = gen_new_label();
+ tcg_gen_andi_tl(LSB, pred, 1);
+
+ tcg_gen_brcondi_tl(cond, LSB, 0, skip);
+ gen_return(ctx, dst, src);
gen_set_label(skip);
}
+/* sub-instruction version (no RddV, so handle it manually) */
+static void gen_cond_return_subinsn(DisasContext *ctx, TCGCond cond, TCGv pred)
+{
+ TCGv_i64 RddV = get_result_gpr_pair(ctx, HEX_REG_FP);
+ gen_cond_return(ctx, RddV, hex_gpr[HEX_REG_FP], pred, cond);
+ gen_log_reg_write_pair(HEX_REG_FP, RddV);
+}
+
static void gen_endloop0(DisasContext *ctx)
{
TCGv lpcfg = tcg_temp_new();
TCGLabel *label3 = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC0], 1, label3);
{
+ TCGv lc0 = get_result_gpr(ctx, HEX_REG_LC0);
gen_jumpr(ctx, hex_gpr[HEX_REG_SA0]);
- tcg_gen_subi_tl(hex_new_value[HEX_REG_LC0],
- hex_gpr[HEX_REG_LC0], 1);
+ tcg_gen_subi_tl(lc0, hex_gpr[HEX_REG_LC0], 1);
}
gen_set_label(label3);
}
+}
+
+static void gen_endloop1(DisasContext *ctx)
+{
+ /*
+ * if (hex_gpr[HEX_REG_LC1] > 1) {
+ * PC = hex_gpr[HEX_REG_SA1];
+ * hex_new_value[HEX_REG_LC1] = hex_gpr[HEX_REG_LC1] - 1;
+ * }
+ */
+ TCGLabel *label = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC1], 1, label);
+ {
+ TCGv lc1 = get_result_gpr(ctx, HEX_REG_LC1);
+ gen_jumpr(ctx, hex_gpr[HEX_REG_SA1]);
+ tcg_gen_subi_tl(lc1, hex_gpr[HEX_REG_LC1], 1);
+ }
+ gen_set_label(label);
+}
+
+static void gen_endloop01(DisasContext *ctx)
+{
+ TCGv lpcfg = tcg_temp_new();
+ TCGLabel *label1 = gen_new_label();
+ TCGLabel *label2 = gen_new_label();
+ TCGLabel *label3 = gen_new_label();
+ TCGLabel *done = gen_new_label();
+
+ GET_USR_FIELD(USR_LPCFG, lpcfg);
+
+ /*
+ * if (lpcfg == 1) {
+ * hex_new_pred_value[3] = 0xff;
+ * hex_pred_written |= 1 << 3;
+ * }
+ */
+ tcg_gen_brcondi_tl(TCG_COND_NE, lpcfg, 1, label1);
+ {
+ tcg_gen_movi_tl(hex_new_pred_value[3], 0xff);
+ tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << 3);
+ }
+ gen_set_label(label1);
+
+ /*
+ * if (lpcfg) {
+ * SET_USR_FIELD(USR_LPCFG, lpcfg - 1);
+ * }
+ */
+ tcg_gen_brcondi_tl(TCG_COND_EQ, lpcfg, 0, label2);
+ {
+ tcg_gen_subi_tl(lpcfg, lpcfg, 1);
+ SET_USR_FIELD(USR_LPCFG, lpcfg);
+ }
+ gen_set_label(label2);
- tcg_temp_free(lpcfg);
+ /*
+ * if (hex_gpr[HEX_REG_LC0] > 1) {
+ * PC = hex_gpr[HEX_REG_SA0];
+ * hex_new_value[HEX_REG_LC0] = hex_gpr[HEX_REG_LC0] - 1;
+ * } else {
+ * if (hex_gpr[HEX_REG_LC1] > 1) {
+ * hex_next_pc = hex_gpr[HEX_REG_SA1];
+ * hex_new_value[HEX_REG_LC1] = hex_gpr[HEX_REG_LC1] - 1;
+ * }
+ * }
+ */
+ tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC0], 1, label3);
+ {
+ TCGv lc0 = get_result_gpr(ctx, HEX_REG_LC0);
+ gen_jumpr(ctx, hex_gpr[HEX_REG_SA0]);
+ tcg_gen_subi_tl(lc0, hex_gpr[HEX_REG_LC0], 1);
+ tcg_gen_br(done);
+ }
+ gen_set_label(label3);
+ tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC1], 1, done);
+ {
+ TCGv lc1 = get_result_gpr(ctx, HEX_REG_LC1);
+ gen_jumpr(ctx, hex_gpr[HEX_REG_SA1]);
+ tcg_gen_subi_tl(lc1, hex_gpr[HEX_REG_LC1], 1);
+ }
+ gen_set_label(done);
}
static void gen_cmp_jumpnv(DisasContext *ctx,
TCGv pred = tcg_temp_new();
tcg_gen_setcond_tl(cond, pred, val, src);
gen_cond_jump(ctx, TCG_COND_EQ, pred, pc_off);
- tcg_temp_free(pred);
}
static void gen_cmpi_jumpnv(DisasContext *ctx,
TCGv pred = tcg_temp_new();
tcg_gen_setcondi_tl(cond, pred, val, src);
gen_cond_jump(ctx, TCG_COND_EQ, pred, pc_off);
- tcg_temp_free(pred);
}
/* Shift left with saturation */
tcg_gen_or_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR], ovf);
tcg_gen_movcond_tl(TCG_COND_EQ, dst, dst_sar, src, dst, satval);
-
- tcg_temp_free(sh32);
- tcg_temp_free(dst_sar);
- tcg_temp_free(ovf);
- tcg_temp_free(satval);
}
static void gen_sar(TCGv dst, TCGv src, TCGv shift_amt)
TCGv tmp = tcg_temp_new();
tcg_gen_umin_tl(tmp, shift_amt, tcg_constant_tl(31));
tcg_gen_sar_tl(dst, src, tmp);
- tcg_temp_free(tmp);
}
/* Bidirectional shift right with saturation */
gen_sar(RdV, RsV, shift_amt);
gen_set_label(done);
-
- tcg_temp_free(shift_amt);
}
/* Bidirectional shift left with saturation */
gen_shl_sat(RdV, RsV, shift_amt);
gen_set_label(done);
-
- tcg_temp_free(shift_amt);
}
static intptr_t vreg_src_off(DisasContext *ctx, int num)
}
static void gen_log_vreg_write(DisasContext *ctx, intptr_t srcoff, int num,
- VRegWriteType type, int slot_num,
- bool is_predicated)
+ VRegWriteType type)
{
- TCGLabel *label_end = NULL;
intptr_t dstoff;
- if (is_predicated) {
- TCGv cancelled = tcg_temp_new();
- label_end = gen_new_label();
-
- /* Don't do anything if the slot was cancelled */
- tcg_gen_extract_tl(cancelled, hex_slot_cancelled, slot_num, 1);
- tcg_gen_brcondi_tl(TCG_COND_NE, cancelled, 0, label_end);
- tcg_temp_free(cancelled);
- }
-
if (type != EXT_TMP) {
dstoff = ctx_future_vreg_off(ctx, num, 1, true);
tcg_gen_gvec_mov(MO_64, dstoff, srcoff,
sizeof(MMVector), sizeof(MMVector));
- tcg_gen_ori_tl(hex_VRegs_updated, hex_VRegs_updated, 1 << num);
} else {
dstoff = ctx_tmp_vreg_off(ctx, num, 1, false);
tcg_gen_gvec_mov(MO_64, dstoff, srcoff,
sizeof(MMVector), sizeof(MMVector));
}
-
- if (is_predicated) {
- gen_set_label(label_end);
- }
}
static void gen_log_vreg_write_pair(DisasContext *ctx, intptr_t srcoff, int num,
- VRegWriteType type, int slot_num,
- bool is_predicated)
+ VRegWriteType type)
{
- gen_log_vreg_write(ctx, srcoff, num ^ 0, type, slot_num, is_predicated);
+ gen_log_vreg_write(ctx, srcoff, num ^ 0, type);
srcoff += sizeof(MMVector);
- gen_log_vreg_write(ctx, srcoff, num ^ 1, type, slot_num, is_predicated);
+ gen_log_vreg_write(ctx, srcoff, num ^ 1, type);
}
-static void gen_log_qreg_write(intptr_t srcoff, int num, int vnew,
- int slot_num, bool is_predicated)
+static intptr_t get_result_qreg(DisasContext *ctx, int qnum)
{
- TCGLabel *label_end = NULL;
- intptr_t dstoff;
-
- if (is_predicated) {
- TCGv cancelled = tcg_temp_new();
- label_end = gen_new_label();
-
- /* Don't do anything if the slot was cancelled */
- tcg_gen_extract_tl(cancelled, hex_slot_cancelled, slot_num, 1);
- tcg_gen_brcondi_tl(TCG_COND_NE, cancelled, 0, label_end);
- tcg_temp_free(cancelled);
- }
-
- dstoff = offsetof(CPUHexagonState, future_QRegs[num]);
- tcg_gen_gvec_mov(MO_64, dstoff, srcoff, sizeof(MMQReg), sizeof(MMQReg));
-
- if (is_predicated) {
- tcg_gen_ori_tl(hex_QRegs_updated, hex_QRegs_updated, 1 << num);
- gen_set_label(label_end);
- }
+ return offsetof(CPUHexagonState, future_QRegs[qnum]);
}
static void gen_vreg_load(DisasContext *ctx, intptr_t dstoff, TCGv src,
tcg_gen_addi_tl(src, src, 8);
tcg_gen_st_i64(tmp, cpu_env, dstoff + i * 8);
}
- tcg_temp_free_i64(tmp);
}
static void gen_vreg_store(DisasContext *ctx, TCGv EA, intptr_t srcoff,
tcg_gen_st8_i64(mask, cpu_env, dstoff + i);
}
- tcg_temp_free_i64(tmp);
- tcg_temp_free_i64(word);
- tcg_temp_free_i64(bits);
- tcg_temp_free_i64(mask);
}
void probe_noshuf_load(TCGv va, int s, int mi)
tcg_gen_or_tl(hex_new_value[HEX_REG_USR],
hex_new_value[HEX_REG_USR],
tmp);
- tcg_temp_free(tmp);
} else {
TCGLabel *skip_label = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_EQ, val, 0, skip_label);
ovfl_64 = tcg_temp_new_i64();
tcg_gen_setcond_i64(TCG_COND_NE, ovfl_64, dest, source);
tcg_gen_trunc_i64_tl(ovfl, ovfl_64);
- tcg_temp_free_i64(ovfl_64);
}
void gen_satu_i64(TCGv_i64 dest, TCGv_i64 source, int width)
ovfl_64 = tcg_temp_new_i64();
tcg_gen_setcond_i64(TCG_COND_NE, ovfl_64, dest, source);
tcg_gen_trunc_i64_tl(ovfl, ovfl_64);
- tcg_temp_free_i64(ovfl_64);
}
/* Implements the fADDSAT64 macro in TCG */
/* if (xor & mask) */
tcg_gen_and_i64(cond1, xor, mask);
- tcg_temp_free_i64(xor);
tcg_gen_brcondi_i64(TCG_COND_NE, cond1, 0, no_ovfl_label);
- tcg_temp_free_i64(cond1);
/* else if ((a ^ sum) & mask) */
tcg_gen_xor_i64(cond2, a, sum);
tcg_gen_and_i64(cond2, cond2, mask);
tcg_gen_brcondi_i64(TCG_COND_NE, cond2, 0, ovfl_label);
- tcg_temp_free_i64(cond2);
/* fallthrough to no_ovfl_label branch */
/* if branch */
/* else if branch */
gen_set_label(ovfl_label);
tcg_gen_and_i64(cond3, sum, mask);
- tcg_temp_free_i64(mask);
- tcg_temp_free_i64(sum);
tcg_gen_movcond_i64(TCG_COND_NE, ret, cond3, zero, max_pos, max_neg);
- tcg_temp_free_i64(cond3);
SET_USR_FIELD(USR_OVF, 1);
gen_set_label(ret_label);