Compile MicroPython with -mregparm=3

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
hua
Posts: 3
Joined: Sat Aug 01, 2015 7:38 am

Compile MicroPython with -mregparm=3

Post by hua » Sat Aug 01, 2015 7:50 am

Hello all,
I'm new to MicroPython and I have successfully ported MicroPython as a standalone binary image to a new embedded SoC platform (x86-based arch 32bit). It runs like a charm and I do not have any issues. Then I tried to combine MicroPython with U-Boot, where U-Boot code by default are all compiled with -mregparm=3, meaning at-most 3 parameters can be passed by CPU registers. This looks like causing issues where MicroPython always facing initialization problems. I also tried to add the "-mregparm=3" to the unix port and forcing 32 bit in mpconfigport.mk, the compilation is fine but the compiled image fails to start.

However the problem seems not exactly the same.

When compiling the unix port with -mregparm=3 it seems clear that it is due to the mismatch of ABI between libc and micropython:

Code: Select all

(gdb) run
Starting program: /home/hua/mp/micropython/unix/micropython 

Program received signal SIGSEGV, Segmentation fault.
0xf7e106f1 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) bt
#0  0xf7e106f1 in ?? () from /lib/i386-linux-gnu/libc.so.6
#1  0xf7dc740c in getenv () from /lib/i386-linux-gnu/libc.so.6
#2  0x08049f43 in ?? ()
#3  0xf7db172e in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6
#4  0x0804a5ab in ?? ()
(gdb) 
Whereas compiling with u-boot, the u-boot is not using libc, the MicroPython main loop can be reached but during the first exception it gives something like invalid opcodes errors.

Anyone having any in-depth knowledge of the MicroPython implementation and how could -mregparm=3 having the impact at run-time? I see the exception handling in MicroPython using something like none-local-return and could this having the assumption that all parameters are passing on stack?

Thanks in advance.
Hua

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: Compile MicroPython with -mregparm=3

Post by Damien » Sat Aug 01, 2015 8:16 am

There are a few bits of uPy which are written in assembler and for the x86 port will assume that all arguments are passed on the stack. So these will need to be modified. See nlrx86.s and gchelper.s.

You can try using nlr setjmp implementation instead of the native assembler version.

hua
Posts: 3
Joined: Sat Aug 01, 2015 7:38 am

Re: Compile MicroPython with -mregparm=3

Post by hua » Sat Aug 01, 2015 8:41 am

Damien wrote:There are a few bits of uPy which are written in assembler and for the x86 port will assume that all arguments are passed on the stack. So these will need to be modified. See nlrx86.s and gchelper.s.

You can try using nlr setjmp implementation instead of the native assembler version.
Thanks a lot Damien! I'm looking at nlrx86.S right now. using setjmp could be difficult as currently we do not link with standard gcc libs, and even the standard libc headers cannot be included for u-boot, also the ABI does not match ... can have a wrapper to work-around this though but linking with libc will give tons of conflicts as many functions are re-defined here and there ...

However looks like there is no gchelper.s implementation for x86/x64 architecture or it is not needed for x86/x64? I went through the code of gc_collect implementation on x86/x64 and it looks like it is using py/gc.c exclusively but not gchelper.s.

Best Regards,
Hua

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: Compile MicroPython with -mregparm=3

Post by Damien » Sat Aug 01, 2015 9:11 pm

Ah yes, you're right: there is no gchelper.s for x86. The unix port has this bit writting in inline assembler in gccollect.c.

But you'll definitely need to modify the code in py/nlrx86.S to use registers to pass arguments into the 2 function nlr_push and nlr_jump. It shouldn't be too difficult since they only take 1 argument.

hua
Posts: 3
Joined: Sat Aug 01, 2015 7:38 am

Re: Compile MicroPython with -mregparm=3

Post by hua » Mon Aug 03, 2015 11:38 am

Damien wrote:Ah yes, you're right: there is no gchelper.s for x86. The unix port has this bit writting in inline assembler in gccollect.c.

But you'll definitely need to modify the code in py/nlrx86.S to use registers to pass arguments into the 2 function nlr_push and nlr_jump. It shouldn't be too difficult since they only take 1 argument.
Exactly, after comment out one instruction for nlr_jump and add one instruction for nlr_push, everything works like a charm now.
Will try to make a patch and enable a new config parameter for regparm=3 case.

Thanks a lot for the prompt support!

Post Reply