4 * Copyright (c) 2002 Wild West Software
5 * Copyright (c) 2001, 2002 Sergey Chaban
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without restriction,
10 * including without limitation the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
24 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 typedef unsigned long arminstr_t;
33 typedef unsigned long armword_t;
35 /* Helper functions */
36 /*void arm_emit_std_prologue(cg_segment_t * segment, unsigned int local_size);
37 void arm_emit_std_epilogue(cg_segment_t * segment, unsigned int local_size, int pop_regs);
38 void arm_emit_lean_prologue(cg_segment_t * segment, unsigned int local_size, int push_regs);
39 int arm_is_power_of_2(armword_t val);
40 int calc_arm_mov_const_shift(armword_t val);
41 int is_arm_const(armword_t val);
42 int arm_bsf(armword_t val);
43 void arm_mov_reg_imm32_cond(cg_segment_t * segment, int reg, armword_t imm32, int cond);
44 void arm_mov_reg_imm32(cg_segment_t * segment, int reg, armword_t imm32);*/
47 //*** check for correctness ***
50 void write_to_file(u32 val);
52 //#define write32(val) { *(u32 *)translation_ptr = val; write_to_file(*(u32 *)translation_ptr); translation_ptr += 4; }
54 //#define write32(val) { if( g_PcWatch.IsReset == RECRESET_OFF ) { *(u32*)pCurPage->pCodeCurrent = val; pCurPage->pCodeCurrent +=4; if( (u32)pCurPage->pCodeCurrent >= (u32)pCurPage->pCodeEnd ) { g_PcWatch.IsReset = RECRESET_START; recResize(); g_PcWatch.IsReset = RECRESET_END; return; } }else{ if( g_PcWatch.IsReset == RECRESET_END ){ g_PcWatch.IsReset = RECRESET_OFF; return; } } }
55 //#define write32_ret(val) { if( g_PcWatch.IsReset == RECRESET_OFF ) { *(u32*)pCurPage->pCodeCurrent = val; pCurPage->pCodeCurrent +=4; if( (u32)pCurPage->pCodeCurrent >= (u32)pCurPage->pCodeEnd ) { g_PcWatch.IsReset = RECRESET_START; recResize(); g_PcWatch.IsReset = RECRESET_END; return 0; } }else{ if( g_PcWatch.IsReset == RECRESET_END ){ g_PcWatch.IsReset = RECRESET_OFF; return 0; } } }
56 //#define write32(val) { *(u32*)pCurPage->pCodeCurrent = val; pCurPage->pCodeCurrent +=4; }
58 #define ARM_EMIT(p, i) write32(i);
60 /*{ *(u32*)translation_ptr = (i); translation_ptr += 4; } */
62 #if defined(GIZMONDO) || defined(POCKETPC) /* Implemented but not working right yet for PPC */
64 // --------------------------------------------------------------------------
65 // These declarations for coredll are extracted from platform builder
67 // --------------------------------------------------------------------------
69 /* Flags for CacheSync/CacheRangeFlush */
70 #define CACHE_SYNC_DISCARD 0x001 /* write back & discard all cached data */
71 #define CACHE_SYNC_INSTRUCTIONS 0x002 /* discard all cached instructions */
72 #define CACHE_SYNC_WRITEBACK 0x004 /* write back but don't discard data cache*/
73 #define CACHE_SYNC_FLUSH_I_TLB 0x008 /* flush I-TLB */
74 #define CACHE_SYNC_FLUSH_D_TLB 0x010 /* flush D-TLB */
75 #define CACHE_SYNC_FLUSH_TLB (CACHE_SYNC_FLUSH_I_TLB|CACHE_SYNC_FLUSH_D_TLB) /* flush all TLB */
76 #define CACHE_SYNC_L2_WRITEBACK 0x020 /* write-back L2 Cache */
77 #define CACHE_SYNC_L2_DISCARD 0x040 /* discard L2 Cache */
79 #define CACHE_SYNC_ALL 0x07F /* sync and discard everything in Cache/TLB */
82 void CacheSync(int flags);
84 #define CLEAR_INSN_CACHE(BEG, END) CacheSync(CACHE_SYNC_INSTRUCTIONS | CACHE_SYNC_WRITEBACK);
89 #define CLEAR_INSN_CACHE(BEG, END) \
91 register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
92 register unsigned long _end __asm ("a2") = (unsigned long) (END); \
93 register unsigned long _flg __asm ("a3") = 0; \
94 register unsigned long _scno __asm ("r7") = 0xf0002; \
95 __asm __volatile ("swi 0x9f0002 @ sys_cacheflush" \
97 : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno)); \
104 #if defined(_MSC_VER) && !defined(ARM_NOIASM)
105 # define ARM_IASM(_expr) __easfdmit (_expr)
107 # define ARM_IASM(_expr)
110 /* even_scale = rot << 1 */
111 #define ARM_SCALE(imm8, even_scale) ( ((imm8) >> (even_scale)) | ((imm8) << (32 - even_scale)) )
136 ARMREG_A1 = ARMREG_R0,
137 ARMREG_A2 = ARMREG_R1,
138 ARMREG_A3 = ARMREG_R2,
139 ARMREG_A4 = ARMREG_R3,
142 ARMREG_V1 = ARMREG_R4,
143 ARMREG_V2 = ARMREG_R5,
144 ARMREG_V3 = ARMREG_R6,
145 ARMREG_V4 = ARMREG_R7,
146 ARMREG_V5 = ARMREG_R8,
147 ARMREG_V6 = ARMREG_R9,
148 ARMREG_V7 = ARMREG_R10,
150 ARMREG_FP = ARMREG_R11,
151 ARMREG_IP = ARMREG_R12,
152 ARMREG_SP = ARMREG_R13,
153 ARMREG_LR = ARMREG_R14,
154 ARMREG_PC = ARMREG_R15,
184 /* XScale: acc0 on CP0 */
185 ARMREG_ACC0 = ARMREG_CR0,
187 ARMREG_MAX = ARMREG_R15,
205 /* number of argument registers */
206 #define ARM_NUM_ARG_REGS 4
208 /* number of non-argument registers */
209 #define ARM_NUM_VARIABLE_REGS 7
211 /* number of global registers */
212 #define ARM_NUM_GLOBAL_REGS 5
214 /* bitvector for all argument regs (A1-A4) */
215 #define ARM_ALL_ARG_REGS \
216 (1 << ARMREG_A1) | (1 << ARMREG_A2) | (1 << ARMREG_A3) | (1 << ARMREG_A4)
220 ARMCOND_EQ = 0x0, /* Equal; Z = 1 */
221 ARMCOND_NE = 0x1, /* Not equal, or unordered; Z = 0 */
222 ARMCOND_CS = 0x2, /* Carry set; C = 1 */
223 ARMCOND_HS = ARMCOND_CS, /* Unsigned higher or same; */
224 ARMCOND_CC = 0x3, /* Carry clear; C = 0 */
225 ARMCOND_LO = ARMCOND_CC, /* Unsigned lower */
226 ARMCOND_MI = 0x4, /* Negative; N = 1 */
227 ARMCOND_PL = 0x5, /* Positive or zero; N = 0 */
228 ARMCOND_VS = 0x6, /* Overflow; V = 1 */
229 ARMCOND_VC = 0x7, /* No overflow; V = 0 */
230 ARMCOND_HI = 0x8, /* Unsigned higher; C = 1 && Z = 0 */
231 ARMCOND_LS = 0x9, /* Unsigned lower or same; C = 0 || Z = 1 */
232 ARMCOND_GE = 0xA, /* Signed greater than or equal; N = V */
233 ARMCOND_LT = 0xB, /* Signed less than; N != V */
234 ARMCOND_GT = 0xC, /* Signed greater than; Z = 0 && N = V */
235 ARMCOND_LE = 0xD, /* Signed less than or equal; Z = 1 && N != V */
236 ARMCOND_AL = 0xE, /* Always */
237 ARMCOND_NV = 0xF, /* Never */
242 #define ARMCOND_MASK (ARMCOND_NV << ARMCOND_SHIFT)
244 #define ARM_DEF_COND(cond) (((cond) & 0xF) << ARMCOND_SHIFT)
254 ARMSHIFT_ASL = ARMSHIFT_LSL
285 /* not really opcodes */
291 ARMOP_MUL = 0x0, /* Rd := Rm*Rs */
292 ARMOP_MLA = 0x1, /* Rd := (Rm*Rs)+Rn */
300 /* for data transfers with register offset */
331 /* Generic form - all ARM instructions are conditional. */
333 arminstr_t icode : 28;
339 /* Branch or Branch with Link instructions. */
341 arminstr_t offset : 24;
343 arminstr_t tag : 3; /* 1 0 1 */
348 #define ARM_BR_MASK 7 << 25
349 #define ARM_BR_TAG ARM_BR_ID << 25
351 #define ARM_DEF_BR(offs, l, cond) ((offs) | ((l) << 24) | (ARM_BR_TAG) | (cond << ARMCOND_SHIFT))
354 #define ARM_B_COND(p, cond, offset) ARM_EMIT(p, ARM_DEF_BR(offset, 0, cond))
355 #define ARM_B(p, offs) ARM_B_COND((p), ARMCOND_AL, (offs))
356 /* branch with link */
357 #define ARM_BL_COND(p, cond, offset) ARM_EMIT(p, ARM_DEF_BR(offset, 1, cond))
358 #define ARM_BL(p, offs) ARM_BL_COND((p), ARMCOND_AL, (offs))
360 /* branch to register and exchange */
361 #define ARM_BX_COND(p, cond, reg) ARM_EMIT(p, ((cond << ARMCOND_SHIFT) | (reg) | 0x12FFF10))
362 #define ARM_BX(p, reg) ARM_BX_COND((p), ARMCOND_AL, (reg))
364 /* branch to register with link */
365 #define ARM_BLX_COND(p, cond, reg) ARM_EMIT(p, ((cond << ARMCOND_SHIFT) | (reg) | 0x12FFF30))
366 #define ARM_BLX(p, reg) ARM_BLX_COND((p), ARMCOND_AL, (reg))
369 /* Data Processing Instructions - there are 3 types. */
378 arminstr_t tag : 1; /* 0 - immediate shift, 1 - reg shift */
379 arminstr_t type : 2; /* shift type - logical, arithmetic, rotate */
380 } ARMDPI_op2_reg_shift;
383 /* op2 is reg shift by imm */
385 ARMDPI_op2_reg_shift r2;
387 arminstr_t _dummy_r2 : 7;
388 arminstr_t shift : 5;
390 } ARMDPI_op2_reg_imm;
392 /* op2 is reg shift by reg */
394 ARMDPI_op2_reg_shift r2;
396 arminstr_t _dummy_r2 : 7;
397 arminstr_t pad : 1; /* always 0, to differentiate from HXFER etc. */
400 } ARMDPI_op2_reg_reg;
402 /* Data processing instrs */
404 ARMDPI_op2_imm op2_imm;
406 ARMDPI_op2_reg_shift op2_reg;
407 ARMDPI_op2_reg_imm op2_reg_imm;
408 ARMDPI_op2_reg_reg op2_reg_reg;
411 arminstr_t op2 : 12; /* raw operand 2 */
412 arminstr_t rd : 4; /* destination reg */
413 arminstr_t rn : 4; /* first operand reg */
414 arminstr_t s : 1; /* S-bit controls PSR update */
415 arminstr_t opcode : 4; /* arithmetic/logic operation */
416 arminstr_t type : 1; /* type of op2, 0 = register, 1 = immediate */
417 arminstr_t tag : 2; /* 0 0 */
423 #define ARM_DPI_MASK 3 << 26
424 #define ARM_DPI_TAG ARM_DPI_ID << 26
426 #define ARM_DEF_DPI_IMM_COND(imm8, rot, rd, rn, s, op, cond) \
428 (((rot) & 0xF) << 8) | \
438 #define ARM_DEF_DPI_IMM(imm8, rot, rd, rn, s, op) \
439 ARM_DEF_DPI_IMM_COND(imm8, rot, rd, rn, s, op, ARMCOND_AL)
442 #define ARM_DPIOP_REG_IMM8ROT_COND(p, op, rd, rn, imm8, rot, cond) \
443 ARM_EMIT(p, ARM_DEF_DPI_IMM_COND((imm8), ((rot) >> 1), (rd), (rn), 0, (op), cond))
444 #define ARM_DPIOP_S_REG_IMM8ROT_COND(p, op, rd, rn, imm8, rot, cond) \
445 ARM_EMIT(p, ARM_DEF_DPI_IMM_COND((imm8), ((rot) >> 1), (rd), (rn), 1, (op), cond))
448 #define ARM_IASM_DPIOP_REG_IMM8ROT_COND(p, op, rd, rn, imm8, rot, cond) \
449 ARM_IASM(ARM_DEF_DPI_IMM_COND((imm8), ((rot) >> 1), (rd), (rn), 0, (op), cond))
450 #define ARM_IASM_DPIOP_S_REG_IMM8ROT_COND(p, op, rd, rn, imm8, rot, cond) \
451 ARM_IASM(ARM_DEF_DPI_IMM_COND((imm8), ((rot) >> 1), (rd), (rn), 1, (op), cond))
455 #define ARM_DEF_DPI_REG_IMMSHIFT_COND(rm, shift_type, imm_shift, rd, rn, s, op, cond) \
457 ((shift_type & 3) << 5) | \
458 (((imm_shift) & 0x1F) << 7) | \
467 #define ARM_DPIOP_REG_IMMSHIFT_COND(p, op, rd, rn, rm, shift_type, imm_shift, cond) \
468 ARM_EMIT(p, ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), shift_type, imm_shift, (rd), (rn), 0, (op), cond))
470 #define ARM_DPIOP_S_REG_IMMSHIFT_COND(p, op, rd, rn, rm, shift_type, imm_shift, cond) \
471 ARM_EMIT(p, ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), shift_type, imm_shift, (rd), (rn), 1, (op), cond))
473 #define ARM_DPIOP_REG_REG_COND(p, op, rd, rn, rm, cond) \
474 ARM_EMIT(p, ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), ARMSHIFT_LSL, 0, (rd), (rn), 0, (op), cond))
476 #define ARM_DPIOP_S_REG_REG_COND(p, op, rd, rn, rm, cond) \
477 ARM_EMIT(p, ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), ARMSHIFT_LSL, 0, (rd), (rn), 1, (op), cond))
480 #define ARM_IASM_DPIOP_REG_IMMSHIFT_COND(p, op, rd, rn, rm, shift_type, imm_shift, cond) \
481 ARM_IASM(ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), shift_type, imm_shift, (rd), (rn), 0, (op), cond))
483 #define ARM_IASM_DPIOP_S_REG_IMMSHIFT_COND(p, op, rd, rn, rm, shift_type, imm_shift, cond) \
484 ARM_IASM(ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), shift_type, imm_shift, (rd), (rn), 1, (op), cond))
486 #define ARM_IASM_DPIOP_REG_REG_COND(p, op, rd, rn, rm, cond) \
487 ARM_IASM(ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), ARMSHIFT_LSL, 0, (rd), (rn), 0, (op), cond))
489 #define ARM_IASM_DPIOP_S_REG_REG_COND(p, op, rd, rn, rm, cond) \
490 ARM_IASM_EMIT(ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), ARMSHIFT_LSL, 0, (rd), (rn), 1, (op), cond))
493 /* Rd := Rn op (Rm shift_type Rs) */
494 #define ARM_DEF_DPI_REG_REGSHIFT_COND(rm, shift_type, rs, rd, rn, s, op, cond) \
497 ((shift_type & 3) << 5) | \
507 #define ARM_DPIOP_REG_REGSHIFT_COND(p, op, rd, rn, rm, shift_type, rs, cond) \
508 ARM_EMIT(p, ARM_DEF_DPI_REG_REGSHIFT_COND((rm), shift_type, (rs), (rd), (rn), 0, (op), cond))
510 #define ARM_DPIOP_S_REG_REGSHIFT_COND(p, op, rd, rn, rm, shift_type, rs, cond) \
511 ARM_EMIT(p, ARM_DEF_DPI_REG_REGSHIFT_COND((rm), shift_type, (rs), (rd), (rn), 1, (op), cond))
514 #define ARM_IASM_DPIOP_REG_REGSHIFT_COND(p, op, rd, rn, rm, shift_type, rs, cond) \
515 ARM_IASM(ARM_DEF_DPI_REG_REGSHIFT_COND((rm), shift_type, (rs), (rd), (rn), 0, (op), cond))
517 #define ARM_IASM_DPIOP_S_REG_REGSHIFT_COND(p, op, rd, rn, rm, shift_type, rs, cond) \
518 ARM_IASM(ARM_DEF_DPI_REG_REGSHIFT_COND((rm), shift_type, (rs), (rd), (rn), 1, (op), cond))
522 /* Multiple register transfer. */
524 arminstr_t reg_list : 16; /* bitfield */
525 arminstr_t rn : 4; /* base reg */
526 arminstr_t ls : 1; /* load(1)/store(0) */
527 arminstr_t wb : 1; /* write-back "!" */
528 arminstr_t s : 1; /* restore PSR, force user bit */
529 arminstr_t u : 1; /* up/down */
530 arminstr_t p : 1; /* pre(1)/post(0) index */
531 arminstr_t tag : 3; /* 1 0 0 */
536 #define ARM_MRT_MASK 7 << 25
537 #define ARM_MRT_TAG ARM_MRT_ID << 25
539 #define ARM_DEF_MRT(regs, rn, l, w, s, u, p, cond) \
550 #define ARM_STMDB(p, rbase, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, rbase, 0, 0, 0, 0, 1, ARMCOND_AL))
551 #define ARM_LDMDB(p, rbase, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, rbase, 1, 0, 0, 0, 1, ARMCOND_AL))
552 #define ARM_STMDB_WB(p, rbase, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, rbase, 0, 1, 0, 0, 1, ARMCOND_AL))
553 #define ARM_LDMIA_WB(p, rbase, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, rbase, 1, 1, 0, 1, 0, ARMCOND_AL))
554 #define ARM_LDMIA(p, rbase, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, rbase, 1, 0, 0, 1, 0, ARMCOND_AL))
555 #define ARM_STMIA(p, rbase, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, rbase, 0, 0, 0, 1, 0, ARMCOND_AL))
556 #define ARM_STMIA_WB(p, rbase, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, rbase, 0, 1, 0, 1, 0, ARMCOND_AL))
558 #define ARM_LDMIA_WB_PC_S(p, rbase, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, rbase, 1, 1, 1, 1, 0, ARMCOND_AL))
561 #define ARM_POP_OP(p) ARM_EMIT(p, 0xFF01BD17)
562 #define ARM_PUSH_OP(p) ARM_EMIT(p, 0xFF02B497)
565 /* stmdb sp!, {regs} */
566 #define ARM_PUSH(p, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, ARMREG_SP, 0, 1, 0, 0, 1, ARMCOND_AL))
567 #define ARM_IASM_PUSH(regs) ARM_IASM(ARM_DEF_MRT(regs, ARMREG_SP, 0, 1, 0, 0, 1, ARMCOND_AL))
569 /* ldmia sp!, {regs} */
570 #define ARM_POP(p, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, ARMREG_SP, 1, 1, 0, 1, 0, ARMCOND_AL))
571 #define ARM_IASM_POP(regs) ARM_IASM_EMIT(ARM_DEF_MRT(regs, ARMREG_SP, 1, 1, 0, 1, 0, ARMCOND_AL))
573 /* ldmia sp, {regs} ; (no write-back) */
574 #define ARM_POP_NWB(p, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, ARMREG_SP, 1, 0, 0, 1, 0, ARMCOND_AL))
575 #define ARM_IASM_POP_NWB(regs) ARM_IASM_EMIT(ARM_DEF_MRT(regs, ARMREG_SP, 1, 0, 0, 1, 0, ARMCOND_AL))
577 #define ARM_PUSH1(p, r1) ARM_PUSH(p, (1 << r1))
578 #define ARM_PUSH2(p, r1, r2) ARM_PUSH(p, (1 << r1) | (1 << r2))
579 #define ARM_PUSH3(p, r1, r2, r3) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3))
580 #define ARM_PUSH4(p, r1, r2, r3, r4) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4))
581 #define ARM_PUSH5(p, r1, r2, r3, r4, r5) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5))
582 #define ARM_PUSH6(p, r1, r2, r3, r4, r5, r6) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5) | (1 << r6))
583 #define ARM_PUSH7(p, r1, r2, r3, r4, r5, r6, r7) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5) | (1 << r6) | (1 << r7))
584 #define ARM_PUSH8(p, r1, r2, r3, r4, r5, r6, r7, r8) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5) | (1 << r6) | (1 << r7) | (1 << r8))
585 #define ARM_PUSH9(p, r1, r2, r3, r4, r5, r6, r7, r8, r9) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5) | (1 << r6) | (1 << r7) | (1 << r8) | (1 << r9))
587 #define ARM_POP9(p, r1, r2, r3, r4, r5, r6, r7, r8, r9) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5) | (1 << r6) | (1 << r7) | (1 << r8) | (1 << r9))
588 #define ARM_POP8(p, r1, r2, r3, r4, r5, r6, r7, r8) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5) | (1 << r6) | (1 << r7) | (1 << r8))
589 #define ARM_POP7(p, r1, r2, r3, r4, r5, r6, r7) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5) | (1 << r6) | (1 << r7))
590 #define ARM_POP6(p, r1, r2, r3, r4, r5, r6) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5) | (1 << r6))
591 #define ARM_POP5(p, r1, r2, r3, r4, r5) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5))
592 #define ARM_POP4(p, r1, r2, r3, r4) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4))
593 #define ARM_POP3(p, r1, r2, r3) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3))
594 #define ARM_POP2(p, r1, r2) ARM_POP(p, (1 << r1) | (1 << r2))
595 #define ARM_POP1(p, r1) ARM_POP(p, (1 << r1))
598 /* Multiply instructions */
601 arminstr_t tag2 : 4; /* 9 */
606 arminstr_t opcode : 3;
612 #define ARM_MUL_ID2 9
613 #define ARM_MUL_MASK ((0xF << 24) | (0xF << 4))
614 #define ARM_MUL_TAG ((ARM_MUL_ID << 24) | (ARM_MUL_ID2 << 4))
616 #define ARM_DEF_MUL_COND(op, rd, rm, rs, rn, s, cond) \
621 (((s) & 1) << 20) | \
622 (((op) & 7) << 21) | \
626 /* Rd := (Rm * Rs)[31:0]; 32 x 32 -> 32 */
627 #define ARM_MUL_COND(p, rd, rm, rs, cond) \
628 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_MUL, rd, rm, rs, 0, 0, cond))
629 #define ARM_MUL(p, rd, rm, rs) \
630 ARM_MUL_COND(p, rd, rm, rs, ARMCOND_AL)
631 #define ARM_MULS_COND(p, rd, rm, rs, cond) \
632 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_MUL, rd, rm, rs, 0, 1, cond))
633 #define ARM_MULS(p, rd, rm, rs) \
634 ARM_MULS_COND(p, rd, rm, rs, ARMCOND_AL)
635 #define ARM_MUL_REG_REG(p, rd, rm, rs) ARM_MUL(p, rd, rm, rs)
636 #define ARM_MULS_REG_REG(p, rd, rm, rs) ARM_MULS(p, rd, rm, rs)
639 #define ARM_IASM_MUL_COND(rd, rm, rs, cond) \
640 ARM_IASM_EMIT(ARM_DEF_MUL_COND(ARMOP_MUL, rd, rm, rs, 0, 0, cond))
641 #define ARM_IASM_MUL(rd, rm, rs) \
642 ARM_IASM_MUL_COND(rd, rm, rs, ARMCOND_AL)
643 #define ARM_IASM_MULS_COND(rd, rm, rs, cond) \
644 ARM_IASM_EMIT(ARM_DEF_MUL_COND(ARMOP_MUL, rd, rm, rs, 0, 1, cond))
645 #define ARM_IASM_MULS(rd, rm, rs) \
646 ARM_IASM_MULS_COND(rd, rm, rs, ARMCOND_AL)
649 /* Rd := (Rm * Rs) + Rn; 32x32+32->32 */
650 #define ARM_MLA_COND(p, rd, rm, rs, rn, cond) \
651 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_MLA, rd, rm, rs, rn, 0, cond))
652 #define ARM_MLA(p, rd, rm, rs, rn) \
653 ARM_MLA_COND(p, rd, rm, rs, rn, ARMCOND_AL)
654 #define ARM_MLAS_COND(p, rd, rm, rs, rn, cond) \
655 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_MLA, rd, rm, rs, rn, 1, cond))
656 #define ARM_MLAS(p, rd, rm, rs, rn) \
657 ARM_MLAS_COND(p, rd, rm, rs, rn, ARMCOND_AL)
660 #define ARM_IASM_MLA_COND(rd, rm, rs, rn, cond) \
661 ARM_IASM_EMIT(ARM_DEF_MUL_COND(ARMOP_MLA, rd, rm, rs, rn, 0, cond))
662 #define ARM_IASM_MLA(rd, rm, rs, rn) \
663 ARM_IASM_MLA_COND(rd, rm, rs, rn, ARMCOND_AL)
664 #define ARM_IASM_MLAS_COND(rd, rm, rs, rn, cond) \
665 ARM_IASM_EMIT(ARM_DEF_MUL_COND(ARMOP_MLA, rd, rm, rs, rn, 1, cond))
666 #define ARM_IASM_MLAS(rd, rm, rs, rn) \
667 ARM_IASM_MLAS_COND(rd, rm, rs, rn, ARMCOND_AL)
670 #define ARM_SMULL_COND(p, rn, rd, rm, rs, cond) \
671 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_SMULL, rd, rm, rs, rn, 0, cond))
672 #define ARM_SMULL(p, rn, rd, rm, rs) \
673 ARM_SMULL_COND(p, rn, rd, rm, rs, ARMCOND_AL)
675 #define ARM_SMLAL_COND(p, rn, rd, rm, rs, cond) \
676 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_SMLAL, rd, rm, rs, rn, 0, cond))
677 #define ARM_SMLAL(p, rn, rd, rm, rs) \
678 ARM_SMLAL_COND(p, rn, rd, rm, rs, ARMCOND_AL)
680 #define ARM_UMULL_COND(p, rn, rd, rm, rs, cond) \
681 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_UMULL, rd, rm, rs, rn, 0, cond))
682 #define ARM_UMULL(p, rn, rd, rm, rs) \
683 ARM_UMULL_COND(p, rn, rd, rm, rs, ARMCOND_AL)
685 #define ARM_UMLAL_COND(p, rn, rd, rm, rs, cond) \
686 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_UMLAL, rd, rm, rs, rn, 0, cond))
687 #define ARM_UMLAL(p, rn, rd, rm, rs) \
688 ARM_UMLAL_COND(p, rn, rd, rm, rs, ARMCOND_AL)
691 #define ARM_SMULLS_COND(p, rn, rd, rm, rs, cond) \
692 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_SMULL, rd, rm, rs, rn, 1, cond))
693 #define ARM_SMULLS(p, rn, rd, rm, rs) \
694 ARM_SMULLS_COND(p, rn, rd, rm, rs, ARMCOND_AL)
696 #define ARM_SMLALS_COND(p, rn, rd, rm, rs, cond) \
697 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_SMLAL, rd, rm, rs, rn, 1, cond))
698 #define ARM_SMLALS(p, rn, rd, rm, rs) \
699 ARM_SMLALS_COND(p, rn, rd, rm, rs, ARMCOND_AL)
701 #define ARM_UMULLS_COND(p, rn, rd, rm, rs, cond) \
702 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_UMULL, rd, rm, rs, rn, 1, cond))
703 #define ARM_UMULLS(p, rn, rd, rm, rs) \
704 ARM_UMULLS_COND(p, rn, rd, rm, rs, ARMCOND_AL)
706 #define ARM_UMLALS_COND(p, rn, rd, rm, rs, cond) \
707 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_UMLAL, rd, rm, rs, rn, 1, cond))
708 #define ARM_UMLALS(p, rn, rd, rm, rs) \
709 ARM_UMLALS_COND(p, rn, rd, rm, rs, ARMCOND_AL)
713 /* Word/byte transfer */
715 ARMDPI_op2_reg_imm op2_reg_imm;
717 arminstr_t op2_imm : 12;
723 arminstr_t u : 1; /* down(0) / up(1) */
724 arminstr_t p : 1; /* post-index(0) / pre-index(1) */
725 arminstr_t type : 1; /* imm(0) / register(1) */
726 arminstr_t tag : 2; /* 0 1 */
731 #define ARM_WXFER_ID 1
732 #define ARM_WXFER_MASK 3 << 26
733 #define ARM_WXFER_TAG ARM_WXFER_ID << 26
737 * ls : opcode, ARMOP_STR(0)/ARMOP_LDR(1)
738 * imm12 : immediate offset
740 * p : index mode, post-index (0, automatic write-back)
741 * or pre-index (1, calc effective address before memory access)
743 #define ARM_DEF_WXFER_IMM(imm12, rd, rn, ls, wb, b, p, cond) \
744 ((((int)(imm12)) < 0) ? -((int)(imm12)) : (imm12)) | \
750 (((int)(imm12) >= 0) << 23) | \
755 #define ARM_WXFER_MAX_OFFS 0xFFF
757 /* this macro checks for imm12 bounds */
758 #define ARM_EMIT_WXFER_IMM(ptr, imm12, rd, rn, ls, wb, b, p, cond) \
760 int _imm12 = (int)(imm12) < -ARM_WXFER_MAX_OFFS \
761 ? -ARM_WXFER_MAX_OFFS \
762 : (int)(imm12) > ARM_WXFER_MAX_OFFS \
763 ? ARM_WXFER_MAX_OFFS \
766 ARM_DEF_WXFER_IMM(_imm12, (rd), (rn), (ls), (wb), (b), (p), (cond))); \
771 /* immediate offset, post-index */
772 #define ARM_LDR_IMM_POST_COND(p, rd, rn, imm, cond) \
773 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_LDR, 0, 0, 0, cond))
775 #define ARM_LDR_IMM_POST(p, rd, rn, imm) ARM_LDR_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
777 #define ARM_LDRB_IMM_POST_COND(p, rd, rn, imm, cond) \
778 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_LDR, 0, 1, 0, cond))
780 #define ARM_LDRB_IMM_POST(p, rd, rn, imm) ARM_LDRB_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
782 /* immediate offset, pre-index */
783 #define ARM_LDR_IMM_COND(p, rd, rn, imm, cond) \
784 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_LDR, 0, 0, 1, cond))
786 #define ARM_LDR_IMM(p, rd, rn, imm) ARM_LDR_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
788 #define ARM_LDRB_IMM_COND(p, rd, rn, imm, cond) \
789 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_LDR, 0, 1, 1, cond))
791 #define ARM_LDRB_IMM(p, rd, rn, imm) ARM_LDRB_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
795 /* immediate offset, post-index */
796 #define ARM_STR_IMM_POST_COND(p, rd, rn, imm, cond) \
797 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 0, 0, cond))
799 #define ARM_STR_IMM_POST(p, rd, rn, imm) ARM_STR_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
801 #define ARM_STRB_IMM_POST_COND(p, rd, rn, imm, cond) \
802 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 1, 0, cond))
804 #define ARM_STRB_IMM_POST(p, rd, rn, imm) ARM_STRB_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
806 /* immediate offset, pre-index */
807 #define ARM_STR_IMM_COND(p, rd, rn, imm, cond) \
808 ARM_EMIT_WXFER_IMM(p, imm, rd, rn, ARMOP_STR, 0, 0, 1, cond)
809 /* ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 0, 1, cond))*/
810 /* ARM_EMIT_WXFER_IMM(p, imm, rd, rn, ARMOP_STR, 0, 0, 1, cond) */
811 /* ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 0, 1, cond)) */
813 #define ARM_STR_IMM(p, rd, rn, imm) ARM_STR_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
815 #define ARM_STRB_IMM_COND(p, rd, rn, imm, cond) \
816 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 1, 1, cond))
818 #define ARM_STRB_IMM(p, rd, rn, imm) ARM_STRB_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
821 #define ARM_STR_IMM_WB_COND(p, rd, rn, imm, cond) \
822 ARM_EMIT_WXFER_IMM(p, imm, rd, rn, ARMOP_STR, 1, 0, 1, cond)
823 #define ARM_STR_IMM_WB(p, rd, rn, imm) ARM_STR_IMM_WB_COND(p, rd, rn, imm, ARMCOND_AL)
828 * u : down(0) / up(1)
829 * p : index mode, post-index (0, automatic write-back) or pre-index (1)
831 #define ARM_DEF_WXFER_REG_REG_UPDOWN_COND(rm, shift_type, shift, rd, rn, ls, wb, b, u, p, cond) \
833 ((shift_type) << 5) | \
846 #define ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ls, wb, b, p, cond) \
847 ARM_DEF_WXFER_REG_REG_UPDOWN_COND(rm, shift_type, shift, rd, rn, ls, wb, b, ARM_UP, p, cond)
848 #define ARM_DEF_WXFER_REG_MINUS_REG_COND(rm, shift_type, shift, rd, rn, ls, wb, b, p, cond) \
849 ARM_DEF_WXFER_REG_REG_UPDOWN_COND(rm, shift_type, shift, rd, rn, ls, wb, b, ARM_DOWN, p, cond)
852 #define ARM_LDR_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, cond) \
853 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_LDR, 0, 0, 1, cond))
854 #define ARM_LDR_REG_REG_SHIFT(p, rd, rn, rm, shift_type, shift) \
855 ARM_LDR_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
856 #define ARM_LDR_REG_REG(p, rd, rn, rm) \
857 ARM_LDR_REG_REG_SHIFT(p, rd, rn, rm, ARMSHIFT_LSL, 0)
859 #define ARM_LDRB_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, cond) \
860 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_LDR, 0, 1, 1, cond))
861 #define ARM_LDRB_REG_REG_SHIFT(p, rd, rn, rm, shift_type, shift) \
862 ARM_LDRB_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
863 #define ARM_LDRB_REG_REG(p, rd, rn, rm) \
864 ARM_LDRB_REG_REG_SHIFT(p, rd, rn, rm, ARMSHIFT_LSL, 0)
866 #define ARM_STR_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, cond) \
867 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_STR, 0, 0, 1, cond))
868 #define ARM_STR_REG_REG_SHIFT(p, rd, rn, rm, shift_type, shift) \
869 ARM_STR_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
870 #define ARM_STR_REG_REG(p, rd, rn, rm) \
871 ARM_STR_REG_REG_SHIFT(p, rd, rn, rm, ARMSHIFT_LSL, 0)
874 #define ARM_STR_REG_REG_SHIFT_POST_COND(p, rd, rn, rm, shift_type, shift, cond) \
875 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_STR, 0, 0, 0, cond))
876 #define ARM_STR_REG_REG_SHIFT_POST(p, rd, rn, rm, shift_type, shift) \
877 ARM_STR_REG_REG_SHIFT_POST_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
878 #define ARM_STR_REG_REG_POST(p, rd, rn, rm) \
879 ARM_STR_REG_REG_SHIFT_POST(p, rd, rn, rm, ARMSHIFT_LSL, 0)
882 #define ARM_STRB_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, cond) \
883 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_STR, 0, 1, 1, cond))
884 #define ARM_STRB_REG_REG_SHIFT(p, rd, rn, rm, shift_type, shift) \
885 ARM_STRB_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
886 #define ARM_STRB_REG_REG(p, rd, rn, rm) \
887 ARM_STRB_REG_REG_SHIFT(p, rd, rn, rm, ARMSHIFT_LSL, 0)
891 /* Half-word or byte (signed) transfer. */
893 arminstr_t rm : 4; /* imm_lo */
894 arminstr_t tag3 : 1; /* 1 */
895 arminstr_t h : 1; /* half-word or byte */
896 arminstr_t s : 1; /* sign-extend or zero-extend */
897 arminstr_t tag2 : 1; /* 1 */
898 arminstr_t imm_hi : 4;
903 arminstr_t type : 1; /* imm(1) / reg(0) */
904 arminstr_t u : 1; /* +- */
905 arminstr_t p : 1; /* pre/post-index */
910 #define ARM_HXFER_ID 0
911 #define ARM_HXFER_ID2 1
912 #define ARM_HXFER_ID3 1
913 #define ARM_HXFER_MASK ((0x7 << 25) | (0x9 << 4))
914 #define ARM_HXFER_TAG ((ARM_HXFER_ID << 25) | (ARM_HXFER_ID2 << 7) | (ARM_HXFER_ID3 << 4))
916 #define ARM_DEF_HXFER_IMM_COND(imm, h, s, rd, rn, ls, wb, p, cond) \
917 (((int)(imm) >= 0 ? (imm) : -(int)(imm)) & 0xF) | \
920 ((((int)(imm) >= 0 ? (imm) : -(int)(imm)) << 4) & (0xF << 8)) | \
926 (((int)(imm) >= 0) << 23) | \
931 #define ARM_LDRH_IMM_COND(p, rd, rn, imm, cond) \
932 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 1, 0, rd, rn, ARMOP_LDR, 0, 1, cond))
933 #define ARM_LDRH_IMM(p, rd, rn, imm) \
934 ARM_LDRH_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
935 #define ARM_LDRSH_IMM_COND(p, rd, rn, imm, cond) \
936 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 1, 1, rd, rn, ARMOP_LDR, 0, 1, cond))
937 #define ARM_LDRSH_IMM(p, rd, rn, imm) \
938 ARM_LDRSH_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
939 #define ARM_LDRSB_IMM_COND(p, rd, rn, imm, cond) \
940 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 0, 1, rd, rn, ARMOP_LDR, 0, 1, cond))
941 #define ARM_LDRSB_IMM(p, rd, rn, imm) \
942 ARM_LDRSB_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
945 #define ARM_STRH_IMM_COND(p, rd, rn, imm, cond) \
946 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 1, 0, rd, rn, ARMOP_STR, 0, 1, cond))
947 #define ARM_STRH_IMM(p, rd, rn, imm) \
948 ARM_STRH_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
950 #define ARM_STRH_IMM_POST_COND(p, rd, rn, imm, cond) \
951 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 1, 0, rd, rn, ARMOP_STR, 0, 0, cond))
952 #define ARM_STRH_IMM_POST(p, rd, rn, imm) \
953 ARM_STRH_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
956 #define ARM_DEF_HXFER_REG_REG_UPDOWN_COND(rm, h, s, rd, rn, ls, wb, u, p, cond) \
970 #define ARM_DEF_HXFER_REG_REG_COND(rm, h, s, rd, rn, ls, wb, p, cond) \
971 ARM_DEF_HXFER_REG_REG_UPDOWN_COND(rm, h, s, rd, rn, ls, wb, ARM_UP, p, cond)
972 #define ARM_DEF_HXFER_REG_MINUS_REG_COND(rm, h, s, rd, rn, ls, wb, p, cond) \
973 ARM_DEF_HXFER_REG_REG_UPDOWN_COND(rm, h, s, rd, rn, ls, wb, ARM_DOWN, p, cond)
975 #define ARM_LDRH_REG_REG_COND(p, rd, rn, rm, cond) \
976 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 1, 0, rd, rn, ARMOP_LDR, 0, 1, cond))
977 #define ARM_LDRH_REG_REG(p, rd, rn, rm) \
978 ARM_LDRH_REG_REG_COND(p, rd, rn, rm, ARMCOND_AL)
979 #define ARM_LDRSH_REG_REG_COND(p, rd, rn, rm, cond) \
980 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 1, 1, rd, rn, ARMOP_LDR, 0, 1, cond))
981 #define ARM_LDRSH_REG_REG(p, rd, rn, rm) \
982 ARM_LDRSH_REG_REG_COND(p, rd, rn, rm, ARMCOND_AL)
983 #define ARM_LDRSB_REG_REG_COND(p, rd, rn, rm, cond) \
984 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 0, 1, rd, rn, ARMOP_LDR, 0, 1, cond))
985 #define ARM_LDRSB_REG_REG(p, rd, rn, rm) ARM_LDRSB_REG_REG_COND(p, rd, rn, rm, ARMCOND_AL)
987 #define ARM_STRH_REG_REG_COND(p, rd, rn, rm, cond) \
988 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 1, 0, rd, rn, ARMOP_STR, 0, 1, cond))
989 #define ARM_STRH_REG_REG(p, rd, rn, rm) \
990 ARM_STRH_REG_REG_COND(p, rd, rn, rm, ARMCOND_AL)
992 #define ARM_STRH_REG_REG_POST_COND(p, rd, rn, rm, cond) \
993 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 1, 0, rd, rn, ARMOP_STR, 0, 0, cond))
994 #define ARM_STRH_REG_REG_POST(p, rd, rn, rm) \
995 ARM_STRH_REG_REG_POST_COND(p, rd, rn, rm, ARMCOND_AL)
1002 arminstr_t tag3 : 8; /* 0x9 */
1005 arminstr_t tag2 : 2;
1007 arminstr_t tag : 5; /* 0x2 */
1008 arminstr_t cond : 4;
1011 #define ARM_SWP_ID 2
1012 #define ARM_SWP_ID2 9
1013 #define ARM_SWP_MASK ((0x1F << 23) | (3 << 20) | (0xFF << 4))
1014 #define ARM_SWP_TAG ((ARM_SWP_ID << 23) | (ARM_SWP_ID2 << 4))
1018 /* Software interrupt */
1020 arminstr_t num : 24;
1022 arminstr_t cond : 4;
1025 #define ARM_SWI_ID 0xF
1026 #define ARM_SWI_MASK (0xF << 24)
1027 #define ARM_SWI_TAG (ARM_SWI_ID << 24)
1031 /* Co-processor Data Processing */
1034 arminstr_t tag2 : 1; /* 0 */
1036 arminstr_t cpn : 4; /* CP number */
1040 arminstr_t tag : 4; /* 0xE */
1041 arminstr_t cond : 4;
1044 #define ARM_CDP_ID 0xE
1045 #define ARM_CDP_ID2 0
1046 #define ARM_CDP_MASK ((0xF << 24) | (1 << 4))
1047 #define ARM_CDP_TAG ((ARM_CDP_ID << 24) | (ARM_CDP_ID2 << 4))
1050 /* Co-processor Data Transfer (ldc/stc) */
1052 arminstr_t offs : 8;
1062 arminstr_t cond : 4;
1065 #define ARM_CDT_ID 6
1066 #define ARM_CDT_MASK (7 << 25)
1067 #define ARM_CDT_TAG (ARM_CDT_ID << 25)
1070 /* Co-processor Register Transfer (mcr/mrc) */
1073 arminstr_t tag2 : 1;
1081 arminstr_t cond : 4;
1084 #define ARM_CRT_ID 0xE
1085 #define ARM_CRT_ID2 0x1
1086 #define ARM_CRT_MASK ((0xF << 24) | (1 << 4))
1087 #define ARM_CRT_TAG ((ARM_CRT_ID << 24) | (ARM_CRT_ID2 << 4))
1090 * Move from co-processor register to CPU register
1091 * Rd := cRn {<op>cRm}
1092 * op{condition} CP#,CPOp,Rd,CRn,CRm{,CPOp2}
1094 #define ARM_DEF_MRC_COND(cpn, cpop, rd, crn, crm, cpop2, cond) \
1100 ((ARMOP_LDR) << 20) |\
1105 #define ARM_MRC_COND(p, cpn, cpop, rd, crn, crm, cpop2, cond) \
1106 ARM_EMIT(p, ARM_DEF_MRC_COND(cpn, cpop, rd, crn, crm, cpop2, cond))
1107 #define ARM_MRC(p, cpn, cpop, rd, crn, crm, cpop2) \
1108 ARM_MRC_COND(p, cpn, cpop, rd, crn, crm, cpop2, ARMCOND_AL)
1112 /* Move register to PSR. */
1114 ARMDPI_op2_imm op2_imm;
1117 arminstr_t pad : 8; /* 0 */
1118 arminstr_t tag4 : 4; /* 0xF */
1120 arminstr_t tag3 : 2; /* 0x2 */
1122 arminstr_t tag2 : 2; /* 0x2 */
1123 arminstr_t type : 1;
1124 arminstr_t tag : 2; /* 0 */
1125 arminstr_t cond : 4;
1129 #define ARM_MSR_ID 0
1130 #define ARM_MSR_ID2 2
1131 #define ARM_MSR_ID3 2
1132 #define ARM_MSR_ID4 0xF
1133 #define ARM_MSR_MASK ((3 << 26) | \
1137 #define ARM_MSR_TAG ((ARM_MSR_ID << 26) | \
1138 (ARM_MSR_ID2 << 23) | \
1139 (ARM_MSR_ID3 << 20) | \
1140 (ARM_MSR_ID4 << 12))
1142 #define ARM_DEF_MSR_REG_COND(mask, rm, r, cond) \
1144 ARM_DEF_COND(cond) | \
1146 (((r) & 1) << 22) | \
1147 (((mask) & 0xf) << 16)
1149 #define ARM_MSR_REG_COND(p, mask, rm, r, cond) \
1150 ARM_EMIT(p, ARM_DEF_MSR_REG_COND(mask, rm, r, cond))
1152 #define ARM_MSR_REG(p, mask, rm, r) \
1153 ARM_MSR_REG_COND(p, mask, rm, r, ARMCOND_AL)
1163 /* Move PSR to register. */
1165 arminstr_t tag3 : 12;
1167 arminstr_t tag2 : 6;
1168 arminstr_t sel : 1; /* CPSR | SPSR */
1170 arminstr_t cond : 4;
1173 #define ARM_MRS_ID 2
1174 #define ARM_MRS_ID2 0xF
1175 #define ARM_MRS_ID3 0
1176 #define ARM_MRS_MASK ((0x1F << 23) | (0x3F << 16) | 0xFFF)
1177 #define ARM_MRS_TAG ((ARM_MRS_ID << 23) | (ARM_MRS_ID2 << 16) | ARM_MRS_ID3)
1179 #define ARM_DEF_MRS_COND(rd, r, cond) \
1181 ARM_DEF_COND(cond) | \
1182 (((r) & 1) << 22) | \
1185 #define ARM_MRS_COND(p, rd, r, cond) \
1186 ARM_EMIT(p, ARM_DEF_MRS_COND(rd, r, cond))
1188 #define ARM_MRS_CPSR_COND(p, rd, cond) \
1189 ARM_MRS_COND(p, rd, ARM_CPSR, cond)
1191 #define ARM_MRS_CPSR(p, rd) \
1192 ARM_MRS_CPSR_COND(p, rd, ARMCOND_AL)
1194 #define ARM_MRS_SPSR_COND(p, rd, cond) \
1195 ARM_MRS_COND(p, rd, ARM_SPSR, cond)
1197 #define ARM_MRS_SPSR(p, rd) \
1198 ARM_MRS_SPSR_COND(p, rd, ARMCOND_AL)
1201 #include "arm_dpimacros.h"
1203 #define ARM_NOP(p) ARM_MOV_REG_REG(p, ARMREG_R0, ARMREG_R0)
1206 #define ARM_SHL_IMM_COND(p, rd, rm, imm, cond) \
1207 ARM_MOV_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_LSL, imm, cond)
1208 #define ARM_SHL_IMM(p, rd, rm, imm) \
1209 ARM_SHL_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
1210 #define ARM_SHLS_IMM_COND(p, rd, rm, imm, cond) \
1211 ARM_MOVS_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_LSL, imm, cond)
1212 #define ARM_SHLS_IMM(p, rd, rm, imm) \
1213 ARM_SHLS_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
1215 #define ARM_SHR_IMM_COND(p, rd, rm, imm, cond) \
1216 ARM_MOV_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_LSR, imm, cond)
1217 #define ARM_SHR_IMM(p, rd, rm, imm) \
1218 ARM_SHR_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
1219 #define ARM_SHRS_IMM_COND(p, rd, rm, imm, cond) \
1220 ARM_MOVS_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_LSR, imm, cond)
1221 #define ARM_SHRS_IMM(p, rd, rm, imm) \
1222 ARM_SHRS_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
1224 #define ARM_SAR_IMM_COND(p, rd, rm, imm, cond) \
1225 ARM_MOV_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_ASR, imm, cond)
1226 #define ARM_SAR_IMM(p, rd, rm, imm) \
1227 ARM_SAR_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
1228 #define ARM_SARS_IMM_COND(p, rd, rm, imm, cond) \
1229 ARM_MOVS_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_ASR, imm, cond)
1230 #define ARM_SARS_IMM(p, rd, rm, imm) \
1231 ARM_SARS_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
1233 #define ARM_ROR_IMM_COND(p, rd, rm, imm, cond) \
1234 ARM_MOV_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_ROR, imm, cond)
1235 #define ARM_ROR_IMM(p, rd, rm, imm) \
1236 ARM_ROR_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
1237 #define ARM_RORS_IMM_COND(p, rd, rm, imm, cond) \
1238 ARM_MOVS_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_ROR, imm, cond)
1239 #define ARM_RORS_IMM(p, rd, rm, imm) \
1240 ARM_RORS_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
1242 #define ARM_SHL_REG_COND(p, rd, rm, rs, cond) \
1243 ARM_MOV_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_LSL, rs, cond)
1244 #define ARM_SHL_REG(p, rd, rm, rs) \
1245 ARM_SHL_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1246 #define ARM_SHLS_REG_COND(p, rd, rm, rs, cond) \
1247 ARM_MOVS_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_LSL, rs, cond)
1248 #define ARM_SHLS_REG(p, rd, rm, rs) \
1249 ARM_SHLS_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1250 #define ARM_SHLS_REG_REG(p, rd, rm, rs) ARM_SHLS_REG(p, rd, rm, rs)
1252 #define ARM_SHR_REG_COND(p, rd, rm, rs, cond) \
1253 ARM_MOV_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_LSR, rs, cond)
1254 #define ARM_SHR_REG(p, rd, rm, rs) \
1255 ARM_SHR_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1256 #define ARM_SHRS_REG_COND(p, rd, rm, rs, cond) \
1257 ARM_MOVS_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_LSR, rs, cond)
1258 #define ARM_SHRS_REG(p, rd, rm, rs) \
1259 ARM_SHRS_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1260 #define ARM_SHRS_REG_REG(p, rd, rm, rs) ARM_SHRS_REG(p, rd, rm, rs)
1262 #define ARM_SAR_REG_COND(p, rd, rm, rs, cond) \
1263 ARM_MOV_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_ASR, rs, cond)
1264 #define ARM_SAR_REG(p, rd, rm, rs) \
1265 ARM_SAR_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1266 #define ARM_SARS_REG_COND(p, rd, rm, rs, cond) \
1267 ARM_MOVS_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_ASR, rs, cond)
1268 #define ARM_SARS_REG(p, rd, rm, rs) \
1269 ARM_SARS_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1270 #define ARM_SARS_REG_REG(p, rd, rm, rs) ARM_SARS_REG(p, rd, rm, rs)
1272 #define ARM_ROR_REG_COND(p, rd, rm, rs, cond) \
1273 ARM_MOV_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_ROR, rs, cond)
1274 #define ARM_ROR_REG(p, rd, rm, rs) \
1275 ARM_ROR_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1276 #define ARM_RORS_REG_COND(p, rd, rm, rs, cond) \
1277 ARM_MOVS_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_ROR, rs, cond)
1278 #define ARM_RORS_REG(p, rd, rm, rs) \
1279 ARM_RORS_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1280 #define ARM_RORS_REG_REG(p, rd, rm, rs) ARM_RORS_REG(p, rd, rm, rs)
1282 #define ARM_DBRK(p) ARM_EMIT(p, 0xE6000010)
1283 #define ARM_IASM_DBRK() ARM_IASM_EMIT(0xE6000010)
1285 #define ARM_INC(p, reg) ARM_ADD_REG_IMM8(p, reg, reg, 1)
1286 #define ARM_DEC(p, reg) ARM_SUB_REG_IMM8(p, reg, reg, 1)
1291 /* Count leading zeros, CLZ{cond} Rd, Rm */
1294 arminstr_t tag2 : 8;
1296 arminstr_t tag : 12;
1297 arminstr_t cond : 4;
1300 #define ARM_CLZ_ID 0x16F
1301 #define ARM_CLZ_ID2 0xF1
1302 #define ARM_CLZ_MASK ((0xFFF << 16) | (0xFF < 4))
1303 #define ARM_CLZ_TAG ((ARM_CLZ_ID << 16) | (ARM_CLZ_ID2 << 4))
1305 #define ARM_DEF_CLZ_COND(rd, rm, cond) \
1307 ARM_DEF_COND(cond) | \
1311 #define ARM_CLZ_COND(p, rd, rm, cond) \
1312 ARM_EMIT(p, ARM_DEF_CLZ_COND(rd, rm, cond))
1314 #define ARM_CLZ(p, rd, rm) \
1315 ARM_EMIT(p, ARM_DEF_CLZ_COND(rd, rm, ARMCOND_AL))
1319 * ARMCOND_NV | 0-1-0 | 0 | +/- | 1 | 0 | 1 | rn -|- 0xF | imm12
1321 #define ARM_PLD_ID 0xF45
1322 #define ARM_PLD_ID2 0xF /* rd */
1323 #define ARM_PLD_MASK ((0xFC7 << 20) | (0xF << 12))
1324 #define ARM_PLD_TAG ((ARM_PLD_ID << 20) | (ARM_PLD_ID2 << 12))
1325 #define ARM_DEF_PLD_IMM(imm12, rn) \
1326 ((((int)imm12) < 0) ? -(int)(imm12) : (imm12)) | \
1329 ((1) << 20) /* ls = load(1) */ | \
1330 ((0) << 21) /* wb = 0 */ | \
1331 ((1) << 22) /* b = 1 */ | \
1332 (((int)(imm12) >= 0) << 23) | \
1333 ((1) << 24) /* pre/post = pre(1) */ | \
1334 ((2) << 25) /* tag */ | \
1335 ARM_DEF_COND(ARMCOND_NV)
1337 #define ARM_PLD_IMM(p, rn, imm12) ARM_EMIT(p, ARM_DEF_PLD_IMM(imm12, rn))
1339 #define ARM_DEF_PLD_REG_REG_UPDOWN_SHIFT(rn, shift_type, shift, rm, u) \
1341 ((shift_type) << 5) | \
1343 (0xF << 12) /* rd = 0xF */ | \
1345 (1 << 20) /* ls = load(1) */ | \
1346 (0 << 21) /* wb = 0 */ | \
1347 (1 << 22) /* b = 1 */ | \
1349 (1 << 24) /* pre(1) */ | \
1351 ARM_DEF_COND(ARMCOND_NV)
1353 #define ARM_PLD_REG_REG_UPDOWN_SHIFT(p, rm, rn, u, shift_type, shift) \
1354 ARM_EMIT(p, ARM_DEF_PLD_REG_REG_UPDOWN_SHIFT(rm, shift_type, shift, rn, u))
1356 #define ARM_PLD_REG_PLUS_REG(p, rm, rn) \
1357 ARM_PLD_REG_REG_UPDOWN_SHIFT(p, rm, rn, ARM_UP, ARMSHIFT_LSL, 0)
1359 #define ARM_PLD_REG_MINUS_REG(p, rm, rn) \
1360 ARM_PLD_REG_REG_UPDOWN_SHIFT(p, rm, rn, ARM_DOWN, ARMSHIFT_LSL, 0)
1363 #define ARM_DEF_STF_IMM_COND(p, prec, freg_const, rd, imm8, rot, cond) \
1365 (((rot) & 0xF) << 8) | \
1366 ((freg_const) << 12) | \
1376 ARMInstrWXfer wxfer;
1377 ARMInstrHXfer hxfer;
1387 ARMInstrGeneric generic;
1391 #endif /* ARM_CG_H */