static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val, unsigned int size, int mem_index) { int l1 = gen_new_label(); TCGv taddr = tcg_temp_local_new(); TCGv tval = tcg_temp_local_new(); TCGv t1 = tcg_temp_local_new(); dc->postinc = 0; cris_evaluate_flags(dc); tcg_gen_mov_tl(taddr, addr); tcg_gen_mov_tl(tval, val); /* Store only if F flag isn't set */ tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10); tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); if (size == 1) { tcg_gen_qemu_st8(tval, taddr, mem_index); } else if (size == 2) { tcg_gen_qemu_st16(tval, taddr, mem_index); } else { tcg_gen_qemu_st32(tval, taddr, mem_index); } gen_set_label(l1); tcg_gen_shri_tl(t1, t1, 1); /* shift F to P position */ tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/ tcg_temp_free(t1); tcg_temp_free(tval); tcg_temp_free(taddr); }
static void dec_sru(DisasContext *dc) { if (dc->format == OP_FMT_RI) { LOG_DIS("srui r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5); } else { LOG_DIS("sru r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1); } if (dc->format == OP_FMT_RI) { if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) { qemu_log_mask(LOG_GUEST_ERROR, "hardware shifter is not available\n"); t_gen_illegal_insn(dc); return; } tcg_gen_shri_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5); } else { TCGLabel *l1 = gen_new_label(); TCGLabel *l2 = gen_new_label(); TCGv t0 = tcg_temp_local_new(); tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f); if (!(dc->features & LM32_FEATURE_SHIFT)) { tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1); t_gen_illegal_insn(dc); tcg_gen_br(l2); } gen_set_label(l1); tcg_gen_shr_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0); gen_set_label(l2); tcg_temp_free(t0); } }
static void dec10_reg_bound(DisasContext *dc, int size) { TCGv t; t = tcg_temp_local_new(); t_gen_zext(t, cpu_R[dc->src], size); cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4); tcg_temp_free(t); }
/* * pop_shack() * Pop next host eip from shadow stack. */ void pop_shack(TCGv_ptr cpu_env, TCGv next_eip) { // labels int label_end = gen_new_label(); // prepare registers TCGv_ptr temp_shack_start = tcg_temp_local_new_ptr(); // store shack start TCGv_ptr temp_shack_top = tcg_temp_local_new_ptr(); // store shack top TCGv eip_on_shack = tcg_temp_local_new(); TCGv_ptr host_slot_addr = tcg_temp_local_new(); TCGv_ptr host_addr = tcg_temp_new(); // load common values tcg_gen_ld_ptr(temp_shack_start, cpu_env, offsetof(CPUState, shack)); tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); // check if stack empty? tcg_gen_brcond_ptr(TCG_COND_EQ,temp_shack_top,temp_shack_start,label_end); // stack not empty, pop one tcg_gen_subi_ptr(temp_shack_top, temp_shack_top, sizeof(uint64_t)); // decrease top tcg_gen_st_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); // store back top tcg_gen_ld_tl(eip_on_shack, temp_shack_top, 0); // get eip // check if the same? tcg_gen_brcond_ptr(TCG_COND_NE,tcg_const_tl(next_eip),eip_on_shack,label_end); // go to "end" if not the same tcg_gen_ld_tl(host_slot_addr, temp_shack_top, sizeof(unsigned long)); // get slot addr tcg_gen_ld_ptr(host_addr, host_slot_addr, 0) ; // get host addr tcg_gen_brcond_ptr(TCG_COND_EQ,tcg_const_tl(0),host_addr,label_end); // go to "end" if addr is zero // jump! *gen_opc_ptr++ = INDEX_op_jmp; *gen_opparam_ptr++ = GET_TCGV_I32(host_addr); // label: end gen_set_label(label_end); tcg_temp_free(eip_on_shack); tcg_temp_free_ptr(host_slot_addr); tcg_temp_free_ptr(host_addr); tcg_temp_free_ptr(temp_shack_top); tcg_temp_free_ptr(temp_shack_start); }
/* * pop_shack() * Pop next host eip from shadow stack. */ void pop_shack(TCGv_ptr cpu_env, TCGv next_eip) { #ifdef OPT_SHACK /* declare variables */ int lab_end = gen_new_label(); TCGv tcg_next_eip = tcg_temp_local_new(); TCGv_ptr tcg_top_host_eip = tcg_temp_local_new_ptr(); TCGv_ptr tcg_shack_top = tcg_temp_new_ptr(); TCGv_ptr tcg_shack = tcg_temp_new_ptr(); TCGv tcg_top_guest_eip = tcg_temp_new(); /* check if shack is empty */ tcg_gen_mov_tl(tcg_next_eip, next_eip); tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); //load shack top tcg_gen_ld_ptr(tcg_shack, cpu_env, offsetof(CPUState, shack)); //load shack tcg_gen_brcond_i32(TCG_COND_EQ, tcg_shack_top, tcg_shack, lab_end); // if(shack_top == shack): jmp to lab_end /* shack not empty -> update shack top*/ tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); //load shack top tcg_gen_subi_i32(tcg_shack_top, tcg_shack_top, sizeof (void *)); //else: shack_top-- tcg_gen_st_tl(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); // store shack top /* check if shack_top->guest_eip == tcg_next_eip */ tcg_gen_ld_ptr(tcg_shack_top, tcg_shack_top, 0); // shack top = shack[shack_top] tcg_gen_ld_tl(tcg_top_guest_eip, tcg_shack_top, offsetof(struct shadow_pair, guest_eip)); //tcg_top_guest_eip = tcg_shack_top->guest_eip tcg_gen_brcond_i32(TCG_COND_NE, tcg_top_guest_eip, tcg_next_eip, lab_end); // if(shack_top->guest_eip != next_eip): jmp to lab_end /* check if shack_top->host_eip is valid */ tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); //load shack top tcg_gen_ld_ptr(tcg_shack_top, tcg_shack_top, 0); // shack top = shack[shack_top] tcg_gen_ld_ptr(tcg_top_host_eip, tcg_shack_top, offsetof(struct shadow_pair, host_eip)); //tcg_top_host_eip = tcg_shack_top->host_eip tcg_gen_brcond_i32(TCG_COND_EQ, tcg_top_host_eip, tcg_const_ptr(NULL), lab_end); // if(shack_top->host_eip == NULL): jmp to lab_end /* update return addr*/ *gen_opc_ptr++ = INDEX_op_jmp; *gen_opparam_ptr++ = tcg_top_host_eip; /* clean up */ gen_set_label(lab_end); tcg_temp_free_ptr(tcg_shack_top); tcg_temp_free_ptr(tcg_shack); tcg_temp_free_ptr(tcg_top_host_eip); tcg_temp_free(tcg_top_guest_eip); tcg_temp_free(tcg_next_eip); #endif }
static int dec10_ind_bound(DisasContext *dc, unsigned int size) { int insn_len = 0; int rd = dc->dst; TCGv t; t = tcg_temp_local_new(); insn_len += dec10_prep_move_m(dc, 0, size, t); cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4); if (dc->dst == 15) { tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); cris_prepare_jmp(dc, JMP_INDIRECT); dc->delayed_branch = 1; return insn_len; } tcg_temp_free(t); return insn_len; }
/* * push_shack() * Push next guest eip into shadow stack. */ void push_shack(CPUState *env, TCGv_ptr cpu_env, target_ulong next_eip) { // label int label_do_push = gen_new_label(); // prepare registers TCGv_ptr temp_shack_end = tcg_temp_local_new_ptr(); // store shack end TCGv_ptr temp_shack_top = tcg_temp_local_new_ptr(); // store shack top TCGv temp_next_eip = tcg_temp_local_new(); // store eip // load common values tcg_gen_ld_ptr(temp_shack_end, cpu_env, offsetof(CPUState, shack_end)); tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); tcg_gen_mov_tl(temp_next_eip, tcg_const_tl(next_eip)); // check shack full? tcg_gen_brcond_ptr(TCG_COND_NE,temp_shack_top,temp_shack_end,label_do_push); // if not full // flush here TCGv_ptr temp_shack_start = tcg_temp_new_ptr(); // store shack start //tcg_en_st_tl(tcg_const_tl(0), cpu_env, offsetof(CPUState, shadow_ret_count)); // reset ret count tcg_gen_ld_ptr(temp_shack_start, cpu_env, offsetof(CPUState, shack)); tcg_gen_mov_tl(temp_shack_top, temp_shack_start); tcg_temp_free_ptr(temp_shack_start); // call helper: flush the hash gen_helper_shack_flush(cpu_env); // end of flush gen_set_label(label_do_push); // do push here // push guest eip tcg_gen_st_ptr(temp_next_eip, temp_shack_top, 0); // store guest eip tcg_gen_addi_ptr(temp_shack_top, temp_shack_top, sizeof(uint64_t)); // increase top // call helper: check if we can fill the ret directly, or need to add hash-pair gen_helper_shack_push(cpu_env, temp_next_eip); // store back top tcg_gen_st_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); // clean up tcg_temp_free(temp_next_eip); tcg_temp_free_ptr(temp_shack_top); tcg_temp_free_ptr(temp_shack_end); }