167 lines
4.1 KiB
C
167 lines
4.1 KiB
C
// 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
|