Skip to content
Archive of posts filed under the ARM category.

Compiling sources with different optimization flags with GCC

I had some strange problems with some GCC bugs with AntSnes and gpsp. For some reason some source files did not compile correctly with “-O2” optimization flags. A quick way to fix this problem was to compile the objects with problems without optimizations.

My quick “hacky” solution was to compile these few files with “-O0” flags into the asm-files from command line, and then include these asm-files from the mmp/makefile into the project.

Compiling the sources into asm-listings can be done like this:

 gcc -O0 -S -c foo.c

Of course you’ll get some problems from missing included etc, but that can be solved by adding all the include folders to the gcc with “-include” flag.

Memory Mapping solution for Dynamic Recompilation in Symbian OS

The gpsp was my first emulator port with dynamic recompilation. The problem in memory mapping and dynarec is  that local data in Symbian OS is too far away from the user area, where we the new memory chunk for the dynamic area was created. My first solution was the memory trampoline pattern.

However I got an optimal solution from Olli Hinkka. The solution is called dynamic text segment relocation routine. Basically the relocator is relocating the process into the user memory are in Symbian. With this approach no memory trampoline is required, since the static side is close enough to the dynamic side.

How to use it:

You’ll need Olli Hinkka’s relocator code. You can find it at least from gpsp github. relocutils.h relocator.cpp and relocator_glue.S

First you’ll have to relocate your process on the user area in the Symbian. The user local data area is between 0x04000000-0x38000000, see the Symbian OS memory map.I’m using 0x10000000 in this example.

#include "relocutils.h"

int main(int argc, char** argv)
// all code from the code section of this process is run in the specified address

// return to the original code section

Continue reading ‘Memory Mapping solution for Dynamic Recompilation in Symbian OS’ »

gpSP: Building A Memory Trampoline

Thanks to the original gpSP creator Exophase for tips. I was really confused with BL instructions and the fact that the memory address was pointing into wrong memory area. The problem was in Symbian OS memory mappings. It’s a very common problem with dynarec and Symbian. I had pr

In Symbian you can create memory partitions for dynamic recompilation with CreateLocalCode and IMB_Range deal, as I wrote few moths ago.  The problem is the way how Symbian OS maps the memory. The pointer to the dynamic code area is too far from the ‘static code’. The BL instruction has a limit of +-32MB. The memory memory is mapped in different way, so we can not use the BL instruction to get to the static code from the dynamic code.

BLX instruction would have longer range than BL, so that could be used. Using the BLX instruction would look like this.

ldr reg, =address
blx reg

The ldr instruction is actually meta-code and compiles into something like this:

mov reg,#0xYYY
orr reg,reg,#0xYY000
orr reg,reg,#0xYY00000
orr reg,reg,#0xY0000000
bx reg

However the way the calling code skips over the bl instruction by adding a shifted bit to the pc it is impossible to replace this call with the register load plus BLX instruction. The solution is to make stubs to the ‘dynamic’ memory area for each function call instead, and then call the stub with bl, and use bx from that stub to reach out to the final destination.

Continue reading ‘gpSP: Building A Memory Trampoline’ »

Using ARM Memory Barrier in Symbian OS

Today I have been digging the methods to  to make a gpSP( I think this is the best GBA emulator) port to Symbian OS.Thanks to the Exophase for developing this wonderful piece of software and for ZodTTD for the awesome ARM port! The gpSP is running “generated” ARM binary in the ARM processor’s memory, so the Memory Barrier has to be used. The next problem is to get the code running on the ARM under Symbian OS.

The ARM9 reference manual tells this about Memory Barrier.

Whenever code is treated as data, for example self-modifying code, or loading code into
memory, then a sequence of instructions called an Instruction Memory Barrier (IMB)
operation must be used to ensure consistency between the data and instruction streams
processed by the ARM926EJ-S processor.

Usually the instruction and data streams are considered to be completely independent
by the ARM926EJ-S processor memory system, and any changes in the data side are
not automatically reflected in the instruction side. For example if code is modified in
main memory then the ICache might contain stale entries. To remove these stale entries
part or all of the ICache must be invalidated.

In Symbian OS the Kernel should take care about ICache invalidation. The Symbian has User library for user side interaction with the Kernel. If we want to generate our own code and run it in specific memory are, we have to first tell to the kernel to threat this area as code. The code example for doing this is below.

RChunk codechunk;
TInt error = codechunk.CreateLocalCode(codechunk_size,codechunk_siz);
void* codechunk_ptr = codechunk.Base();

Now the codechunk is created. The ARM documentation told that ICache must be invalidated before executing the code. The Symbian should take care for invalidating the ICache, when IMB_Range is called.

void CLEAR_INSN_CACHE(void* code, int size)
User::IMB_Range( code, (void*)(code + size));

Porting the ARM9 optimized asm code to ARM11

This is just a short post about my modifications to the Snes9x assembly sources. You can find the sources at the 0.1 release post. Actually there was only one modification required, which I will share with you. It might help others to port fast assembly code to ARM11 processors.

ARM9 optimized source:

STMFD    R13!,{PC} @ Push return address
MOV    R1,#0
B    myASMFunc
B   arm9ReturnPoint

and the function return in myASMFuc with code

Continue reading ‘Porting the ARM9 optimized asm code to ARM11’ »