qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH moxie 3/5] Moxie target code


From: Richard Henderson
Subject: Re: [Qemu-devel] [PATCH moxie 3/5] Moxie target code
Date: Thu, 14 Feb 2013 16:37:03 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2

On 02/14/2013 03:19 PM, Richard Henderson wrote:
>> > +            tcg_gen_brcond_i32(TCG_COND_EQ, REG(a), REG(b), label_equal);
>> > +
>> > +#define CMPTEST(t,CODE)                                         \
>> > +            {                                                   \
>> > +              int lyes = gen_new_label();                       \
>> > +              int lno = gen_new_label();                        \
>> > +              TCGv t1 = new_tmp();                              \
>> > +              tcg_gen_brcond_i32(t, REG(a), REG(b), lyes);      \
>> > +              tcg_gen_br(lno);                                  \
>> > +              gen_set_label(lyes);                              \
>> > +              tcg_gen_ori_i32(t1, cc, CODE);                    \
>> > +              tcg_gen_mov_i32(cc, t1);                          \
>> > +              gen_set_label(lno);                               \
>> > +              dead_tmp(t1);                                     \
> Consider making use of tcg_setcond_i32 here.  It's probably new since
> you wrote all this in the first place.
> 

That said, I wonder if the amount of code generated here even with
setcond would be too big.

The quick and easy option is to use a helper function.  If we mark it
as-if gcc's pure, aka TCG_CALL_NO_RWG_SE, it should be relatively
efficient, as far as TCG goes:

target_long helper_cmp(target_long x, target_long y)
{
    target_ulong ux = x, uy = y;
    if (x == y) {
        return CC_EQ;
    }
    return (x < y ? CC_LT : CC_GT) | (ux < uy ? CC_LTU : CC_GTU);
}

Optimizes pretty well inside gcc:

        cmpl    %esi, %edi
        movl    $4, %eax
        je      .L11
        setl    %dl
        movzbl  %dl, %edx
        addl    $1, %edx
        cmpl    %esi, %edi
        sbbl    %eax, %eax
        andl    $8, %eax
        addl    $8, %eax
        orl     %edx, %eax
.L11:
        rep
        ret

Now, given that CC is only settable via CMP, and apparently only
readable via branches. means that we could optimize things a bit.

What if the CMP insn merely copies its inputs to TCG globals CMP1 and
CMP2?  Then the actual implementation of BEQ (et al) is

        tcg_gen_brcond_i32(TCG_COND_EQ, cpu_cmp1, cpu_cmp2, lab_true);

Since these are globals, a subsequent BGT in a different TB will still
read the same values and perform the appropriate comparison in
performing its branch.

What I don't know is how this affects the moxie exception model, of
which I can find no information.  There doesn't seem to be any
implementation of such a model in the patches sent here.

When saving/restoring the CC value, one could presumably translate the
two variables into a canonical CC code as above, and for the reverse
transformation chose two values that create any valid comparison.

                        cmp1    cmp2
        EQ              0       0
        LT & LTU        0       1
        LT & GTU        -1      1
        GT & LTU        1       -1
        GT & GTU        1       0

as everything else is logically impossible.


r~



reply via email to

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