LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer
User Name
Password
Linux - Embedded & Single-board computer This forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.

Notices


Reply
  Search this Thread
Old 04-04-2017, 07:59 AM   #1
MarkoSan
Member
 
Registered: Jun 2006
Location: Ljubljana
Distribution: KUbuntu
Posts: 61

Rep: Reputation: 1
MONO on PowerPC (e500v2) from NXP failing to convert double to long


Dear Sirs and Madams!

Me and my college are trying to resolve following MONO problem:
We managed to cross compile mono using gcc (ELDK-5) and a lot of mono works but there are some obvious issue. There is a problem when converting from double to long for example and I see that the .NET execution gets stuck at the end and the process just hangs rather than completes execution. Since that could easily be related to the fundamental type conversion issues we have addressed that issue first.

The e500v2 is an interesting CPU. It is a dual core 32bit CPU when it comes to addressing but it actually has 64bit registers. And with the SPU (Signal Processing Unit) it even offers floating point instructions. I see that for the PPC platform a decision has been made to use GCC compiled functions in jit-icall.c (ex: mono_fconv_i8) to perform type conversions. I suppose not a bad choice considering the many variations in the PPC CPU feature availability.

However when the mono_fconv_i8 gets called we see that the function parameter v has an incorrect value. Here is the latest git version of the function:
https://image.ibb.co/jAie0a/image001.png
I have extended the function a little bit initially when trying to isolate the issue:
https://image.ibb.co/gBTCLa/image002.png
And what we see from this is that when I try to convert a constant directly in C, the conversion works perfectly. And that the problem is that the parameter v has an incorrect value.

The function will print the following:
mono_fconv_i8: convert v: 0, lval: 0
v: 0, lval: 0, giVal: 0
v: 200, lval: 200
v: 200, lval: 200, giVal: 200

This way we can tell that the GCC generated code works perfectly, but that the bytecode generated by mono JIT has a problem somewhere.

At this point it was clear that a debugger would be useful and that printf alone will not give enough information on the issue.

To make things clearer here is the C# code that I have compiled for MSIL using Visual Studio 2015. The code was designed to test and provoke the issue.
https://image.ibb.co/bxeK0a/image003.png
Interestingly enough the long to double conversion works and the call to the mono_lconv_to_r8 function returns the correct value. But double to long will tend to return 0.

With a lot of digging I also found the get_call_info function (mini-ppc.c:1060) that seems to be responsible to calculate the method in which the icall will be performed.

The long to double is handled like this:
https://preview.ibb.co/gUD1Dv/image004.png
and the add_general function will attempt to pass the parameter to the mono_lconv_to_r8 using GPR (General Purpose Registers) while the mono_fconv_i8 will get called with the value in the "floating point" registers. On e500v2 there are no special FPRs (Floating Point Registers) and instead GPRs are used to perform floating point operations. So not knowing how precisely FPRs would be interpreted later in the actually function call emit code I initially tried and updated the PPC_LAST_FPARG_REG to 0 to force the parameters to be passed through stack.
https://preview.ibb.co/mXX6fa/image005.png
To see how the code works I have instrumented it a little with printf calls and this is the current variation:
https://preview.ibb.co/iVfsLa/image006.png
With GDB I can see the following:
https://preview.ibb.co/n0Kmfa/image007.png
At the point where the evstdd (Vector Store Double of Double) instruction reaches out for the double value, it is using an incorrect offset of 40. Memory examination seems to indicate that the correct value (of 30.0f) is 16 bytes higher up. What I am not sure is why the value repeats another 24 bytes later but several explanations come to mind.

The code continues to convert the wrong value:
https://image.ibb.co/mP3q6F/image008.png
evmergelo (Vector Merge Low) and efdctsiz (Convert Floating-Point to Signed Integer with Round toward Zero) get executed and r31 ends up containing a value of no relevance.

This summarizes my findings so far.

What I am planning to do next is play with PPC_STACK_PARAM_OFFSET... And maybe try and pass the parameter in the GPR as a double value and some other reverse engineering attempts that show how GCC passes values to another function that essentially does the same thing as mono_lconv_to_r8. This would allow me to examine the way GCC expects the stack to be formed.

I have also attempted to correct the size of the registers define SIZEOF_REGISTER to 8 (since the registers are after all 64 bit registers) but this would require me to implement about 60 IL instructions related to handling 64 bit values. Solving this issue will likely take more time than fixing a 32 bit implementation of mono.

So my question is if you can recommend a way forward or perhaps advise on how to best solve the issue in the shortest time possible.

Last edited by MarkoSan; 04-04-2017 at 08:14 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
sox convert a-law mono 8000hz wav to pcm signed 16bit mono wav saiyen2002 Linux - Software 2 02-23-2012 08:02 PM
How to convert stereo flv video to mono? Mr. Alex Linux - Software 7 03-21-2011 02:02 PM
C double to unsigned long long Conversion with mingw32 random0 Programming 1 12-15-2010 09:53 AM
convert string to long long vbx_wx Programming 4 07-02-2010 09:45 AM
[SOLVED] What program can I use to convert stereo MP3 to mono? Mr. Alex Linux - Software 1 06-01-2010 04:48 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer

All times are GMT -5. The time now is 10:25 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration