will fix.

On Tue, Sep 1, 2009 at 1:10 PM, Russ Cox<r...@swtch.com> wrote:
>> temporarly out of time on this one.  it appears
>> from the assembly output that 8c multiplies by
>> 0 and not 1 when computing z a second time.
>> nonetheless, i haven't yet seen the problem.
>
> not quite that simple.
> it's a register allocation
> (really register management) bug.
>
> On Mon, Aug 31, 2009 at 6:51 PM, Bruce Ellis<bruce.el...@gmail.com> wrote:
>> if it's my fault i'll fix it. it did screw up mod in a subtle way but
>> that's been fixed.
>
> it looks like the cgen64 multiply case is
> not managing the registers correctly
> when AX is not where it expects.
> more details for you:
>
> int three = 3;
> int one = 1;
> uvlong twelve = 12;
>
> /* ok */
> uvlong
> mul1(void)
> {
>        return one * (twelve - three);
> }
>
> TEXT    mul1+0(SB),0,$12
>        MOVL    three+0(SB),AX
>        MOVL    AX,CX
>        SARL    $31,CX
>        // three is now in CX:AX
>
>        LEAL    twelve+0(SB),DX
>        MOVL    (DX),BX
>        SUBL    AX,BX
>        MOVL    4(DX),AX
>        SBBL    CX,AX
>        // twelve - three is now in AX:BX
>        MOVL    AX,CX
>        // twelve - three is now in CX:BX
>
>        MOVL    one+0(SB),AX
>        MOVL    AX,DX
>        SARL    $31,DX
>        // one is now in DX:AX
>
>        // 64-bit multiply CX:BX * DX:AX -> DX:AX
>        MOVL    CX,BP
>        ORL     DX,BP
>        CMPL    BP,$0
>        JNE     ,3(PC)
>        MULL    BX,
>        JMP     ,8(PC)
>        IMULL   BX,DX
>        MOVL    AX,BP
>        IMULL   CX,BP
>        ADDL    DX,BP
>        MOVL    BX,DX
>        MULL    DX,
>        ADDL    BP,DX
>
>        MOVL    .ret+0(FP),CX   // probably LEAL
>        MOVL    AX,(CX)
>        MOVL    DX,4(CX)
>        RET     ,
>        RET     ,
>
> vs
>
> /* not ok */
>
> uvlong
> mul2(void)
> {
>        return (twelve - three) * one;
> }
>
> TEXT    mul2+0(SB),0,$12
>        MOVL    one+0(SB),AX
>        MOVL    AX,CX
>        SARL    $31,CX
>        MOVL    AX,BX
>        // one is now in CX:BX
>
>        MOVL    three+0(SB),AX
>        MOVL    AX,DX
>        SARL    $31,DX
>        // three is now in DX:AX
>
>        LEAL    twelve+0(SB),BP
>        MOVL    (BP),SI
>        SUBL    AX,SI
>        MOVL    4(BP),AX
>        SBBL    DX,AX
>        // twelve - three is now in AX:SI
>
>        // 64-bit multiply CX:BX * AX:SI
>        // saving AX and DX so they can be reused.
>        // DX doesn't even need saving.
>        MOVL    AX,.safe+-4(SP)
>        MOVL    DX,.safe+-8(SP)
>        MOVL    SI,DX
>
>        // 8c is very confused at this point.
>        // it is using AX for multiple purposes.
>        MOVL    CX,AX
>        ORL     SI,AX
>        CMPL    AX,$0
>        JNE     ,4(PC)
>        MOVL    BX,AX
>        MULL    AX,
>        JMP     ,7(PC)
>        IMULL   BX,DX
>        IMULL   CX,AX
>        ADDL    DX,AX
>        MOVL    BX,DX
>        MULL    DX,
>        ADDL    AX,DX
>
>        // restore old AX DX now that multiply is over.
>        // (forgot that multiply left result in DX:AX)
>        MOVL    .safe+-4(SP),AX
>        MOVL    .safe+-8(SP),DX
>
>        MOVL    .ret+0(FP),CX   // probably LEAL
>        MOVL    AX,(CX)
>        MOVL    DX,4(CX)
>        RET     ,
>
>

Reply via email to