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.


_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to