Пример #1
0
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);
    }
}
Пример #2
0
// #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
void pop_shack(TCGv_ptr cpu_env, TCGv next_eip){
	//----------------------TCG operations 
	TCGv_ptr temp_shack_top = tcg_temp_new_ptr();
	TCGv_ptr temp_shack_empty = tcg_temp_new_ptr();
	TCGv_ptr temp_shack_top_next = tcg_temp_new_ptr();
	TCGv_ptr temp_entry_ptr = tcg_temp_new_ptr();
	TCGv_ptr temp_host_eip = tcg_temp_new_ptr();
	TCGv temp_guest_eip = tcg_temp_local_new_i32();
	TCGv temp_next_eip = tcg_temp_local_new_i32();
	int eip_match_label = gen_new_label(); // create label
	int empty_label = gen_new_label(); // create label
	
	//load next_eip into temp_next_eip
	tcg_gen_mov_i32(temp_next_eip, next_eip);
	// load shack_top ptr into temp_shack_top	
	tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top));
	tcg_gen_ld_ptr(temp_shack_empty, cpu_env, offsetof(CPUState, shack));

	//check if stack is empty
	tcg_gen_brcond_ptr(TCG_COND_EQ, temp_shack_top, temp_shack_empty, empty_label);

		// get (shack_top - 8)
		tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top));
		tcg_gen_subi_tl(temp_shack_top_next, temp_shack_top, sizeof(uint64_t));
		// get entry
		tcg_gen_ld_ptr(temp_entry_ptr, temp_shack_top_next, 0);
		// load entry.guest_eip
		tcg_gen_ld_ptr(temp_guest_eip, temp_entry_ptr, offsetof(shack_hash_entry, guest_eip));

		// branch to label
		tcg_gen_brcond_ptr(TCG_COND_NE, temp_next_eip, temp_guest_eip, eip_match_label);
		//reload all temps.
			tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top));
			tcg_gen_subi_tl(temp_shack_top_next, temp_shack_top, sizeof(uint64_t));
			tcg_gen_ld_ptr(temp_entry_ptr, temp_shack_top_next, 0);
			// load entry.host_eip into temp_host_eip
			tcg_gen_ld_ptr(temp_host_eip, temp_entry_ptr, offsetof(shack_hash_entry, host_eip));
			// update shack_top
			tcg_gen_st_ptr(temp_shack_top_next, cpu_env, offsetof(CPUState, shack_top)); 
			
			// jump
			*gen_opc_ptr++ = INDEX_op_jmp;
			*gen_opparam_ptr++ = temp_host_eip;
		
		// set label here
		gen_set_label(eip_match_label);
	
	// empty stack do nothing
	gen_set_label(empty_label);
}
Пример #3
0
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);
}
Пример #4
0
static inline void gen_cond_branch(DisasContext *dc, int cond)
{
    TCGLabel *l1 = gen_new_label();
    tcg_gen_brcond_tl(cond, cpu_R[dc->r0], cpu_R[dc->r1], l1);
    gen_goto_tb(dc, 0, dc->pc + 4);
    gen_set_label(l1);
    gen_goto_tb(dc, 1, dc->pc + (sign_extend(dc->imm16 << 2, 16)));
    dc->is_jmp = DISAS_TB_JUMP;
}
Пример #5
0
/* Delayed conditional jump (bt or bf) */
static void gen_delayed_conditional_jump(DisasContext * ctx)
{
    int l1;

    l1 = gen_new_label();
    gen_op_jdelayed(l1);
    gen_goto_tb(ctx, 1, ctx->pc);
    gen_set_label(l1);
    gen_jump(ctx);
}
Пример #6
0
/* Immediate conditional jump (bt or bf) */
static void gen_conditional_jump(DisasContext * ctx,
				 target_ulong ift, target_ulong ifnott)
{
    int l1;

    l1 = gen_new_label();
    gen_op_jT(l1);
    gen_goto_tb(ctx, 0, ifnott);
    gen_set_label(l1);
    gen_goto_tb(ctx, 1, ift);
}
Пример #7
0
static void dec_b(DisasContext *dc)
{
    if (dc->r0 == R_RA) {
        LOG_DIS("ret\n");
    } else if (dc->r0 == R_EA) {
        LOG_DIS("eret\n");
    } else if (dc->r0 == R_BA) {
        LOG_DIS("bret\n");
    } else {
        LOG_DIS("b r%d\n", dc->r0);
    }

    /* restore IE.IE in case of an eret */
    if (dc->r0 == R_EA) {
        TCGv t0 = tcg_temp_new();
        TCGLabel *l1 = gen_new_label();
        tcg_gen_andi_tl(t0, cpu_ie, IE_EIE);
        tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE);
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_EIE, l1);
        tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
        gen_set_label(l1);
        tcg_temp_free(t0);
    } else if (dc->r0 == R_BA) {
        TCGv t0 = tcg_temp_new();
        TCGLabel *l1 = gen_new_label();
        tcg_gen_andi_tl(t0, cpu_ie, IE_BIE);
        tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE);
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_BIE, l1);
        tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
        gen_set_label(l1);
        tcg_temp_free(t0);
    }
    tcg_gen_mov_tl(cpu_pc, cpu_R[dc->r0]);

    dc->is_jmp = DISAS_JUMP;
}
Пример #8
0
/*
 * 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
}
Пример #9
0
static void dec_modu(DisasContext *dc)
{
    TCGLabel *l1;

    LOG_DIS("modu r%d, r%d, %d\n", dc->r2, dc->r0, dc->r1);

    if (!(dc->features & LM32_FEATURE_DIVIDE)) {
        qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
        t_gen_illegal_insn(dc);
        return;
    }

    l1 = gen_new_label();
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);
    tcg_gen_movi_tl(cpu_pc, dc->pc);
    t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);
    gen_set_label(l1);
    tcg_gen_remu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
}
Пример #10
0
static void dec10_reg_scc(DisasContext *dc)
{
    int cond = dc->dst;

    LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src);

    if (cond != CC_A)
    {
        int l1;

        gen_tst_cc (dc, cpu_R[dc->src], cond);
        l1 = gen_new_label();
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->src], 0, l1);
        tcg_gen_movi_tl(cpu_R[dc->src], 1);
        gen_set_label(l1);
    } else {
        tcg_gen_movi_tl(cpu_R[dc->src], 1);
    }

    cris_cc_mask(dc, 0);
}
Пример #11
0
/*
 * 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);
}
Пример #12
0
/*
 * 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);
}
Пример #13
0
/*
 * push_shack()
 *  Push next guest eip into shadow stack.
 */
