diff options
Diffstat (limited to 'emulator/qtools/opcode.h')
-rw-r--r-- | emulator/qtools/opcode.h | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/emulator/qtools/opcode.h b/emulator/qtools/opcode.h new file mode 100644 index 0000000..c8b67a6 --- /dev/null +++ b/emulator/qtools/opcode.h @@ -0,0 +1,166 @@ +// Copyright 2006 The Android Open Source Project + +#ifndef OPCODE_H +#define OPCODE_H + +#include <inttypes.h> + +// Note: this list of opcodes must match the list used to initialize +// the opflags[] array in opcode.cpp. +enum Opcode { + OP_INVALID, + OP_UNDEFINED, + OP_ADC, + OP_ADD, + OP_AND, + OP_B, + OP_BL, + OP_BIC, + OP_BKPT, + OP_BLX, + OP_BX, + OP_CDP, + OP_CLZ, + OP_CMN, + OP_CMP, + OP_EOR, + OP_LDC, + OP_LDM, + OP_LDR, + OP_LDRB, + OP_LDRBT, + OP_LDRH, + OP_LDRSB, + OP_LDRSH, + OP_LDRT, + OP_MCR, + OP_MLA, + OP_MOV, + OP_MRC, + OP_MRS, + OP_MSR, + OP_MUL, + OP_MVN, + OP_ORR, + OP_PLD, + OP_RSB, + OP_RSC, + OP_SBC, + OP_SMLAL, + OP_SMULL, + OP_STC, + OP_STM, + OP_STR, + OP_STRB, + OP_STRBT, + OP_STRH, + OP_STRT, + OP_SUB, + OP_SWI, + OP_SWP, + OP_SWPB, + OP_TEQ, + OP_TST, + OP_UMLAL, + OP_UMULL, + + // Define thumb opcodes + OP_THUMB_UNDEFINED, + OP_THUMB_ADC, + OP_THUMB_ADD, + OP_THUMB_AND, + OP_THUMB_ASR, + OP_THUMB_B, + OP_THUMB_BIC, + OP_THUMB_BKPT, + OP_THUMB_BL, + OP_THUMB_BLX, + OP_THUMB_BX, + OP_THUMB_CMN, + OP_THUMB_CMP, + OP_THUMB_EOR, + OP_THUMB_LDMIA, + OP_THUMB_LDR, + OP_THUMB_LDRB, + OP_THUMB_LDRH, + OP_THUMB_LDRSB, + OP_THUMB_LDRSH, + OP_THUMB_LSL, + OP_THUMB_LSR, + OP_THUMB_MOV, + OP_THUMB_MUL, + OP_THUMB_MVN, + OP_THUMB_NEG, + OP_THUMB_ORR, + OP_THUMB_POP, + OP_THUMB_PUSH, + OP_THUMB_ROR, + OP_THUMB_SBC, + OP_THUMB_STMIA, + OP_THUMB_STR, + OP_THUMB_STRB, + OP_THUMB_STRH, + OP_THUMB_SUB, + OP_THUMB_SWI, + OP_THUMB_TST, + + OP_END // must be last +}; + +extern uint32_t opcode_flags[]; +extern const char *opcode_names[]; + +// Define bit flags for the opcode categories +static const uint32_t kCatByte = 0x0001; +static const uint32_t kCatHalf = 0x0002; +static const uint32_t kCatWord = 0x0004; +static const uint32_t kCatLong = 0x0008; +static const uint32_t kCatNumBytes = (kCatByte | kCatHalf | kCatWord | kCatLong); +static const uint32_t kCatMultiple = 0x0010; +static const uint32_t kCatSigned = 0x0020; +static const uint32_t kCatLoad = 0x0040; +static const uint32_t kCatStore = 0x0080; +static const uint32_t kCatMemoryRef = (kCatLoad | kCatStore); +static const uint32_t kCatAlu = 0x0100; +static const uint32_t kCatBranch = 0x0200; +static const uint32_t kCatBranchLink = 0x0400; +static const uint32_t kCatBranchExch = 0x0800; +static const uint32_t kCatCoproc = 0x1000; +static const uint32_t kCatLoadMultiple = (kCatLoad | kCatMultiple); +static const uint32_t kCatStoreMultiple = (kCatStore | kCatMultiple); + +inline bool isALU(Opcode op) { return (opcode_flags[op] & kCatAlu) != 0; } +inline bool isBranch(Opcode op) { return (opcode_flags[op] & kCatBranch) != 0; } +inline bool isBranchLink(Opcode op) { + return (opcode_flags[op] & kCatBranchLink) != 0; +} +inline bool isBranchExch(Opcode op) { + return (opcode_flags[op] & kCatBranchExch) != 0; +} +inline bool isLoad(Opcode op) { return (opcode_flags[op] & kCatLoad) != 0; } +inline bool isLoadMultiple(Opcode op) { + return (opcode_flags[op] & kCatLoadMultiple) == kCatLoadMultiple; +} +inline bool isStoreMultiple(Opcode op) { + return (opcode_flags[op] & kCatStoreMultiple) == kCatStoreMultiple; +} +inline bool isStore(Opcode op) { return (opcode_flags[op] & kCatStore) != 0; } +inline bool isSigned(Opcode op) { return (opcode_flags[op] & kCatSigned) != 0; } +inline bool isMemoryRef(Opcode op) { + return (opcode_flags[op] & kCatMemoryRef) != 0; +} +inline int getAccessSize(Opcode op) { return opcode_flags[op] & kCatNumBytes; } +inline bool isCoproc(Opcode op) { return (opcode_flags[op] & kCatCoproc) != 0; } +inline int getNumAccesses(Opcode op, uint32_t binary) { + extern int num_one_bits[]; + int num_accesses = 0; + if (opcode_flags[op] & kCatNumBytes) + num_accesses = 1; + else if (opcode_flags[op] & kCatMultiple) { + num_accesses = num_one_bits[(binary >> 8) & 0xff] + + num_one_bits[binary & 0xff]; + } + return num_accesses; +} + +#endif // OPCODE_H |