<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:small">Hi Tobias,<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jun 21, 2021 at 4:20 AM Tobias Pape <<a href="mailto:Das.Linux@gmx.de">Das.Linux@gmx.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"> <br>
Hi<br>
<br>
<br>
> On 21. Jun 2021, at 12:15, Bruce O'Neel <<a href="mailto:bruce.oneel@pckswarms.ch" target="_blank">bruce.oneel@pckswarms.ch</a>> wrote:<br>
> <br>
> Hi,<br>
> <br>
> I have now gone back and checked this carefully.  The git repository at the commit before this one produces the right answer for 2 raisedTo: 64 on Aarch64.  It produces the wrong answer, 0, when this commit is included.<br>
> <br>
> So it's this commit.  I'll look at the code to see if I can see why the code is bad.<br>
> <br>
> BTW, how would one find the two referenced packages?<br>
<br>
<a href="https://source.squeak.org/VMMaker/" rel="noreferrer" target="_blank">https://source.squeak.org/VMMaker/</a> has all the packages. (or <a href="http://source.squeak.org/VMMaker.html" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker.html</a>)<br>
<br>
        The diff for the first one (<a href="https://source.squeak.org/VMMaker/VMMaker.oscog-eem.2799.diff" rel="noreferrer" target="_blank">https://source.squeak.org/VMMaker/VMMaker.oscog-eem.2799.diff</a>) ist truncated,<br>
        while the diff-changeset is ok: <a href="http://source.squeak.org/VMMaker/changes/VMMaker.oscog-eem.2799(2798).cs" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/changes/VMMaker.oscog-eem.2799(2798).cs</a><br>
        (you see all changed methods, but not the actual diff)<br>
<br>
But this only adds the JumpMulOverflow / JumpNoMulOverflow names/class-vars.<br>
<br>
The implementation diff is found at<br>
        <a href="http://www.squeaksource.com/ClosedVMMaker/ClosedVMMaker-eem.98.diff" rel="noreferrer" target="_blank">http://www.squeaksource.com/ClosedVMMaker/ClosedVMMaker-eem.98.diff</a><br>
<br>
I would suggest that our bug does not concern Jumps, but rather only Mul, so we have to start looking<br>
at the differences for concretizeMulOverflowRRR ...<br>
<br>
>From what I see, tho, is that the MUL and the SMULH instruction order has been reversed.<br></blockquote><div><br></div><div class="gmail_default" style="font-size:small">Indeed.  I created a regression.  Apologies for all this effort over my mistake.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
(Also, the arm blog uses an different interesting method of detecting overflow,<br>
by missusing the argument shitfter of CMP: <a href="https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/detecting-overflow-from-mul" rel="noreferrer" target="_blank">https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/detecting-overflow-from-mul</a><br>
Although this is written for older arm, it seems to be applicable to the 64-variant too)<br></blockquote><div><br></div><div class="gmail_default" style="font-size:small">So here's how I decided to do it on AArch64.  Maybe you can find something better.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">AArch64 implement 64 x 64 => 128 bit multiply by providing a 64x64 => low 64 bits and a 64x64 => high 64 bits multiply instruction.  So if a 64x64=>128 multiply has not overflowed the high 64 bits will be an extension of the sign bit of the 64x64=>low 64 instruction.  i.e. high 64 will either be all 0s or all 1s (all 1s = -1). So if one subtracts the sign bit from the high 64 result one gets 0 if there is no overflow.  Here's the instruction sequence:</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><div class="gmail_default"><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>smulh<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>x9/RISCTemp, x4/Class, x8/Arg1</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>mul<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>x4/Class, x4/Class, x8/Arg1</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>lsr<span class="gmail-Apple-tab-span" style="white-space:pre">           </span>x1, x4/Class, #63</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>adds<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>x9/RISCTemp, x9/RISCTemp, x1</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span><a href="http://b.ne">b.ne</a><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>0x44b8  // b.any = *@88 (to overflow)</div><div><br></div><div>In the JIT's assembler back end for ARMv8 this is done by two methods:</div><div><br></div></div></div><div class="gmail_default" style="font-size:small"><div class="gmail_default">concretizeMulOverflowRRR</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>"ARMv8 has no multiply overflow detection.  Instead it is synthesized from the two halves of</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span> a 64x64=>128 bit multiply. The upper 64-bits are tested.  The sequence is</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>high64 := SMULH a,b</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span>a/low64 := MUL a,b</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">             </span>signBit := low64/a >> 63</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>high64 := high64 + signBit</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span> If high64 is zero after this sequence then the multiply has not overflowed,</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span> since high64 is an extension of signBit if no overflow (either 0 or -1) and</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span> both -1 + 1 = 0 and 0 + 0 = 0. Note that because we restrict ourselves to</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span> three concrete ARMv8 instructions per abstract instruction the last operation</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span> of the sequence is generated in concretizeMulOverflowJump.</div><div class="gmail_default"><br></div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span> C6.2.196<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>MUL<span class="gmail-Apple-tab-span" style="white-space:pre">                           </span>C6-1111</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span> C6.2.242<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>SMULH<span class="gmail-Apple-tab-span" style="white-space:pre">                         </span>C6-1184</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span> C6.2.180<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>LSR (immediate)<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>C6-1081<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>110100110 (1)"</div><div class="gmail_default"><br></div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span><inline: true></div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>| reg1 reg2 reg3 |</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>reg1 := operands at: 0.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>reg2 := operands at: 1.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>reg3 := operands at: 2.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>"RISCTempReg := high(reg1 * reg2); must precede destructive MUL"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>machineCode</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span>at: 0</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>put: 2r1001101101 << 22</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                  </span>+ (reg1 << 16)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>+ (XZR << 10)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>+ (reg2 << 5)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>+ RISCTempReg.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>"reg3 := reg1 * reg2"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>machineCode</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span>at: 1</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>put: 2r10011011 << 24</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>+ (reg1 << 16)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>+ (XZR << 10)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>+ (reg2 << 5)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>+ reg3.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>"CArg1Reg := sign(reg3)"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>machineCode</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span>at: 2</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>put: 2r1101001101 << 22</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                  </span>+ (63 << 16) "constant to shift by"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>+ (63 << 10)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>+ (reg3 << 5)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>+ CArg1Reg. "cuz CArg0Reg == TempReg"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>"RISCTempReg := RISCTempReg + CArg1Reg/sign</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span> is in concretizeMulOverflowJump"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>"cogit processor disassembleInstructionAt: 0 In: machineCode object"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>"cogit processor disassembleInstructionAt: 4 In: machineCode object"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>"cogit processor disassembleInstructionAt: 8 In: machineCode object"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>^12</div><div class="gmail_default"><br></div><div class="gmail_default"><div class="gmail_default">concretizeMulOverflowJump</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>"Sizing/generating jumps.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>Jump targets can be to absolute addresses or other abstract instructions.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">              </span>Generating initial trampolines instructions may have no maxSize and be to absolute addresses.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>Otherwise instructions must have a machineCodeSize which must be kept to."</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span><inline: false></div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>| offset |</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>offset := self computeJumpTargetOffset - 4. "-4 because the jump is from the second word..."</div><div class="gmail_default"> <span class="gmail-Apple-tab-span" style="white-space:pre">       </span>self assert: (offset ~= 0 and: [self isInImmediateBranchRange: offset]).</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>"See concretizeMulOverflowRRR</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span> RISCTempReg := RISCTempReg + CArg1Reg/sign.</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span> JumpZero/NonZero"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>machineCode</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span>at: 0</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>put: 2r10001011 << 24</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>+ (ArithmeticAddS << 29)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                 </span>+ (CArg1Reg << 16)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                       </span>+ (RISCTempReg << 5)</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>+ RISCTempReg;</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>at: 1</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>put: (self</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                             </span>cond: (opcode = JumpMulOverflow ifTrue: [NE] ifFalse: [EQ])</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">                            </span>offset: offset). "B offset"</div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>^8</div><div class="gmail_default"><br></div></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Best regards<br>
        -Tobias<br>
<br>
<br>
<br>
> cheers<br>
> <br>
> bruce<br>
> <br>
> On 2021-06-20T22:44:36.000+02:00, Bruce O'Neel <<a href="mailto:bruce.oneel@pckswarms.ch" target="_blank">bruce.oneel@pckswarms.ch</a>> wrote:<br>
> Playing with Git bisect gets us to the commit below as the first bad one.<br>
> <br>
> I started the git bisect with the two commits below.  The first one is bad, the second is the good one.<br>
> <br>
> a783502b249c4a4fedc88b6e07837d405feab144 - zero9 - builds, zero error.<br>
> <br>
> 9f73148b8da4bc00278b83faa8da6b1c418fa54f - zero10 - builds works<br>
> <br>
> Now this is not 100% guaranteed because one of the commits that git bisect chose had a build error so I had to mark that one as bad.  But the commit found does sound possible.<br>
> <br>
> f632ee2888014ee88330ee994e13c9c609b57b5f is the first bad commit<br>
> commit f632ee2888014ee88330ee994e13c9c609b57b5f<br>
> Author: Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>><br>
> Date:   Wed Sep 2 10:45:27 2020 -0700<br>
> <br>
>     CogVM source as per VMMaker.oscog-eem.2799/ClosedVMMaker-eem.98<br>
>     <br>
>     Ha!  I am *STUPID*.<br>
>     Integer overflow is not only determined by the upper 64-bits of a 64x64=>128 bit<br>
>     multiply being either all zero or all ones (0 or -1), but by the upper 64-bits<br>
>     being an extension of the most significant bit of the lower 64 bits!!<br>
> <br>
> :040000 040000 ffb8fbcd8ab5e2ca1936429b2daaade62909c178 a5ac89d8b1d4980c5329835cdd3d4a2387b1fac5 M      nsspur64src<br>
> :040000 040000 e606dac14ee1db4ac59b0949bb03cd8e657d7aa7 be666051cd1d52d0055e319432b66a0fba61063e M      spur64src<br>
> :040000 040000 1dea4faf99821c60e2c2461076bfe8b99d4dea9b afbef904e8cbc7e4b80e1606420dd6293e12f3e9 M      spurlowcode64src<br>
> :040000 040000 f66c681004806d5880af7c0a3115038f4f2f3361 0e8d76bedcf22b6ad7497ea2e3dc44f3c36c2f3a M      spursista64src<br>
> <br>
> On 2021-06-20T21:48:49.000+02:00, Craig Latta <<a href="mailto:craig@blackpagedigital.com" target="_blank">craig@blackpagedigital.com</a>> wrote:<br>
> Hi Ken--<br>
> <br>
> I brought up a development environment on a Raspberry Pi 4.<br>
> <br>
> > Unfortunately, my attempt to build a VM simulator on aarch64 fails due<br>
> > to a divide by zero bug.<br>
> ><br>
> > Perhaps because<br>
> > 16r8000000000000000 printStringHex. ==> '0'<br>
> <br>
> update-eem-463.mcm has a postload action which turns on Sista, <br>
> which recompiles the system, which tries to recompile <br>
> FloatArrayTest>>testFloatArrayPluginPrimitiveAtPut, which exercises this <br>
> very bug during scanning, when trying to create the float 1e-127.<br>
> <br>
> For now I've rewritten testFloatArrayPluginPrimitiveAtPut and <br>
> testFloatArrayPluginPrimitiveAt on my system to do nothing. When <br>
> building GdbARMv8Plugin, there's some other kind of <br>
> header-include-ordering mayhem, similar to the problem with Linux <br>
> features.h when building the VM. (At least two levels of it, between <br>
> bfd.h and the aarch64 simulator's config.h, and config.h and other <br>
> system headers.) I expect no one has successfully built GdbARMv8Plugin <br>
> on anything but a M1 macOS machine so far.<br>
> <br>
> <br>
> -C<br>
<br>
<br>
<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div></div></div></div></div></div></div></div></div>