[Mono-dev] mono on PPC - casting issue

Taloth Saldono talothsaldono at gmail.com
Tue Oct 11 21:20:23 UTC 2016

Based on the generated machine code, you can see what path
emit_float_to_int takes:
sreg = f1
dreg = r29
ppc_f0 = f0
offset = 32
sub_offset = 4
cfg->frame_reg = r1 (stack register)

ppc_fctiwz (code, ppc_f0, sreg);
ppc_stfd (code, ppc_f0, offset, cfg->frame_reg);
ppc_lwz (code, dreg, offset + sub_offset, cfg->frame_reg);

I'm not sure where the ppc_clrldi (code, dreg, dreg, 32); went.

It could go wrong at any of those locations, just look up those
instructions in the datasheet to see if they're supported. You can also
step through the assembly, see what happens with each of those registers
during execution.

P1020 has e500v2 cores. 32-bit processors with 64-bit floating point units.
Google e500 instruction set
- https://cache.freescale.com/files/32bit/doc/ref_manual/E500CORERM.pdf
Particularly chapters 3.1.3, 3.1.4. TL;DR: "Book E Floating-Point
instructions are unsupported."
Table 3-2 lists 32-bit instructions that are NOT implemented in the e500:
- Floating Convert To Integer Word [and round to Zero] [and record CR]

So, that's the one, fctiwz isn't supported. Now go figure out how to do the
same function and try it out. At first glance I'd look at chapter 3.2, -> efdcfui & efdctsi.
Also, check codegen & mini-ppc for any other instruction in table 3-2.

Finally, I have no friggin idea how mono usually auto-detects (in the
mini-ppc.c) what cpu you have and thus what option to take. But there may
be similar cases that do some detection logic once and store a flag.

On a sidenote, totally unrelated to your issue, but wtf is this code doing:
"ppc_is_imm16(ppc_is_imm16(..))" that's pretty pointless code from what I
can glance. Been there since 2004, but probably a typo... well w/e.

On Tue, Oct 11, 2016 at 10:46 PM, M Jam <mjam.mono at gmail.com> wrote:

