Beispiel #1
0
void s390_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                         int flags)
{
    S390CPU *cpu = S390_CPU(cs);
    CPUS390XState *env = &cpu->env;
    int i;

    if (env->cc_op > 3) {
        cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %15s\n",
                    env->psw.mask, env->psw.addr, cc_name(env->cc_op));
    } else {
        cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %02x\n",
                    env->psw.mask, env->psw.addr, env->cc_op);
    }

    for (i = 0; i < 16; i++) {
        cpu_fprintf(f, "R%02d=%016" PRIx64, i, env->regs[i]);
        if ((i % 4) == 3) {
            cpu_fprintf(f, "\n");
        } else {
            cpu_fprintf(f, " ");
        }
    }

    if (flags & CPU_DUMP_FPU) {
        if (s390_has_feat(S390_FEAT_VECTOR)) {
            for (i = 0; i < 32; i++) {
                cpu_fprintf(f, "V%02d=%016" PRIx64 "%016" PRIx64 "%c",
                            i, env->vregs[i][0].ll, env->vregs[i][1].ll,
                            i % 2 ? '\n' : ' ');
            }
        } else {
            for (i = 0; i < 16; i++) {
                cpu_fprintf(f, "F%02d=%016" PRIx64 "%c",
                            i, get_freg(env, i)->ll,
                            (i % 4) == 3 ? '\n' : ' ');
            }
        }
    }

#ifndef CONFIG_USER_ONLY
    for (i = 0; i < 16; i++) {
        cpu_fprintf(f, "C%02d=%016" PRIx64, i, env->cregs[i]);
        if ((i % 4) == 3) {
            cpu_fprintf(f, "\n");
        } else {
            cpu_fprintf(f, " ");
        }
    }
#endif

#ifdef DEBUG_INLINE_BRANCHES
    for (i = 0; i < CC_OP_MAX; i++) {
        cpu_fprintf(f, "  %15s = %10ld\t%10ld\n", cc_name(i),
                    inline_branch_miss[i], inline_branch_hit[i]);
    }
