From mboxrd@z Thu Jan 1 00:00:00 1970 MIME-Version: 1.0 In-Reply-To: <775b8d190908311851t701d860av587b7433bea29fcf@mail.gmail.com> References: <10afea42a3af8daf8abd3b8e8775850e@quanstro.net> <775b8d190908311851t701d860av587b7433bea29fcf@mail.gmail.com> Date: Mon, 31 Aug 2009 20:10:05 -0700 Message-ID: Subject: Re: [9fans] 8c vlong bug From: Russ Cox To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Topicbox-Message-UUID: 5dc16e6c-ead5-11e9-9d60-3106f5b1d025 > 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 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 ,