<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
I think I have this aspect dealt with now.<BR>
 <BR>
Convert.m3:<BR>
 <BR>
     -----LINE 129  -----<BR> load              tv.25[_nDigits] 0 Int.32 Int.32<BR> check_range       0 n:8,x:0,0,0,0,0,0,0,0 64 n:4,x:40,0,0,0,0,0,0,0 2<BR> 00000435: 8B5DFC              MOV EBX tv.25[_nDigits]<BR> 00000438: 83FB40              CMP EBX $64<BR> 0000043B: 7600                JBE rel8 L.68<BR> 0000043D: B822100000          MOV EAX $4130<BR> 00000442: E800000000          CALL L.0<BR> loophole          Int.32 Int.32<BR> load_address      tv.31[_result] 0<BR> 00000447: 8D75AE              LEA ESI tv.31[_result]<BR> swap              Int.32 Addr<BR> index_address     Int.32 1<BR> 0000044A: 03F3                ADD ESI EBX            ** result location in ESI *<BR> load              tv.35[_base] 0 Word.8 Int.32<BR> loophole          Int.32 Int.64<BR> 0000044C: 33D2                XOR EDX EDX<BR> 0000044E: 8A5514              MOV EDX tv.35[_base]:Word.8<BR> 00000451: 33FF                XOR EDI EDI<BR> load              tv.34[_value] 0 Int.64 Int.64<BR> swap              Int.64 Int.64<BR> mod               Int.64 X P<BR> call_64          m3_mod64 2<BR> import_procedure   m3_mod64 2 Int.64 "__stdcall" p.31[m3_mod64]<BR> declare_param     * 8 8 Word.64 0 F F 100 tv.201[T$201] 8<BR> declare_param     * 8 8 Word.64 0 F F 100 tv.202[T$202] 16<BR> start_call_direct   p.31[_m3_mod64@16] 0 Int.64<BR> load_stack_param   Word.64 1<BR> 00000453: 8B4D0C              MOV ECX tv.34[_value]<BR> 00000456: 8B4510              MOV EAX tv.34[_value]+4<BR> 00000459: 50                  PUSH EAX<BR> 0000045A: 51                  PUSH ECX<BR> load_stack_param   Word.64 0<BR> 0000045B: 57                  PUSH EDI<BR> 0000045C: 52                  PUSH EDX<BR> declare_temp      4 4 Addr F tv.203[T$203] -92<BR> 0000045D: 8975A4              MOV tv.203[T$203] ESI         ** ESI saved unnecessarily in temporary to satisfy us **<BR> call_direct       p.31[_m3_mod64@16] Int.64<BR> 00000460: FF1500000000        CALL p.31[_m3_mod64@16]<BR> loophole          Int.64 Int.32<BR> loophole          Int.32 Int.32<BR> load_address      gv.2[_MM_Convert] 52<BR> 00000466: 8D3534000000        LEA ESI gv.2[_MM_Convert]+52<BR> swap              Int.32 Addr<BR> index_address     Int.32 1<BR> 0000046C: 03F0                ADD ESI EAX<BR> load_indirect     0 Word.8 Int.32<BR> 0000046E: 33DB                XOR EBX EBX<BR> 00000470: 8A5E00              MOV EBX ESI^[0:Word.8]<BR> store_indirect    0 Int.32 Word.8<BR> 00000473: 8B75A4              MOV ESI tv.203[T$203]:Addr   ** ESI refetched from temporary **<BR> free_temp         tv.203[T$203]<BR> 00000476: 885E00              MOV ESI^[0:Word.8] EBX<BR>     -----LINE 130  -----<BR><BR>
 <BR>
Pretty wasteful.<BR>
Instead it should just compute the destination when it does the store.<BR>
 <BR>
 <BR>
 - Jay<BR><BR> <BR>
