3 * Copyright (c) 2002-2003 Sergey Chaban <serge@wildwestsoftware.com>
4 * Copyright 2005-2011 Novell Inc
5 * Copyright 2011 Xamarin Inc
16 typedef unsigned int arminstr_t;
17 typedef unsigned int armword_t;
19 /* Helper functions */
20 arminstr_t* arm_emit_std_prologue(arminstr_t* p, unsigned int local_size);
21 arminstr_t* arm_emit_std_epilogue(arminstr_t* p, unsigned int local_size, int pop_regs);
22 arminstr_t* arm_emit_lean_prologue(arminstr_t* p, unsigned int local_size, int push_regs);
23 int arm_is_power_of_2(armword_t val);
24 int calc_arm_mov_const_shift(armword_t val);
25 int is_arm_const(armword_t val);
26 int arm_bsf(armword_t val);
27 arminstr_t* arm_mov_reg_imm32_cond(arminstr_t* p, int reg, armword_t imm32, int cond);
28 arminstr_t* arm_mov_reg_imm32(arminstr_t* p, int reg, armword_t imm32);
32 #if defined(_MSC_VER) || defined(__CC_NORCROFT)
33 void __inline _arm_emit(arminstr_t** p, arminstr_t i) {**p = i; (*p)++;}
34 # define ARM_EMIT(p, i) _arm_emit((arminstr_t**)&p, (arminstr_t)(i))
36 # define ARM_EMIT(p, i) do { arminstr_t *__ainstrp = (void*)(p); *__ainstrp = (arminstr_t)(i); (p) = (void*)(__ainstrp+1);} while (0)
39 #if defined(_MSC_VER) && !defined(ARM_NOIASM)
40 # define ARM_IASM(_expr) __emit (_expr)
42 # define ARM_IASM(_expr)
45 /* even_scale = rot << 1 */
46 #define ARM_SCALE(imm8, even_scale) ( ((imm8) >> (even_scale)) | ((imm8) << (32 - even_scale)) )
71 ARMREG_A1 = ARMREG_R0,
72 ARMREG_A2 = ARMREG_R1,
73 ARMREG_A3 = ARMREG_R2,
74 ARMREG_A4 = ARMREG_R3,
77 ARMREG_V1 = ARMREG_R4,
78 ARMREG_V2 = ARMREG_R5,
79 ARMREG_V3 = ARMREG_R6,
80 ARMREG_V4 = ARMREG_R7,
81 ARMREG_V5 = ARMREG_R8,
82 ARMREG_V6 = ARMREG_R9,
83 ARMREG_V7 = ARMREG_R10,
85 ARMREG_FP = ARMREG_R11,
86 ARMREG_IP = ARMREG_R12,
87 ARMREG_SP = ARMREG_R13,
88 ARMREG_LR = ARMREG_R14,
89 ARMREG_PC = ARMREG_R15,
109 /* XScale: acc0 on CP0 */
110 ARMREG_ACC0 = ARMREG_CR0,
112 ARMREG_MAX = ARMREG_R15
115 /* number of argument registers */
116 #define ARM_NUM_ARG_REGS 4
118 /* bitvector for all argument regs (A1-A4) */
119 #define ARM_ALL_ARG_REGS \
120 (1 << ARMREG_A1) | (1 << ARMREG_A2) | (1 << ARMREG_A3) | (1 << ARMREG_A4)
124 ARMCOND_EQ = 0x0, /* Equal; Z = 1 */
125 ARMCOND_NE = 0x1, /* Not equal, or unordered; Z = 0 */
126 ARMCOND_CS = 0x2, /* Carry set; C = 1 */
127 ARMCOND_HS = ARMCOND_CS, /* Unsigned higher or same; */
128 ARMCOND_CC = 0x3, /* Carry clear; C = 0 */
129 ARMCOND_LO = ARMCOND_CC, /* Unsigned lower */
130 ARMCOND_MI = 0x4, /* Negative; N = 1 */
131 ARMCOND_PL = 0x5, /* Positive or zero; N = 0 */
132 ARMCOND_VS = 0x6, /* Overflow; V = 1 */
133 ARMCOND_VC = 0x7, /* No overflow; V = 0 */
134 ARMCOND_HI = 0x8, /* Unsigned higher; C = 1 && Z = 0 */
135 ARMCOND_LS = 0x9, /* Unsigned lower or same; C = 0 || Z = 1 */
136 ARMCOND_GE = 0xA, /* Signed greater than or equal; N = V */
137 ARMCOND_LT = 0xB, /* Signed less than; N != V */
138 ARMCOND_GT = 0xC, /* Signed greater than; Z = 0 && N = V */
139 ARMCOND_LE = 0xD, /* Signed less than or equal; Z = 1 && N != V */
140 ARMCOND_AL = 0xE, /* Always */
141 ARMCOND_NV = 0xF, /* Never */
146 #define ARMCOND_MASK (ARMCOND_NV << ARMCOND_SHIFT)
148 #define ARM_DEF_COND(cond) (((cond) & 0xF) << ARMCOND_SHIFT)
158 ARMSHIFT_ASL = ARMSHIFT_LSL
189 /* not really opcodes */
195 ARMOP_MUL = 0x0, /* Rd := Rm*Rs */
196 ARMOP_MLA = 0x1, /* Rd := (Rm*Rs)+Rn */
204 /* for data transfers with register offset */
235 /* Generic form - all ARM instructions are conditional. */
237 arminstr_t icode : 28;
243 /* Branch or Branch with Link instructions. */
245 arminstr_t offset : 24;
247 arminstr_t tag : 3; /* 1 0 1 */
252 #define ARM_BR_MASK 7 << 25
253 #define ARM_BR_TAG ARM_BR_ID << 25
255 #define ARM_DEF_BR(offs, l, cond) ((offs) | ((l) << 24) | (ARM_BR_TAG) | (cond << ARMCOND_SHIFT))
258 #define ARM_B_COND(p, cond, offset) ARM_EMIT(p, ARM_DEF_BR(offset, 0, cond))
259 #define ARM_B(p, offs) ARM_B_COND((p), ARMCOND_AL, (offs))
260 /* branch with link */
261 #define ARM_BL_COND(p, cond, offset) ARM_EMIT(p, ARM_DEF_BR(offset, 1, cond))
262 #define ARM_BL(p, offs) ARM_BL_COND((p), ARMCOND_AL, (offs))
264 #define ARM_DEF_BX(reg,sub,cond) (0x12fff << 8 | (reg) | ((sub) << 4) | ((cond) << ARMCOND_SHIFT))
266 #define ARM_BX_COND(p, cond, reg) ARM_EMIT(p, ARM_DEF_BX(reg, 1, cond))
267 #define ARM_BX(p, reg) ARM_BX_COND((p), ARMCOND_AL, (reg))
269 #define ARM_BLX_REG_COND(p, cond, reg) ARM_EMIT(p, ARM_DEF_BX(reg, 3, cond))
270 #define ARM_BLX_REG(p, reg) ARM_BLX_REG_COND((p), ARMCOND_AL, (reg))
272 /* Data Processing Instructions - there are 3 types. */
281 arminstr_t tag : 1; /* 0 - immediate shift, 1 - reg shift */
282 arminstr_t type : 2; /* shift type - logical, arithmetic, rotate */
283 } ARMDPI_op2_reg_shift;
286 /* op2 is reg shift by imm */
288 ARMDPI_op2_reg_shift r2;
290 arminstr_t _dummy_r2 : 7;
291 arminstr_t shift : 5;
293 } ARMDPI_op2_reg_imm;
295 /* op2 is reg shift by reg */
297 ARMDPI_op2_reg_shift r2;
299 arminstr_t _dummy_r2 : 7;
300 arminstr_t pad : 1; /* always 0, to differentiate from HXFER etc. */
303 } ARMDPI_op2_reg_reg;
305 /* Data processing instrs */
307 ARMDPI_op2_imm op2_imm;
309 ARMDPI_op2_reg_shift op2_reg;
310 ARMDPI_op2_reg_imm op2_reg_imm;
311 ARMDPI_op2_reg_reg op2_reg_reg;
314 arminstr_t op2 : 12; /* raw operand 2 */
315 arminstr_t rd : 4; /* destination reg */
316 arminstr_t rn : 4; /* first operand reg */
317 arminstr_t s : 1; /* S-bit controls PSR update */
318 arminstr_t opcode : 4; /* arithmetic/logic operation */
319 arminstr_t type : 1; /* type of op2, 0 = register, 1 = immediate */
320 arminstr_t tag : 2; /* 0 0 */
326 #define ARM_DPI_MASK 3 << 26
327 #define ARM_DPI_TAG ARM_DPI_ID << 26
329 #define ARM_DEF_DPI_IMM_COND(imm8, rot, rd, rn, s, op, cond) \
331 (((rot) & 0xF) << 8) | \
341 #define ARM_DEF_DPI_IMM(imm8, rot, rd, rn, s, op) \
342 ARM_DEF_DPI_IMM_COND(imm8, rot, rd, rn, s, op, ARMCOND_AL)
345 #define ARM_DPIOP_REG_IMM8ROT_COND(p, op, rd, rn, imm8, rot, cond) \
346 ARM_EMIT(p, ARM_DEF_DPI_IMM_COND((imm8), ((rot) >> 1), (rd), (rn), 0, (op), cond))
347 #define ARM_DPIOP_S_REG_IMM8ROT_COND(p, op, rd, rn, imm8, rot, cond) \
348 ARM_EMIT(p, ARM_DEF_DPI_IMM_COND((imm8), ((rot) >> 1), (rd), (rn), 1, (op), cond))
351 #define ARM_IASM_DPIOP_REG_IMM8ROT_COND(p, op, rd, rn, imm8, rot, cond) \
352 ARM_IASM(ARM_DEF_DPI_IMM_COND((imm8), ((rot) >> 1), (rd), (rn), 0, (op), cond))
353 #define ARM_IASM_DPIOP_S_REG_IMM8ROT_COND(p, op, rd, rn, imm8, rot, cond) \
354 ARM_IASM(ARM_DEF_DPI_IMM_COND((imm8), ((rot) >> 1), (rd), (rn), 1, (op), cond))
358 #define ARM_DEF_DPI_REG_IMMSHIFT_COND(rm, shift_type, imm_shift, rd, rn, s, op, cond) \
360 ((shift_type & 3) << 5) | \
361 (((imm_shift) & 0x1F) << 7) | \
370 #define ARM_DPIOP_REG_IMMSHIFT_COND(p, op, rd, rn, rm, shift_t, imm_shift, cond) \
371 ARM_EMIT(p, ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), shift_t, imm_shift, (rd), (rn), 0, (op), cond))
373 #define ARM_DPIOP_S_REG_IMMSHIFT_COND(p, op, rd, rn, rm, shift_t, imm_shift, cond) \
374 ARM_EMIT(p, ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), shift_t, imm_shift, (rd), (rn), 1, (op), cond))
376 #define ARM_DPIOP_REG_REG_COND(p, op, rd, rn, rm, cond) \
377 ARM_EMIT(p, ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), ARMSHIFT_LSL, 0, (rd), (rn), 0, (op), cond))
379 #define ARM_DPIOP_S_REG_REG_COND(p, op, rd, rn, rm, cond) \
380 ARM_EMIT(p, ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), ARMSHIFT_LSL, 0, (rd), (rn), 1, (op), cond))
383 #define ARM_IASM_DPIOP_REG_IMMSHIFT_COND(p, op, rd, rn, rm, shift_t, imm_shift, cond) \
384 ARM_IASM(ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), shift_t, imm_shift, (rd), (rn), 0, (op), cond))
386 #define ARM_IASM_DPIOP_S_REG_IMMSHIFT_COND(p, op, rd, rn, rm, shift_t, imm_shift, cond) \
387 ARM_IASM(ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), shift_t, imm_shift, (rd), (rn), 1, (op), cond))
389 #define ARM_IASM_DPIOP_REG_REG_COND(p, op, rd, rn, rm, cond) \
390 ARM_IASM(ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), ARMSHIFT_LSL, 0, (rd), (rn), 0, (op), cond))
392 #define ARM_IASM_DPIOP_S_REG_REG_COND(p, op, rd, rn, rm, cond) \
393 ARM_IASM_EMIT(ARM_DEF_DPI_REG_IMMSHIFT_COND((rm), ARMSHIFT_LSL, 0, (rd), (rn), 1, (op), cond))
396 /* Rd := Rn op (Rm shift_type Rs) */
397 #define ARM_DEF_DPI_REG_REGSHIFT_COND(rm, shift_type, rs, rd, rn, s, op, cond) \
400 ((shift_type & 3) << 5) | \
410 #define ARM_DPIOP_REG_REGSHIFT_COND(p, op, rd, rn, rm, shift_t, rs, cond) \
411 ARM_EMIT(p, ARM_DEF_DPI_REG_REGSHIFT_COND((rm), shift_t, (rs), (rd), (rn), 0, (op), cond))
413 #define ARM_DPIOP_S_REG_REGSHIFT_COND(p, op, rd, rn, rm, shift_t, rs, cond) \
414 ARM_EMIT(p, ARM_DEF_DPI_REG_REGSHIFT_COND((rm), shift_t, (rs), (rd), (rn), 1, (op), cond))
417 #define ARM_IASM_DPIOP_REG_REGSHIFT_COND(p, op, rd, rn, rm, shift_t, rs, cond) \
418 ARM_IASM(ARM_DEF_DPI_REG_REGSHIFT_COND((rm), shift_t, (rs), (rd), (rn), 0, (op), cond))
420 #define ARM_IASM_DPIOP_S_REG_REGSHIFT_COND(p, op, rd, rn, rm, shift_t, rs, cond) \
421 ARM_IASM(ARM_DEF_DPI_REG_REGSHIFT_COND((rm), shift_t, (rs), (rd), (rn), 1, (op), cond))
425 /* Multiple register transfer. */
427 arminstr_t reg_list : 16; /* bitfield */
428 arminstr_t rn : 4; /* base reg */
429 arminstr_t ls : 1; /* load(1)/store(0) */
430 arminstr_t wb : 1; /* write-back "!" */
431 arminstr_t s : 1; /* restore PSR, force user bit */
432 arminstr_t u : 1; /* up/down */
433 arminstr_t p : 1; /* pre(1)/post(0) index */
434 arminstr_t tag : 3; /* 1 0 0 */
439 #define ARM_MRT_MASK 7 << 25
440 #define ARM_MRT_TAG ARM_MRT_ID << 25
442 #define ARM_DEF_MRT(regs, rn, l, w, s, u, p, cond) \
454 #define ARM_LDM(p, base, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, base, 1, 0, 0, 1, 0, ARMCOND_AL))
455 #define ARM_STM(p, base, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, base, 0, 0, 0, 1, 0, ARMCOND_AL))
457 /* stmdb sp!, {regs} */
458 #define ARM_PUSH(p, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, ARMREG_SP, 0, 1, 0, 0, 1, ARMCOND_AL))
459 #define ARM_IASM_PUSH(regs) ARM_IASM(ARM_DEF_MRT(regs, ARMREG_SP, 0, 1, 0, 0, 1, ARMCOND_AL))
461 /* ldmia sp!, {regs} */
462 #define ARM_POP(p, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, ARMREG_SP, 1, 1, 0, 1, 0, ARMCOND_AL))
463 #define ARM_IASM_POP(regs) ARM_IASM_EMIT(ARM_DEF_MRT(regs, ARMREG_SP, 1, 1, 0, 1, 0, ARMCOND_AL))
465 /* ldmia sp, {regs} ; (no write-back) */
466 #define ARM_POP_NWB(p, regs) ARM_EMIT(p, ARM_DEF_MRT(regs, ARMREG_SP, 1, 0, 0, 1, 0, ARMCOND_AL))
467 #define ARM_IASM_POP_NWB(regs) ARM_IASM_EMIT(ARM_DEF_MRT(regs, ARMREG_SP, 1, 0, 0, 1, 0, ARMCOND_AL))
469 #define ARM_PUSH1(p, r1) ARM_PUSH(p, (1 << r1))
470 #define ARM_PUSH2(p, r1, r2) ARM_PUSH(p, (1 << r1) | (1 << r2))
471 #define ARM_PUSH3(p, r1, r2, r3) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3))
472 #define ARM_PUSH4(p, r1, r2, r3, r4) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4))
473 #define ARM_PUSH5(p, r1, r2, r3, r4, r5) ARM_PUSH(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5))
474 #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))
475 #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))
476 #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))
478 #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))
479 #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))
480 #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))
481 #define ARM_POP5(p, r1, r2, r3, r4, r5) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4) | (1 << r5))
482 #define ARM_POP4(p, r1, r2, r3, r4) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3) | (1 << r4))
483 #define ARM_POP3(p, r1, r2, r3) ARM_POP(p, (1 << r1) | (1 << r2) | (1 << r3))
484 #define ARM_POP2(p, r1, r2) ARM_POP(p, (1 << r1) | (1 << r2))
485 #define ARM_POP1(p, r1) ARM_POP(p, (1 << r1))
488 /* Multiply instructions */
491 arminstr_t tag2 : 4; /* 9 */
496 arminstr_t opcode : 3;
502 #define ARM_MUL_ID2 9
503 #define ARM_MUL_MASK ((0xF << 24) | (0xF << 4))
504 #define ARM_MUL_TAG ((ARM_MUL_ID << 24) | (ARM_MUL_ID2 << 4))
506 #define ARM_DEF_MUL_COND(op, rd, rm, rs, rn, s, cond) \
516 /* Rd := (Rm * Rs)[31:0]; 32 x 32 -> 32 */
517 #define ARM_MUL_COND(p, rd, rm, rs, cond) \
518 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_MUL, rd, rm, rs, 0, 0, cond))
519 #define ARM_MUL(p, rd, rm, rs) \
520 ARM_MUL_COND(p, rd, rm, rs, ARMCOND_AL)
521 #define ARM_MULS_COND(p, rd, rm, rs, cond) \
522 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_MUL, rd, rm, rs, 0, 1, cond))
523 #define ARM_MULS(p, rd, rm, rs) \
524 ARM_MULS_COND(p, rd, rm, rs, ARMCOND_AL)
525 #define ARM_MUL_REG_REG(p, rd, rm, rs) ARM_MUL(p, rd, rm, rs)
526 #define ARM_MULS_REG_REG(p, rd, rm, rs) ARM_MULS(p, rd, rm, rs)
529 #define ARM_IASM_MUL_COND(rd, rm, rs, cond) \
530 ARM_IASM_EMIT(ARM_DEF_MUL_COND(ARMOP_MUL, rd, rm, rs, 0, 0, cond))
531 #define ARM_IASM_MUL(rd, rm, rs) \
532 ARM_IASM_MUL_COND(rd, rm, rs, ARMCOND_AL)
533 #define ARM_IASM_MULS_COND(rd, rm, rs, cond) \
534 ARM_IASM_EMIT(ARM_DEF_MUL_COND(ARMOP_MUL, rd, rm, rs, 0, 1, cond))
535 #define ARM_IASM_MULS(rd, rm, rs) \
536 ARM_IASM_MULS_COND(rd, rm, rs, ARMCOND_AL)
539 /* Rd := (Rm * Rs) + Rn; 32x32+32->32 */
540 #define ARM_MLA_COND(p, rd, rm, rs, rn, cond) \
541 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_MLA, rd, rm, rs, rn, 0, cond))
542 #define ARM_MLA(p, rd, rm, rs, rn) \
543 ARM_MLA_COND(p, rd, rm, rs, rn, ARMCOND_AL)
544 #define ARM_MLAS_COND(p, rd, rm, rs, rn, cond) \
545 ARM_EMIT(p, ARM_DEF_MUL_COND(ARMOP_MLA, rd, rm, rs, rn, 1, cond))
546 #define ARM_MLAS(p, rd, rm, rs, rn) \
547 ARM_MLAS_COND(p, rd, rm, rs, rn, ARMCOND_AL)
550 #define ARM_IASM_MLA_COND(rd, rm, rs, rn, cond) \
551 ARM_IASM_EMIT(ARM_DEF_MUL_COND(ARMOP_MLA, rd, rm, rs, rn, 0, cond))
552 #define ARM_IASM_MLA(rd, rm, rs, rn) \
553 ARM_IASM_MLA_COND(rd, rm, rs, rn, ARMCOND_AL)
554 #define ARM_IASM_MLAS_COND(rd, rm, rs, rn, cond) \
555 ARM_IASM_EMIT(ARM_DEF_MUL_COND(ARMOP_MLA, rd, rm, rs, rn, 1, cond))
556 #define ARM_IASM_MLAS(rd, rm, rs, rn) \
557 ARM_IASM_MLAS_COND(rd, rm, rs, rn, ARMCOND_AL)
561 /* Word/byte transfer */
563 ARMDPI_op2_reg_imm op2_reg_imm;
565 arminstr_t op2_imm : 12;
571 arminstr_t u : 1; /* down(0) / up(1) */
572 arminstr_t p : 1; /* post-index(0) / pre-index(1) */
573 arminstr_t type : 1; /* imm(0) / register(1) */
574 arminstr_t tag : 2; /* 0 1 */
579 #define ARM_WXFER_ID 1
580 #define ARM_WXFER_MASK 3 << 26
581 #define ARM_WXFER_TAG ARM_WXFER_ID << 26
584 #define ARM_DEF_WXFER_IMM(imm12, rd, rn, ls, wb, b, p, cond) \
585 ((((int)imm12) < 0) ? -(int)(imm12) : (imm12)) | \
591 (((int)(imm12) >= 0) << 23) | \
596 #define ARM_WXFER_MAX_OFFS 0xFFF
598 /* this macro checks for imm12 bounds */
599 #define ARM_EMIT_WXFER_IMM(ptr, imm12, rd, rn, ls, wb, b, p, cond) \
601 int _imm12 = (int)(imm12) < -ARM_WXFER_MAX_OFFS \
602 ? -ARM_WXFER_MAX_OFFS \
603 : (int)(imm12) > ARM_WXFER_MAX_OFFS \
604 ? ARM_WXFER_MAX_OFFS \
607 ARM_DEF_WXFER_IMM(_imm12, (rd), (rn), (ls), (wb), (b), (p), (cond))); \
612 /* immediate offset, post-index */
613 #define ARM_LDR_IMM_POST_COND(p, rd, rn, imm, cond) \
614 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_LDR, 0, 0, 0, cond))
616 #define ARM_LDR_IMM_POST(p, rd, rn, imm) ARM_LDR_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
618 #define ARM_LDRB_IMM_POST_COND(p, rd, rn, imm, cond) \
619 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_LDR, 0, 1, 0, cond))
621 #define ARM_LDRB_IMM_POST(p, rd, rn, imm) ARM_LDRB_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
623 /* immediate offset, pre-index */
624 #define ARM_LDR_IMM_COND(p, rd, rn, imm, cond) \
625 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_LDR, 0, 0, 1, cond))
627 #define ARM_LDR_IMM(p, rd, rn, imm) ARM_LDR_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
629 #define ARM_LDRB_IMM_COND(p, rd, rn, imm, cond) \
630 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_LDR, 0, 1, 1, cond))
632 #define ARM_LDRB_IMM(p, rd, rn, imm) ARM_LDRB_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
635 /* immediate offset, post-index */
636 #define ARM_STR_IMM_POST_COND(p, rd, rn, imm, cond) \
637 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 0, 0, cond))
639 #define ARM_STR_IMM_POST(p, rd, rn, imm) ARM_STR_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
641 #define ARM_STRB_IMM_POST_COND(p, rd, rn, imm, cond) \
642 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 1, 0, cond))
644 #define ARM_STRB_IMM_POST(p, rd, rn, imm) ARM_STRB_IMM_POST_COND(p, rd, rn, imm, ARMCOND_AL)
646 /* immediate offset, pre-index */
647 #define ARM_STR_IMM_COND(p, rd, rn, imm, cond) \
648 ARM_EMIT_WXFER_IMM(p, imm, rd, rn, ARMOP_STR, 0, 0, 1, cond)
649 /* ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 0, 1, cond)) */
651 #define ARM_STR_IMM(p, rd, rn, imm) ARM_STR_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
653 #define ARM_STRB_IMM_COND(p, rd, rn, imm, cond) \
654 ARM_EMIT(p, ARM_DEF_WXFER_IMM(imm, rd, rn, ARMOP_STR, 0, 1, 1, cond))
656 #define ARM_STRB_IMM(p, rd, rn, imm) ARM_STRB_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
659 #define ARM_STR_IMM_WB_COND(p, rd, rn, imm, cond) \
660 ARM_EMIT_WXFER_IMM(p, imm, rd, rn, ARMOP_STR, 1, 0, 1, cond)
661 #define ARM_STR_IMM_WB(p, rd, rn, imm) ARM_STR_IMM_WB_COND(p, rd, rn, imm, ARMCOND_AL)
664 #define ARM_DEF_WXFER_REG_REG_UPDOWN_COND(rm, shift_type, shift, rd, rn, ls, wb, b, u, p, cond) \
666 ((shift_type) << 5) | \
679 #define ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ls, wb, b, p, cond) \
680 ARM_DEF_WXFER_REG_REG_UPDOWN_COND(rm, shift_type, shift, rd, rn, ls, wb, b, ARM_UP, p, cond)
681 #define ARM_DEF_WXFER_REG_MINUS_REG_COND(rm, shift_type, shift, rd, rn, ls, wb, b, p, cond) \
682 ARM_DEF_WXFER_REG_REG_UPDOWN_COND(rm, shift_type, shift, rd, rn, ls, wb, b, ARM_DOWN, p, cond)
685 #define ARM_LDR_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, cond) \
686 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_LDR, 0, 0, 1, cond))
687 #define ARM_LDR_REG_REG_SHIFT(p, rd, rn, rm, shift_type, shift) \
688 ARM_LDR_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
689 #define ARM_LDR_REG_REG(p, rd, rn, rm) \
690 ARM_LDR_REG_REG_SHIFT(p, rd, rn, rm, ARMSHIFT_LSL, 0)
692 #define ARM_LDRB_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, cond) \
693 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_LDR, 0, 1, 1, cond))
694 #define ARM_LDRB_REG_REG_SHIFT(p, rd, rn, rm, shift_type, shift) \
695 ARM_LDRB_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
696 #define ARM_LDRB_REG_REG(p, rd, rn, rm) \
697 ARM_LDRB_REG_REG_SHIFT(p, rd, rn, rm, ARMSHIFT_LSL, 0)
699 #define ARM_STR_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, cond) \
700 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_STR, 0, 0, 1, cond))
701 #define ARM_STR_REG_REG_SHIFT(p, rd, rn, rm, shift_type, shift) \
702 ARM_STR_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
703 #define ARM_STR_REG_REG(p, rd, rn, rm) \
704 ARM_STR_REG_REG_SHIFT(p, rd, rn, rm, ARMSHIFT_LSL, 0)
707 #define ARM_STRB_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, cond) \
708 ARM_EMIT(p, ARM_DEF_WXFER_REG_REG_COND(rm, shift_type, shift, rd, rn, ARMOP_STR, 0, 1, 1, cond))
709 #define ARM_STRB_REG_REG_SHIFT(p, rd, rn, rm, shift_type, shift) \
710 ARM_STRB_REG_REG_SHIFT_COND(p, rd, rn, rm, shift_type, shift, ARMCOND_AL)
711 #define ARM_STRB_REG_REG(p, rd, rn, rm) \
712 ARM_STRB_REG_REG_SHIFT(p, rd, rn, rm, ARMSHIFT_LSL, 0)
716 /* Half-word or byte (signed) transfer. */
718 arminstr_t rm : 4; /* imm_lo */
719 arminstr_t tag3 : 1; /* 1 */
720 arminstr_t h : 1; /* half-word or byte */
721 arminstr_t s : 1; /* sign-extend or zero-extend */
722 arminstr_t tag2 : 1; /* 1 */
723 arminstr_t imm_hi : 4;
728 arminstr_t type : 1; /* imm(1) / reg(0) */
729 arminstr_t u : 1; /* +- */
730 arminstr_t p : 1; /* pre/post-index */
735 #define ARM_HXFER_ID 0
736 #define ARM_HXFER_ID2 1
737 #define ARM_HXFER_ID3 1
738 #define ARM_HXFER_MASK ((0x7 << 25) | (0x9 << 4))
739 #define ARM_HXFER_TAG ((ARM_HXFER_ID << 25) | (ARM_HXFER_ID2 << 7) | (ARM_HXFER_ID3 << 4))
741 #define ARM_DEF_HXFER_IMM_COND(imm, h, s, rd, rn, ls, wb, p, cond) \
742 ((imm) < 0?(-(imm)) & 0xF:(imm) & 0xF) | \
745 ((imm) < 0?((-(imm)) << 4) & 0xF00:((imm) << 4) & 0xF00) | \
751 (((int)(imm) >= 0) << 23) | \
756 #define ARM_LDRH_IMM_COND(p, rd, rn, imm, cond) \
757 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 1, 0, rd, rn, ARMOP_LDR, 0, 1, cond))
758 #define ARM_LDRH_IMM(p, rd, rn, imm) \
759 ARM_LDRH_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
760 #define ARM_LDRSH_IMM_COND(p, rd, rn, imm, cond) \
761 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 1, 1, rd, rn, ARMOP_LDR, 0, 1, cond))
762 #define ARM_LDRSH_IMM(p, rd, rn, imm) \
763 ARM_LDRSH_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
764 #define ARM_LDRSB_IMM_COND(p, rd, rn, imm, cond) \
765 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 0, 1, rd, rn, ARMOP_LDR, 0, 1, cond))
766 #define ARM_LDRSB_IMM(p, rd, rn, imm) \
767 ARM_LDRSB_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
770 #define ARM_STRH_IMM_COND(p, rd, rn, imm, cond) \
771 ARM_EMIT(p, ARM_DEF_HXFER_IMM_COND(imm, 1, 0, rd, rn, ARMOP_STR, 0, 1, cond))
772 #define ARM_STRH_IMM(p, rd, rn, imm) \
773 ARM_STRH_IMM_COND(p, rd, rn, imm, ARMCOND_AL)
776 #define ARM_DEF_HXFER_REG_REG_UPDOWN_COND(rm, h, s, rd, rn, ls, wb, u, p, cond) \
790 #define ARM_DEF_HXFER_REG_REG_COND(rm, h, s, rd, rn, ls, wb, p, cond) \
791 ARM_DEF_HXFER_REG_REG_UPDOWN_COND(rm, h, s, rd, rn, ls, wb, ARM_UP, p, cond)
792 #define ARM_DEF_HXFER_REG_MINUS_REG_COND(rm, h, s, rd, rn, ls, wb, p, cond) \
793 ARM_DEF_HXFER_REG_REG_UPDOWN_COND(rm, h, s, rd, rn, ls, wb, ARM_DOWN, p, cond)
795 #define ARM_LDRH_REG_REG_COND(p, rd, rm, rn, cond) \
796 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 1, 0, rd, rn, ARMOP_LDR, 0, 1, cond))
797 #define ARM_LDRH_REG_REG(p, rd, rm, rn) \
798 ARM_LDRH_REG_REG_COND(p, rd, rm, rn, ARMCOND_AL)
799 #define ARM_LDRSH_REG_REG_COND(p, rd, rm, rn, cond) \
800 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 1, 1, rd, rn, ARMOP_LDR, 0, 1, cond))
801 #define ARM_LDRSH_REG_REG(p, rd, rm, rn) \
802 ARM_LDRSH_REG_REG_COND(p, rd, rm, rn, ARMCOND_AL)
803 #define ARM_LDRSB_REG_REG_COND(p, rd, rm, rn, cond) \
804 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 0, 1, rd, rn, ARMOP_LDR, 0, 1, cond))
805 #define ARM_LDRSB_REG_REG(p, rd, rm, rn) ARM_LDRSB_REG_REG_COND(p, rd, rm, rn, ARMCOND_AL)
807 #define ARM_STRH_REG_REG_COND(p, rd, rm, rn, cond) \
808 ARM_EMIT(p, ARM_DEF_HXFER_REG_REG_COND(rm, 1, 0, rd, rn, ARMOP_STR, 0, 1, cond))
809 #define ARM_STRH_REG_REG(p, rd, rm, rn) \
810 ARM_STRH_REG_REG_COND(p, rd, rm, rn, ARMCOND_AL)
817 arminstr_t tag3 : 8; /* 0x9 */
822 arminstr_t tag : 5; /* 0x2 */
827 #define ARM_SWP_ID2 9
828 #define ARM_SWP_MASK ((0x1F << 23) | (3 << 20) | (0xFF << 4))
829 #define ARM_SWP_TAG ((ARM_SWP_ID << 23) | (ARM_SWP_ID2 << 4))
833 /* Software interrupt */
840 #define ARM_SWI_ID 0xF
841 #define ARM_SWI_MASK (0xF << 24)
842 #define ARM_SWI_TAG (ARM_SWI_ID << 24)
846 /* Co-processor Data Processing */
849 arminstr_t tag2 : 1; /* 0 */
851 arminstr_t cpn : 4; /* CP number */
855 arminstr_t tag : 4; /* 0xE */
859 #define ARM_CDP_ID 0xE
860 #define ARM_CDP_ID2 0
861 #define ARM_CDP_MASK ((0xF << 24) | (1 << 4))
862 #define ARM_CDP_TAG ((ARM_CDP_ID << 24) | (ARM_CDP_ID2 << 4))
865 /* Co-processor Data Transfer (ldc/stc) */
881 #define ARM_CDT_MASK (7 << 25)
882 #define ARM_CDT_TAG (ARM_CDT_ID << 25)
885 /* Co-processor Register Transfer (mcr/mrc) */
899 #define ARM_CRT_ID 0xE
900 #define ARM_CRT_ID2 0x1
901 #define ARM_CRT_MASK ((0xF << 24) | (1 << 4))
902 #define ARM_CRT_TAG ((ARM_CRT_ID << 24) | (ARM_CRT_ID2 << 4))
904 /* Move register to PSR. */
906 ARMDPI_op2_imm op2_imm;
909 arminstr_t pad : 8; /* 0 */
910 arminstr_t tag4 : 4; /* 0xF */
912 arminstr_t tag3 : 2; /* 0x2 */
914 arminstr_t tag2 : 2; /* 0x2 */
916 arminstr_t tag : 2; /* 0 */
922 #define ARM_MSR_ID2 2
923 #define ARM_MSR_ID3 2
924 #define ARM_MSR_ID4 0xF
925 #define ARM_MSR_MASK ((3 << 26) | \
929 #define ARM_MSR_TAG ((ARM_MSR_ID << 26) | \
930 (ARM_MSR_ID2 << 23) | \
931 (ARM_MSR_ID3 << 20) | \
935 /* Move PSR to register. */
937 arminstr_t tag3 : 12;
940 arminstr_t sel : 1; /* CPSR | SPSR */
946 #define ARM_MRS_ID2 0xF
947 #define ARM_MRS_ID3 0
948 #define ARM_MRS_MASK ((0x1F << 23) | (0x3F << 16) | 0xFFF)
949 #define ARM_MRS_TAG ((ARM_MRS_ID << 23) | (ARM_MRS_ID2 << 16) | ARM_MRS_ID3)
953 #include "mono/arch/arm/arm_dpimacros.h"
955 #define ARM_NOP(p) ARM_MOV_REG_REG(p, ARMREG_R0, ARMREG_R0)
958 #define ARM_SHL_IMM_COND(p, rd, rm, imm, cond) \
959 ARM_MOV_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_LSL, imm, cond)
960 #define ARM_SHL_IMM(p, rd, rm, imm) \
961 ARM_SHL_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
962 #define ARM_SHLS_IMM_COND(p, rd, rm, imm, cond) \
963 ARM_MOVS_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_LSL, imm, cond)
964 #define ARM_SHLS_IMM(p, rd, rm, imm) \
965 ARM_SHLS_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
967 #define ARM_SHR_IMM_COND(p, rd, rm, imm, cond) \
968 ARM_MOV_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_LSR, imm, cond)
969 #define ARM_SHR_IMM(p, rd, rm, imm) \
970 ARM_SHR_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
971 #define ARM_SHRS_IMM_COND(p, rd, rm, imm, cond) \
972 ARM_MOVS_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_LSR, imm, cond)
973 #define ARM_SHRS_IMM(p, rd, rm, imm) \
974 ARM_SHRS_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
976 #define ARM_SAR_IMM_COND(p, rd, rm, imm, cond) \
977 ARM_MOV_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_ASR, imm, cond)
978 #define ARM_SAR_IMM(p, rd, rm, imm) \
979 ARM_SAR_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
980 #define ARM_SARS_IMM_COND(p, rd, rm, imm, cond) \
981 ARM_MOVS_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_ASR, imm, cond)
982 #define ARM_SARS_IMM(p, rd, rm, imm) \
983 ARM_SARS_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
985 #define ARM_ROR_IMM_COND(p, rd, rm, imm, cond) \
986 ARM_MOV_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_ROR, imm, cond)
987 #define ARM_ROR_IMM(p, rd, rm, imm) \
988 ARM_ROR_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
989 #define ARM_RORS_IMM_COND(p, rd, rm, imm, cond) \
990 ARM_MOVS_REG_IMMSHIFT_COND(p, rd, rm, ARMSHIFT_ROR, imm, cond)
991 #define ARM_RORS_IMM(p, rd, rm, imm) \
992 ARM_RORS_IMM_COND(p, rd, rm, imm, ARMCOND_AL)
994 #define ARM_SHL_REG_COND(p, rd, rm, rs, cond) \
995 ARM_MOV_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_LSL, rs, cond)
996 #define ARM_SHL_REG(p, rd, rm, rs) \
997 ARM_SHL_REG_COND(p, rd, rm, rs, ARMCOND_AL)
998 #define ARM_SHLS_REG_COND(p, rd, rm, rs, cond) \
999 ARM_MOVS_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_LSL, rs, cond)
1000 #define ARM_SHLS_REG(p, rd, rm, rs) \
1001 ARM_SHLS_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1002 #define ARM_SHLS_REG_REG(p, rd, rm, rs) ARM_SHLS_REG(p, rd, rm, rs)
1004 #define ARM_SHR_REG_COND(p, rd, rm, rs, cond) \
1005 ARM_MOV_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_LSR, rs, cond)
1006 #define ARM_SHR_REG(p, rd, rm, rs) \
1007 ARM_SHR_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1008 #define ARM_SHRS_REG_COND(p, rd, rm, rs, cond) \
1009 ARM_MOVS_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_LSR, rs, cond)
1010 #define ARM_SHRS_REG(p, rd, rm, rs) \
1011 ARM_SHRS_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1012 #define ARM_SHRS_REG_REG(p, rd, rm, rs) ARM_SHRS_REG(p, rd, rm, rs)
1014 #define ARM_SAR_REG_COND(p, rd, rm, rs, cond) \
1015 ARM_MOV_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_ASR, rs, cond)
1016 #define ARM_SAR_REG(p, rd, rm, rs) \
1017 ARM_SAR_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1018 #define ARM_SARS_REG_COND(p, rd, rm, rs, cond) \
1019 ARM_MOVS_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_ASR, rs, cond)
1020 #define ARM_SARS_REG(p, rd, rm, rs) \
1021 ARM_SARS_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1022 #define ARM_SARS_REG_REG(p, rd, rm, rs) ARM_SARS_REG(p, rd, rm, rs)
1024 #define ARM_ROR_REG_COND(p, rd, rm, rs, cond) \
1025 ARM_MOV_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_ROR, rs, cond)
1026 #define ARM_ROR_REG(p, rd, rm, rs) \
1027 ARM_ROR_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1028 #define ARM_RORS_REG_COND(p, rd, rm, rs, cond) \
1029 ARM_MOVS_REG_REGSHIFT_COND(p, rd, rm, ARMSHIFT_ROR, rs, cond)
1030 #define ARM_RORS_REG(p, rd, rm, rs) \
1031 ARM_RORS_REG_COND(p, rd, rm, rs, ARMCOND_AL)
1032 #define ARM_RORS_REG_REG(p, rd, rm, rs) ARM_RORS_REG(p, rd, rm, rs)
1034 #ifdef __native_client_codegen__
1035 #define ARM_DBRK(p) ARM_EMIT(p, 0xE7FEDEF0)
1037 #define ARM_DBRK(p) ARM_EMIT(p, 0xE6000010)
1039 #define ARM_IASM_DBRK() ARM_IASM_EMIT(0xE6000010)
1041 #define ARM_INC(p, reg) ARM_ADD_REG_IMM8(p, reg, reg, 1)
1042 #define ARM_DEC(p, reg) ARM_SUB_REG_IMM8(p, reg, reg, 1)
1044 #define ARM_MLS(p, rd, rn, rm, ra) ARM_EMIT((p), (ARMCOND_AL << 28) | (0x6 << 20) | ((rd) << 16) | ((ra) << 12) | ((rm) << 8) | (0x9 << 4) | ((rn) << 0))
1048 /* Count leading zeros, CLZ{cond} Rd, Rm */
1051 arminstr_t tag2 : 8;
1053 arminstr_t tag : 12;
1054 arminstr_t cond : 4;
1057 #define ARM_CLZ_ID 0x16F
1058 #define ARM_CLZ_ID2 0xF1
1059 #define ARM_CLZ_MASK ((0xFFF << 16) | (0xFF < 4))
1060 #define ARM_CLZ_TAG ((ARM_CLZ_ID << 16) | (ARM_CLZ_ID2 << 4))
1070 ARMInstrWXfer wxfer;
1071 ARMInstrHXfer hxfer;
1081 ARMInstrGeneric generic;
1087 #define ARM_MOVW_REG_IMM_COND(p, rd, imm16, cond) ARM_EMIT(p, (((cond) << 28) | (3 << 24) | (0 << 20) | ((((guint32)(imm16)) >> 12) << 16) | ((rd) << 12) | (((guint32)(imm16)) & 0xfff)))
1088 #define ARM_MOVW_REG_IMM(p, rd, imm16) ARM_MOVW_REG_IMM_COND ((p), (rd), (imm16), ARMCOND_AL)
1090 #define ARM_MOVT_REG_IMM_COND(p, rd, imm16, cond) ARM_EMIT(p, (((cond) << 28) | (3 << 24) | (4 << 20) | ((((guint32)(imm16)) >> 12) << 16) | ((rd) << 12) | (((guint32)(imm16)) & 0xfff)))
1091 #define ARM_MOVT_REG_IMM(p, rd, imm16) ARM_MOVT_REG_IMM_COND ((p), (rd), (imm16), ARMCOND_AL)
1094 #define ARM_DEF_MCR_COND(coproc, opc1, rt, crn, crm, opc2, cond) \
1095 ARM_DEF_COND ((cond)) | ((0xe << 24) | (((opc1) & 0x7) << 21) | (0 << 20) | (((crn) & 0xf) << 16) | (((rt) & 0xf) << 12) | (((coproc) & 0xf) << 8) | (((opc2) & 0x7) << 5) | (1 << 4) | (((crm) & 0xf) << 0))
1097 #define ARM_MCR_COND(p, coproc, opc1, rt, crn, crm, opc2, cond) \
1098 ARM_EMIT(p, ARM_DEF_MCR_COND ((coproc), (opc1), (rt), (crn), (crm), (opc2), (cond)))
1100 #define ARM_MCR(p, coproc, opc1, rt, crn, crm, opc2) \
1101 ARM_MCR_COND ((p), (coproc), (opc1), (rt), (crn), (crm), (opc2), ARMCOND_AL)
1104 #define ARM_SDIV_COND(p, rd, rn, rm, cond) ARM_EMIT (p, (((cond) << 28) | (0xe << 23) | (0x1 << 20) | ((rd) << 16) | (0xf << 12) | ((rm) << 8) | (0x0 << 5) | (0x1 << 4) | ((rn) << 0)))
1105 #define ARM_SDIV(p, rd, rn, rm) ARM_SDIV_COND ((p), (rd), (rn), (rm), ARMCOND_AL)
1107 #define ARM_UDIV_COND(p, rd, rn, rm, cond) ARM_EMIT (p, (((cond) << 28) | (0xe << 23) | (0x3 << 20) | ((rd) << 16) | (0xf << 12) | ((rm) << 8) | (0x0 << 5) | (0x1 << 4) | ((rn) << 0)))
1108 #define ARM_UDIV(p, rd, rn, rm) ARM_UDIV_COND ((p), (rd), (rn), (rm), ARMCOND_AL)