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  page 18 (section 2, Register
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
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
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).
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);
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.