aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/qtools/opcode.h
diff options
context:
space:
mode:
Diffstat (limited to 'emulator/qtools/opcode.h')
-rw-r--r--emulator/qtools/opcode.h166
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