From 76dbfce3c304e6f0b21fa2be67b8a4966faf9ee5 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 9 Apr 2013 02:57:24 -0700 Subject: [PATCH] Start filling in THUMB table with insane preprocessor tricks --- src/isa-arm.c | 26 ++----------------- src/isa-inlines.h | 22 ++++++++++++++++ src/isa-thumb.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ src/isa-thumb.h | 11 ++++++++ 4 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 src/isa-thumb.c create mode 100644 src/isa-thumb.h diff --git a/src/isa-arm.c b/src/isa-arm.c index 9692adbf2..9248a51da 100644 --- a/src/isa-arm.c +++ b/src/isa-arm.c @@ -126,8 +126,6 @@ void ARMStep(struct ARMCore* cpu) { // 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_INSTRUCTION_ARM(SWI,) #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_INSTRUCTION_ARM(SWI,) #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 @@ DEFINE_INSTRUCTION_ARM(SWI,) DECLARE_ARM_SWI_BLOCK(EMITTER) static const ARMInstruction _armTable[0x1000] = { - DECLARE_EMITTER_BLOCK(_ARMInstruction) + DECLARE_ARM_EMITTER_BLOCK(_ARMInstruction) }; diff --git a/src/isa-inlines.h b/src/isa-inlines.h index 78e74e6bf..a925177e7 100644 --- a/src/isa-inlines.h +++ b/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) diff --git a/src/isa-thumb.c b/src/isa-thumb.c new file mode 100644 index 000000000..3e9bd03b7 --- /dev/null +++ b/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) +}; diff --git a/src/isa-thumb.h b/src/isa-thumb.h new file mode 100644 index 000000000..081043f7d --- /dev/null +++ b/src/isa-thumb.h @@ -0,0 +1,11 @@ +#ifndef ISA_THUMB_H +#define ISA_THUMB_H + +#include + +struct ARMCore; + +void ThumbStep(struct ARMCore* cpu); +typedef void (*ThumbInstruction)(struct ARMCore*, uint16_t opcode); + +#endif