/*++ BUILD Version: 0001 // Increment this if a change has global effects Copyright (c) 1993-1997 Microsoft Corporation Module Name: arminst.h Abstract: ARM instruction definitions. Author: Janet Schneider 31-March-1997 Revision History: --*/ #ifndef _ARMINST_ #define _ARMINST_ // // Define ARM instruction format structures. // #define COND_EQ 0x00000000L // Z set #define COND_NE 0x10000000L // Z clear #define COND_CS 0x20000000L // C set // aka HS #define COND_CC 0x30000000L // C clear // aka LO #define COND_MI 0x40000000L // N set #define COND_PL 0x50000000L // N clear #define COND_VS 0x60000000L // V set #define COND_VC 0x70000000L // V clear #define COND_HI 0x80000000L // C set and Z clear #define COND_LS 0x90000000L // C clear or Z set #define COND_GE 0xa0000000L // N == V #define COND_LT 0xb0000000L // N != V #define COND_GT 0xc0000000L // Z clear, and N == V #define COND_LE 0xd0000000L // Z set, and N != V #define COND_AL 0xe0000000L // Always execute #define COND_NV 0xf0000000L // Never - undefined #define COND_MASK COND_NV #define COND_SHIFT 28 #define OP_AND 0x0 // 0000 #define OP_EOR 0x1 // 0001 #define OP_SUB 0x2 // 0010 #define OP_RSB 0x3 // 0011 #define OP_ADD 0x4 // 0100 #define OP_ADC 0x5 // 0101 #define OP_SBC 0x6 // 0110 #define OP_RSC 0x7 // 0111 #define OP_TST 0x8 // 1000 #define OP_TEQ 0x9 // 1001 #define OP_CMP 0xa // 1010 #define OP_CMN 0xb // 1011 #define OP_ORR 0xc // 1100 #define OP_MOV 0xd // 1101 #define OP_BIC 0xe // 1110 #define OP_MVN 0xf // 1111 #define MOV_PC_LR_MASK 0x0de0f00eL // All types of mov - i, is, rs #define MOV_PC_LR 0x01a0f00eL #define MOV_PC_X_MASK 0x0de0f000L #define MOV_PC_X 0x01a0f000L #define DATA_PROC_MASK 0x0c00f000L #define DP_PC_INSTR 0x0000f000L // Data process instr w/PC as destination #define DP_R11_INSTR 0x0000b000L // Data process instr w/R11 as destination #define ADD_SP_MASK 0x0de0f000L #define ADD_SP_INSTR 0x0080d000L // Add instr with SP as destination #define SUB_SP_MASK 0x0de0f000L #define SUB_SP_INSTR 0x0040d000L // Sub instr with SP as destination #define BX_MASK 0x0ffffff0L // Branch and exchange instr sets #define BX_INSTR 0x012fff10L // return (LR) or call (Rn != LR) #define LDM_PC_MASK 0x0e108000L #define LDM_PC_INSTR 0x08108000L // Load multiple with PC bit set #define LDM_LR_MASK 0x0e104000L #define LDM_LR_INSTR 0x08104000L // Load multiple with LR bit set #define STRI_LR_SPU_MASK 0x073de000L // Load or Store of LR with stack update #define STRI_LR_SPU_INSTR 0x052de000L // Store LR (with immediate offset, update SP) #define STM_MASK 0x0e100000L #define STM_INSTR 0x08000000L // Store multiple instruction #define B_BL_MASK 0x0f000000L // Regular branches #define B_INSTR 0x0a000000L #define BL_INSTR 0x0b000000L #define LDR_MASK 0x0f3ff000L #define LDR_PC_INSTR 0x051fc000L // Load an address from PC + offset to R12 #define LDR_THUNK_1 0xe59fc000L // ldr r12, [pc] #define LDR_THUNK_2 0xe59cf000L // ldr pc, [r12] typedef union _ARMI { struct { ULONG operand2 : 12; ULONG rd : 4; ULONG rn : 4; ULONG s : 1; ULONG opcode : 4; ULONG bits : 3; // Specifies immediate (001) or register (000) ULONG cond : 4; } dataproc; // Data processing, PSR transfer struct { // // Type 1 - Immediate // ULONG immediate : 8; ULONG rotate : 4; ULONG dpbits : 20; } dpi; struct { // // Form: Shift or rotate by immediate // // Type bits Name // // 2 (000) Register (Shift is 0) // 3 (000) Logical shift left by immediate // 5 (010) Logical shift right by immediate // 7 (100) Arithmetic shift right by immediate // 9 (110) Rotate right by immediate // ULONG rm : 4; ULONG bits : 3; ULONG shift : 5; ULONG dpbits : 20; } dpshi; struct { // // Form: Shift or rotate by register // // Type bits Name // 4 (0001) Logical shift left by register // 6 (0011) Logical shift right by register // 8 (0101) Arithmetic shift right by register // 10 (0111) Rotate right by register // ULONG rm : 4; ULONG bits : 4; ULONG rs : 4; ULONG dpbits : 20; } dpshr; struct { // // Type 11 - Rotate right with extended // ULONG rm : 4; ULONG bits : 8; // (00000110) ULONG dpbits : 20; } dprre; struct { ULONG bits1 : 12; // (000000000000) ULONG rd : 4; ULONG bits2 : 6; // (001111) ULONG ps : 1; // spsr = 1, cpsr = 0 ULONG bits3 : 5; // (00010) ULONG cond : 4; } dpmrs; struct { ULONG operand : 12; ULONG bits1 : 4; // (1111) ULONG fc : 1; // control fields = 1 ULONG fx : 1; // extension fields = 1 ULONG fs : 1; // status fields = 1 ULONG ff : 1; // flags fields = 1 ULONG bits2 : 2; // (10) ULONG pd : 1; // spsr = 1, cpsr = 0 ULONG bits3 : 2; // (10) ULONG i : 1; // immedate = 1, register = 0 ULONG bits4 : 2; // (00) ULONG cond : 4; } dpmsr; struct { ULONG rm : 4; ULONG bits1 : 8; // (00001001) ULONG rd : 4; ULONG rn : 4; ULONG bits2 : 2; // (00) ULONG b : 1; ULONG bits3 : 5; // (00010) ULONG cond : 4; } swp; // Swap instructions struct { ULONG rm : 4; ULONG bits1 : 4; // (1001) ULONG rs : 4; ULONG rn : 4; ULONG rd : 4; ULONG s : 1; ULONG a : 1; ULONG sgn : 1; ULONG lng : 1; ULONG bits2 : 4; // (0000) ULONG cond : 4; } mul; // Multiply and multiply-accumulate struct { ULONG rn : 4; ULONG bits : 24; ULONG cond : 4; } bx; // Branch and exchange instruction sets struct { ULONG offset : 24; ULONG h : 1; ULONG bits : 7; // (1111101) } blxi; // blx immediate struct { ULONG immed1 : 4; ULONG bits1 : 4; // (0111) ULONG immed2 : 12; ULONG bits2 : 12; // (111000010010) } bkpt; struct { ULONG any1 : 4; ULONG bits1 : 1; // (1) ULONG any2 : 20; ULONG bits2 : 3; // (011) ULONG cond : 4; } ud; // Undefined instruction struct { ULONG operand1 : 4; ULONG bits1 : 1; // (1) ULONG h : 1; // halfword = 1, byte = 0 ULONG s : 1; // signed = 1, unsigned = 0 ULONG bits2 : 1; // (1) ULONG operand2 : 4; ULONG rd : 4; ULONG rn : 4; ULONG l : 1; // load = 1, store = 0 ULONG w : 1; // update base register bit ULONG i : 1; // immediate = 1, register = 0 ULONG u : 1; // increment = 1, decrement = 0 ULONG p : 1; // pre-indexing = 1, post-indexing = 0 ULONG bits3 : 3; // (000) ULONG cond : 4; } miscdt; // Misc data transfer struct { ULONG offset : 12; ULONG rd : 4; ULONG rn : 4; ULONG l : 1; // load = 1, store = 0 ULONG w : 1; // update base register bit ULONG b : 1; // unsigned byte = 1, word = 0 ULONG u : 1; // increment = 1, decrement = 0 ULONG p : 1; // pre-indexing = 1, post-indexing = 0 ULONG i : 1; // immediate = 1, register = 0 ULONG bits : 2; ULONG cond : 4; } ldr; // Load register struct { ULONG reglist : 16; ULONG rn : 4; ULONG l : 1; // load = 1, store = 0 ULONG w : 1; // update base register after transfer ULONG s : 1; ULONG u : 1; // increment = 1, decrement = 0 ULONG p : 1; // before = 1, after = 0 ULONG bits : 3; ULONG cond : 4; } ldm; // Load multiple struct { ULONG offset : 24; ULONG link : 1; ULONG bits : 3; ULONG cond : 4; } bl; // Branch, Branch and link struct { ULONG rm : 4; ULONG bits1 : 8; // (11110001) ULONG rd : 4; ULONG bits2 : 12; // (000101101111) ULONG cond : 4; } clz; struct { ULONG crm : 4; ULONG bits1 : 1; // (0) ULONG cp : 3; ULONG cpn : 4; ULONG crd : 4; ULONG crn : 4; ULONG cpop : 4; ULONG bits2 : 4; // (1110) ULONG cond : 4; } cpdo; struct { ULONG crm : 4; ULONG bits1 : 1; // (1) ULONG cp : 3; ULONG cpn : 4; ULONG rd : 4; ULONG crn : 4; ULONG l : 1; // load = 1, store = 0 ULONG cpop : 3; ULONG bits2 : 4; // (1110) ULONG cond : 4; } cprt; struct { ULONG offset : 8; ULONG cpn : 4; ULONG crd : 4; ULONG rn : 4; ULONG l : 1; // load = 1, store = 0 ULONG w : 1; // write back = 1, no write back = 0 ULONG n : 1; // long = 1, short = 0 ULONG u : 1; // up = 1, down = 0 ULONG p : 1; // pre = 1, post = 0 ULONG bits : 3; // (011) ULONG cond : 4; } cpdt; struct { ULONG crm : 4; ULONG cpop : 4; ULONG cpn : 4; ULONG rd : 4; ULONG rn : 4; ULONG bits : 8; ULONG cond : 4; } mcrr; struct { ULONG rm : 4; ULONG bits1 : 8; // (00000101) ULONG rd : 4; ULONG rn : 4; ULONG bits2 : 8; // (00010010) ULONG cond : 4; } qadd; struct { ULONG rm : 4; ULONG bits1 : 1; // (0) ULONG x : 1; // T = 1, B = 0 ULONG y : 1; // T = 1, B = 0 ULONG bits2 : 1; // (1) ULONG rs : 4; ULONG rn : 4; ULONG rd : 4; ULONG bits3 : 8; // (00010000) ULONG cond : 4; } smla; struct { ULONG rm : 4; ULONG bits1 : 1; // (0) ULONG x : 1; // T = 1, B = 0 ULONG y : 1; // T = 1, B = 0 ULONG bits2 : 1; // (1) ULONG rs : 4; ULONG rdlo : 4; ULONG rdhi : 4; ULONG bits3 : 8; // (00010000) ULONG cond : 4; } smlal; struct { ULONG rm : 4; ULONG bits1 : 1; // (0) ULONG x : 1; // T = 1, B = 0 ULONG y : 1; // T = 1, B = 0 ULONG bits2 : 1; // (1) ULONG rs : 4; ULONG bits3 : 4; // (0000) ULONG rd : 4; ULONG bits4 : 8; // (00010010) ULONG cond : 4; } smul; struct { ULONG comment : 24; ULONG bits : 4; // (1111) ULONG cond : 4; } swi; ULONG instruction; } ARMI, *PARMI; // Thumb instruction descriptions follow. #define THUMB_B_COND_MASK 0xf000 #define THUMB_B_COND_INSTR 0xd000 #define THUMB_B_MASK 0xf800 #define THUMB_B_INSTR 0xe000 #define THUMB_BL_MASK 0xf000 #define THUMB_BL_INSTR 0xf000 #define THUMB_BX_MASK 0xff80 #define THUMB_BX_INSTR 0x4700 #define THUMB_ADD_HI_MASK 0xff00 #define THUMB_ADD_HI_INSTR 0x4400 #define THUMB_MOV_HI_MASK 0xff00 #define THUMB_MOV_HI_INSTR 0x4600 #define THUMB_POP_MASK 0xfe00 #define THUMB_POP_INSTR 0xbc00 typedef union _THUMBI { struct { USHORT reg_list:8; USHORT pc:1; // pc==1 -> pop pc from list USHORT Op:7; USHORT Next:16; } pop_instr; struct { USHORT reg_list:8; USHORT lr:1; // lr==1 -> push lr to list USHORT Op:7; USHORT Next:16; } push_instr; struct { USHORT target:8; // sign-extend USHORT cond:4; USHORT Op:4; USHORT Next:16; } b_cond_instr; struct { USHORT target:11; // sign-extend USHORT op:5; USHORT Next:16; } b_instr; struct { USHORT SBZ:3; USHORT Rm:3; USHORT hi_reg:1; // hi_reg==1 -> use high register for Rm USHORT op:9; USHORT Next:16; } bx_instr; struct { USHORT target22_12:11; // will not be sign-extended USHORT not_the_prefix:1; // should be 0: is the prefix USHORT prefix_op:4; USHORT target11_1:11; // will be sign-extended USHORT not_the_prefix2:1; // should be 1: not the prefix USHORT main_op:4; } bl_instr; struct { USHORT Rd:3; USHORT Rm:3; USHORT hi_m:1; // Rm is high register USHORT hi_d:1; // Rd is high register USHORT func:2; // 00->AddHi, 01->CmpHi, 10->MovHi, 11->Bx USHORT op:6; // 010001 = 0x11 USHORT Next:16; } spx_dp_instr; struct { USHORT imm:8; USHORT Rd:3; USHORT sp:1; // 0-> rd = pc+imm, 1-> rd=sp+imm. USHORT op:4; USHORT Next:16; } add_sp_pc_instr; struct { USHORT imm:7; USHORT op:9; USHORT Next:16; } incr_sp_instr; ULONG instruction; } THUMB_INSTRUCTION, *PTHUMB_INSTRUCTION; #endif // _ARMINST_