void push_shack(CPUState *env, TCGv_ptr cpu_env, target_ulong next_eip) //next_eip contains the guest return address
{
#ifdef OPT_SHACK
    /* find the corresponding slot */
    struct shadow_pair *pair_ptr = find_hash_pair(env, next_eip);

    /* declare variables */
    TCGv_ptr tcg_shack_top = tcg_temp_new_ptr();
    TCGv_ptr tcg_shack_end = tcg_temp_new_ptr();
    int lab_push = gen_new_label();

    /* check if need flush
     * if(env->shack_top == env->shack_end)
     *      env->shack_top = env->shack;
     */
    tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); //load shack top
    tcg_gen_ld_ptr(tcg_shack_end, cpu_env, offsetof(CPUState, shack_end)); //load shack end
    tcg_gen_brcond_i32(TCG_COND_NE, tcg_shack_top, tcg_shack_end, lab_push); //if(env->shack_top != env->shack_end): jmp to lab_push
    tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack)); //env->shack_top = env->shack (flush)
    tcg_gen_st_tl(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); // store shack top
    
    /* push the slot addr onto shack
     * env->shack_top = pair_ptr;
     * env->shack_top++;
     */
    gen_set_label(lab_push);
    tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); //load shack top
    tcg_gen_st_tl(tcg_const_ptr(pair_ptr), tcg_shack_top, 0); // env->shack_top = pair_ptr
    tcg_gen_addi_ptr(tcg_shack_top, tcg_shack_top, sizeof (void *)); //shack_top++
    tcg_gen_st_tl(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); // store shack top

    /* clean up */
    tcg_temp_free_ptr(tcg_shack_top);
    tcg_temp_free_ptr(tcg_shack_end);
#endif
}