1

this is my first posting on Stack Overflow so I hope I am doing it correctly. ;-)

I am trying to develop a TriCore emulator but cannot decide on a strategy when to load operands for an instruction. The TriCore is maybe a rather obscure kind of microcontroller, so let me explain the architecture a bit.

There are two types of instructions, 16 bit and 32 bit. Whether it is a 16 bit or 32 bit one is determined by bit 0 in the last byte; as the byte order is little endian, it is always the first byte in memory. No problem there.

These two instruction types have several opcode formats, 14 for 16 bit and 25 for 32 bit instructions. Opcodes are divided into two separate opcode fields, although most of the 16 bit ones only have one opcode field. The first opcode field is in the lower 8 bits; it directly describes the instruction for 16 bit instructions and for many of the 32 bit instructions, it describes the operand encoding whereas the second field describes the actual instruction (but, of course there are exceptions).

My plan would be to always extract all opcode fields (which is a bit annoying as the position of the second field is not the same for all instruction formats) and put them together into a 16 bit value which would be used in a function pointer table.

Depending on this value, I would like to extract the operands. For example, when in a 32 bit instruction the first opcode is 0x8B, the operands are two data registers and one 9 bit constant. BUT, there are exceptions which are really tedious:

The ADD.A and ADDSC.A instruction both have opcode 1 == 0x01. But ADD.A uses three address registers whereas ADDSC.A uses two address registers, one data register and an index, encoded into the instruction.

My question in the end is: Is it feasible at all to load operands in an architecture like this before executing the instruction? Or would it be better to call the instruction function first and extract the operands there?

For anyone interested, the instruction set manual is here: http://www.infineon.com/dgdl/tc_v131_instructionset_v138.pdf?folderId=db3a304412b407950112b409b6cd0351&fileId=db3a304412b407950112b409b6dd0352

Thanks for any hint!

BTW: The language of choice would be C or C++.


(By request, I inserted my thoughts into my original question.)

Well, I thought extensively about the different options I have and I think I will settle with the following.

I will divide the whole process into two parts:

  1. Program analysis and operand extraction
  2. Execution

In the first step, each instruction is loaded and aligned to 32 bits. Then the loaded instruction is compared against a set of bit masks to determine the right opcode which tells me not only what has to be executed in the end but also how the operands are loaded. In address mode-specific functions, the operands are loaded into pointers; the instruction immediates are stored as necessary.

This boils down to a struct similar to this:

struct instruction_t {
    int32_t **operands;
    int32_t *immediates;
};

This will be basically allocated for each instruction (biggest drawback: memory consumption. I calculated around 40 bytes for such a struct as worst case (with 64 bit pointers) which means that a program which is normally 4 megabytes consisting of only 16 bit instructions would take up around 80 megabytes of memory in the end. On the other hand I think that execution speed could be reasonably fast).

With this approach, I am then able to implement each instruction just once as it does not matter how my operands are loaded - plus that executing the same instruction with the same set of operands would behave like on the real machine. Execution of the code would only mean to load the right set of operands by selecting the right struct and calling the instruction function accordingly.

I know that there are other approaches - I especially like dynamic recompilation. But then this system is rather complex with different on-chip components and I/O mapped registers which would add a significant amount of boilerplate code anyway.

I would really appreciate some comments on my approach. Maybe you know a better way to do it?

Thank you!

1 Answers1

-1

(Moved my approach into the original question.)

  • This is better off as an edit to your original question, rather than an answer in its own right. –  Jun 15 '12 at 08:31