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 ,
>
>