Start filling in THUMB table with insane preprocessor tricks
Jeffrey Pfau jeffrey@endrift.com
Tue, 09 Apr 2013 02:57:24 -0700
4 files changed,
101 insertions(+),
24 deletions(-)
M
src/isa-arm.c
→
src/isa-arm.c
@@ -126,8 +126,6 @@
// Instruction definitions // Beware pre-processor antics -#define UNUSED(V) (void)(V) - #define ARM_WRITE_PC \ cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM@@ -457,26 +455,6 @@
#define DECLARE_INSTRUCTION_ARM(EMITTER, NAME) \ EMITTER ## NAME -#define DO_8(DIRECTIVE) \ - DIRECTIVE, \ - DIRECTIVE, \ - DIRECTIVE, \ - DIRECTIVE, \ - DIRECTIVE, \ - DIRECTIVE, \ - DIRECTIVE, \ - DIRECTIVE - -#define DO_256(DIRECTIVE) \ - DO_8(DO_8(DIRECTIVE)), \ - DO_8(DO_8(DIRECTIVE)), \ - DO_8(DO_8(DIRECTIVE)), \ - DO_8(DO_8(DIRECTIVE)) - -#define DO_INTERLACE(LEFT, RIGHT) \ - LEFT, \ - RIGHT - #define DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ALU) \ DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I)), \ DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I))@@ -533,7 +511,7 @@
#define DECLARE_ARM_SWI_BLOCK(EMITTER) \ DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI)) -#define DECLARE_EMITTER_BLOCK(EMITTER) \ +#define DECLARE_ARM_EMITTER_BLOCK(EMITTER) \ DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL), \ DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH), \ DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, ILL, ILL, ILL), \@@ -747,5 +725,5 @@ DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR), \
DECLARE_ARM_SWI_BLOCK(EMITTER) static const ARMInstruction _armTable[0x1000] = { - DECLARE_EMITTER_BLOCK(_ARMInstruction) + DECLARE_ARM_EMITTER_BLOCK(_ARMInstruction) };
M
src/isa-inlines.h
→
src/isa-inlines.h
@@ -1,6 +1,28 @@
#ifndef ISA_INLINES_H #define ISA_INLINES_H +#define UNUSED(V) (void)(V) + +#define DO_8(DIRECTIVE) \ + DIRECTIVE, \ + DIRECTIVE, \ + DIRECTIVE, \ + DIRECTIVE, \ + DIRECTIVE, \ + DIRECTIVE, \ + DIRECTIVE, \ + DIRECTIVE + +#define DO_256(DIRECTIVE) \ + DO_8(DO_8(DIRECTIVE)), \ + DO_8(DO_8(DIRECTIVE)), \ + DO_8(DO_8(DIRECTIVE)), \ + DO_8(DO_8(DIRECTIVE)) + +#define DO_INTERLACE(LEFT, RIGHT) \ + LEFT, \ + RIGHT + #define ARM_COND_EQ (cpu->cpsr.z) #define ARM_COND_NE (!cpu->cpsr.z) #define ARM_COND_CS (cpu->cpsr.c)
A
src/isa-thumb.c
@@ -0,0 +1,66 @@
+#include "isa-thumb.h" + +static const ThumbInstruction _thumbTable[0x400]; + +// Instruction definitions + +#define APPLY(F, ...) F(__VA_ARGS__) +#define DUMMY(...) __VA_ARGS__ + +#define COUNT_1(EMITTER, PREFIX, ...) \ + EMITTER(PREFIX ## 0, __VA_ARGS__) \ + EMITTER(PREFIX ## 1, __VA_ARGS__) + +#define COUNT_2(EMITTER, PREFIX, ...) \ + COUNT_1(EMITTER, PREFIX, __VA_ARGS__) \ + EMITTER(PREFIX ## 2, __VA_ARGS__) \ + EMITTER(PREFIX ## 3, __VA_ARGS__) + +#define COUNT_3(EMITTER, PREFIX, ...) \ + COUNT_2(EMITTER, PREFIX, __VA_ARGS__) \ + EMITTER(PREFIX ## 4, __VA_ARGS__) \ + EMITTER(PREFIX ## 5, __VA_ARGS__) \ + EMITTER(PREFIX ## 6, __VA_ARGS__) \ + EMITTER(PREFIX ## 7, __VA_ARGS__) + +#define COUNT_4(EMITTER, PREFIX, ...) \ + COUNT_3(EMITTER, PREFIX, __VA_ARGS__) \ + EMITTER(PREFIX ## 8, __VA_ARGS__) \ + EMITTER(PREFIX ## 9, __VA_ARGS__) \ + EMITTER(PREFIX ## A, __VA_ARGS__) \ + EMITTER(PREFIX ## B, __VA_ARGS__) \ + EMITTER(PREFIX ## C, __VA_ARGS__) \ + EMITTER(PREFIX ## D, __VA_ARGS__) \ + EMITTER(PREFIX ## E, __VA_ARGS__) \ + EMITTER(PREFIX ## F, __VA_ARGS__) + +#define COUNT_5(EMITTER, PREFIX, ...) \ + COUNT_4(EMITTER, PREFIX ## 0, __VA_ARGS__) \ + COUNT_4(EMITTER, PREFIX ## 1, __VA_ARGS__) + +#define THUMB_WRITE_PC \ + cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB) + WORD_SIZE_THUMB + +#define DEFINE_INSTRUCTION_THUMB(NAME, BODY) \ + static void _ThumbInstruction ## NAME (struct ARMCore* cpu, uint16_t opcode) { \ + BODY; \ + } + +#define DEFINE_SHIFT_INSTRUCTION_THUMB(NAME, BODY) \ + COUNT_5(DEFINE_INSTRUCTION_THUMB, NAME ## _, BODY) + +DEFINE_SHIFT_INSTRUCTION_THUMB(LSL, ) +DEFINE_SHIFT_INSTRUCTION_THUMB(LSR, ) +DEFINE_SHIFT_INSTRUCTION_THUMB(ASR, ) + +#define DECLARE_INSTRUCTION_THUMB(EMITTER, NAME) \ + EMITTER ## NAME + +#define DECLARE_THUMB_EMITTER_BLOCK(EMITTER) \ + APPLY(COUNT_5, DUMMY, DECLARE_INSTRUCTION_THUMB(EMITTER, LSL_)) \ + APPLY(COUNT_5, DUMMY, DECLARE_INSTRUCTION_THUMB(EMITTER, LSR_)) \ + APPLY(COUNT_5, DUMMY, DECLARE_INSTRUCTION_THUMB(EMITTER, ASR_)) \ + +static const ThumbInstruction _thumbTable[0x400] = { + DECLARE_THUMB_EMITTER_BLOCK(_ThumbInstruction) +};
A
src/isa-thumb.h
@@ -0,0 +1,11 @@
+#ifndef ISA_THUMB_H +#define ISA_THUMB_H + +#include <stdint.h> + +struct ARMCore; + +void ThumbStep(struct ARMCore* cpu); +typedef void (*ThumbInstruction)(struct ARMCore*, uint16_t opcode); + +#endif