#ifndef _JIT_GEN_ARM_H
#define _JIT_GEN_ARM_H
#include <assert.h>
#include <jit-rules-arm.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
ARM_R0 = 0,
ARM_R1 = 1,
ARM_R2 = 2,
ARM_R3 = 3,
ARM_R4 = 4,
ARM_R5 = 5,
ARM_R6 = 6,
ARM_R7 = 7,
ARM_R8 = 8,
ARM_R9 = 9,
ARM_R10 = 10,
ARM_R11 = 11,
ARM_R12 = 12,
ARM_R13 = 13,
ARM_R14 = 14,
ARM_R15 = 15,
ARM_FP = ARM_R11,
ARM_LINK = ARM_R14,
ARM_PC = ARM_R15,
ARM_WORK = ARM_R12,
ARM_SP = ARM_R13
} ARM_REG;
#ifdef JIT_ARM_HAS_FPA
typedef enum
{
ARM_F0 = 0,
ARM_F1 = 1,
ARM_F2 = 2,
ARM_F3 = 3,
ARM_F4 = 4,
ARM_F5 = 5,
ARM_F6 = 6,
ARM_F7 = 7
} ARM_FREG;
#endif
#ifdef JIT_ARM_HAS_VFP
typedef enum
{
ARM_S0 = 0,
ARM_S1 = 1,
ARM_S2 = 2,
ARM_S3 = 3,
ARM_S4 = 4,
ARM_S5 = 5,
ARM_S6 = 6,
ARM_S7 = 7,
ARM_S8 = 8,
ARM_S9 = 9,
ARM_S10 = 10,
ARM_S11 = 11,
ARM_S12 = 12,
ARM_S13 = 13,
ARM_S14 = 14,
ARM_S15 = 15,
ARM_D8 = 8,
ARM_D9 = 9,
ARM_D10 = 10,
ARM_D11 = 11,
ARM_D12 = 12,
ARM_D13 = 13,
ARM_D14 = 14,
ARM_D15 = 15
} ARM_FREG;
#endif
typedef enum
{
ARM_CC_EQ = 0,
ARM_CC_NE = 1,
ARM_CC_CS = 2,
ARM_CC_CC = 3,
ARM_CC_MI = 4,
ARM_CC_PL = 5,
ARM_CC_VS = 6,
ARM_CC_VC = 7,
ARM_CC_HI = 8,
ARM_CC_LS = 9,
ARM_CC_GE = 10,
ARM_CC_LT = 11,
ARM_CC_GT = 12,
ARM_CC_LE = 13,
ARM_CC_AL = 14,
ARM_CC_NV = 15,
ARM_CC_GE_UN = ARM_CC_CS,
ARM_CC_LT_UN = ARM_CC_CC,
ARM_CC_GT_UN = ARM_CC_HI,
ARM_CC_LE_UN = ARM_CC_LS
} ARM_CC;
typedef enum
{
ARM_AND = 0,
ARM_EOR = 1,
ARM_SUB = 2,
ARM_RSB = 3,
ARM_ADD = 4,
ARM_ADC = 5,
ARM_SBC = 6,
ARM_RSC = 7,
ARM_TST = 8,
ARM_TEQ = 9,
ARM_CMP = 10,
ARM_CMN = 11,
ARM_ORR = 12,
ARM_MOV = 13,
ARM_BIC = 14,
ARM_MVN = 15
} ARM_OP;
typedef enum
{
ARM_SHL = 0,
ARM_SHR = 1,
ARM_SAR = 2,
ARM_ROR = 3
} ARM_SHIFT;
#ifdef JIT_ARM_HAS_FPA
typedef enum
{
ARM_MVF = 0,
ARM_MNF = 1,
ARM_ABS = 2,
ARM_RND = 3,
ARM_SQT = 4,
ARM_LOG = 5,
ARM_LGN = 6,
ARM_EXP = 7,
ARM_SIN = 8,
ARM_COS = 9,
ARM_TAN = 10,
ARM_ASN = 11,
ARM_ACS = 12,
ARM_ATN = 13
} ARM_FUNARY;
typedef enum
{
ARM_ADF = 0,
ARM_MUF = 1,
ARM_SUF = 2,
ARM_RSF = 3,
ARM_DVF = 4,
ARM_RDF = 5,
ARM_POW = 6,
ARM_RPW = 7,
ARM_RMF = 8,
ARM_FML = 9,
ARM_FDV = 10,
ARM_FRD = 11,
ARM_POL = 12
} ARM_FBINARY;
#endif
#ifdef JIT_ARM_HAS_VFP
typedef enum
{
ARM_MVF = 0,
ARM_MNF = 1,
ARM_ABS = 2
} ARM_FUNARY;
typedef enum
{
ARM_FADD = 0,
ARM_FMUL = 1,
ARM_FSUB = 2,
ARM_FDIV = 4
} ARM_FBINARY;
#endif
#define ARM_NUM_PARAM_REGS 4
typedef unsigned int arm_inst_word;
typedef struct
{
arm_inst_word *current;
arm_inst_word *limit;
} arm_inst_buf;
#define arm_inst_get_posn(inst) ((inst).current)
#define arm_inst_get_limit(inst) ((inst).limit)
#define arm_build_prefix(cond,mask) \
((((unsigned int)(cond)) << 28) | ((unsigned int)(mask)))
#define arm_prefix(mask) (arm_build_prefix(ARM_CC_AL, (mask)))
#define arm_always (arm_build_prefix(ARM_CC_AL, 0))
#define arm_always_cc (arm_build_prefix(ARM_CC_AL, (1 << 20)))
#define arm_always_imm (arm_build_prefix(ARM_CC_AL, (1 << 25)))
#ifndef arm_execute
#define arm_execute arm_always
#define arm_execute_cc arm_always_cc
#define arm_execute_imm arm_always_imm
#endif
#define arm_inst_buf_init(inst,start,end) \
do { \
(inst).current = (arm_inst_word *)(start); \
(inst).limit = (arm_inst_word *)(end); \
} while (0)
#define arm_inst_add(inst,value) \
do { \
if((inst).current < (inst).limit) \
{ \
*((inst).current)++ = (value); \
} \
} while (0)
#define arm_alu_reg_reg(inst,opc,dreg,sreg1,sreg2) \
do { \
arm_inst_add((inst), arm_execute | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg1)) << 16) | \
((unsigned int)(sreg2))); \
} while (0)
#define arm_alu_reg_imm8(inst,opc,dreg,sreg,imm) \
do { \
arm_inst_add((inst), arm_execute_imm | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg)) << 16) | \
((unsigned int)((imm) & 0xFF))); \
} while (0)
#define arm_alu_reg_imm8_cond(inst,opc,dreg,sreg,imm,cond) \
do { \
arm_inst_add((inst), arm_build_prefix((cond), (1 << 25)) | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg)) << 16) | \
((unsigned int)((imm) & 0xFF))); \
} while (0)
#define arm_alu_reg_imm8_rotate(inst,opc,dreg,sreg,imm,rotate) \
do { \
arm_inst_add((inst), arm_execute_imm | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg)) << 16) | \
(((unsigned int)(rotate)) << 8) | \
((unsigned int)((imm) & 0xFF))); \
} while (0)
extern void _arm_alu_reg_imm
(arm_inst_buf *inst, int opc, int dreg,
int sreg, int imm, int saveWork, int execute_prefix);
#define arm_alu_reg_imm(inst,opc,dreg,sreg,imm) \
do { \
int __alu_imm = (int)(imm); \
if(__alu_imm >= 0 && __alu_imm < 256) \
{ \
arm_alu_reg_imm8 \
((inst), (opc), (dreg), (sreg), __alu_imm); \
} \
else \
{ \
_arm_alu_reg_imm \
(&(inst), (opc), (dreg), (sreg), __alu_imm, 0, \
arm_execute); \
} \
} while (0)
#define arm_alu_reg_imm_save_work(inst,opc,dreg,sreg,imm) \
do { \
int __alu_imm_save = (int)(imm); \
if(__alu_imm_save >= 0 && __alu_imm_save < 256) \
{ \
arm_alu_reg_imm8 \
((inst), (opc), (dreg), (sreg), __alu_imm_save); \
} \
else \
{ \
_arm_alu_reg_imm \
(&(inst), (opc), (dreg), (sreg), __alu_imm_save, 1, \
arm_execute); \
} \
} while (0)
#define arm_alu_reg(inst,opc,dreg,sreg) \
do { \
arm_inst_add((inst), arm_execute | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
((unsigned int)(sreg))); \
} while (0)
#define arm_alu_reg_cond(inst,opc,dreg,sreg,cond) \
do { \
arm_inst_add((inst), arm_build_prefix((cond), 0) | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
((unsigned int)(sreg))); \
} while (0)
#define arm_alu_cc_reg_reg(inst,opc,dreg,sreg1,sreg2) \
do { \
arm_inst_add((inst), arm_execute_cc | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg1)) << 16) | \
((unsigned int)(sreg2))); \
} while (0)
#define arm_alu_cc_reg_imm8(inst,opc,dreg,sreg,imm) \
do { \
arm_inst_add((inst), arm_execute_imm | arm_execute_cc | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg)) << 16) | \
((unsigned int)((imm) & 0xFF))); \
} while (0)
#define arm_alu_cc_reg(inst,opc,dreg,sreg) \
do { \
arm_inst_add((inst), arm_execute_cc | \
(((unsigned int)(opc)) << 21) | \
(((unsigned int)(dreg)) << 12) | \
((unsigned int)(sreg))); \
} while (0)
#define arm_test_reg_reg(inst,opc,sreg1,sreg2) \
do { \
arm_alu_cc_reg_reg((inst), (opc), 0, (sreg1), (sreg2)); \
} while (0)
#define arm_test_reg_imm8(inst,opc,sreg,imm) \
do { \
arm_alu_cc_reg_imm8((inst), (opc), 0, (sreg), (imm)); \
} while (0)
#define arm_test_reg_imm(inst,opc,sreg,imm) \
do { \
int __test_imm = (int)(imm); \
if(__test_imm >= 0 && __test_imm < 256) \
{ \
arm_alu_cc_reg_imm8((inst), (opc), 0, (sreg), __test_imm); \
} \
else \
{ \
arm_mov_reg_imm((inst), ARM_WORK, __test_imm); \
arm_test_reg_reg((inst), (opc), (sreg), ARM_WORK); \
} \
} while (0)
#define arm_test_reg_membase(inst,opc,reg,basereg,disp,scratchreg) \
do { \
assert(reg!=scratchreg); \
assert(basereg!=scratchreg); \
arm_load_membase((inst), (tmpreg),(basereg),(disp)); \
arm_test_reg_reg((inst), (opc), (reg), (tmpreg)); \
} while (0)
#define arm_mov_reg_reg(inst,dreg,sreg) \
do { \
arm_alu_reg((inst), ARM_MOV, (dreg), (sreg)); \
} while (0)
#define arm_mov_freg_freg(inst,dreg,sreg) \
do { \
arm_alu_freg((inst), ARM_MVF, (dreg), (sreg)); \
} while (0)
#define arm_mov_reg_imm8(inst,reg,imm) \
do { \
arm_alu_reg_imm8((inst), ARM_MOV, (reg), 0, (imm)); \
} while (0)
#define arm_mov_reg_imm8_rotate(inst,reg,imm,rotate) \
do { \
arm_alu_reg_imm8_rotate((inst), ARM_MOV, (reg), \
0, (imm), (rotate)); \
} while (0)
extern void _arm_mov_reg_imm
(arm_inst_buf *inst, int reg, int value, int execute_prefix);
extern int arm_is_complex_imm(int value);
#define arm_mov_reg_imm(inst,reg,imm) \
do { \
int __imm = (int)(imm); \
if(__imm >= 0 && __imm < 256) \
{ \
arm_mov_reg_imm8((inst), (reg), __imm); \
} \
else if((reg) == ARM_PC) \
{ \
_arm_mov_reg_imm \
(&(inst), ARM_WORK, __imm, arm_execute); \
arm_mov_reg_reg((inst), ARM_PC, ARM_WORK); \
} \
else if(__imm > -256 && __imm < 0) \
{ \
arm_mov_reg_imm8((inst), (reg), ~(__imm)); \
arm_alu_reg((inst), ARM_MVN, (reg), (reg)); \
} \
else \
{ \
_arm_mov_reg_imm(&(inst), (reg), __imm, arm_execute); \
} \
} while (0)
#define ARM_NOBASEREG (-1)
#define arm_mov_reg_memindex(inst,reg,basereg,disp,indexreg,shift,size,scratchreg) \
do { \
if (basereg==ARM_NOBASEREG) \
{ \
fprintf(stderr, "TODO(NOBASEREG) at %s, %d\n", __FILE__, (int)__LINE__); \
} \
else \
{ \
\
int tempreg=(basereg); \
if (disp!=0) \
{ \
tempreg=(scratchreg); \
assert(tempreg!=basereg); \
assert(tempreg!=indexreg); \
arm_alu_reg_imm((inst), ARM_ADD, (tempreg), (basereg), (disp)); \
} \
\
switch ((size)) { \
case 1: arm_load_memindex_either(inst,reg,(tempreg),indexreg,shift,0x00400000); break; \
case 2: arm_load_memindex_either(inst,reg,tempreg,indexreg,shift,0); \
arm_shift_reg_imm8((inst), ARM_SHL, (reg), (reg), 16); \
arm_shift_reg_imm8((inst), ARM_SHR, (reg), (reg), 16); \
break; \
case 4: arm_load_memindex_either(inst,reg,tempreg,indexreg,shift,0); break; \
default: assert (0); \
} \
} \
} while (0)
#define arm_mov_memindex_reg(inst,basereg,disp,indexreg,shift,reg,size,scratchreg) \
do { \
if (basereg==ARM_NOBASEREG) \
{ \
fprintf(stderr, "TODO(NOBASEREG) at %s, %d\n", __FILE__, (int)__LINE__); \
} \
else \
{ \
arm_shift_reg_imm8((inst), ARM_SHL, (ARM_WORK), (indexreg), (shift)); \
arm_alu_reg_reg((inst), ARM_ADD, (scratchreg), (basereg), ARM_WORK); \
arm_mov_membase_reg((inst),(scratchreg),(disp),(reg),(size)) \
} \
} while (0);
#define arm_mov_mem_reg(inst,mem,reg,size) \
do { \
arm_mov_reg_imm((inst), ARM_WORK, (mem)); \
switch ((size)) { \
case 1: arm_store_membase_byte((inst), (reg), ARM_WORK, 0); break; \
case 2: arm_store_membase_short((inst), (reg), ARM_WORK, 0); break; \
case 4: arm_store_membase((inst), (reg), ARM_WORK, 0); break; \
default: jit_assert(0); \
} \
} while (0)
#define arm_mov_mem_imm(inst,mem,imm,size,scratchreg) \
do { \
arm_mov_reg_imm((inst), (scratchreg), (imm)); \
arm_mov_reg_imm((inst), ARM_WORK, (mem)); \
switch ((size)) { \
case 1: arm_store_membase_byte((inst), (scratchreg), ARM_WORK, 0); break; \
case 2: arm_store_membase_short((inst), (scratchreg), ARM_WORK, 0); break; \
case 4: arm_store_membase((inst), (scratchreg), ARM_WORK, 0); break; \
default: assert(0); \
} \
} while (0)
#define arm_mov_membase_imm(inst,basereg,disp,imm,size,scratchreg) \
do { \
arm_mov_reg_imm((inst), (scratchreg), imm); \
arm_mov_membase_reg((inst), (basereg), (disp), (scratchreg), (size)); \
} while(0);
#define arm_mov_membase_reg(inst,basereg,disp,reg,size) \
do { \
switch ((size)) { \
case 1: arm_store_membase_byte((inst), (reg), (basereg), (disp)); break; \
case 2: arm_store_membase_short((inst), (reg), (basereg), (disp)); break; \
case 4: arm_store_membase((inst), (reg), (basereg), (disp)); break; \
default: jit_assert(0); \
} \
} while(0);
#define arm_mov_reg_membase(inst,reg,basereg,disp,size) \
do { \
switch ((size)) { \
case 1: arm_load_membase_byte((inst), (reg), (basereg), (disp)); break; \
case 2: arm_load_membase_short((inst), (reg), (basereg), (disp)); break; \
case 4: arm_load_membase((inst), (reg), (basereg), (disp)); break; \
default: jit_assert(0); \
} \
} while(0);
#define arm_clear_reg(inst,reg) \
do { \
arm_mov_reg_imm8((inst), (reg), 0); \
} while (0)
#define arm_nop(inst) arm_mov_reg_reg((inst), ARM_R0, ARM_R0)
#define arm_shift_reg_reg(inst,opc,dreg,sreg1,sreg2) \
do { \
arm_inst_add((inst), arm_execute | \
(((unsigned int)ARM_MOV) << 21) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg2)) << 8) | \
(((unsigned int)(opc)) << 5) | \
((unsigned int)(1 << 4)) | \
((unsigned int)(sreg1))); \
} while (0)
#define arm_shift_reg_imm8(inst,opc,dreg,sreg,imm) \
do { \
arm_inst_add((inst), arm_execute | \
(((unsigned int)ARM_MOV) << 21) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(opc)) << 5) | \
(((unsigned int)(imm)) << 7) | \
((unsigned int)(sreg))); \
} while (0)
#define arm_mul_reg_reg(inst,dreg,sreg1,sreg2) \
do { \
if((dreg) != (sreg2)) \
{ \
arm_inst_add((inst), arm_prefix(0x00000090) | \
(((unsigned int)(dreg)) << 16) | \
(((unsigned int)(sreg1)) << 8) | \
((unsigned int)(sreg2))); \
} \
else \
{ \
arm_inst_add((inst), arm_prefix(0x00000090) | \
(((unsigned int)(dreg)) << 16) | \
(((unsigned int)(sreg2)) << 8) | \
((unsigned int)(sreg1))); \
} \
} while (0)
#ifdef JIT_ARM_HAS_FPA
#define arm_alu_freg_freg(inst,opc,dreg,sreg1,sreg2) \
do { \
arm_inst_add((inst), arm_prefix(0x0E000180) | \
(((unsigned int)(opc)) << 20) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg1)) << 16) | \
((unsigned int)(sreg2))); \
} while (0)
#define arm_alu_freg_freg_32(inst,opc,dreg,sreg1,sreg2) \
do { \
arm_inst_add((inst), arm_prefix(0x0E000100) | \
(((unsigned int)(opc)) << 20) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg1)) << 16) | \
((unsigned int)(sreg2))); \
} while (0)
#define arm_alu_freg(inst,opc,dreg,sreg) \
do { \
arm_inst_add((inst), arm_prefix(0x0E008180) | \
(((unsigned int)(opc)) << 20) | \
(((unsigned int)(dreg)) << 12) | \
((unsigned int)(sreg))); \
} while (0)
#define arm_alu_freg_32(inst,opc,dreg,sreg) \
do { \
arm_inst_add((inst), arm_prefix(0x0E008100) | \
(((unsigned int)(opc)) << 20) | \
(((unsigned int)(dreg)) << 12) | \
((unsigned int)(sreg))); \
} while (0)
#endif
#ifdef JIT_ARM_HAS_VFP
#define arm_alu_freg_freg(inst,opc,dreg,sreg1,sreg2) \
do { \
unsigned int mask; \
switch(opc) \
{ \
case ARM_FADD: \
mask=0x0E300B00; \
break; \
case ARM_FMUL: \
mask=0x0E200B00; \
break; \
case ARM_FSUB: \
mask=0x0E300B40; \
break; \
case ARM_FDIV: \
mask=0x0E800B00; \
break; \
default: \
printf("Unimplemented binary operation %d in %s\n", opc, __FILE__); \
abort(); \
} \
arm_inst_add((inst), arm_prefix(mask) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg1)) << 16) | \
((unsigned int)(sreg2))); \
} while (0)
#define arm_alu_freg_freg_32(inst,opc,dreg,sreg1,sreg2) \
do { \
unsigned int mask; \
switch(opc) \
{ \
case ARM_FADD: \
mask=0x0E300A00; \
break; \
case ARM_FMUL: \
mask=0x0E200A00; \
break; \
case ARM_FSUB: \
mask=0x0E300A40; \
break; \
case ARM_FDIV: \
mask=0x0E800A00; \
break; \
default: \
printf("Unimplemented binary operation %d in %s\n", opc, __FILE__); \
abort(); \
} \
unsigned int dreg_top_4_bits = (dreg & 0x1E) >> 1; \
unsigned int dreg_bottom_bit = (dreg & 0x01); \
unsigned int sreg1_top_4_bits = (sreg1 & 0x1E) >> 1; \
unsigned int sreg1_bottom_bit = (sreg1 & 0x01); \
unsigned int sreg2_top_4_bits = (sreg2 & 0x1E) >> 1; \
unsigned int sreg2_bottom_bit = (sreg2 & 0x01); \
arm_inst_add((inst), arm_prefix(mask) | \
(((unsigned int)(dreg_top_4_bits)) << 12) | \
(((unsigned int)(dreg_bottom_bit)) << 22) | \
(((unsigned int)(sreg1_top_4_bits)) << 16) | \
(((unsigned int)(sreg1_bottom_bit)) << 7) | \
(((unsigned int)(sreg2_bottom_bit)) << 5) | \
((unsigned int)(sreg2_top_4_bits))); \
} while (0)
#define arm_alu_freg(inst,opc,dreg,sreg) \
do { \
unsigned int mask; \
switch(opc) \
{ \
case ARM_MVF: \
mask=0xEB00B40; \
break; \
case ARM_MNF: \
mask=0xEB10B40; \
break; \
case ARM_ABS: \
mask=0xEB00BC0; \
break; \
default: \
printf("Unimplemented unary operation %d in %s\n", opc, __FILE__); \
abort(); \
} \
arm_inst_add((inst), arm_prefix(mask) | \
(((unsigned int)(dreg)) << 12) | \
((unsigned int)(sreg))); \
} while (0)
#define arm_alu_freg_32(inst,opc,dreg,sreg) \
do { \
unsigned int mask; \
switch(opc) \
{ \
case ARM_MVF: \
mask=0xEB00A40; \
break; \
case ARM_MNF: \
mask=0xEB10A40; \
break; \
case ARM_ABS: \
mask=0xEB00AC0; \
break; \
default: \
printf("Unimplemented OPCODE in %s\n", __FILE__); \
abort(); \
} \
unsigned int dreg_top_4_bits = (dreg & 0x1E) >> 1; \
unsigned int dreg_bottom_bit = (dreg & 0x01); \
unsigned int sreg_top_4_bits = (sreg & 0x1E) >> 1; \
unsigned int sreg_bottom_bit = (sreg & 0x01); \
arm_inst_add((inst), arm_prefix(mask) | \
(((unsigned int)(dreg_top_4_bits)) << 12) | \
(((unsigned int)(dreg_bottom_bit)) << 22) | \
(((unsigned int)(sreg_bottom_bit)) << 5) | \
((unsigned int)(sreg_top_4_bits))); \
} while (0)
#endif
#define arm_branch_imm(inst,cond,imm) \
do { \
arm_inst_add((inst), arm_build_prefix((cond), 0x0A000000) | \
(((unsigned int)(((int)(imm)) >> 2)) & \
0x00FFFFFF)); \
} while (0)
#define arm_jump_imm(inst,imm) arm_branch_imm((inst), ARM_CC_AL, (imm))
#define arm_branch(inst,cond,target) \
do { \
int __br_offset = (int)(((unsigned char *)(target)) - \
(((unsigned char *)((inst).current)) + 8)); \
arm_branch_imm((inst), (cond), __br_offset); \
} while (0)
#define arm_jump(inst,target) arm_branch((inst), ARM_CC_AL, (target))
#define arm_jump_long(inst,target) \
do { \
int __jmp_offset = (int)(((unsigned char *)(target)) - \
(((unsigned char *)((inst).current)) + 8)); \
if(__jmp_offset >= -0x04000000 && __jmp_offset < 0x04000000) \
{ \
arm_jump_imm((inst), __jmp_offset); \
} \
else \
{ \
arm_mov_reg_imm((inst), ARM_PC, (int)(target)); \
} \
} while (0)
#define arm_patch(inst,posn,target) \
do { \
int __p_offset = (int)(((unsigned char *)(target)) - \
(((unsigned char *)(posn)) + 8)); \
__p_offset = (__p_offset >> 2) & 0x00FFFFFF; \
if(((arm_inst_word *)(posn)) < (inst).limit) \
{ \
*((int *)(posn)) = (*((int *)(posn)) & 0xFF000000) | \
__p_offset; \
} \
} while (0)
#define arm_call_imm(inst,imm) \
do { \
arm_inst_add((inst), arm_prefix(0x0B000000) | \
(((unsigned int)(((int)(imm)) >> 2)) & \
0x00FFFFFF)); \
} while (0)
#define arm_call(inst,target) \
do { \
int __call_offset = (int)(((unsigned char *)(target)) - \
(((unsigned char *)((inst).current)) + 8)); \
if(__call_offset >= -0x04000000 && __call_offset < 0x04000000) \
{ \
arm_call_imm((inst), __call_offset); \
} \
else \
{ \
arm_load_membase((inst), ARM_WORK, ARM_PC, 4); \
arm_alu_reg_imm8((inst), ARM_ADD, ARM_LINK, ARM_PC, 4); \
arm_mov_reg_reg((inst), ARM_PC, ARM_WORK); \
arm_inst_add((inst), (int)(target)); \
} \
} while (0)
#define arm_return(inst) \
do { \
arm_mov_reg_reg((inst), ARM_PC, ARM_LINK); \
} while (0)
#define arm_push_reg(inst,reg) \
do { \
arm_inst_add((inst), arm_prefix(0x05200004) | \
(((unsigned int)ARM_SP) << 16) | \
(((unsigned int)(reg)) << 12)); \
} while (0)
#define arm_pop_reg(inst,reg) \
do { \
arm_inst_add((inst), arm_prefix(0x04900004) | \
(((unsigned int)ARM_SP) << 16) | \
(((unsigned int)(reg)) << 12)); \
} while (0)
#define arm_pop_membase(inst,basereg,offset) \
do { \
arm_pop_reg((inst), ARM_WORK); \
arm_store_membase((inst),ARM_WORK,basereg,offset); \
} while (0)
#define arm_setup_frame(inst,regset) \
do { \
arm_mov_reg_reg((inst), ARM_WORK, ARM_SP); \
arm_inst_add((inst), arm_prefix(0x0920D800) | \
(((unsigned int)ARM_SP) << 16) | \
(((unsigned int)(regset)))); \
arm_alu_reg_imm8((inst), ARM_SUB, ARM_FP, ARM_WORK, 4); \
} while (0)
#define arm_pop_frame(inst,regset) \
do { \
arm_inst_add((inst), arm_prefix(0x0910A800) | \
(((unsigned int)ARM_FP) << 16) | \
(((unsigned int)(regset)))); \
} while (0)
#define arm_pop_frame_tail(inst,regset) \
do { \
arm_inst_add((inst), arm_prefix(0x09106800) | \
(((unsigned int)ARM_FP) << 16) | \
(((unsigned int)(regset)))); \
} while (0)
#define arm_load_advance(inst,dreg,sreg) \
do { \
arm_inst_add((inst), arm_prefix(0x04900004) | \
(((unsigned int)(sreg)) << 16) | \
(((unsigned int)(dreg)) << 12)); \
} while (0)
#define arm_load_membase_either(inst,reg,basereg,imm,mask) \
do { \
int __mb_offset = (int)(imm); \
if(__mb_offset >= 0 && __mb_offset < (1 << 12)) \
{ \
arm_inst_add((inst), arm_prefix(0x05900000 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)__mb_offset)); \
} \
else if(__mb_offset > -(1 << 12) && __mb_offset < 0) \
{ \
arm_inst_add((inst), arm_prefix(0x05100000 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)(-__mb_offset))); \
} \
else \
{ \
assert(basereg!=ARM_WORK); \
arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
arm_inst_add((inst), arm_prefix(0x07900000 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)ARM_WORK)); \
} \
} while (0)
#define arm_load_membase(inst,reg,basereg,imm) \
do { \
arm_load_membase_either((inst), (reg), (basereg), (imm), 0); \
} while (0)
#define arm_widen_memindex(inst,dreg,basereg,disp,indexreg,shift,is_signed,is_half) \
do { \
int scratchreg=ARM_WORK; \
if(is_half) \
{ \
arm_mov_reg_memindex((inst),(dreg),(basereg),(disp),(indexreg),(shift),2, scratchreg); \
} \
else \
{ \
arm_mov_reg_memindex((inst),(dreg),(basereg),(disp),(indexreg),(shift),1, scratchreg); \
} \
if(is_signed) \
{ \
int shiftSize; \
if (is_half) \
{ \
shiftSize=16; \
} \
else \
{ \
shiftSize=24; \
} \
arm_shift_reg_imm8((inst), ARM_SHL, (dreg), (dreg), shiftSize); \
arm_shift_reg_imm8((inst), ARM_SAR, (dreg), (dreg), shiftSize); \
} \
} while (0)
#define arm_load_membase_byte(inst,reg,basereg,imm) \
do { \
arm_load_membase_either((inst), (reg), (basereg), (imm), \
0x00400000); \
} while (0)
#define arm_load_membase_sbyte(inst,reg,basereg,imm) \
do { \
arm_load_membase_either((inst), (reg), (basereg), (imm), \
0x00400000); \
arm_shift_reg_imm8((inst), ARM_SHL, (reg), (reg), 24); \
arm_shift_reg_imm8((inst), ARM_SAR, (reg), (reg), 24); \
} while (0)
#define arm_load_membase_ushort(inst,reg,basereg,imm) \
do { \
arm_load_membase_byte((inst), ARM_WORK, (basereg), (imm)); \
arm_load_membase_byte((inst), (reg), (basereg), (imm) + 1); \
arm_shift_reg_imm8((inst), ARM_SHL, (reg), (reg), 8); \
arm_alu_reg_reg((inst), ARM_ORR, (reg), (reg), ARM_WORK); \
} while (0)
#define arm_load_membase_short(inst,reg,basereg,imm) \
do { \
arm_load_membase_byte((inst), ARM_WORK, (basereg), (imm)); \
arm_load_membase_byte((inst), (reg), (basereg), (imm) + 1); \
arm_shift_reg_imm8((inst), ARM_SHL, (reg), (reg), 24); \
arm_shift_reg_imm8((inst), ARM_SAR, (reg), (reg), 16); \
arm_alu_reg_reg((inst), ARM_ORR, (reg), (reg), ARM_WORK); \
} while (0)
#ifdef JIT_ARM_HAS_FPA
#define arm_load_membase_float(inst,reg,basereg,imm,mask) \
do { \
int __mb_offset = (int)(imm); \
if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D900100 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)((__mb_offset / 4) & 0xFF))); \
} \
else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D180100 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)(((-__mb_offset) / 4) & 0xFF)));\
} \
else \
{ \
arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, \
(basereg), ARM_WORK); \
arm_inst_add((inst), arm_prefix(0x0D900100 | (mask)) | \
(((unsigned int)ARM_WORK) << 16) | \
(((unsigned int)(reg)) << 12)); \
} \
} while (0)
#define arm_load_membase_float32(inst,reg,basereg,imm) \
do { \
arm_load_membase_float((inst), (reg), (basereg), (imm), 0); \
} while (0)
#define arm_load_membase_float64(inst,reg,basereg,imm) \
do { \
arm_load_membase_float((inst), (reg), (basereg), \
(imm), 0x00008000); \
} while (0)
#endif
#ifdef JIT_ARM_HAS_VFP
#define arm_load_membase_float(inst,reg,basereg,imm,mask) \
do { \
unsigned int reg_top_4_bits = (reg & 0x1E) >> 1; \
unsigned int reg_bottom_bit = (reg & 0x01); \
int __mb_offset = (int)(imm); \
if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D900A00 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg_top_4_bits)) << 12) | \
(((unsigned int)(reg_bottom_bit)) << 22) | \
((unsigned int)((__mb_offset / 4) & 0xFF))); \
} \
else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D100A00 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg_top_4_bits)) << 12) | \
(((unsigned int)(reg_bottom_bit)) << 22) | \
((unsigned int)(((-__mb_offset) / 4) & 0xFF)));\
} \
else \
{ \
assert(reg != ARM_WORK); \
assert(basereg!=ARM_WORK); \
if(__mb_offset > 0) \
{ \
arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, (basereg), ARM_WORK); \
} \
else \
{ \
arm_mov_reg_imm((inst), ARM_WORK, -__mb_offset); \
arm_alu_reg_reg((inst), ARM_SUB, ARM_WORK, (basereg), ARM_WORK); \
} \
arm_inst_add((inst), arm_prefix(0x0D900A00 | (mask)) | \
(((unsigned int)ARM_WORK) << 16) | \
(((unsigned int)(reg_top_4_bits)) << 12) | \
(((unsigned int)(reg_bottom_bit)) << 22)); \
} \
} while (0)
#define arm_load_membase_float64(inst,reg,basereg,imm) \
do { \
int __mb_offset = (int)(imm); \
if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D900B00) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)((__mb_offset / 4) & 0xFF))); \
} \
else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D100B00) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)(((-__mb_offset) / 4) & 0xFF)));\
} \
else \
{ \
assert(reg != ARM_WORK); \
assert(basereg!=ARM_WORK); \
if(__mb_offset > 0) \
{ \
arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, (basereg), ARM_WORK); \
} \
else \
{ \
arm_mov_reg_imm((inst), ARM_WORK, -__mb_offset); \
arm_alu_reg_reg((inst), ARM_SUB, ARM_WORK, (basereg), ARM_WORK); \
} \
arm_inst_add((inst), arm_prefix(0x0D900B00) | \
(((unsigned int)ARM_WORK) << 16) | \
(((unsigned int)(reg)) << 12)); \
} \
} while (0)
#define arm_load_membase_float32(inst,reg,basereg,imm) \
do { \
arm_load_membase_float((inst), (reg), (basereg), (imm), 0); \
} while (0)
#define arm_fld_membase(inst,dfreg,basereg,disp,is_double) \
do { \
if (is_double) \
{ \
arm_load_membase_float64((inst), (dfreg), (basereg), (disp)); \
} \
else \
{ \
arm_load_membase_float32((inst), (dfreg), (basereg), (disp)); \
}\
} while(0)
#define arm_fld_memindex(inst,dfreg,basereg,disp,indexreg,shift,is_double,scratchreg) \
do { \
if (is_double) \
{ \
arm_load_memindex_float64((inst), (dfreg), (basereg), (disp), (indexreg), (shift), (scratchreg)); \
} \
else \
{ \
arm_load_memindex_float32((inst), (dfreg), (basereg), (disp), (indexreg), (shift), (scratchreg)); \
}\
} while(0)
#define arm_load_memindex_float64(inst,dfreg,basereg,disp,indexreg,shift,scratchreg) \
do { \
arm_shift_reg_imm8((inst), ARM_SHL, ARM_WORK, (indexreg), (shift)); \
arm_alu_reg_reg((inst), ARM_ADD, (scratchreg), (basereg), ARM_WORK); \
arm_load_membase_float64((inst), (dfreg), (scratchreg), (disp)); \
} while (0)
#define arm_load_memindex_float32(inst,dfreg,basereg,disp,indexreg,shift,scratchreg) \
do { \
arm_shift_reg_imm8((inst), ARM_SHL, ARM_WORK, (indexreg), (shift)); \
arm_alu_reg_reg((inst), ARM_ADD, (scratchreg), (basereg), ARM_WORK); \
arm_load_membase_float32((inst), (dfreg), (scratchreg), (disp)); \
} while (0)
#define arm_fst_memindex(inst,sfreg,basereg,disp,indexreg,shift,is_double,scratchreg) \
do { \
if (is_double) \
{ \
arm_store_memindex_float64((inst), (sfreg), (basereg), (disp), (indexreg), (shift), (scratchreg)); \
} \
else \
{ \
arm_store_memindex_float32((inst), (sfreg), (basereg), (disp), (indexreg), (shift), (scratchreg)); \
}\
} while(0)
#define arm_store_memindex_float64(inst,dfreg,basereg,disp,indexreg,shift,scratchreg) \
do { \
arm_shift_reg_imm8((inst), ARM_SHL, ARM_WORK, (indexreg), (shift)); \
arm_alu_reg_reg((inst), ARM_ADD, (scratchreg), (basereg), ARM_WORK); \
arm_store_membase_float64((inst), (dfreg), (scratchreg), (disp)); \
} while (0)
#define arm_store_memindex_float32(inst,dfreg,basereg,disp,indexreg,shift,scratchreg) \
do { \
arm_shift_reg_imm8((inst), ARM_SHL, ARM_WORK, (indexreg), (shift)); \
arm_alu_reg_reg((inst), ARM_ADD, (scratchreg), (basereg), ARM_WORK); \
arm_store_membase_float32((inst), (dfreg), (scratchreg), (disp)); \
} while (0)
#endif
#define arm_store_membase_either(inst,reg,basereg,imm,mask) \
do { \
int __sm_offset = (int)(imm); \
if(__sm_offset >= 0 && __sm_offset < (1 << 12)) \
{ \
arm_inst_add((inst), arm_prefix(0x05800000 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)__sm_offset)); \
} \
else if(__sm_offset > -(1 << 12) && __sm_offset < 0) \
{ \
arm_inst_add((inst), arm_prefix(0x05000000 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)(-__sm_offset))); \
} \
else \
{ \
assert(reg != ARM_WORK); \
assert(basereg!=ARM_WORK); \
arm_mov_reg_imm((inst), ARM_WORK, __sm_offset); \
arm_inst_add((inst), arm_prefix(0x07800000 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)ARM_WORK)); \
} \
} while (0)
#define arm_store_membase(inst,reg,basereg,imm) \
do { \
arm_store_membase_either((inst), (reg), (basereg), (imm), 0); \
} while (0)
#define arm_store_membase_byte(inst,reg,basereg,imm) \
do { \
arm_store_membase_either((inst), (reg), (basereg), (imm), \
0x00400000); \
} while (0)
#define arm_store_membase_sbyte(inst,reg,basereg,imm) \
do { \
arm_store_membase_byte((inst), (reg), (basereg), (imm)); \
} while (0)
#define arm_store_membase_short(inst,reg,basereg,imm) \
do { \
arm_store_membase_either((inst), (reg), (basereg), (imm), \
0x00400000); \
arm_shift_reg_imm8((inst), ARM_SHR, (reg), (reg), 8); \
arm_store_membase_either((inst), (reg), (basereg), \
(imm) + 1, 0x00400000); \
} while (0)
#define arm_store_membase_ushort(inst,reg,basereg,imm) \
do { \
arm_store_membase_short((inst), (reg), (basereg), (imm)); \
} while (0)
#ifdef JIT_ARM_HAS_FPA
#define arm_store_membase_float(inst,reg,basereg,imm,mask) \
do { \
int __mb_offset = (int)(imm); \
if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D800100 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)((__mb_offset / 4) & 0xFF))); \
} \
else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D080100 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)(((-__mb_offset) / 4) & 0xFF)));\
} \
else \
{ \
arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, \
(basereg), ARM_WORK); \
arm_inst_add((inst), arm_prefix(0x0D800100 | (mask)) | \
(((unsigned int)ARM_WORK) << 16) | \
(((unsigned int)(reg)) << 12)); \
} \
} while (0)
#define arm_store_membase_float32(inst,reg,basereg,imm) \
do { \
arm_store_membase_float((inst), (reg), (basereg), (imm), 0); \
} while (0)
#define arm_store_membase_float64(inst,reg,basereg,imm) \
do { \
arm_store_membase_float((inst), (reg), (basereg), \
(imm), 0x00008000); \
} while (0)
#define arm_push_reg_float32(inst,reg) \
do { \
arm_store_membase_float((inst), (reg), ARM_SP, \
-4, 0x00200000); \
} while (0)
#define arm_push_reg_float64(inst,reg) \
do { \
arm_store_membase_float((inst), (reg), ARM_SP, \
-4, 0x00208000); \
} while (0)
#endif
#ifdef JIT_ARM_HAS_VFP
#define arm_store_membase_float32(inst,reg,basereg,imm) \
do { \
unsigned int reg_top_4_bits = (reg & 0x1E) >> 1; \
unsigned int reg_bottom_bit = (reg & 0x01); \
int __mb_offset = (int)(imm); \
if(__mb_offset >= 0 && __mb_offset < (1 << 10) && (__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D800A00) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg_top_4_bits)) << 12) | \
(((unsigned int)(reg_bottom_bit)) << 22) | \
((unsigned int)((__mb_offset / 4) & 0xFF))); \
} \
else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && (__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D000A00) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg_top_4_bits)) << 12) | \
(((unsigned int)(reg_bottom_bit)) << 22) | \
((unsigned int)(((-__mb_offset) / 4) & 0xFF))); \
} \
else \
{ \
assert(reg != ARM_WORK); \
assert(basereg!=ARM_WORK); \
if(__mb_offset > 0) \
{ \
arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, (basereg), ARM_WORK); \
} \
else \
{ \
arm_mov_reg_imm((inst), ARM_WORK, -__mb_offset); \
arm_alu_reg_reg((inst), ARM_SUB, ARM_WORK, (basereg), ARM_WORK); \
} \
arm_inst_add((inst), arm_prefix(0x0D800A00) | \
(((unsigned int)ARM_WORK) << 16) | \
(((unsigned int)(reg_top_4_bits)) << 12) | \
(((unsigned int)(reg_bottom_bit)) << 22)); \
} \
} while (0)
#define arm_store_membase_float64(inst,reg,basereg,imm) \
do { \
int __mb_offset = (int)(imm); \
if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D800B00 | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)((__mb_offset / 4) & 0xFF)))); \
} \
else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \
(__mb_offset & 3) == 0) \
{ \
arm_inst_add((inst), arm_prefix(0x0D000B00 | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
((unsigned int)(((-__mb_offset) / 4) & 0xFF))));\
} \
else \
{ \
assert(reg != ARM_WORK); \
assert(basereg!=ARM_WORK); \
if(__mb_offset > 0) \
{ \
arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, (basereg), ARM_WORK); \
} \
else \
{ \
arm_mov_reg_imm((inst), ARM_WORK, -__mb_offset); \
arm_alu_reg_reg((inst), ARM_SUB, ARM_WORK, (basereg), ARM_WORK);\
} \
arm_inst_add((inst), arm_prefix(0x0D800B00 | \
(((unsigned int)ARM_WORK) << 16) | \
(((unsigned int)(reg)) << 12)));\
} \
} while (0)
#define arm_push_reg_float64(inst,reg) \
do { \
arm_store_membase_float64((inst), (reg), ARM_SP, -8); \
arm_alu_reg_imm(inst, ARM_SUB, ARM_SP, ARM_SP, 8); \
} while (0)
#define arm_push_reg_float32(inst,reg) \
do { \
arm_store_membase_float32((inst), (reg), ARM_SP, -4); \
arm_alu_reg_imm(inst, ARM_SUB, ARM_SP, ARM_SP, 4); \
} while (0)
#define arm_mov_double_reg_reg(inst,dreg,lowsreg,highsreg) \
do { \
arm_inst_add((inst), arm_prefix(0x0C400B10) | \
(((unsigned int)(lowsreg)) << 12) | \
(((unsigned int)(highsreg)) << 16) | \
((unsigned int)(dreg))); \
} while(0)
#define arm_mov_reg_reg_double(inst,lowsreg,highsreg,sreg) \
do { \
arm_inst_add((inst), arm_prefix(0x0C500B10) | \
(((unsigned int)(lowsreg)) << 12) | \
(((unsigned int)(highsreg)) << 16) | \
((unsigned int)(sreg))); \
} while(0)
#define arm_mov_float_reg(inst,dreg,sreg) \
do { \
char dreg_top_4_bits = (dreg & 0x1E) >> 1; \
char dreg_bottom_bit = (dreg & 0x01); \
arm_inst_add((inst), arm_prefix(0x0E000A10) | \
(((unsigned int)(sreg)) << 12) | \
(((unsigned int)(dreg_top_4_bits)) << 16) | \
(((unsigned int)(dreg_bottom_bit)) << 7)); \
} while(0)
#define arm_mov_reg_float(inst,dreg,sreg) \
do { \
char sreg_top_4_bits = (sreg & 0x1E) >> 1; \
char sreg_bottom_bit = (sreg & 0x01); \
arm_inst_add((inst), arm_prefix(0x0E100A10) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg_top_4_bits)) << 16) | \
(((unsigned int)(sreg_bottom_bit)) << 7)); \
} while(0)
#define arm_convert_float_double_single(inst,dreg,sreg) \
{ \
unsigned char sreg_top_4_bits = (sreg & 0x1E) >> 1; \
unsigned char sreg_bottom_bit = (sreg & 0x01); \
arm_inst_add((inst), arm_prefix(0x0EB70AC0) | \
(((unsigned int)(sreg_top_4_bits))) | \
(((unsigned int)(sreg_bottom_bit)) << 5) | \
(((unsigned int)(dreg)) << 12)); \
}
#define arm_convert_float_single_double(inst,dreg,sreg) \
{ \
unsigned char dreg_top_4_bits = (dreg & 0x1E) >> 1; \
unsigned char dreg_bottom_bit = (dreg & 0x01); \
arm_inst_add((inst), arm_prefix(0x0EB70BC0) | \
(((unsigned int)(dreg_top_4_bits)) << 12) | \
(((unsigned int)(dreg_bottom_bit)) << 22) | \
((unsigned int)(sreg))); \
}
#define arm_convert_float_signed_integer_double(inst,dreg,sreg) \
unsigned char sreg_top_4_bits = (sreg & 0x1E) >> 1; \
unsigned char sreg_bottom_bit = (sreg & 0x01); \
arm_inst_add((inst), arm_prefix(0x0EB80BC0) | \
(((unsigned int)(dreg)) << 12) | \
(((unsigned int)(sreg_bottom_bit)) << 5) | \
((unsigned int)(sreg_top_4_bits)));
#endif
#define arm_load_memindex_either(inst,reg,basereg,indexreg,shift,mask) \
do { \
arm_inst_add((inst), arm_prefix(0x07900000 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
(((unsigned int)(shift)) << 7) | \
((unsigned int)(indexreg))); \
} while (0)
#define arm_load_memindex(inst,reg,basereg,indexreg) \
do { \
arm_load_memindex_either((inst), (reg), (basereg), \
(indexreg), 2, 0); \
} while (0)
#define arm_load_memindex_byte(inst,reg,basereg,indexreg) \
do { \
arm_load_memindex_either((inst), (reg), (basereg), \
(indexreg), 0, 0x00400000); \
} while (0)
#define arm_load_memindex_sbyte(inst,reg,basereg,indexreg) \
do { \
arm_load_memindex_either((inst), (reg), (basereg), \
(indexreg), 0, 0x00400000); \
arm_shift_reg_imm8((inst), ARM_SHL, (reg), (reg), 24); \
arm_shift_reg_imm8((inst), ARM_SAR, (reg), (reg), 24); \
} while (0)
#define arm_load_memindex_ushort(inst,reg,basereg,indexreg) \
do { \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, (basereg), \
(indexreg)); \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, ARM_WORK, \
(indexreg)); \
arm_load_membase_byte((inst), (reg), ARM_WORK, 0); \
arm_load_membase_byte((inst), ARM_WORK, ARM_WORK, 1); \
arm_shift_reg_imm8((inst), ARM_SHL, ARM_WORK, ARM_WORK, 8); \
arm_alu_reg_reg((inst), ARM_ORR, (reg), (reg), ARM_WORK); \
} while (0)
#define arm_load_memindex_short(inst,reg,basereg,indexreg) \
do { \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, (basereg), \
(indexreg)); \
arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, ARM_WORK, \
(indexreg)); \
arm_load_membase_byte((inst), (reg), ARM_WORK, 0); \
arm_load_membase_byte((inst), ARM_WORK, ARM_WORK, 1); \
arm_shift_reg_imm8((inst), ARM_SHL, ARM_WORK, ARM_WORK, 24); \
arm_shift_reg_imm8((inst), ARM_SAR, ARM_WORK, ARM_WORK, 16); \
arm_alu_reg_reg((inst), ARM_ORR, (reg), (reg), ARM_WORK); \
} while (0)
#define arm_store_memindex_either(inst,reg,basereg,indexreg,shift,mask) \
do { \
arm_inst_add((inst), arm_prefix(0x07800000 | (mask)) | \
(((unsigned int)(basereg)) << 16) | \
(((unsigned int)(reg)) << 12) | \
(((unsigned int)(shift)) << 7) | \
((unsigned int)(indexreg))); \
} while (0)
#define arm_store_memindex(inst,reg,basereg,indexreg) \
do { \
arm_store_memindex_either((inst), (reg), (basereg), \
(indexreg), 2, 0); \
} while (0)
#define arm_store_memindex_byte(inst,reg,basereg,indexreg) \
do { \
arm_store_memindex_either((inst), (reg), (basereg), \
(indexreg), 0, 0x00400000); \
} while (0)
#define arm_store_memindex_sbyte(inst,reg,basereg,indexreg) \
do { \
arm_store_memindex_byte((inst), (reg), (basereg), \
(indexreg)); \
} while (0)
#define arm_store_memindex_short(inst,reg,basereg,indexreg) \
do { \
arm_store_memindex_either((inst), (reg), (basereg), \
(indexreg), 1, 0x00400000); \
arm_alu_reg_imm8((inst), ARM_ADD, (basereg), (basereg), 1); \
arm_shift_reg_imm8((inst), ARM_SHR, (reg), (reg), 8); \
arm_store_memindex_either((inst), (reg), (basereg), \
(indexreg), 1, 0x00400000); \
} while (0)
#define arm_store_memindex_ushort(inst,reg,basereg,indexreg) \
do { \
arm_store_memindex_short((inst), (reg), \
(basereg), (indexreg)); \
} while (0)
#ifdef __cplusplus
};
#endif
#endif