qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support


From: Marek Vasut
Subject: Re: [Qemu-devel] [PATCH 2/7] nios2: Add architecture emulation support
Date: Tue, 18 Oct 2016 20:32:39 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.4.0

On 10/18/2016 05:31 PM, Richard Henderson wrote:
> On 10/17/2016 08:58 PM, Marek Vasut wrote:
>>> There's no particular reason why R_PC needs to be 64; if you change it
>>> to 32, you can simplify this.
>>
>> I believe this is in fact needed, see [1] page 18 (section 2, Register
>> file), quote:
>>
>> "
>> The Nios II architecture supports a flat register file, consisting of
>> thirty-two 32-bit general-purpose integer
>> registers, and up to thirty-two 32-bit control registers. The
>> architecture supports supervisor and user
>> modes that allow system code to protect the control registers from
>> errant applications.
>> "
>>
>> So the CPU supports 32 general purpose regs (R_ZERO..R_RA), then up-to
>> 32 Control registers (CR_STATUS..CR_MPUACC) and then the PC .
> 
> The architecture manual doesn't imply anything about the numbering of
> these registers.

But the instruction encoding does, so I can use the field from the
instruction to directly index the register array.

>>> You're not doing anything to make sure that r0 reads as 0, and ignores
>>> writes. You need to look at target-alpha, target-mips, or target-sparc
>>> to see various ways in which a zero register may be handled.
>>
>> Any hint on this one ?
> 
> Well, there's three hints right there.  But look at target-alpha, and
> the functions load_gpr and dest_gpr (note that for alpha, 31 is the zero
> register).

Thanks, I hope this is fixed now, although I mostly special-case the
R_ZERO handling throughout the code. Any writes to R_ZERO are now
ignored and any usage is converted to mov/movi instructions where
applicable.

>>> Since divide-by-zero is undefined, this can be done with
>>>
>>>   TCGv t0 = tcg_const_tl(0);
>>>   tcg_gen_setcond_tl(TCG_COND_EQ, t0, dc->cpu_R[instr->b], t0);
>>>   tcg_gen_or_tl(t0, t0, dc->cpu_R[instr->b]);
>>>   tcg_gen_divu_tl(dc->cpu_R[instr->c], dc->cpu_R[instr->a], t0);
>>>   tcg_temp_free_tl(t0);
>>
>> Just so I get it completely, isn't this handled somehow by the
>> tcg_gen_divu_tl() itself ?
> 
> No, tcg_gen_divu_tl is a plain host divide instruction.
> 
> For guests that require exceptions to be raised, we handle those
> manually beforehand.  At which point extra checks in tcg_gen_divu_tl are
> wasted.

OK, got it, thanks!

-- 
Best regards,
Marek Vasut



reply via email to

[Prev in Thread] Current Thread [Next in Thread]