ARM VFP: Part 1 - GCC Inline Assembler

28
Jan/09
2

So you’ve gotten your feet wet developing for the iPhone, learned XCode if you didn’t already know it, and now you’re looking for a way to speed up your matrix and vector operations so you can write some wicked OpenGL ES apps.  Luckily, the iPhone and iPod Touch have a Vector Floating-point (VFP) co-processor, which allows you to perform multiple (up to 8) simultaneous floating point operations with one instruction.

Chances are however, that you already knew that, why else would you be reading a blog post about the ARM VFP? So, I might as well get to the point eh?

GCC Inline Assembly

As you, more than likely, know GCC is the compiler used by XCode when developing for the iPhone. As such, it is GCC’s syntax we must abide by in order to combine the powers of either Objective-C or C++, with the assembly we’ll need to utilize the VFP co-processor.

Telling GCC that we’d like to provide some assembly to be mixed in with our C/C++ code is pretty straight forward. Utilizing the asm statement we can provide GCC with a string representing all of the instructions that we’d like to inject into the compiler’s output. So, we might do something like:

asm volatile("bkpt 0x0001\n\t");

Well, we probably wouldn’t, but that’s a quick and easy example. Notice the “\n\t” at the end of the instruction. Since GCC is going to output our asm right into the asm that it is already generating when it compiles our C/C++ code, we need the asm instruction to play nice with the surrounding assembly. So, we clear the end of line, and tab in to put it inline with the other instructions. Keep that in mind if you ever see an error such as:

garbage following instruction — `mov r0, r1mov r2, r1′

The other thing to notice, is the keyword volatile, which tells GCC to leave your asm block right where it is, and don’t attempt any optimizations.

In other compilers that I’ve used, inline assembly is treated by the compiler as a “You’re on your own” block of code, requiring you to sanitize all of the registers so you don’t accidently step on the compiler’s toes.  GCC however, has what is called “extended inline assembly” which allows you to tell GCC what registers you’re going to use, and even provide GCC with enough information that it can choose registers for you and incorporate your assembly into it’s optimizations.

For example, if I wanted to write a quick assembly routine to add two integer values using ARM assembly I might do something like this:

inline int add2f(int a, int b) {
   int ret = 0;
   asm volatile (
      "add  %0, %1, %2     \n\t"
      : "=r"(ret)       // Output registers
      : "r"(a), "r"(b)  // Input registers
      : "r0", "r1"      // Clobber List
   );
   return ret;
}

As you can see from the above code, there are 3 trailing statements after the actual assembly instruction template. These trailing statements (labeled: Output registers, Input registers, and clobber list) are what tell the compiler your intentions for register usage.

The output registers section allows us to tell GCC what our requirements are for using registers to bring values from the assembly, back into our C/C++ code.  In the above example I’m telling GCC that I need one register, and the value in the register needs to be accessible from the local variable ret after the assembly block is done.  You’ll notice, the syntax — “=r”(ret) — the “=” tells GCC that the register is going to be written to.  The “r” tells GCC that we need a general purpose register.  There are a few different options that can be used here, such as “f” for a floating point register, but for our purposes the majority of the time “r” is all we need.

Likewise, the input section allows us to tell GCC what our register requirements are for bringing values from our C/C++ code into the assembly block.  So in the above example again, I’m telling GCC that I need two registers, one to hold the value of “a“, and the other for “b“, both being general registers.

These input and output statements are known as constraints, and when you define them it allows GCC to provide you with registers that won’t interfere with what GCC is doing with the rest of your code.  As such, you’ll need a method for GCC to tell you what registers it has chosen, and this is done via the assembly template.

The assembly template is the actual assembly code string that precedes the constraint statements. You’ll notice in the above example I have the statement, mov r0, %1 \n\t The %1 signifies the second requested register in the constraint list. So, using the above example, %0 represents the output register, %1 represents ‘a’, and %2 represents ‘b’.

Finally, after the input/output constraint lists, is what is known as the clobber list.  This is a list of registers that your assembly simply, clobbers, without worrying about GCC’s usage for them.  By telling GCC that you plan to destroy the values in these registers, GCC can make preparations for saving them, or simply not using their values after your assembly block.

Along with registers if your assembly also changes values in memory you can specify “memory” in the clobber list, so that GCC knows to re-fetch any values from memory before proceeding.


That is GCC’s extended inline assembly in a nutshell.  The next part of this series will begin working with the ARM VFP co-processor. Feel free to provide any feedback via comments or twitter (nirosys), this was a pretty basic intro so I may not have gone into enough detail with some things.

Tagged as: , , ,

iPhone: Accessing the Simulator’s File System

15
Dec/08
2

Anyone working with the iPhone SDK has probably used the iPhone Simulator. While generally it is pretty speedy when pushing new applications to it, or making minor changes to code, and re-pushing your application for testing, there are some times that you may wish to update something non-code related. Like a simple text file, that your application might read occasionally.

Something like this might not even require an app restart. Such as modifying a database table that is re-read every time a certain screen is accessed.

For tasks like this, it may be easier to just modify the file in question on the simulator’s “File system” for real-time changes.  Luckily, such things are possible.

When you run the simulator, it creates a directory under your home directory located at:

~/Library/Application Support/iPhone Simulator/

When you install an application onto the simulator, it creates a sandbox for the application in a path that looks something like this:

~/Library/Application Support/iPhone Simulator/user/Applications/<GUID>

Where <GUID> is a directory with the name being a GUID assigned to the application during the installation process.  The GUID isn’t particularly necessary to find for you application, and the path to your application’s sandbox can be found with a quick display of command-line foo. From the ~/Library/Application Support/iPhone Simulator/User/Applications/ directory, run:

neuron:Applications glitch$ find ./ -name “SQLiteBooks.app”
.//9A08D2DD-58CE-4878-9D75-BE4F0B5E511D/SQLiteBooks.app

And, voila. The returned path is the path is the path to the application’s bundle, and while you can access the “private” data for your app inside that directory generally you’ll want to go to the Documents directory inside the GUID directory.  So, if we go to:
neuron:Applications glitch$ cd 9A08D2DD-58CE-4878-9D75-BE4F0B5E511D/Documents/
neuron:Documents glitch$ ls
bookdb.sql
neuron:Documents glitch$ 

A well behaved app will copy any data that it will be modifying into the Documents directory so that it can be modified without invalidating the application’s digital signature by writing to a file in the bundle’s directory. So, from here we can freely modify any data that your app will modify and test the changes either while the app is running, or with a quick restart from the iPhone Simulator.

Another use for accessing the files directly, is to test user supplied data for tracking down bugs. Or, in the case of the SQLiteBooks demo, copying a new database that contains many many books, to test performance. Having access to the files directly, lets you swap out new files easily, without having to play around with your XCode project.

Filed under: iPhone

Obligatory “starting over” post.

11
Nov/08
0

I tend to do this with my blog every so often (once a year it seems).  This time was not exactly due to me falling out of interest with it, and then attempting to rekindle that interest.  Instead, this “do over” was triggered by me wanting to use WordPress, and being too disinterested in my old posts to bring them over to this new WordPress install.

I’ve been a b2evolution user since the early beginnings, and am now starting to lean towards WordPress after using it in another site I’m getting ready to unleash onto the world.

So my apologies to the 2 or 3 people out there who subscribed to my RSS feed. ;) It won’t happen again.

Filed under: Uncategorized