* [9fans] 8c vlong bug
@ 2009-09-01 1:47 erik quanstrom
2009-09-01 1:51 ` Bruce Ellis
0 siblings, 1 reply; 4+ messages in thread
From: erik quanstrom @ 2009-09-01 1:47 UTC (permalink / raw)
To: 9fans
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.
#include <u.h>
#include <libc.h>
void
main(void)
{
int three, one;
uvlong twelve, z;
one = 1;
three = 3;
twelve = 12;
z = one*(twelve - three);
print("z = %llud\n", z);
z = (twelve - three) * one;
print("z = %llud\n", z);
exits(0);
}
output:
z = 9
z = 0
- erik
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [9fans] 8c vlong bug
2009-09-01 1:47 [9fans] 8c vlong bug erik quanstrom
@ 2009-09-01 1:51 ` Bruce Ellis
2009-09-01 3:10 ` Russ Cox
0 siblings, 1 reply; 4+ messages in thread
From: Bruce Ellis @ 2009-09-01 1:51 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
if it's my fault i'll fix it. it did screw up mod in a subtle way but
that's been fixed.
brucee
On Tue, Sep 1, 2009 at 11:47 AM, erik quanstrom<quanstro@quanstro.net> 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.
>
> #include <u.h>
> #include <libc.h>
>
> void
> main(void)
> {
> int three, one;
> uvlong twelve, z;
>
> one = 1;
> three = 3;
> twelve = 12;
>
> z = one*(twelve - three);
> print("z = %llud\n", z);
>
> z = (twelve - three) * one;
> print("z = %llud\n", z);
>
> exits(0);
> }
>
> output:
>
> z = 9
> z = 0
>
> - erik
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [9fans] 8c vlong bug
2009-09-01 1:51 ` Bruce Ellis
@ 2009-09-01 3:10 ` Russ Cox
2009-09-01 3:24 ` Bruce Ellis
0 siblings, 1 reply; 4+ messages in thread
From: Russ Cox @ 2009-09-01 3:10 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
> 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.ellis@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 ,
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [9fans] 8c vlong bug
2009-09-01 3:10 ` Russ Cox
@ 2009-09-01 3:24 ` Bruce Ellis
0 siblings, 0 replies; 4+ messages in thread
From: Bruce Ellis @ 2009-09-01 3:24 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
will fix.
On Tue, Sep 1, 2009 at 1:10 PM, Russ Cox<rsc@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.ellis@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 ,
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-09-01 3:24 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-01 1:47 [9fans] 8c vlong bug erik quanstrom
2009-09-01 1:51 ` Bruce Ellis
2009-09-01 3:10 ` Russ Cox
2009-09-01 3:24 ` Bruce Ellis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).