[fpc-devel] FPC and Windows Phone 8

Vsevolod Alekseyev sevaa at sprynet.com
Mon Mar 10 00:20:14 CET 2014

Following requests, let me tell how I made a chunk of Pascal code compile and work on Windows Phone 8, with help from FPC.

Here's my story. I have an algorithm library written in Delphi. No input/output, just operations in memory; all calls for I/O are factored away into a dedicated unit that I'm free to replace. I've already succeeded in running this code in iOS and Android using Free Pascal's built-in means. Interaction with the main body of my code, which is in C++, is accomplished via a bunch of "cdecl" functions on the Pascal side, and an object with cdecl callback function pointers, populated on the C++ side. Pascal code is compiled into a static library for iOS, dynamic library on Android. It all works.

Enter Windows Phone 8. In order to have a good debugging experience, you need to build the code both for Intel x86 (for the emulator), and for ARM (for devices). The flavor of ARM that WP8 uses is strictly Thumb-2, with hard floating point and hard-float calling convention (i. e. parameters in floating point registers). Also, on Intel, even the integer calling convention doesn't match between C and Pascal. Here's what I do. 

I compile my FPC sources to assembly for Win32/Intel (with -a option). I'm applying some search-replace fixes so that the generated assembly works with MASM. Then I copy the assembly into the WP8 project, where it's assembled and put into a static library.

Free Pascal code relies on its RTL. Even if you don't call library functions much (my library doesn't), there's string stuff, set stuff, some floating point routines like rounding. I've put together a replacement implementation in C for a limited subset of the FPC RTL. String/set functions are implemented faithfully, the rest just pass it along to the relevant C RTL functions. I've also built an assembly file for Intel that translates the calling conventions. For some FPC routines, it contains stubs - a trivial implementation that consists of a single RET statement.

As the starting point for the ARM build, I compile my Pascal for ARM/Android while specifying -CpARMV7A -CfVFPV3_D16; that approximates WP8's dialect of ARM the closest. Naturally, for this to work, I need a copy of the FPC cross-RTL built for the same configuration. I didn't know about the ARMHF target when I was first designing all this; I could've approximated the WP8 dialect even better with ARMHF. Windows Phone 8 uses hard-FP ABI. Maybe later.

Anyway, on the ARM side, things are more involved. For one thing, the generated assembly assumes the ARM mode while WP8 only takes Thumb. So I've put together a translation script in JavaScript that takes ARM assembly with GAS-style directives and makes it work as Thumb-2 with MASM-style directives. For most commands, there's no change; but sometimes, ARM and Thumb has different limits for immediate operands and such; in those cases, my translation script replaces a single command with a small sequence (instead of ldr rd,[rm,offset] with an overlarge offset - add/ldr combo, etc). Also, Microsoft ARMASM assumes the UAL syntax, while FPC generates pre-UAL mnemonics. Replacing those is a part of the translation. Finally, I had work around a bug in ARMASM.

There's also a separate RTL glue assembly file for ARM. It's not as big as the Intel one, since the integer calling conventions match. Among other things, it translates calling conventions for FP functions.

As you see, I've never meant to implement a whole application, or even a whole native layer in Pascal. It's just an algorithm library. Also, I'm heavily relying on the fact that RTL use is limited in the library. Reimplementing a large body of FPC RTL from scratch would be unimaginably hard.

More information about the fpc-devel mailing list