#endif

    cpu_fprintf(f, "\n");
}
Beispiel #2
0
/* Text representation of status */
void tty_report(int cyc) {
    sim_log("\nCycle %d. CC=%s, Stat=%s\n", cyc, cc_name(cc), stat_name(status));

    sim_log("F: predPC = 0x%x\n", pc_curr->pc);

    sim_log("D: instr = %s, rA = %s, rB = %s, valC = 0x%x, valP = 0x%x, Stat = %s\n",
            iname(HPACK(if_id_curr->icode, if_id_curr->ifun)),
            reg_name(if_id_curr->ra), reg_name(if_id_curr->rb),
            if_id_curr->valc, if_id_curr->valp,
            stat_name(if_id_curr->status));

    sim_log("E: instr = %s, valC = 0x%x, valA = 0x%x, valB = 0x%x\n   srcA = %s, srcB = %s, dstE = %s, dstM = %s, Stat = %s\n",
            iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)),
            id_ex_curr->valc, id_ex_curr->vala, id_ex_curr->valb,
            reg_name(id_ex_curr->srca), reg_name(id_ex_curr->srcb),
            reg_name(id_ex_curr->deste), reg_name(id_ex_curr->destm),
            stat_name(id_ex_curr->status));

    sim_log("M: instr = %s, Cnd = %d, valE = 0x%x, valA = 0x%x\n   dstE = %s, dstM = %s, Stat = %s\n",
            iname(HPACK(ex_mem_curr->icode, ex_mem_curr->ifun)),
            ex_mem_curr->takebranch,
            ex_mem_curr->vale, ex_mem_curr->vala,
            reg_name(ex_mem_curr->deste), reg_name(ex_mem_curr->destm),
            stat_name(ex_mem_curr->status));

    sim_log("W: instr = %s, valE = 0x%x, valM = 0x%x, dstE = %s, dstM = %s, Stat = %s\n",
            iname(HPACK(mem_wb_curr->icode, mem_wb_curr->ifun)),
            mem_wb_curr->vale, mem_wb_curr->valm,
            reg_name(mem_wb_curr->deste), reg_name(mem_wb_curr->destm),
            stat_name(mem_wb_curr->status));
}
Beispiel #3
0
int main(int argc, char *argv[])
{
    FILE *binfile;
    int max_steps = MAX_STEP;
    y86sim_t *sim;
    mem_t *saver, *savem;
    int step = 0;
    stat_t e = STAT_AOK;

    if (argc < 2 || argc > 3)
        usage(argv[0]);

    /* set max steps */
    if (argc > 2)
        max_steps = atoi(argv[2]);

    /* load binary file to memory */
    if (strcmp(argv[1]+(strlen(argv[1])-4), ".bin"))
        usage(argv[0]); /* only support *.bin file */
    
    binfile = fopen(argv[1], "rb");
    if (!binfile) {
        err_print("Can't open binary file '%s'", argv[1]);
        exit(1);
    }

    sim = new_y86sim(MEM_SIZE);
    if (load_binfile(sim->m, binfile) < 0) {
        err_print("Failed to load binary file '%s'", argv[1]);
        free_y86sim(sim);
        exit(1);
    }
    fclose(binfile);

    /* save initial register and memory stat */
    saver = dup_reg(sim->r);
    savem = dup_mem(sim->m);

    /* execute binary code step-by-step */
    for (step = 0; step < max_steps && e == STAT_AOK; step++)
        e = nexti(sim);

    /* print final stat of y86sim */
    printf("Stopped in %d steps at PC = 0x%x.  Status '%s', CC %s\n",
            step, sim->pc, stat_name(e), cc_name(sim->cc));

    printf("Changes to registers:\n");
    diff_reg(saver, sim->r, stdout);

    printf("\nChanges to memory:\n");
    diff_mem(savem, sim->m, stdout);

    free_y86sim(sim);
    free_reg(saver);
    free_mem(savem);

    return 0;
}
int main(int argc, char *argv[])
{
    FILE *code_file;
    int max_steps = 10000;

    // edit by leo
    init_sharemem();
    // edit end
	

    state_ptr s = new_state(MEM_SIZE);
    
    mem_t saver = copy_reg(s->r);
    mem_t savem;
    int step = 0;

    stat_t e = STAT_AOK;

    if (argc < 2 || argc > 3)
	usage(argv[0]);
    code_file = fopen(argv[1], "r");
    if (!code_file) {
	fprintf(stderr, "Can't open code file '%s'\n", argv[1]);
	exit(1);
    }
    
    if (!load_mem(s->m, code_file, 1)) {
	printf("Exiting\n");
	return 1;
    }    
    savem = copy_mem(s->m);
  
    // edit by leo
    // printf("error happen after here!\n");
    // edit end
    if (argc > 2)
	max_steps = atoi(argv[2]);

    for (step = 0; step < max_steps && e == STAT_AOK; step++)
	e = step_state(s, stdout);
    
    
    printf("Stopped in %d steps at PC = 0x%x.  Status '%s', CC %s\n",
	   step, s->pc, stat_name(e), cc_name(s->cc));

    printf("Changes to registers:\n");
    diff_reg(saver, s->r, stdout);

    printf("\nChanges to memory:\n");
    diff_mem(savem, s->m, stdout);

    free_state(s);
    free_reg(saver);
    free_mem(savem);

    return 0;
}
Beispiel #5
0
void do_ex_stage()
{
    alu_t alufun = gen_alufun();
    bool_t setcc = gen_set_cc();
    word_t alua, alub;

    alua = gen_aluA();
    alub = gen_aluB();

    e_bcond = 	take_branch(cc, id_ex_curr->ifun);
    
    ex_mem_next->takebranch = id_ex_curr->icode == I_JMP &&
	e_bcond;

    if (id_ex_curr->icode == I_JMP)
	sim_log("Execute: %s instruction, cc = %s, branch %staken\n",
		iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)),
		cc_name(cc),
		ex_mem_next->takebranch ? "" : "not ");
    
    /* Perform the ALU operation */
    ex_mem_next->vale = compute_alu(alufun, alua, alub);

    {
	byte_t instr = HPACK(id_ex_curr->icode, id_ex_curr->ifun);
	sim_log("Execute: Instruction %s\n",
		iname(instr));
    }

    if (setcc) {
	cc_in = compute_cc(alufun, alua, alub);
	sim_log("Execute: CC cc = %s\n", cc_name(cc_in));
    }

    ex_mem_next->icode = id_ex_curr->icode;
    ex_mem_next->ifun = id_ex_curr->ifun;
    ex_mem_next->vala = gen_new_M_valA();
    ex_mem_next->deste = id_ex_curr->deste;
    ex_mem_next->destm = id_ex_curr->destm;
    ex_mem_next->srca = id_ex_curr->srca;
    ex_mem_next->exception = id_ex_curr->exception;
    ex_mem_next->stage_pc = id_ex_curr->stage_pc;
}
Beispiel #6
0
bool_t diff_state(state_ptr olds, state_ptr news, FILE *outfile) {
    bool_t diff = FALSE;

    if (olds->pc != news->pc) {
	diff = TRUE;
	if (outfile) {
	    fprintf(outfile, "pc:\t0x%.8x\t0x%.8x\n", olds->pc, news->pc);
	}
    }
    if (olds->cc != news->cc) {
	diff = TRUE;
	if (outfile) {
	    fprintf(outfile, "cc:\t%s\t%s\n", cc_name(olds->cc), cc_name(news->cc));
	}
    }
    if (diff_reg(olds->r, news->r, outfile))
	diff = TRUE;
    if (diff_mem(olds->m, news->m, outfile))
	diff = TRUE;
    return diff;
}
Beispiel #7
0
void do_ex_stage()
{
    alu_t alufun = gen_alufun();
    bool_t setcc = gen_set_cc();
    word_t alua, alub;

    alua = gen_aluA();
    alub = gen_aluB();

    e_bcond = 	cond_holds(cc, id_ex_curr->ifun);
    
    ex_mem_next->takebranch = e_bcond;

    if (id_ex_curr->icode == I_JMP)
      sim_log("\tExecute: instr = %s, cc = %s, branch %staken\n",
	      iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)),
	      cc_name(cc),
	      ex_mem_next->takebranch ? "" : "not ");
    
    /* Perform the ALU operation */
    word_t aluout = compute_alu(alufun, alua, alub);
    ex_mem_next->vale = aluout;
    sim_log("\tExecute: ALU: %c 0x%x 0x%x --> 0x%x\n",
	    op_name(alufun), alua, alub, aluout);

    if (setcc) {
	cc_in = compute_cc(alufun, alua, alub);
	sim_log("\tExecute: New cc = %s\n", cc_name(cc_in));
    }

    ex_mem_next->icode = id_ex_curr->icode;
    ex_mem_next->ifun = id_ex_curr->ifun;
    ex_mem_next->vala = gen_e_valA();
    ex_mem_next->deste = gen_e_dstE();
    ex_mem_next->destm = id_ex_curr->destm;
    ex_mem_next->srca = id_ex_curr->srca;
    ex_mem_next->status = id_ex_curr->status;
    ex_mem_next->stage_pc = id_ex_curr->stage_pc;

}
int main(int argc, char *argv[])
{
    FILE *code_file;
    int max_steps = 10000;

    state_ptr s = new_state(MEM_SIZE);
    mem_t saver = copy_reg(s->r);
    mem_t savem;
    int step = 0;

    exc_t e = EXC_NONE;

    if (argc < 2 || argc > 3)
	usage(argv[0]);
    code_file = fopen(argv[1], "r");
    if (!code_file) {
	fprintf(stderr, "Can't open code file '%s'\n", argv[1]);
	exit(1);
    }

    if (!load_mem(s->m, code_file, 1)) {
	printf("Exiting\n");
	return 1;
    }

    savem = copy_mem(s->m);
  
    if (argc > 2)
	max_steps = atoi(argv[2]);

    for (step = 0; step < max_steps && e == EXC_NONE; step++)
	e = step_state(s, stdout);

    printf("Stopped in %d steps at PC = 0x%x.  Exception '%s', CC %s\n",
	   step, s->pc, exc_name(e), cc_name(s->cc));

    printf("Changes to registers:\n");
    diff_reg(saver, s->r, stdout);

    printf("\nChanges to memory:\n");
    diff_mem(savem, s->m, stdout);

    free_state(s);
    free_reg(saver);
    free_mem(savem);

    return 0;
}
Beispiel #9
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);
}
Beispiel #10
0
/* 
 * run_tty_sim - Run the simulator in TTY mode
 */
