// Copyright 2006 The Android Open Source Project #ifndef OPCODE_H #define OPCODE_H #include // 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