On Fri, Sep 8, 2023 at 1:49 AM Takayuki 'January June' Suwa
<jjsuwa_sys3...@yahoo.co.jp> wrote:
>
> An idiomatic implementation of boolean evaluation of whether a register is
> zero or not in Xtensa is to assign 0 and 1 to the temporary and destination,
> and then issue the MOV[EQ/NE]Z machine instruction
> (See 8.3.2 Instruction Idioms, Xtensa ISA refman., p.599):
>
> ;; A2 = (A3 != 0) ? 1 : 0;
>         movi.n  a9, 1
>         movi.n  a2, 0
>         movnez  a2, a9, a3  ;; if (A3 != 0) A2 = A9;
>
> As you can see in the above idiom, if the source and destination are the
> same register, a move instruction from the source to another temporary
> register must be prepended:
>
> ;; A2 = (A2 == 0) ? 1 : 0;
>         mov.n   a10, a2
>         movi.n  a9, 1
>         movi.n  a2, 0
>         moveqz  a2, a9, a10  ;; if (A10 == 0) A2 = A9;
>
> Fortunately, we can reduce the number of instructions and temporary
> registers with a few tweaks:
>
> ;; A2 = (A3 != 0) ? 1 : 0;
>         movi.n  a2, 1
>         moveqz  a2, a3, a3  ;; if (A3 == 0) A2 = A3;
>
> ;; A2 = (A2 != 0) ? 1 : 0;
>         movi.n  a9, 1
>         movnez  a2, a9, a2  ;; if (A2 != 0) A2 = A9;
>
> ;; A2 = (A3 == 0) ? 1 : 0;
>         movi.n  a2, -1
>         moveqz  a2, a3, a3  ;; if (A3 == 0) A2 = A3;
>         addi.n  a2, a2, 1
>
> ;; A2 = (A2 == 0) ? 1 : 0;
>         movi.n  a9, -1
>         movnez  a2, a9, a2  ;; if (A2 != 0) A2 = A9;
>         addi.n  a2, a2, 1
>
> Additionally, if TARGET_NSA is configured, the fact that it returns 32 iff
> the source of the NSAU machine instruction is 0, otherwise less than, can be
> used in boolean evaluation of EQ comparison.
>
> ;; A2 = (A3 == 0) ? 1 : 0;
>         nsau    a2, a3      ;; Source and destination can be the same register
>         srli    a2, a2, 5
>
> Furthermore, this patch also saves one instruction when determining whether
> the ANDing with mask values in which 1s are lined up from the upper or lower
> bit end (for example, 0xFFE00000 or 0x003FFFFF) is 0 or not.
>
> gcc/ChangeLog:
>
>         * config/xtensa/xtensa.cc (xtensa_expand_scc):
>         Revert the changes from the last patch, as the work in the RTL
>         expansion pass is too far to determine the physical registers.
>         * config/xtensa/xtensa.md (*eqne_INT_MIN): Ditto.
>         (eq_zero_NSA, eqne_zero, *eqne_zero_masked_bits): New patterns.
> ---
>  gcc/config/xtensa/xtensa.cc |  35 +----------
>  gcc/config/xtensa/xtensa.md | 112 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 113 insertions(+), 34 deletions(-)

Regtested for target=xtensa-linux-uclibc, no new regressions.
Committed to master.

-- 
Thanks.
-- Max

Reply via email to