ljx

FORK: LuaJIT with native 5.2 and 5.3 support
git clone https://git.neptards.moe/neptards/ljx.git
Log | Files | Refs | README

lj_target_arm.h (7103B)


      1 /*
      2 ** Definitions for ARM CPUs.
      3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
      4 */
      5 
      6 #ifndef _LJ_TARGET_ARM_H
      7 #define _LJ_TARGET_ARM_H
      8 
      9 /* -- Registers IDs ------------------------------------------------------- */
     10 
     11 #define GPRDEF(_) \
     12   _(R0) _(R1) _(R2) _(R3) _(R4) _(R5) _(R6) _(R7) \
     13   _(R8) _(R9) _(R10) _(R11) _(R12) _(SP) _(LR) _(PC)
     14 #if LJ_SOFTFP
     15 #define FPRDEF(_)
     16 #else
     17 #define FPRDEF(_) \
     18   _(D0) _(D1) _(D2) _(D3) _(D4) _(D5) _(D6) _(D7) \
     19   _(D8) _(D9) _(D10) _(D11) _(D12) _(D13) _(D14) _(D15)
     20 #endif
     21 #define VRIDDEF(_)
     22 
     23 #define RIDENUM(name)	RID_##name,
     24 
     25 enum {
     26   GPRDEF(RIDENUM)		/* General-purpose registers (GPRs). */
     27   FPRDEF(RIDENUM)		/* Floating-point registers (FPRs). */
     28   RID_MAX,
     29   RID_TMP = RID_LR,
     30 
     31   /* Calling conventions. */
     32   RID_RET = RID_R0,
     33   RID_RETLO = RID_R0,
     34   RID_RETHI = RID_R1,
     35 #if LJ_SOFTFP
     36   RID_FPRET = RID_R0,
     37 #else
     38   RID_FPRET = RID_D0,
     39 #endif
     40 
     41   /* These definitions must match with the *.dasc file(s): */
     42   RID_BASE = RID_R9,		/* Interpreter BASE. */
     43   RID_LPC = RID_R6,		/* Interpreter PC. */
     44   RID_DISPATCH = RID_R7,	/* Interpreter DISPATCH table. */
     45   RID_LREG = RID_R8,		/* Interpreter L. */
     46 
     47   /* Register ranges [min, max) and number of registers. */
     48   RID_MIN_GPR = RID_R0,
     49   RID_MAX_GPR = RID_PC+1,
     50   RID_MIN_FPR = RID_MAX_GPR,
     51 #if LJ_SOFTFP
     52   RID_MAX_FPR = RID_MIN_FPR,
     53 #else
     54   RID_MAX_FPR = RID_D15+1,
     55 #endif
     56   RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
     57   RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR
     58 };
     59 
     60 #define RID_NUM_KREF		RID_NUM_GPR
     61 #define RID_MIN_KREF		RID_R0
     62 
     63 /* -- Register sets ------------------------------------------------------- */
     64 
     65 /* Make use of all registers, except sp, lr and pc. */
     66 #define RSET_GPR		(RSET_RANGE(RID_MIN_GPR, RID_R12+1))
     67 #define RSET_GPREVEN \
     68   (RID2RSET(RID_R0)|RID2RSET(RID_R2)|RID2RSET(RID_R4)|RID2RSET(RID_R6)| \
     69    RID2RSET(RID_R8)|RID2RSET(RID_R10))
     70 #define RSET_GPRODD \
     71   (RID2RSET(RID_R1)|RID2RSET(RID_R3)|RID2RSET(RID_R5)|RID2RSET(RID_R7)| \
     72    RID2RSET(RID_R9)|RID2RSET(RID_R11))
     73 #if LJ_SOFTFP
     74 #define RSET_FPR		0
     75 #else
     76 #define RSET_FPR		(RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR))
     77 #endif
     78 #define RSET_ALL		(RSET_GPR|RSET_FPR)
     79 #define RSET_INIT		RSET_ALL
     80 
     81 /* ABI-specific register sets. lr is an implicit scratch register. */
     82 #define RSET_SCRATCH_GPR_	(RSET_RANGE(RID_R0, RID_R3+1)|RID2RSET(RID_R12))
     83 #ifdef __APPLE__
     84 #define RSET_SCRATCH_GPR	(RSET_SCRATCH_GPR_|RID2RSET(RID_R9))
     85 #else
     86 #define RSET_SCRATCH_GPR	RSET_SCRATCH_GPR_
     87 #endif
     88 #if LJ_SOFTFP
     89 #define RSET_SCRATCH_FPR	0
     90 #else
     91 #define RSET_SCRATCH_FPR	(RSET_RANGE(RID_D0, RID_D7+1))
     92 #endif
     93 #define RSET_SCRATCH		(RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
     94 #define REGARG_FIRSTGPR		RID_R0
     95 #define REGARG_LASTGPR		RID_R3
     96 #define REGARG_NUMGPR		4
     97 #if LJ_ABI_SOFTFP
     98 #define REGARG_FIRSTFPR		0
     99 #define REGARG_LASTFPR		0
    100 #define REGARG_NUMFPR		0
    101 #else
    102 #define REGARG_FIRSTFPR		RID_D0
    103 #define REGARG_LASTFPR		RID_D7
    104 #define REGARG_NUMFPR		8
    105 #endif
    106 
    107 /* -- Spill slots --------------------------------------------------------- */
    108 
    109 /* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
    110 **
    111 ** SPS_FIXED: Available fixed spill slots in interpreter frame.
    112 ** This definition must match with the *.dasc file(s).
    113 **
    114 ** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
    115 */
    116 #define SPS_FIXED	2
    117 #define SPS_FIRST	2
    118 
    119 #define SPOFS_TMP	0
    120 
    121 #define sps_scale(slot)		(4 * (int32_t)(slot))
    122 #define sps_align(slot)		(((slot) - SPS_FIXED + 1) & ~1)
    123 
    124 /* -- Exit state ---------------------------------------------------------- */
    125 
    126 /* This definition must match with the *.dasc file(s). */
    127 typedef struct {
    128 #if !LJ_SOFTFP
    129   lua_Number fpr[RID_NUM_FPR];	/* Floating-point registers. */
    130 #endif
    131   int32_t gpr[RID_NUM_GPR];	/* General-purpose registers. */
    132   int32_t spill[256];		/* Spill slots. */
    133 } ExitState;
    134 
    135 /* PC after instruction that caused an exit. Used to find the trace number. */
    136 #define EXITSTATE_PCREG		RID_PC
    137 /* Highest exit + 1 indicates stack check. */
    138 #define EXITSTATE_CHECKEXIT	1
    139 
    140 #define EXITSTUB_SPACING        4
    141 #define EXITSTUBS_PER_GROUP     32
    142 
    143 /* -- Instructions -------------------------------------------------------- */
    144 
    145 /* Instruction fields. */
    146 #define ARMF_CC(ai, cc)	(((ai) ^ ARMI_CCAL) | ((cc) << 28))
    147 #define ARMF_N(r)	((r) << 16)
    148 #define ARMF_D(r)	((r) << 12)
    149 #define ARMF_S(r)	((r) << 8)
    150 #define ARMF_M(r)	(r)
    151 #define ARMF_SH(sh, n)	(((sh) << 5) | ((n) << 7))
    152 #define ARMF_RSH(sh, r)	(0x10 | ((sh) << 5) | ARMF_S(r))
    153 
    154 typedef enum ARMIns {
    155   ARMI_CCAL = 0xe0000000,
    156   ARMI_S = 0x000100000,
    157   ARMI_K12 = 0x02000000,
    158   ARMI_KNEG = 0x00200000,
    159   ARMI_LS_W = 0x00200000,
    160   ARMI_LS_U = 0x00800000,
    161   ARMI_LS_P = 0x01000000,
    162   ARMI_LS_R = 0x02000000,
    163   ARMI_LSX_I = 0x00400000,
    164 
    165   ARMI_AND = 0xe0000000,
    166   ARMI_EOR = 0xe0200000,
    167   ARMI_SUB = 0xe0400000,
    168   ARMI_RSB = 0xe0600000,
    169   ARMI_ADD = 0xe0800000,
    170   ARMI_ADC = 0xe0a00000,
    171   ARMI_SBC = 0xe0c00000,
    172   ARMI_RSC = 0xe0e00000,
    173   ARMI_TST = 0xe1100000,
    174   ARMI_TEQ = 0xe1300000,
    175   ARMI_CMP = 0xe1500000,
    176   ARMI_CMN = 0xe1700000,
    177   ARMI_ORR = 0xe1800000,
    178   ARMI_MOV = 0xe1a00000,
    179   ARMI_BIC = 0xe1c00000,
    180   ARMI_MVN = 0xe1e00000,
    181 
    182   ARMI_NOP = 0xe1a00000,
    183 
    184   ARMI_MUL = 0xe0000090,
    185   ARMI_SMULL = 0xe0c00090,
    186 
    187   ARMI_LDR = 0xe4100000,
    188   ARMI_LDRB = 0xe4500000,
    189   ARMI_LDRH = 0xe01000b0,
    190   ARMI_LDRSB = 0xe01000d0,
    191   ARMI_LDRSH = 0xe01000f0,
    192   ARMI_LDRD = 0xe00000d0,
    193   ARMI_STR = 0xe4000000,
    194   ARMI_STRB = 0xe4400000,
    195   ARMI_STRH = 0xe00000b0,
    196   ARMI_STRD = 0xe00000f0,
    197   ARMI_PUSH = 0xe92d0000,
    198 
    199   ARMI_B = 0xea000000,
    200   ARMI_BL = 0xeb000000,
    201   ARMI_BLX = 0xfa000000,
    202   ARMI_BLXr = 0xe12fff30,
    203 
    204   /* ARMv6 */
    205   ARMI_REV = 0xe6bf0f30,
    206   ARMI_SXTB = 0xe6af0070,
    207   ARMI_SXTH = 0xe6bf0070,
    208   ARMI_UXTB = 0xe6ef0070,
    209   ARMI_UXTH = 0xe6ff0070,
    210 
    211   /* ARMv6T2 */
    212   ARMI_MOVW = 0xe3000000,
    213   ARMI_MOVT = 0xe3400000,
    214 
    215   /* VFP */
    216   ARMI_VMOV_D = 0xeeb00b40,
    217   ARMI_VMOV_S = 0xeeb00a40,
    218   ARMI_VMOVI_D = 0xeeb00b00,
    219 
    220   ARMI_VMOV_R_S = 0xee100a10,
    221   ARMI_VMOV_S_R = 0xee000a10,
    222   ARMI_VMOV_RR_D = 0xec500b10,
    223   ARMI_VMOV_D_RR = 0xec400b10,
    224 
    225   ARMI_VADD_D = 0xee300b00,
    226   ARMI_VSUB_D = 0xee300b40,
    227   ARMI_VMUL_D = 0xee200b00,
    228   ARMI_VMLA_D = 0xee000b00,
    229   ARMI_VMLS_D = 0xee000b40,
    230   ARMI_VNMLS_D = 0xee100b00,
    231   ARMI_VDIV_D = 0xee800b00,
    232 
    233   ARMI_VABS_D = 0xeeb00bc0,
    234   ARMI_VNEG_D = 0xeeb10b40,
    235   ARMI_VSQRT_D = 0xeeb10bc0,
    236 
    237   ARMI_VCMP_D = 0xeeb40b40,
    238   ARMI_VCMPZ_D = 0xeeb50b40,
    239 
    240   ARMI_VMRS = 0xeef1fa10,
    241 
    242   ARMI_VCVT_S32_F32 = 0xeebd0ac0,
    243   ARMI_VCVT_S32_F64 = 0xeebd0bc0,
    244   ARMI_VCVT_U32_F32 = 0xeebc0ac0,
    245   ARMI_VCVT_U32_F64 = 0xeebc0bc0,
    246   ARMI_VCVT_F32_S32 = 0xeeb80ac0,
    247   ARMI_VCVT_F64_S32 = 0xeeb80bc0,
    248   ARMI_VCVT_F32_U32 = 0xeeb80a40,
    249   ARMI_VCVT_F64_U32 = 0xeeb80b40,
    250   ARMI_VCVT_F32_F64 = 0xeeb70bc0,
    251   ARMI_VCVT_F64_F32 = 0xeeb70ac0,
    252 
    253   ARMI_VLDR_S = 0xed100a00,
    254   ARMI_VLDR_D = 0xed100b00,
    255   ARMI_VSTR_S = 0xed000a00,
    256   ARMI_VSTR_D = 0xed000b00,
    257 } ARMIns;
    258 
    259 typedef enum ARMShift {
    260   ARMSH_LSL, ARMSH_LSR, ARMSH_ASR, ARMSH_ROR
    261 } ARMShift;
    262 
    263 /* ARM condition codes. */
    264 typedef enum ARMCC {
    265   CC_EQ, CC_NE, CC_CS, CC_CC, CC_MI, CC_PL, CC_VS, CC_VC,
    266   CC_HI, CC_LS, CC_GE, CC_LT, CC_GT, CC_LE, CC_AL,
    267   CC_HS = CC_CS, CC_LO = CC_CC
    268 } ARMCC;
    269 
    270 #endif