static void run_tty_sim() 
{
    int icount = 0;
    exc_t status = EXC_NONE;
    cc_t result_cc = 0;
    int byte_cnt = 0;
    mem_t mem0, reg0;
    state_ptr isa_state = NULL;


    /* In TTY mode, the default object file comes from stdin */
    if (!object_file) {
	object_file = stdin;
    }

    /* Initializations */
    if (verbosity >= 2)
	sim_set_dumpfile(stdout);
    sim_init();

    /* Emit simulator name */
    printf("%s\n", simname);

    byte_cnt = load_mem(mem, object_file, 1);
    if (byte_cnt == 0) {
	fprintf(stderr, "No lines of code found\n");
	exit(1);
    } else if (verbosity >= 2) {
	printf("%d bytes of code read\n", byte_cnt);
    }
    fclose(object_file);
    if (do_check) {
	isa_state = new_state(0);
	free_mem(isa_state->r);
	free_mem(isa_state->m);
	isa_state->m = copy_mem(mem);
	isa_state->r = copy_mem(reg);
	isa_state->cc = cc;
    }

    mem0 = copy_mem(mem);
    reg0 = copy_mem(reg);
    

    icount = sim_run(instr_limit, &status, &result_cc);
    if (verbosity > 0) {
	printf("%d instructions executed\n", icount);
	printf("Exception status = %s\n", exc_name(status));
	printf("Condition Codes: %s\n", cc_name(result_cc));
	printf("Changed Register State:\n");
	diff_reg(reg0, reg, stdout);
	printf("Changed Memory State:\n");
	diff_mem(mem0, mem, stdout);
    }
    if (do_check) {
	exc_t e = EXC_NONE;
	int step;
	bool_t match = TRUE;

	for (step = 0; step < instr_limit && e == EXC_NONE; step++) {
	    e = step_state(isa_state, stdout);
	}

	if (diff_reg(isa_state->r, reg, NULL)) {
	    match = FALSE;
	    if (verbosity > 0) {
		printf("ISA Register != Pipeline Register File\n");
		diff_reg(isa_state->r, reg, stdout);
	    }
	}
	if (diff_mem(isa_state->m, mem, NULL)) {
	    match = FALSE;
	    if (verbosity > 0) {
		printf("ISA Memory != Pipeline Memory\n");
		diff_mem(isa_state->m, mem, stdout);
	    }
	}
	if (isa_state->cc != result_cc) {
	    match = FALSE;
	    if (verbosity > 0) {
		printf("ISA Cond. Codes (%s) != Pipeline Cond. Codes (%s)\n",
		       cc_name(isa_state->cc), cc_name(result_cc));
	    }
	}
	if (match) {
	    printf("ISA Check Succeeds\n");
	} else {
	    printf("ISA Check Fails\n");
	}
    }
}
Beispiel #11
0
/* 
 * run_tty_sim - Run the simulator in TTY mode
 */