<HR id=stopSpelling>
From: jay.krell@cornell.edu<BR>To: hosking@cs.purdue.edu<BR>CC: m3devel@elegosoft.com<BR>Subject: RE: front end function about a "virtual stack"<BR>Date: Sun, 7 Feb 2010 06:49:11 +0000<BR><BR>
<STYLE>
.ExternalClass .ecxhmmessage P
{padding:0px;}
.ExternalClass body.ecxhmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
 > But, there have always been calls for mod/div<BR><BR>Not on NT386.<BR> <BR> - Jay<BR> <BR>
<HR id=ecxstopSpelling>
Subject: Re: front end function about a "virtual stack"<BR>From: hosking@cs.purdue.edu<BR>Date: Sat, 6 Feb 2010 13:07:23 -0500<BR>CC: m3devel@elegosoft.com<BR>To: jay.krell@cornell.edu<BR><BR>
<DIV>The front-end does do that for known calls.  But not for arithmetic ops.  You will need to cope in the backend.  But, there have always been calls for mod/div, so I think it really comes down to the back-end needing to do the right thing.<BR><BR>
<DIV>
<DIV>On 6 Feb 2010, at 07:29, Jay K wrote:</DIV><BR class=ecxecxApple-interchange-newline>
<BLOCKQUOTE><SPAN style="TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: medium Helvetica; WHITE-SPACE: normal; LETTER-SPACING: normal; WORD-SPACING: 0px" class=ecxecxApple-style-span>
<DIV style="FONT-FAMILY: Verdana; FONT-SIZE: 10pt" class=ecxecxhmmessage>Tony, can you confirm something?<BR>It's hard to explain.<BR> <BR><BR>The NT36 backend of course maintains<BR>a bunch of information as to which registers are in use.<BR><BR> <BR>For example, at the start of the function, it<BR>marks all registers as not in use.<BR>  (It always preserves all volatile registers I believe.<BR>  Obviously it could do better. It should only<BR>  mark non-volatile registers as in use, see<BR>  which registers it uses in the function, and<BR>  then only preserve/restore the nonvolatile ones<BR>  that it uses.)<BR><BR> <BR>As well when it generates a function call it<BR>marks them as all not in use too.<BR>But in that case, it checks itself.<BR>Again, it is a bit dumb -- nonvolatile registers<BR> would be ok to still be in use.<BR> <BR><BR>Now, all is ok.<BR>But then, I've introduced function calls where<BR>they weren't before -- multiply, divide, mod etc.<BR> <BR><BR>Upon generating the call to mod (for example),<BR>I get an assertion failure, because registers<BR>are still in use. In this case it is a nonvolatile<BR>register, but I think that's largely luck.<BR> <BR><BR>In particular I think the location that<BR>will be stored to after the mod is in a register.<BR>That is reasonable.<BR>You know..as a compiler, given:<BR> *(a + b) = f();<BR><BR> <BR>you might generate code to evaluate a + b first,<BR>put it in a (non volatile) register, then call f(),<BR>or you might call f() first.<BR> <BR><BR>A simpler approach is to call all the functions first,<BR>so you have more easy use of registers.<BR> <BR><BR>But then imagine<BR> *(a + b) = (c % d);<BR><BR> <BR>is there a function call in there or not?<BR>It depends.<BR><BR> <BR>So then my question is, like, when does the<BR>frontend assume a "stack based code generator"'s<BR>stack can/should/will be empty?<BR>Does it endeavor to make it so?<BR> <BR><BR>That is, is it very reasonable to for the NT386<BR>backend to assume its stack is empty when<BR>it calls a function, because the front end<BR>colludes to make it so, but then<BR>the front end doesn't do similar for things<BR>like multiply/divide?<BR> <BR><BR>I can deal with this pretty easily either way.<BR>Around function calls I introduce that weren't<BR>previously there I can save whatever volatile<BR>registers are in use.<BR> <BR><BR>But I'd like to understand.<BR> <BR><BR>Thanks,<BR> - Jay<BR></DIV></SPAN></BLOCKQUOTE></DIV><BR></DIV>                                      </body>
</html>