[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH V5 2/7] nios2: Add architecture emulation suppor
From: |
Marek Vasut |
Subject: |
Re: [Qemu-devel] [PATCH V5 2/7] nios2: Add architecture emulation support |
Date: |
Sun, 23 Oct 2016 05:01:38 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.4.0 |
On 10/20/2016 04:35 PM, Richard Henderson wrote:
> On 10/20/2016 06:44 AM, Marek Vasut wrote:
>> +typedef struct Nios2Instruction {
>> + void (*handler)(DisasContext *dc, uint32_t code, TCGMemOp
>> flags);
>> + uint32_t flags;
>> +} Nios2Instruction;
>
> I gave you some bad advice wrt the type of flags beforehand. I had
> failed to divine that it was also used for EXCP_* and TCG_COND_*. I
> think you were right the first time with unsigned.
>
> My bad, sorry.
I undid the change, thanks.
>> +/* Load instructions */
>> +static void gen_ldx(DisasContext *dc, uint32_t code, TCGMemOp flags)
>> +{
>> + I_TYPE(instr, code);
>> +
>> + TCGv addr = tcg_temp_new();
>> + TCGv data = tcg_temp_new();
>> + tcg_gen_addi_tl(addr, load_gpr(dc, instr.a), instr.imm16s);
>> + tcg_gen_qemu_ld_tl(data, addr, dc->mem_idx, flags);
>> +
>> + /*
>> + * WARNING: Loads into R_ZERO are ignored, but we must generate the
>> + * memory access itself to emulate the CPU precisely. Load
>> + * from a protected page to R_ZERO will cause SIGSEGV on
>> + * the Nios2 CPU.
>> + */
>> + if (likely(instr.b != R_ZERO)) {
>> + tcg_gen_mov_tl(dc->cpu_R[instr.b], data);
>> + }
>
> Consider
>
> TCGv data;
>
> if (unlikely(instr.b == R_ZERO)) {
> /* The writeback to R_ZERO is ignored, but we must generate the
> * memory access itself to emulate the CPU precisely. Load from
> * a protected page to R_ZERO will cause SIGSEGV on the Nios2 CPU.
> */
> data = tcg_temp_new();
> } else {
> data = dc->cpu_R[instr.b];
> }
>
> tcg_gen_qemu_ld_tl(data, addr, dc->mem_idx, flags);
>
> if (unlikely(instr.b == R_ZERO)) {
> tcg_temp_free(data);
> }
>
> so that you don't require the mov opcode.
>
> That's really what I do on Alpha with dest_gpr.
OK
>> +#define gen_r_div(fname,
>> insn) \
>> +static void (fname)(DisasContext *dc, uint32_t code, TCGMemOp
>> flags) \
>> +{
>> \
>> + R_TYPE(instr,
>> (code)); \
>> + if (likely(instr.c != R_ZERO))
>> { \
>> + TCGv val =
>> tcg_const_tl(0); \
>> + tcg_gen_setcond_tl(TCG_COND_EQ, val, load_gpr((dc), instr.b),
>> val); \
>> + tcg_gen_or_tl(val, val, load_gpr((dc),
>> instr.b)); \
>> + tcg_gen_##insn((dc)->cpu_R[instr.c], load_gpr((dc), instr.a),
>> val); \
>> +
>> tcg_temp_free(val); \
>> +
>> } \
>> +}
>> +
>> +gen_r_div(divs, div_tl)
>
> For signed division, you have to protect against 0x80000000 / -1 as
> well, which raises an overflow exception on the x86 host.
You mean similar to what mips does on OPC_DIV vs OPC_DIVU , right ?
>> + /* Set up instruction counts */
>> + num_insns = 0;
>> + max_insns = tb->cflags & CF_COUNT_MASK;
>> + if (max_insns == 0) {
>> + max_insns = CF_COUNT_MASK;
>> + }
>> + if (max_insns > TCG_MAX_INSNS) {
>> + max_insns = TCG_MAX_INSNS;
>> + }
>> + next_page_start = (tb->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
> ...
>> + } while (!dc->is_jmp &&
>> + !tcg_op_buf_full() &&
>> + !cs->singlestep_enabled &&
>> + !singlestep &&
>> + dc->pc < next_page_start &&
>> + num_insns < max_insns);
>
> Consider
>
> if (cs->singlestep_enabled || singlestep) {
> max_insns = 1;
> } else {
> int page_insns = (TARGET_PAGE_SIZE - (tb->pc & TARGET_PAGE_MASK)) / 4;
> max_insns = tb->cflags & CF_COUNT_MASK;
> if (max_insns == 0) {
> max_insns = CF_COUNT_MASK;
> }
> if (max_insns > page_insns) {
> max_insns = page_insns;
> }
> if (max_insns > TCG_MAX_INSNS) {
> max_insns = TCG_MAX_INSNS;
> }
> }
>
> so that we collapse the last 4 loop conditions into: num_insns < max_insns.
OK, fixed.
>> + /* End off the block */
>> + gen_tb_end(tb, num_insns);
>> +
>> + /* Mark instruction starts for the final generated instruction */
>> + tb->size = dc->pc - tb->pc;
>> + tb->icount = num_insns;
>
> No CPU_LOG_TB_IN_ASM disassembly? I thought patch 1 added a nios2
> disassembler.
Nope, I removed it in V4, maybe i misunderstood the review comment?
"
> + /* Dump the CPU state to the log */
> + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
> + qemu_log("--------------\n");
> + log_cpu_state(cs, 0);
> + }
Cpu state is dumped by -d cpu generically.
"
--
Best regards,
Marek Vasut
- [Qemu-devel] [PATCH V3 2/7] nios2: Add architecture emulation support, (continued)
- [Qemu-devel] [PATCH V3 2/7] nios2: Add architecture emulation support, Marek Vasut, 2016/10/18
- Re: [Qemu-devel] [PATCH V3 2/7] nios2: Add architecture emulation support, Richard Henderson, 2016/10/18
- Re: [Qemu-devel] [PATCH V3 2/7] nios2: Add architecture emulation support, Marek Vasut, 2016/10/18
- Re: [Qemu-devel] [PATCH V3 2/7] nios2: Add architecture emulation support, Richard Henderson, 2016/10/19
- Re: [Qemu-devel] [PATCH V3 2/7] nios2: Add architecture emulation support, Marek Vasut, 2016/10/19
- Re: [Qemu-devel] [PATCH V3 2/7] nios2: Add architecture emulation support, Richard Henderson, 2016/10/20
- Re: [Qemu-devel] [PATCH V3 2/7] nios2: Add architecture emulation support, Marek Vasut, 2016/10/20
[Qemu-devel] [PATCH V4 2/7] nios2: Add architecture emulation support, Marek Vasut, 2016/10/18
[Qemu-devel] [PATCH V6 2/7] nios2: Add architecture emulation support, Marek Vasut, 2016/10/25
[Qemu-devel] [PATCH V3 6/7] nios2: Add Altera 10M50 GHRD emulation, Marek Vasut, 2016/10/18