static void run_tty_sim() 
{
    int icount = 0;
    byte_t run_status = STAT_AOK;
    cc_t result_cc = 0;
    int byte_cnt = 0;
    mem_t mem0, reg0;
    state_ptr isa_state = NULL;


    /* In TTY mode, the default object file comes from stdin */
    if (!object_file) {
        object_file = stdin;
    }

    if (verbosity >= 2)
        sim_set_dumpfile(stdout);
    sim_init();

    /* Emit simulator name */
    if (verbosity >= 2)
        printf("%s\n", simname);

    byte_cnt = load_mem(mem, object_file, 1, START_PLACE);
    if (byte_cnt == 0) {
        fprintf(stderr, "No lines of code found\n");
        exit(1);
    } else if (verbosity >= 2) {
        printf("%d bytes of code read\n", byte_cnt);
    }
    fclose(object_file);
    if (do_check) {
        isa_state = new_state(0);
        free_reg(isa_state->r);
        free_mem(isa_state->m);
        isa_state->m = copy_mem(mem);
        isa_state->r = copy_reg(reg);
        isa_state->cc = cc;
    }

    if(verbosity > 0){
        mem0 = copy_mem(mem);
        reg0 = copy_reg(reg);
    }

    icount = sim_run_pipe(instr_limit, 5*instr_limit, &run_status, &result_cc);
    if (verbosity > 0) {
        printf("%d instructions executed\n", icount);
        printf("Status = %s\n", stat_name(run_status));
        printf("Condition Codes: %s\n", cc_name(result_cc));
        printf("Changed Register State:\n");
        diff_reg(reg0, reg, stdout);
        printf("Changed Memory State:\n");
        diff_mem(mem0, mem, stdout);
    }
    if (do_check) {
        exit(0);
        byte_t e = STAT_AOK;
        int step;
        bool_t match = TRUE;

        for (step = 0; step < instr_limit && e == STAT_AOK; step++) {
            e = step_state(isa_state, stdout);
        }

        if (diff_reg(isa_state->r, reg, NULL)) {
            match = FALSE;
            if (verbosity > 0) {
                printf("ISA Register != Pipeline Register File\n");
                diff_reg(isa_state->r, reg, stdout);
            }
        }
        if (diff_mem(isa_state->m, mem, NULL)) {
            match = FALSE;
            if (verbosity > 0) {
                printf("ISA Memory != Pipeline Memory\n");
                diff_mem(isa_state->m, mem, stdout);
            }
        }
        if (isa_state->cc != result_cc) {
            match = FALSE;
            if (verbosity > 0) {
                printf("ISA Cond. Codes (%s) != Pipeline Cond. Codes (%s)\n",
                        cc_name(isa_state->cc), cc_name(result_cc));
            }
        }
        if (match) {
            printf("ISA Check Succeeds\n");
        } else {
            printf("ISA Check Fails\n");
        }
    }

    /* Emit CPI statistics */
    {
        double cpi = instructions > 0 ? (double) cycles/instructions : 1.0;
        printf("%d CPI: %d cycles/%d instructions = %.2f\n", PSIM_ID,
                cycles, instructions, cpi);
    }
}
Beispiel #12
0
static unsigned int dec10_quick_imm(DisasContext *dc)
{
    int32_t imm, simm;
    int op;

    /* sign extend.  */
    imm = dc->ir & ((1 << 6) - 1);
    simm = (int8_t) (imm << 2);
    simm >>= 2;
    switch (dc->opcode) {
        case CRISV10_QIMM_BDAP_R0:
        case CRISV10_QIMM_BDAP_R1:
        case CRISV10_QIMM_BDAP_R2:
        case CRISV10_QIMM_BDAP_R3:
            simm = (int8_t)dc->ir;
            LOG_DIS("bdap %d $r%d\n", simm, dc->dst);
            LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
                     dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
            cris_set_prefix(dc);
            if (dc->dst == 15) {
                tcg_gen_movi_tl(cpu_PR[PR_PREFIX], dc->pc + 2 + simm);
            } else {
                tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
            }
            break;

        case CRISV10_QIMM_MOVEQ:
            LOG_DIS("moveq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
            break;
        case CRISV10_QIMM_CMPQ:
            LOG_DIS("cmpq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
            break;
        case CRISV10_QIMM_ADDQ:
            LOG_DIS("addq %d, $r%d\n", imm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_ADD, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
            break;
        case CRISV10_QIMM_ANDQ:
            LOG_DIS("andq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_AND, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
            break;
        case CRISV10_QIMM_ASHQ:
            LOG_DIS("ashq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            op = imm & (1 << 5);
            imm &= 0x1f;
            if (op) {
                cris_alu(dc, CC_OP_ASR, cpu_R[dc->dst],
                          cpu_R[dc->dst], tcg_const_tl(imm), 4);
            } else {
                /* BTST */
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
                gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
                           tcg_const_tl(imm), cpu_PR[PR_CCS]);
            }
            break;
        case CRISV10_QIMM_LSHQ:
            LOG_DIS("lshq %d, $r%d\n", simm, dc->dst);

            op = CC_OP_LSL;
            if (imm & (1 << 5)) {
                op = CC_OP_LSR; 
            }
            imm &= 0x1f;
            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, op, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
            break;
        case CRISV10_QIMM_SUBQ:
            LOG_DIS("subq %d, $r%d\n", imm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_SUB, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
            break;
        case CRISV10_QIMM_ORQ:
            LOG_DIS("andq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_OR, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
            break;

        case CRISV10_QIMM_BCC_R0:
        case CRISV10_QIMM_BCC_R1:
        case CRISV10_QIMM_BCC_R2:
        case CRISV10_QIMM_BCC_R3:
            imm = dc->ir & 0xff;
            /* bit 0 is a sign bit.  */
            if (imm & 1) {
                imm |= 0xffffff00;   /* sign extend.  */
                imm &= ~1;           /* get rid of the sign bit.  */
            }
            imm += 2;
            LOG_DIS("b%s %d\n", cc_name(dc->cond), imm);

            cris_cc_mask(dc, 0);
            cris_prepare_cc_branch(dc, imm, dc->cond); 
            break;

        default:
            LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
                     dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
            cpu_abort(dc->env, "Unhandled quickimm\n");
            break;
    }
    return 2;
}
Beispiel #13
0
static unsigned int dec10_ind(DisasContext *dc)
{
    unsigned int insn_len = 2;
    unsigned int size = dec10_size(dc->size);
    uint32_t imm;
    int32_t simm;
    TCGv t[2];

    if (dc->size != 3) {
        switch (dc->opcode) {
            case CRISV10_IND_MOVE_M_R:
                return dec10_ind_move_m_r(dc, size);
                break;
            case CRISV10_IND_MOVE_R_M:
                return dec10_ind_move_r_m(dc, size);
                break;
            case CRISV10_IND_CMP:
                LOG_DIS("cmp size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_CMP, size);
                break;
            case CRISV10_IND_TEST:
                LOG_DIS("test size=%d op=%d %d\n",  size, dc->src, dc->dst);

                cris_evaluate_flags(dc);
                cris_cc_mask(dc, CC_MASK_NZVC);
                cris_alu_m_alloc_temps(t);
                insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
                cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
                         t[0], tcg_const_tl(0), size);
                cris_alu_m_free_temps(t);
                break;
            case CRISV10_IND_ADD:
                LOG_DIS("add size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_ADD, size);
                break;
            case CRISV10_IND_SUB:
                LOG_DIS("sub size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_SUB, size);
                break;
            case CRISV10_IND_BOUND:
                LOG_DIS("bound size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_bound(dc, size);
                break;
            case CRISV10_IND_AND:
                LOG_DIS("and size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_AND, size);
                break;
            case CRISV10_IND_OR:
                LOG_DIS("or size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_OR, size);
                break;
            case CRISV10_IND_MOVX:
                insn_len = dec10_alux_m(dc, CC_OP_MOVE);
                break;
            case CRISV10_IND_ADDX:
                insn_len = dec10_alux_m(dc, CC_OP_ADD);
                break;
            case CRISV10_IND_SUBX:
                insn_len = dec10_alux_m(dc, CC_OP_SUB);
                break;
            case CRISV10_IND_CMPX:
                insn_len = dec10_alux_m(dc, CC_OP_CMP);
                break;
            case CRISV10_IND_MUL:
                /* This is a reg insn coded in the mem indir space.  */
                LOG_DIS("mul pc=%x opcode=%d\n", dc->pc, dc->opcode);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_mul(dc, size, dc->ir & (1 << 10));
                break;
            case CRISV10_IND_BDAP_M:
                insn_len = dec10_bdap_m(dc, size);
                break;
            default:
                LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n",
                          dc->pc, size, dc->opcode, dc->src, dc->dst);
                cpu_abort(dc->env, "Unhandled opcode");
                break;
        }
        return insn_len;
    }

    switch (dc->opcode) {
        case CRISV10_IND_MOVE_M_SPR:
            insn_len = dec10_ind_move_m_pr(dc);
            break;
        case CRISV10_IND_MOVE_SPR_M:
            insn_len = dec10_ind_move_pr_m(dc);
            break;
        case CRISV10_IND_JUMP_M:
            if (dc->src == 15) {
                LOG_DIS("jump.%d %d r%d r%d direct\n", size,
                         dc->opcode, dc->src, dc->dst);
                imm = ldl_code(dc->pc + 2);
                if (dc->mode == CRISV10_MODE_AUTOINC)
                    insn_len += size;

                t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
                dc->jmp_pc = imm;
                cris_prepare_jmp(dc, JMP_DIRECT);
                dc->delayed_branch--; /* v10 has no dslot here.  */
            } else {
                if (dc->dst == 14) {
                    LOG_DIS("break %d\n", dc->src);
                    cris_evaluate_flags(dc);
                    tcg_gen_movi_tl(env_pc, dc->pc + 2);
                    t_gen_raise_exception(EXCP_BREAK);
                    dc->is_jmp = DISAS_UPDATE;
                    return insn_len;
                }
                LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size,
                         dc->opcode, dc->src, dc->dst);
                t[0] = tcg_temp_new();
                t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
                crisv10_prepare_memaddr(dc, t[0], size);
                gen_load(dc, env_btarget, t[0], 4, 0);
                insn_len += crisv10_post_memaddr(dc, size);
                cris_prepare_jmp(dc, JMP_INDIRECT);
                dc->delayed_branch--; /* v10 has no dslot here.  */
                tcg_temp_free(t[0]);
            }
            break;

        case CRISV10_IND_MOVEM_R_M:
            LOG_DIS("movem_r_m pc=%x opcode=%d r%d r%d\n",
                        dc->pc, dc->opcode, dc->dst, dc->src);
            dec10_movem_r_m(dc);
            break;
        case CRISV10_IND_MOVEM_M_R:
            LOG_DIS("movem_m_r pc=%x opcode=%d\n", dc->pc, dc->opcode);
            dec10_movem_m_r(dc);
            break;
        case CRISV10_IND_JUMP_R:
            LOG_DIS("jmp pc=%x opcode=%d r%d r%d\n",
                        dc->pc, dc->opcode, dc->dst, dc->src);
            tcg_gen_mov_tl(env_btarget, cpu_R[dc->src]);
            t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
            cris_prepare_jmp(dc, JMP_INDIRECT);
            dc->delayed_branch--; /* v10 has no dslot here.  */
            break;
        case CRISV10_IND_MOVX:
            insn_len = dec10_alux_m(dc, CC_OP_MOVE);
            break;
        case CRISV10_IND_ADDX:
            insn_len = dec10_alux_m(dc, CC_OP_ADD);
            break;
        case CRISV10_IND_SUBX:
            insn_len = dec10_alux_m(dc, CC_OP_SUB);
            break;
        case CRISV10_IND_CMPX:
            insn_len = dec10_alux_m(dc, CC_OP_CMP);
            break;
        case CRISV10_IND_DIP:
            insn_len = dec10_dip(dc);
            break;
        case CRISV10_IND_BCC_M:

            cris_cc_mask(dc, 0);
            imm = ldsw_code(dc->pc + 2);
            simm = (int16_t)imm;
            simm += 4;

            LOG_DIS("bcc_m: b%s %x\n", cc_name(dc->cond), dc->pc + simm);
            cris_prepare_cc_branch(dc, simm, dc->cond);
            insn_len = 4;
            break;
        default:
            LOG_DIS("ERROR pc=%x opcode=%d\n", dc->pc, dc->opcode);
            cpu_abort(dc->env, "Unhandled opcode");
            break;
    }

    return insn_len;
}
Beispiel #14
0
static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
                                  uint64_t src, uint64_t dst, uint64_t vr)
{
    S390CPU *cpu = s390_env_get_cpu(env);
    uint32_t r = 0;

    switch (cc_op) {
    case CC_OP_CONST0:
    case CC_OP_CONST1:
    case CC_OP_CONST2:
    case CC_OP_CONST3:
        /* cc_op value _is_ cc */
        r = cc_op;
        break;
    case CC_OP_LTGT0_32:
        r = cc_calc_ltgt0_32(dst);
        break;
    case CC_OP_LTGT0_64:
        r =  cc_calc_ltgt0_64(dst);
        break;
    case CC_OP_LTGT_32:
        r =  cc_calc_ltgt_32(src, dst);
        break;
    case CC_OP_LTGT_64:
        r =  cc_calc_ltgt_64(src, dst);
        break;
    case CC_OP_LTUGTU_32:
        r =  cc_calc_ltugtu_32(src, dst);
        break;
    case CC_OP_LTUGTU_64:
        r =  cc_calc_ltugtu_64(src, dst);
        break;
    case CC_OP_TM_32:
        r =  cc_calc_tm_32(src, dst);
        break;
    case CC_OP_TM_64:
        r =  cc_calc_tm_64(src, dst);
        break;
    case CC_OP_NZ:
        r =  cc_calc_nz(dst);
        break;
    case CC_OP_ADD_64:
        r =  cc_calc_add_64(src, dst, vr);
        break;
    case CC_OP_ADDU_64:
        r =  cc_calc_addu_64(src, dst, vr);
        break;
    case CC_OP_ADDC_64:
        r =  cc_calc_addc_64(src, dst, vr);
        break;
    case CC_OP_SUB_64:
        r =  cc_calc_sub_64(src, dst, vr);
        break;
    case CC_OP_SUBU_64:
        r =  cc_calc_subu_64(src, dst, vr);
        break;
    case CC_OP_SUBB_64:
        r =  cc_calc_subb_64(src, dst, vr);
        break;
    case CC_OP_ABS_64:
        r =  cc_calc_abs_64(dst);
        break;
    case CC_OP_NABS_64:
        r =  cc_calc_nabs_64(dst);
        break;
    case CC_OP_COMP_64:
        r =  cc_calc_comp_64(dst);
        break;

    case CC_OP_ADD_32:
        r =  cc_calc_add_32(src, dst, vr);
        break;
    case CC_OP_ADDU_32:
        r =  cc_calc_addu_32(src, dst, vr);
        break;
    case CC_OP_ADDC_32:
        r =  cc_calc_addc_32(src, dst, vr);
        break;
    case CC_OP_SUB_32:
        r =  cc_calc_sub_32(src, dst, vr);
        break;
    case CC_OP_SUBU_32:
        r =  cc_calc_subu_32(src, dst, vr);
        break;
    case CC_OP_SUBB_32:
        r =  cc_calc_subb_32(src, dst, vr);
        break;
    case CC_OP_ABS_32:
        r =  cc_calc_abs_32(dst);
        break;
    case CC_OP_NABS_32:
        r =  cc_calc_nabs_32(dst);
        break;
    case CC_OP_COMP_32:
        r =  cc_calc_comp_32(dst);
        break;

    case CC_OP_ICM:
        r =  cc_calc_icm(src, dst);
        break;
    case CC_OP_SLA_32:
        r =  cc_calc_sla_32(src, dst);
        break;
    case CC_OP_SLA_64:
        r =  cc_calc_sla_64(src, dst);
        break;
    case CC_OP_FLOGR:
        r = cc_calc_flogr(dst);
        break;

    case CC_OP_NZ_F32:
        r = set_cc_nz_f32(dst);
        break;
    case CC_OP_NZ_F64:
        r = set_cc_nz_f64(dst);
        break;
    case CC_OP_NZ_F128:
        r = set_cc_nz_f128(make_float128(src, dst));
        break;

    default:
        cpu_abort(CPU(cpu), "Unknown CC operation: %s\n", cc_name(cc_op));
    }

    HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __func__,
               cc_name(cc_op), src, dst, vr, r);
    return r;
}