> I did all this with mono-sgen -v -v hello.exe
> disassmble of ppc
> http://pastebin.com/tzwF7pvz
> disassmble of Intel
> http://pastebin.com/vwnpp3Cq
> Looks like the real PPC instruction that is being used to convert from
> float to int is 'fctiwz'.
> I see only one occurrence of 'fctiwz'.
> Is there a way to  do inline disassembly like 'objdump -S'?
> On intel disassembly, I see reference to cvttsd2si twice which is a good
> thing.
> Thanks,
> Mukund J
> On Tue, Oct 11, 2016 at 12:40 PM, M Jam <mjam.mono at gmail.com> wrote:
>> Thanks for your responses.
>> I have to learn PPC instruction set now.
>> code
>> http://pastebin.com/wRgB1JuU
>> Intel MIR Code:
>> http://pastebin.com/bcbbe9mk
>> PPC MIR Code:
>> http://pastebin.com/gNnrtAtk
>> Please notice Line 53 of 'PPC MIR Code' is different from Line 26 of
>> 'Intel MIR Code'.
>> Looks like in mono, the jit flow is this: IL -> IR -> machine code.
>> emit_float_to_int -> is called when the JIT does IR -> machine code.
>> Right?
>> If so, is there a know good practice to pause execution @ this level?
>> As per the documentation, I see a lot of other places this can happen
>>  -  marshalling, call conventions, trampoline.
>> Any thought on these areas being suspects.
>> M Jam
>> On Mon, Oct 10, 2016 at 2:17 PM, Taloth Saldono <talothsaldono at gmail.com>
>> wrote:
>>> Hey M Jam,
>>> I'm an app developer and our users tend to try run our software on any
>>> device imaginable. (Yes, ppl asked if they could run it on Nvidia Shield...
>>> 3 days after it came out)
>>> We first ran into the issue when some users over at synocommunity tried
>>> to port the app to synology devices based on QorIQ. It was crashing
>>> constantly (iirc, time and date calculations were messed up). After some
>>> dummy test apps (with inexplicable results) I finally had the user run
>>> those regression tests and, voila, a lightbulb went on.
>>> However, I never fixed actually it. I neither had access to a device,
>>> time nor the inclination to dive into a mono port for that platform. I
>>> basically dumped a message about it in the synocommunity thread explaining
>>> the issue, and emphasized that any dev attempting to fix it would need a
>>> little bit of know-how and a couple of weekends.
>>> As for the cpu datasheet, basically yes, to find out which instructions
>>> can be used for the cast. So you can lookup the exact instructions that
>>> `emit_float_to_int` generates and see if they're valid. Possibly you can
>>> come up with an alternative set of instructions that succeeds on your
>>> device.
>>> Based on what you said, you should check the unsigned instructions in
>>> the datasheet against the `emit_float_to_int` method, you can see it uses
>>> CLRLDI/RLDICL for unsigned and EXTSW for signed.
>>> If CLRLDI/RLDICL isn't valid for your CPU, then OP_ZEXT_I4 likely gets
>>> processed incorrectly as well.
>>> Just an educated guess, I haven't actually checked what the rldicl and
>>> extsw instructions do exactly. You'll have to start pulling that thread and
>>> see where it leads.
>>> Lemme know how it goes. (btw. Welcome down the rabbit hole)
>>> Taloth
>>> On Mon, Oct 10, 2016 at 10:32 PM, M Jam <mjam.mono at gmail.com> wrote:
>>>> Hi Taloth,
>>>> Sorry, I have overlooked this message by mistake. Thanks for your
>>>> response.
>>>> The is the exact issue we have. We don't have this issue for real PPC
>>>> 64 QorIQ processors i.e. T1040
>>>> But we have this issue on P1020 processors which is 32-bit processors.
>>>> I did the regression tests and this is what they look like.
>>>> http://pastebin.com/5RjxxDdY
>>>> When you ran into this issue, how did you work around? Did you end up
>>>> finding a fix?
>>>> I did try and put a break point at  OP_FCONV_TO_I4 in mini-ppc.c and
>>>> it was never getting hit. It could as well be my GDB. not sure.
>>>> I am new to mono project. The documentations is wild and big for me to
>>>> go though. Even then I tried and I am little clueless on
>>>> how this whole things is tied together. So, not sure how to debug this.
>>>> Anyways, I see 2 cases being handled.
>>>> Thought I am not sure if this is real code that's
>>>> A type case of unit does NOT work while typecast of int works fine.
>>>> The switch case
>>>>                 case OP_FCONV_TO_I4:
>>>>  <<<<< this is one that's fine.
>>>>                 case OP_FCONV_TO_I:
>>>>                         code = emit_float_to_int (cfg, code, ins->dreg,
>>>> ins->sreg1, 4, TRUE);
>>>>                         break;
>>>>                 case OP_FCONV_TO_U4:
>>>>  <<<<<< this is the one that fails
>>>>                 case OP_FCONV_TO_U:
>>>>                         code = emit_float_to_int (cfg, code, ins->dreg,
>>>> ins->sreg1, 4, FALSE);
>>>> > But I recommend you get those regression tests compiled first, and
>>>> then lookup your CPU datasheet to find out what instruction set it supports.
>>>> You mean, what instruction set it supported to convert from FLOAT to
>>>> UNIT?
>>>> Thanks,
>>>> M Jam
>>>> On Fri, Sep 16, 2016 at 3:21 PM, Taloth Saldono <
>>>> talothsaldono at gmail.com> wrote:
>>>>> Hey M Jam,
>>>>> I'm not involved in PPC or mono development at all, but I've seen a
>>>>> similar case over 2 years ago, that was on a Qoriq-based Synology NAS. For
>>>>> that device it was that the mono jitter emitted powerpc extended 64-bit
>>>>> instructions which were unsupported by that specific CPU. But of course I
>>>>> don't know if it's related to your issue, also, there have been changes to
>>>>> the ppc jitter since then.
>>>>> Running the mono basic regression tests was particularly telling, you
>>>>> could see all the specific cases going wrong. (
>>>>> https://github.com/mono/mono/blob/mono-3.10.0-branch/mono/m
>>>>> ini/Makefile.am.in#L438-L458)
>>>>> The Jitter for PPC is here: https://github.com/mono/
>>>>> mono/blob/mono-3.10.0-branch/mono/mini/mini-ppc.c
>>>>> search for OP_FCONV_TO_I4.
>>>>> But I recommend you get those regression tests compiled first, and
>>>>> then lookup your CPU datasheet to find out what instruction set it supports.
>>>>> Cheers,
>>>>> Taloth
>>>>> On Fri, Sep 16, 2016 at 11:45 PM, M Jam <mjam.mono at gmail.com> wrote:
>>>>>> Hi all,
>>>>>> I am trying to get mono working on ppc.
>>>>>> Apparently, on one else is using it. even debian.
>>>>>> I did a lot of debugging and finally at a point where I know the
>>>>>> problem is in mono runtime.
>>>>>> The even generated the CIL code on both x86 and ppc and compared
>>>>>> them. They are exactly identical.
>>>>>> problem area is as simple as this:
>>>>>> int x = (int) 2.0
>>>>>> If I print x, I get 0.
>>>>>> other broken things: Also math.ceiling() is broken and may be more
>>>>>> are broken.
>>>>>> At this point, I am not sure what is the best route to debug other
>>>>>> than disassembling the code for which I need some preparation as I don't
>>>>>> has 'as' and 'ld' on my ppc platform.
>>>>>> I need to build them.
>>>>>> In the mean time, if anyone has an advice on debugging this issue, I
>>>>>> highly appreciate it.
>>>>>> Also, lastly CIL code between a cast of int and uint is
>>>>>> <       IL_0015:  conv.i4
>>>>>> ---
>>>>>> >       IL_0015:  conv.u4
>>>>>> Where is it in the JIT this code gets handled.
>>>>>> Thanks,
>>>>>> M Jam
>>>>>> _______________________________________________
>>>>>> Mono-devel-list mailing list
>>>>>> Mono-devel-list at lists.dot.net
>>>>>> http://lists.dot.net/mailman/listinfo/mono-devel-list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dot.net/pipermail/mono-devel-list/attachments/20161011/1f8532e1/attachment.html>

More information about the Mono-devel-list mailing list