[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