[Vm-dev] [ARM Compiler & Plugin] Design Decisions

Lars lars.wassermann at googlemail.com
Tue Oct 2 10:22:56 UTC 2012


Hello,
for documentation purposes, a list of design decisions and alternatives 
which might be implemented later.

In general, the plugin is as similar as possible to the original 
Bochsplugin. The C functions have the same interface. The Smalltalk 
GdbARMPlugin class is an exact copy of BochIA32Plugin, to generate the 
according calls to the handwritten C part.

We patched the ARMulator memory system, to enable bounds checking on 
memory and have direct addresses relative to the memory chunk supplied 
when calling. The code for that is in armulmem.c. For direct access, 
like i.a. ldm, stm, we patched GetWord and PutWord. For those, we have 
memory access boundaries of minimum address and size, or rather 
minimumWriteAddress and size in case of PutWord.
To enable the maxExecAddress, we need a trick using SWIs, because ARM 
prefetches 2 instruction after the one executed. Thus, we also patched 
ReLoadInstr, which is eventually called in all instruction fetch cases. 
Even if I added 8 to the execution bound, there is no stop check after 
fetching an instruction, thus prohibiting jumping out of the main 
emulation loop, without patching it.
So we instead return a custom software interrupt instruction when 
fetching illegal addresses. When executed, ARMul_OSHandleSWI is called, 
which is patched to stop emulation and give a proper error message(at 
the bottom of sqGdbARMPlugin.c).

For the conditional jumps, we use the condition codes as encoded in the 
first four bits of every ARM instruction. Those condition codes are 
available in ARMCompiler as class variables. They are set to the 
according  value in ARMCompiler class>>#initialize.

IA32 is a variable length instruction set, allowing to encode word 
constants within an instruction. ARM on the other hand is a fixed length 
instruction set, and thus we can not encode constant words in one 
instruction.
As a first (simple) version, word constants are included loading them 
byte by byte into the abstract register RISCTempReg (R10 at the moment). 
Therefore, all abstract opcodes which have word arguments are at least 
four ARM instructions long. Changing those word constants means usually 
changing the lowest 12bit of those four instructions. The generation is 
done in CogARMCompiler>>#at:moveCw:intoR:. We have to change the last 
12bit, because the ARM standard asks for minimal rotation values (higher 
4bit).

Once the ARMCompiler works, there is the idea of introducing constant 
tables after the final jump back in each method, allowing PC relative 
addressing for word constants, thus reducing the number of instructions 
but increasing random access. Implementing both methods also allows 
measuring the performance change.

Are there any questions?
Best, Lars


More information about the Vm-dev mailing list