/[pcre]/code/trunk/sljit/sljitNativeARM_v5.c
ViewVC logotype

Diff of /code/trunk/sljit/sljitNativeARM_v5.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1194 by zherczeg, Sun Oct 28 05:22:32 2012 UTC revision 1195 by zherczeg, Thu Nov 1 15:21:27 2012 UTC
# Line 41  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST cha Line 41  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST cha
41  #define TMP_REG3        (SLJIT_NO_REGISTERS + 3)  #define TMP_REG3        (SLJIT_NO_REGISTERS + 3)
42  #define TMP_PC          (SLJIT_NO_REGISTERS + 4)  #define TMP_PC          (SLJIT_NO_REGISTERS + 4)
43    
44  #define TMP_FREG1       (SLJIT_FLOAT_REG4 + 1)  #define TMP_FREG1       (0)
45  #define TMP_FREG2       (SLJIT_FLOAT_REG4 + 2)  #define TMP_FREG2       (SLJIT_FLOAT_REG6 + 1)
46    
47  /* In ARM instruction words.  /* In ARM instruction words.
48     Cache lines are usually 32 byte aligned. */     Cache lines are usually 32 byte aligned. */
# Line 52  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST cha Line 52  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST cha
52  #define ALIGN_INSTRUCTION(ptr) \  #define ALIGN_INSTRUCTION(ptr) \
53          (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1))          (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1))
54  #define MAX_DIFFERENCE(max_diff) \  #define MAX_DIFFERENCE(max_diff) \
55          (((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))          (((max_diff) / (sljit_si)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))
56    
57  /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */  /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
58  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
# Line 99  static SLJIT_CONST sljit_ub reg_map[SLJI Line 99  static SLJIT_CONST sljit_ub reg_map[SLJI
99  #define SMULL           0xe0c00090  #define SMULL           0xe0c00090
100  #define SUB_DP          0x2  #define SUB_DP          0x2
101  #define UMULL           0xe0800090  #define UMULL           0xe0800090
102  #define VABS_F64        0xeeb00bc0  #define VABS_F32        0xeeb00ac0
103  #define VADD_F64        0xee300b00  #define VADD_F32        0xee300a00
104  #define VCMP_F64        0xeeb40b40  #define VCMP_F32        0xeeb40a40
105  #define VDIV_F64        0xee800b00  #define VDIV_F32        0xee800a00
106  #define VMOV_F64        0xeeb00b40  #define VMOV_F32        0xeeb00a40
107  #define VMRS            0xeef1fa10  #define VMRS            0xeef1fa10
108  #define VMUL_F64        0xee200b00  #define VMUL_F32        0xee200a00
109  #define VNEG_F64        0xeeb10b40  #define VNEG_F32        0xeeb10a40
110  #define VSTR            0xed000b00  #define VSTR_F32        0xed000a00
111  #define VSUB_F64        0xee300b40  #define VSUB_F32        0xee300a40
112    
113  #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)  #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
114  /* Arm v7 specific instructions. */  /* Arm v7 specific instructions. */
# Line 122  static SLJIT_CONST sljit_ub reg_map[SLJI Line 122  static SLJIT_CONST sljit_ub reg_map[SLJI
122    
123  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
124    
125  static int push_cpool(struct sljit_compiler *compiler)  static sljit_si push_cpool(struct sljit_compiler *compiler)
126  {  {
127          /* Pushing the constant pool into the instruction stream. */          /* Pushing the constant pool into the instruction stream. */
128          sljit_uw* inst;          sljit_uw* inst;
129          sljit_uw* cpool_ptr;          sljit_uw* cpool_ptr;
130          sljit_uw* cpool_end;          sljit_uw* cpool_end;
131          int i;          sljit_si i;
132    
133          /* The label could point the address after the constant pool. */          /* The label could point the address after the constant pool. */
134          if (compiler->last_label && compiler->last_label->size == compiler->size)          if (compiler->last_label && compiler->last_label->size == compiler->size)
# Line 160  static int push_cpool(struct sljit_compi Line 160  static int push_cpool(struct sljit_compi
160          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
161  }  }
162    
163  static int push_inst(struct sljit_compiler *compiler, sljit_uw inst)  static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst)
164  {  {
165          sljit_uw* ptr;          sljit_uw* ptr;
166    
# Line 174  static int push_inst(struct sljit_compil Line 174  static int push_inst(struct sljit_compil
174          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
175  }  }
176    
177  static int push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)  static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
178  {  {
179          sljit_uw* ptr;          sljit_uw* ptr;
180          sljit_uw cpool_index = CPOOL_SIZE;          sljit_uw cpool_index = CPOOL_SIZE;
# Line 224  static int push_inst_with_literal(struct Line 224  static int push_inst_with_literal(struct
224          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
225  }  }
226    
227  static int push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)  static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
228  {  {
229          sljit_uw* ptr;          sljit_uw* ptr;
230          if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE))          if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE))
# Line 244  static int push_inst_with_unique_literal Line 244  static int push_inst_with_unique_literal
244          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
245  }  }
246    
247  static SLJIT_INLINE int prepare_blx(struct sljit_compiler *compiler)  static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler)
248  {  {
249          /* Place for at least two instruction (doesn't matter whether the first has a literal). */          /* Place for at least two instruction (doesn't matter whether the first has a literal). */
250          if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088)))          if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088)))
# Line 252  static SLJIT_INLINE int prepare_blx(stru Line 252  static SLJIT_INLINE int prepare_blx(stru
252          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
253  }  }
254    
255  static SLJIT_INLINE int emit_blx(struct sljit_compiler *compiler)  static SLJIT_INLINE sljit_si emit_blx(struct sljit_compiler *compiler)
256  {  {
257          /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */          /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */
258          SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092));          SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092));
# Line 282  static sljit_uw patch_pc_relative_loads( Line 282  static sljit_uw patch_pc_relative_loads(
282    
283                          /* Must be a load instruction with immediate offset. */                          /* Must be a load instruction with immediate offset. */
284                          SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20)));                          SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20)));
285                          if ((int)const_pool[ind] < 0) {                          if ((sljit_si)const_pool[ind] < 0) {
286                                  const_pool[ind] = counter;                                  const_pool[ind] = counter;
287                                  ind = counter;                                  ind = counter;
288                                  counter++;                                  counter++;
# Line 307  static sljit_uw patch_pc_relative_loads( Line 307  static sljit_uw patch_pc_relative_loads(
307  /* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */  /* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */
308  struct future_patch {  struct future_patch {
309          struct future_patch* next;          struct future_patch* next;
310          int index;          sljit_si index;
311          int value;          sljit_si value;
312  };  };
313    
314  static SLJIT_INLINE int resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)  static SLJIT_INLINE sljit_si resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)
315  {  {
316          int value;          sljit_si value;
317          struct future_patch *curr_patch, *prev_patch;          struct future_patch *curr_patch, *prev_patch;
318    
319          /* Using the values generated by patch_pc_relative_loads. */          /* Using the values generated by patch_pc_relative_loads. */
320          if (!*first_patch)          if (!*first_patch)
321                  value = (int)cpool_start_address[cpool_current_index];                  value = (sljit_si)cpool_start_address[cpool_current_index];
322          else {          else {
323                  curr_patch = *first_patch;                  curr_patch = *first_patch;
324                  prev_patch = 0;                  prev_patch = 0;
325                  while (1) {                  while (1) {
326                          if (!curr_patch) {                          if (!curr_patch) {
327                                  value = (int)cpool_start_address[cpool_current_index];                                  value = (sljit_si)cpool_start_address[cpool_current_index];
328                                  break;                                  break;
329                          }                          }
330                          if ((sljit_uw)curr_patch->index == cpool_current_index) {                          if ((sljit_uw)curr_patch->index == cpool_current_index) {
# Line 364  static SLJIT_INLINE int resolve_const_po Line 364  static SLJIT_INLINE int resolve_const_po
364    
365  #else  #else
366    
367  static int push_inst(struct sljit_compiler *compiler, sljit_uw inst)  static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst)
368  {  {
369          sljit_uw* ptr;          sljit_uw* ptr;
370    
# Line 375  static int push_inst(struct sljit_compil Line 375  static int push_inst(struct sljit_compil
375          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
376  }  }
377    
378  static SLJIT_INLINE int emit_imm(struct sljit_compiler *compiler, int reg, sljit_w imm)  static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
379  {  {
380          FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));          FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));
381          return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));          return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));
# Line 383  static SLJIT_INLINE int emit_imm(struct Line 383  static SLJIT_INLINE int emit_imm(struct
383    
384  #endif  #endif
385    
386  static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code)  static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code)
387  {  {
388          sljit_w diff;          sljit_sw diff;
389    
390          if (jump->flags & SLJIT_REWRITABLE_JUMP)          if (jump->flags & SLJIT_REWRITABLE_JUMP)
391                  return 0;                  return 0;
# Line 395  static SLJIT_INLINE int detect_jump_type Line 395  static SLJIT_INLINE int detect_jump_type
395                  code_ptr--;                  code_ptr--;
396    
397          if (jump->flags & JUMP_ADDR)          if (jump->flags & JUMP_ADDR)
398                  diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2));                  diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2));
399          else {          else {
400                  SLJIT_ASSERT(jump->flags & JUMP_LABEL);                  SLJIT_ASSERT(jump->flags & JUMP_LABEL);
401                  diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2));                  diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2));
402          }          }
403    
404          /* Branch to Thumb code has not been optimized yet. */          /* Branch to Thumb code has not been optimized yet. */
# Line 421  static SLJIT_INLINE int detect_jump_type Line 421  static SLJIT_INLINE int detect_jump_type
421          }          }
422  #else  #else
423          if (jump->flags & JUMP_ADDR)          if (jump->flags & JUMP_ADDR)
424                  diff = ((sljit_w)jump->u.target - (sljit_w)code_ptr);                  diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr);
425          else {          else {
426                  SLJIT_ASSERT(jump->flags & JUMP_LABEL);                  SLJIT_ASSERT(jump->flags & JUMP_LABEL);
427                  diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)code_ptr);                  diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr);
428          }          }
429    
430          /* Branch to Thumb code has not been optimized yet. */          /* Branch to Thumb code has not been optimized yet. */
# Line 442  static SLJIT_INLINE int detect_jump_type Line 442  static SLJIT_INLINE int detect_jump_type
442          return 0;          return 0;
443  }  }
444    
445  static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush)  static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_si flush)
446  {  {
447  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
448          sljit_uw *ptr = (sljit_uw*)addr;          sljit_uw *ptr = (sljit_uw*)addr;
449          sljit_uw *inst = (sljit_uw*)ptr[0];          sljit_uw *inst = (sljit_uw*)ptr[0];
450          sljit_uw mov_pc = ptr[1];          sljit_uw mov_pc = ptr[1];
451          int bl = (mov_pc & 0x0000f000) != RD(TMP_PC);          sljit_si bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
452          sljit_w diff = (sljit_w)(((sljit_w)new_addr - (sljit_w)(inst + 2)) >> 2);          sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2);
453    
454          if (diff <= 0x7fffff && diff >= -0x800000) {          if (diff <= 0x7fffff && diff >= -0x800000) {
455                  /* Turn to branch. */                  /* Turn to branch. */
# Line 498  static SLJIT_INLINE void inline_set_jump Line 498  static SLJIT_INLINE void inline_set_jump
498  #endif  #endif
499  }  }
500    
501  static sljit_uw get_immediate(sljit_uw imm);  static sljit_uw get_imm(sljit_uw imm);
502    
503  static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_w new_constant, int flush)  static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_si flush)
504  {  {
505  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
506          sljit_uw *ptr = (sljit_uw*)addr;          sljit_uw *ptr = (sljit_uw*)addr;
# Line 508  static SLJIT_INLINE void inline_set_cons Line 508  static SLJIT_INLINE void inline_set_cons
508          sljit_uw ldr_literal = ptr[1];          sljit_uw ldr_literal = ptr[1];
509          sljit_uw src2;          sljit_uw src2;
510    
511          src2 = get_immediate(new_constant);          src2 = get_imm(new_constant);
512          if (src2) {          if (src2) {
513                  *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;                  *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
514                  if (flush) {                  if (flush) {
# Line 517  static SLJIT_INLINE void inline_set_cons Line 517  static SLJIT_INLINE void inline_set_cons
517                  return;                  return;
518          }          }
519    
520          src2 = get_immediate(~new_constant);          src2 = get_imm(~new_constant);
521          if (src2) {          if (src2) {
522                  *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;                  *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
523                  if (flush) {                  if (flush) {
# Line 730  SLJIT_API_FUNC_ATTRIBUTE void* sljit_gen Line 730  SLJIT_API_FUNC_ATTRIBUTE void* sljit_gen
730                  if (jump->flags & PATCH_B) {                  if (jump->flags & PATCH_B) {
731                          if (!(jump->flags & JUMP_ADDR)) {                          if (!(jump->flags & JUMP_ADDR)) {
732                                  SLJIT_ASSERT(jump->flags & JUMP_LABEL);                                  SLJIT_ASSERT(jump->flags & JUMP_LABEL);
733                                  SLJIT_ASSERT(((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >= -0x02000000);                                  SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000);
734                                  *buf_ptr |= (((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff;                                  *buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff;
735                          }                          }
736                          else {                          else {
737                                  SLJIT_ASSERT(((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >= -0x02000000);                                  SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000);
738                                  *buf_ptr |= (((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff;                                  *buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff;
739                          }                          }
740                  }                  }
741                  else if (jump->flags & SLJIT_REWRITABLE_JUMP) {                  else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
# Line 785  SLJIT_API_FUNC_ATTRIBUTE void* sljit_gen Line 785  SLJIT_API_FUNC_ATTRIBUTE void* sljit_gen
785          }          }
786  #endif  #endif
787    
788          SLJIT_ASSERT(code_ptr - code <= (int)size);          SLJIT_ASSERT(code_ptr - code <= (sljit_si)size);
789    
790          SLJIT_CACHE_FLUSH(code, code_ptr);          SLJIT_CACHE_FLUSH(code, code_ptr);
791          compiler->error = SLJIT_ERR_COMPILED;          compiler->error = SLJIT_ERR_COMPILED;
# Line 819  SLJIT_API_FUNC_ATTRIBUTE void* sljit_gen Line 819  SLJIT_API_FUNC_ATTRIBUTE void* sljit_gen
819  #define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \  #define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \
820          (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2))          (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2))
821    
822  static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,  static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags,
823          int dst, sljit_w dstw,          sljit_si dst, sljit_sw dstw,
824          int src1, sljit_w src1w,          sljit_si src1, sljit_sw src1w,
825          int src2, sljit_w src2w);          sljit_si src2, sljit_sw src2w);
826    
827  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size)
828  {  {
829          int size;          sljit_si size;
830          sljit_uw push;          sljit_uw push;
831    
832          CHECK_ERROR();          CHECK_ERROR();
# Line 878  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 878  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
878          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
879  }  }
880    
881  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size)
882  {  {
883          int size;          sljit_si size;
884    
885          CHECK_ERROR_VOID();          CHECK_ERROR_VOID();
886          check_sljit_set_context(compiler, args, temporaries, saveds, local_size);          check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
# Line 900  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_ Line 900  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_
900          compiler->local_size = local_size;          compiler->local_size = local_size;
901  }  }
902    
903  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
904  {  {
905          sljit_uw pop;          sljit_uw pop;
906    
# Line 942  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 942  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
942     w/b/h/N - word/byte/half/NOT allowed (2 bit)     w/b/h/N - word/byte/half/NOT allowed (2 bit)
943     It contans 16 items, but not all are different. */     It contans 16 items, but not all are different. */
944    
945  static sljit_w data_transfer_insts[16] = {  static sljit_sw data_transfer_insts[16] = {
946  /* s u w */ 0xe5000000 /* str */,  /* s u w */ 0xe5000000 /* str */,
947  /* s u b */ 0xe5400000 /* strb */,  /* s u b */ 0xe5400000 /* strb */,
948  /* s u h */ 0xe10000b0 /* strh */,  /* s u h */ 0xe10000b0 /* strh */,
# Line 1008  static sljit_w data_transfer_insts[16] = Line 1008  static sljit_w data_transfer_insts[16] =
1008          } \          } \
1009          return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1])));          return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1])));
1010    
1011  static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,  static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
1012          int dst, int src1, int src2)          sljit_si dst, sljit_si src1, sljit_si src2)
1013  {  {
1014          sljit_w mul_inst;          sljit_sw mul_inst;
1015    
1016          switch (GET_OPCODE(op)) {          switch (GET_OPCODE(op)) {
1017          case SLJIT_MOV:          case SLJIT_MOV:
# Line 1162  static SLJIT_INLINE int emit_single_op(s Line 1162  static SLJIT_INLINE int emit_single_op(s
1162    
1163  /* Tests whether the immediate can be stored in the 12 bit imm field.  /* Tests whether the immediate can be stored in the 12 bit imm field.
1164     Returns with 0 if not possible. */     Returns with 0 if not possible. */
1165  static sljit_uw get_immediate(sljit_uw imm)  static sljit_uw get_imm(sljit_uw imm)
1166  {  {
1167          int rol;          sljit_si rol;
1168    
1169          if (imm <= 0xff)          if (imm <= 0xff)
1170                  return SRC2_IMM | imm;                  return SRC2_IMM | imm;
# Line 1200  static sljit_uw get_immediate(sljit_uw i Line 1200  static sljit_uw get_immediate(sljit_uw i
1200  }  }
1201    
1202  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
1203  static int generate_int(struct sljit_compiler *compiler, int reg, sljit_uw imm, int positive)  static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm, sljit_si positive)
1204  {  {
1205          sljit_uw mask;          sljit_uw mask;
1206          sljit_uw imm1;          sljit_uw imm1;
1207          sljit_uw imm2;          sljit_uw imm2;
1208          int rol;          sljit_si rol;
1209    
1210          /* Step1: Search a zero byte (8 continous zero bit). */          /* Step1: Search a zero byte (8 continous zero bit). */
1211          mask = 0xff000000;          mask = 0xff000000;
# Line 1311  static int generate_int(struct sljit_com Line 1311  static int generate_int(struct sljit_com
1311  }  }
1312  #endif  #endif
1313    
1314  static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_uw imm)  static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm)
1315  {  {
1316          sljit_uw tmp;          sljit_uw tmp;
1317    
# Line 1321  static int load_immediate(struct sljit_c Line 1321  static int load_immediate(struct sljit_c
1321  #endif  #endif
1322    
1323          /* Create imm by 1 inst. */          /* Create imm by 1 inst. */
1324          tmp = get_immediate(imm);          tmp = get_imm(imm);
1325          if (tmp) {          if (tmp) {
1326                  EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp));                  EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp));
1327                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
1328          }          }
1329    
1330          tmp = get_immediate(~imm);          tmp = get_imm(~imm);
1331          if (tmp) {          if (tmp) {
1332                  EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp));                  EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp));
1333                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
# Line 1345  static int load_immediate(struct sljit_c Line 1345  static int load_immediate(struct sljit_c
1345  #endif  #endif
1346  }  }
1347    
1348    /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
1349    static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value)
1350    {
1351            if (value >= 0) {
1352                    value = get_imm(value);
1353                    if (value)
1354                            return push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, dst, reg, value));
1355            }
1356            else {
1357                    value = get_imm(-value);
1358                    if (value)
1359                            return push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, dst, reg, value));
1360            }
1361            return SLJIT_ERR_UNSUPPORTED;
1362    }
1363    
1364  /* Can perform an operation using at most 1 instruction. */  /* Can perform an operation using at most 1 instruction. */
1365  static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw)  static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw)
1366  {  {
1367          sljit_uw imm;          sljit_uw imm;
1368    
1369          if (arg & SLJIT_IMM) {          if (arg & SLJIT_IMM) {
1370                  imm = get_immediate(argw);                  imm = get_imm(argw);
1371                  if (imm) {                  if (imm) {
1372                          if (inp_flags & ARG_TEST)                          if (inp_flags & ARG_TEST)
1373                                  return 1;                                  return 1;
1374                          EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm));                          EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm));
1375                          return -1;                          return -1;
1376                  }                  }
1377                  imm = get_immediate(~argw);                  imm = get_imm(~argw);
1378                  if (imm) {                  if (imm) {
1379                          if (inp_flags & ARG_TEST)                          if (inp_flags & ARG_TEST)
1380                                  return 1;                                  return 1;
# Line 1418  static int getput_arg_fast(struct sljit_ Line 1434  static int getput_arg_fast(struct sljit_
1434  /* See getput_arg below.  /* See getput_arg below.
1435     Note: can_cache is called only for binary operators. Those     Note: can_cache is called only for binary operators. Those
1436     operators always uses word arguments without write back. */     operators always uses word arguments without write back. */
1437  static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)  static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
1438  {  {
1439          /* Immediate caching is not supported as it would be an operation on constant arguments. */          /* Immediate caching is not supported as it would be an operation on constant arguments. */
1440          if (arg & SLJIT_IMM)          if (arg & SLJIT_IMM)
# Line 1466  static int can_cache(int arg, sljit_w ar Line 1482  static int can_cache(int arg, sljit_w ar
1482          }          }
1483    
1484  /* Emit the necessary instructions. See can_cache above. */  /* Emit the necessary instructions. See can_cache above. */
1485  static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw)  static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
1486  {  {
1487          int tmp_r;          sljit_si tmp_r;
1488          sljit_w max_delta;          sljit_sw max_delta;
1489          sljit_w sign;          sljit_sw sign;
1490            sljit_uw imm;
1491    
1492          if (arg & SLJIT_IMM) {          if (arg & SLJIT_IMM) {
1493                  SLJIT_ASSERT(inp_flags & LOAD_DATA);                  SLJIT_ASSERT(inp_flags & LOAD_DATA);
# Line 1484  static int getput_arg(struct sljit_compi Line 1501  static int getput_arg(struct sljit_compi
1501    
1502          if ((arg & 0xf) == SLJIT_UNUSED) {          if ((arg & 0xf) == SLJIT_UNUSED) {
1503                  /* Write back is not used. */                  /* Write back is not used. */
1504                  if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta)) {                  imm = (sljit_uw)(argw - compiler->cache_argw);
1505                          if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) {                  if ((compiler->cache_arg & SLJIT_IMM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
1506                            if (imm <= (sljit_uw)max_delta) {
1507                                  sign = 1;                                  sign = 1;
1508                                  argw = argw - compiler->cache_argw;                                  argw = argw - compiler->cache_argw;
1509                          }                          }
# Line 1494  static int getput_arg(struct sljit_compi Line 1512  static int getput_arg(struct sljit_compi
1512                                  argw = compiler->cache_argw - argw;                                  argw = compiler->cache_argw - argw;
1513                          }                          }
1514    
1515                          if (max_delta & 0xf00) {                          GETPUT_ARG_DATA_TRANSFER(sign, 0, reg, TMP_REG3, argw);
                                 EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, argw));  
                         }  
                         else {  
                                 EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, TYPE2_TRANSFER_IMM(argw)));  
                         }  
1516                          return SLJIT_SUCCESS;                          return SLJIT_SUCCESS;
1517                  }                  }
1518    
1519                  /* With write back, we can create some sophisticated loads, but                  /* With write back, we can create some sophisticated loads, but
1520                     it is hard to decide whether we should convert downward (0s) or upward (1s). */                     it is hard to decide whether we should convert downward (0s) or upward (1s). */
1521                  if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) {                  imm = (sljit_uw)(argw - next_argw);
1522                    if ((next_arg & SLJIT_MEM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
1523                          SLJIT_ASSERT(inp_flags & LOAD_DATA);                          SLJIT_ASSERT(inp_flags & LOAD_DATA);
1524    
1525                          compiler->cache_arg = SLJIT_IMM;                          compiler->cache_arg = SLJIT_IMM;
# Line 1518  static int getput_arg(struct sljit_compi Line 1532  static int getput_arg(struct sljit_compi
1532                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
1533          }          }
1534    
         /* Extended imm addressing for [reg+imm] format. */  
         sign = (max_delta << 8) | 0xff;  
         if (!(arg & 0xf0) && argw <= sign && argw >= -sign) {  
                 TEST_WRITE_BACK();  
                 if (argw >= 0) {  
                         sign = 1;  
                 }  
                 else {  
                         sign = 0;  
                         argw = -argw;  
                 }  
   
                 /* Optimization: add is 0x4, sub is 0x2. Sign is 1 for add and 0 for sub. */  
                 if (max_delta & 0xf00)  
                         EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 12) | 0xa00));  
                 else  
                         EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 8) | 0xc00));  
   
                 argw &= max_delta;  
                 GETPUT_ARG_DATA_TRANSFER(sign, inp_flags & WRITE_BACK, reg, tmp_r, argw);  
                 return SLJIT_SUCCESS;  
         }  
   
1535          if (arg & 0xf0) {          if (arg & 0xf0) {
1536                  SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00));                  SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00));
1537                  if (inp_flags & WRITE_BACK)                  if (inp_flags & WRITE_BACK)
# Line 1550  static int getput_arg(struct sljit_compi Line 1541  static int getput_arg(struct sljit_compi
1541                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
1542          }          }
1543    
1544          if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) {          imm = (sljit_uw)(argw - compiler->cache_argw);
1545            if (compiler->cache_arg == arg && imm <= (sljit_uw)max_delta) {
1546                  SLJIT_ASSERT(!(inp_flags & WRITE_BACK));                  SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
1547                  argw = argw - compiler->cache_argw;                  GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, imm);
                 GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, argw);  
1548                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
1549          }          }
1550            if (compiler->cache_arg == arg && imm >= (sljit_uw)-max_delta) {
         if (compiler->cache_arg == arg && ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta) {  
1551                  SLJIT_ASSERT(!(inp_flags & WRITE_BACK));                  SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
1552                  argw = compiler->cache_argw - argw;                  imm = (sljit_uw)-(sljit_sw)imm;
1553                  GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, argw);                  GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, imm);
1554                    return SLJIT_SUCCESS;
1555            }
1556    
1557            imm = get_imm(argw & ~max_delta);
1558            if (imm) {
1559                    TEST_WRITE_BACK();
1560                    EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & 0xf, imm));
1561                    GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta);
1562                    return SLJIT_SUCCESS;
1563            }
1564    
1565            imm = get_imm(-argw & ~max_delta);
1566            if (imm) {
1567                    argw = -argw;
1568                    TEST_WRITE_BACK();
1569                    EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & 0xf, imm));
1570                    GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta);
1571                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
1572          }          }
1573    
# Line 1582  static int getput_arg(struct sljit_compi Line 1589  static int getput_arg(struct sljit_compi
1589                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
1590          }          }
1591    
1592          if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) {          imm = (sljit_uw)(argw - next_argw);
1593            if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
1594                  SLJIT_ASSERT(inp_flags & LOAD_DATA);                  SLJIT_ASSERT(inp_flags & LOAD_DATA);
1595                  FAIL_IF(load_immediate(compiler, TMP_REG3, argw));                  FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
1596                  EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & 0xf]));                  EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & 0xf]));
# Line 1605  static int getput_arg(struct sljit_compi Line 1613  static int getput_arg(struct sljit_compi
1613          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
1614  }  }
1615    
1616  static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,  static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags,
1617          int dst, sljit_w dstw,          sljit_si dst, sljit_sw dstw,
1618          int src1, sljit_w src1w,          sljit_si src1, sljit_sw src1w,
1619          int src2, sljit_w src2w)          sljit_si src2, sljit_sw src2w)
1620  {  {
1621          /* arg1 goes to TMP_REG1 or src reg          /* arg1 goes to TMP_REG1 or src reg
1622             arg2 goes to TMP_REG2, imm or src reg             arg2 goes to TMP_REG2, imm or src reg
# Line 1616  static int emit_op(struct sljit_compiler Line 1624  static int emit_op(struct sljit_compiler
1624             result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */             result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
1625    
1626          /* We prefers register and simple consts. */          /* We prefers register and simple consts. */
1627          int dst_r;          sljit_si dst_r;
1628          int src1_r;          sljit_si src1_r;
1629          int src2_r = 0;          sljit_si src2_r = 0;
1630          int sugg_src2_r = TMP_REG2;          sljit_si sugg_src2_r = TMP_REG2;
1631          int flags = GET_FLAGS(op) ? SET_FLAGS : 0;          sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
1632    
1633          compiler->cache_arg = 0;          compiler->cache_arg = 0;
1634          compiler->cache_argw = 0;          compiler->cache_argw = 0;
# Line 1662  static int emit_op(struct sljit_compiler Line 1670  static int emit_op(struct sljit_compiler
1670                  src1_r = 0;                  src1_r = 0;
1671                  if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) {                  if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) {
1672                          /* The second check will generate a hit. */                          /* The second check will generate a hit. */
1673                          src2_r = get_immediate(src1w);                          src2_r = get_imm(src1w);
1674                          if (src2_r) {                          if (src2_r) {
1675                                  flags |= ARGS_SWAPPED;                                  flags |= ARGS_SWAPPED;
1676                                  src1 = src2;                                  src1 = src2;
# Line 1670  static int emit_op(struct sljit_compiler Line 1678  static int emit_op(struct sljit_compiler
1678                                  break;                                  break;
1679                          }                          }
1680                          if (inp_flags & ALLOW_INV_IMM) {                          if (inp_flags & ALLOW_INV_IMM) {
1681                                  src2_r = get_immediate(~src1w);                                  src2_r = get_imm(~src1w);
1682                                  if (src2_r) {                                  if (src2_r) {
1683                                          flags |= ARGS_SWAPPED | INV_IMM;                                          flags |= ARGS_SWAPPED | INV_IMM;
1684                                          src1 = src2;                                          src1 = src2;
# Line 1679  static int emit_op(struct sljit_compiler Line 1687  static int emit_op(struct sljit_compiler
1687                                  }                                  }
1688                          }                          }
1689                          if (GET_OPCODE(op) == SLJIT_ADD) {                          if (GET_OPCODE(op) == SLJIT_ADD) {
1690                                  src2_r = get_immediate(-src1w);                                  src2_r = get_imm(-src1w);
1691                                  if (src2_r) {                                  if (src2_r) {
1692                                          /* Note: ARGS_SWAPPED is intentionally not applied! */                                          /* Note: ARGS_SWAPPED is intentionally not applied! */
1693                                          src1 = src2;                                          src1 = src2;
# Line 1706  static int emit_op(struct sljit_compiler Line 1714  static int emit_op(struct sljit_compiler
1714                  }                  }
1715                  else do { /* do { } while(0) is used because of breaks. */                  else do { /* do { } while(0) is used because of breaks. */
1716                          if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) {                          if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) {
1717                                  src2_r = get_immediate(src2w);                                  src2_r = get_imm(src2w);
1718                                  if (src2_r)                                  if (src2_r)
1719                                          break;                                          break;
1720                                  if (inp_flags & ALLOW_INV_IMM) {                                  if (inp_flags & ALLOW_INV_IMM) {
1721                                          src2_r = get_immediate(~src2w);                                          src2_r = get_imm(~src2w);
1722                                          if (src2_r) {                                          if (src2_r) {
1723                                                  flags |= INV_IMM;                                                  flags |= INV_IMM;
1724                                                  break;                                                  break;
1725                                          }                                          }
1726                                  }                                  }
1727                                  if (GET_OPCODE(op) == SLJIT_ADD) {                                  if (GET_OPCODE(op) == SLJIT_ADD) {
1728                                          src2_r = get_immediate(-src2w);                                          src2_r = get_imm(-src2w);
1729                                          if (src2_r) {                                          if (src2_r) {
1730                                                  op = SLJIT_SUB | GET_ALL_FLAGS(op);                                                  op = SLJIT_SUB | GET_ALL_FLAGS(op);
1731                                                  flags &= ~ARGS_SWAPPED;                                                  flags &= ~ARGS_SWAPPED;
# Line 1725  static int emit_op(struct sljit_compiler Line 1733  static int emit_op(struct sljit_compiler
1733                                          }                                          }
1734                                  }                                  }
1735                                  if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) {                                  if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) {
1736                                          src2_r = get_immediate(-src2w);                                          src2_r = get_imm(-src2w);
1737                                          if (src2_r) {                                          if (src2_r) {
1738                                                  op = SLJIT_ADD | GET_ALL_FLAGS(op);                                                  op = SLJIT_ADD | GET_ALL_FLAGS(op);
1739                                                  flags &= ~ARGS_SWAPPED;                                                  flags &= ~ARGS_SWAPPED;
# Line 1800  extern "C" { Line 1808  extern "C" {
1808  #endif  #endif
1809    
1810  #if defined(__GNUC__)  #if defined(__GNUC__)
1811  extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator);  extern unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator);
1812  extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator);  extern int __aeabi_idivmod(int numerator, int denominator);
1813  #else  #else
1814  #error "Software divmod functions are needed"  #error "Software divmod functions are needed"
1815  #endif  #endif
# Line 1810  extern unsigned int __aeabi_idivmod(unsi Line 1818  extern unsigned int __aeabi_idivmod(unsi
1818  }  }
1819  #endif  #endif
1820    
1821  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
1822  {  {
1823          CHECK_ERROR();          CHECK_ERROR();
1824          check_sljit_emit_op0(compiler, op);          check_sljit_emit_op0(compiler, op);
# Line 1857  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1865  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1865          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
1866  }  }
1867    
1868  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
1869          int dst, sljit_w dstw,          sljit_si dst, sljit_sw dstw,
1870          int src, sljit_w srcw)          sljit_si src, sljit_sw srcw)
1871  {  {
1872          CHECK_ERROR();          CHECK_ERROR();
1873          check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);          check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
# Line 1877  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1885  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1885                  return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);                  return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
1886    
1887          case SLJIT_MOV_SB:          case SLJIT_MOV_SB:
1888                  return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_b)srcw : srcw);                  return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
1889    
1890          case SLJIT_MOV_UH:          case SLJIT_MOV_UH:
1891                  return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);                  return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
1892    
1893          case SLJIT_MOV_SH:          case SLJIT_MOV_SH:
1894                  return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_h)srcw : srcw);                  return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
1895    
1896          case SLJIT_MOVU:          case SLJIT_MOVU:
1897          case SLJIT_MOVU_UI:          case SLJIT_MOVU_UI:
# Line 1895  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1903  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1903                  return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);                  return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
1904    
1905          case SLJIT_MOVU_SB:          case SLJIT_MOVU_SB:
1906                  return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_b)srcw : srcw);                  return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
1907    
1908          case SLJIT_MOVU_UH:          case SLJIT_MOVU_UH:
1909                  return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);                  return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
1910    
1911          case SLJIT_MOVU_SH:          case SLJIT_MOVU_SH:
1912                  return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_h)srcw : srcw);                  return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
1913    
1914          case SLJIT_NOT:          case SLJIT_NOT:
1915                  return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);                  return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
# Line 1919  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1927  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1927          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
1928  }  }
1929    
1930  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
1931          int dst, sljit_w dstw,          sljit_si dst, sljit_sw dstw,
1932          int src1, sljit_w src1w,          sljit_si src1, sljit_sw src1w,
1933          int src2, sljit_w src2w)          sljit_si src2, sljit_sw src2w)
1934  {  {
1935          CHECK_ERROR();          CHECK_ERROR();
1936          check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);          check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
# Line 1961  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1969  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1969          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
1970  }  }
1971    
1972  SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
1973  {  {
1974          check_sljit_get_register_index(reg);          check_sljit_get_register_index(reg);
1975          return reg_map[reg];          return reg_map[reg];
1976  }  }
1977    
1978  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
1979          void *instruction, int size)          void *instruction, sljit_si size)
1980  {  {
1981          CHECK_ERROR();          CHECK_ERROR();
1982          check_sljit_emit_op_custom(compiler, instruction, size);          check_sljit_emit_op_custom(compiler, instruction, size);
# Line 1985  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1993  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1993    
1994  /* 0 - no fpu  /* 0 - no fpu
1995     1 - vfp */     1 - vfp */
1996  static int arm_fpu_type = -1;  static sljit_si arm_fpu_type = -1;
1997    
1998  static void init_compiler(void)  static void init_compiler(void)
1999  {  {
# Line 1996  static void init_compiler(void) Line 2004  static void init_compiler(void)
2004          arm_fpu_type = 1;          arm_fpu_type = 1;
2005  }  }
2006    
2007  SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
2008  {  {
2009          if (arm_fpu_type == -1)          if (arm_fpu_type == -1)
2010                  init_compiler();                  init_compiler();
# Line 2007  SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fp Line 2015  SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fp
2015    
2016  #define arm_fpu_type 1  #define arm_fpu_type 1
2017    
2018  SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
2019  {  {
2020          /* Always available. */          /* Always available. */
2021          return 1;          return 1;
# Line 2015  SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fp Line 2023  SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fp
2023    
2024  #endif  #endif
2025    
2026  #define EMIT_FPU_DATA_TRANSFER(add, load, base, freg, offs) \  #define FPU_LOAD (1 << 20)
2027          (VSTR | ((add) << 23) | ((load) << 20) | (reg_map[base] << 16) | (freg << 12) | (offs))  #define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \
2028  #define EMIT_FPU_OPERATION(opcode, dst, src1, src2) \          ((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg << 12) | (offs))
2029          ((opcode) | ((dst) << 12) | (src1) | ((src2) << 16))  #define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \
2030            ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16))
2031    
2032  static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw)  static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
2033  {  {
2034            sljit_sw tmp;
2035            sljit_uw imm;
2036            sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD));
2037          SLJIT_ASSERT(arg & SLJIT_MEM);          SLJIT_ASSERT(arg & SLJIT_MEM);
2038    
2039            if (SLJIT_UNLIKELY(arg & 0xf0)) {
2040                    EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7)));
2041                    arg = SLJIT_MEM | TMP_REG1;
2042                    argw = 0;
2043            }
2044    
2045          /* Fast loads and stores. */          /* Fast loads and stores. */
2046          if ((arg & 0xf) && !(arg & 0xf0) && (argw & 0x3) == 0) {          if ((arg & 0xf)) {
2047                  if (argw >= 0 && argw <= 0x3ff) {                  if (!(argw & ~0x3fc))
2048                          EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, arg & 0xf, fpu_reg, argw >> 2));                          return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & 0xf, reg, argw >> 2));
2049                          return SLJIT_SUCCESS;                  if (!(-argw & ~0x3fc))
2050                  }                          return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & 0xf, reg, (-argw) >> 2));
                 if (argw < 0 && argw >= -0x3ff) {  
                         EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, arg & 0xf, fpu_reg, (-argw) >> 2));  
                         return SLJIT_SUCCESS;  
                 }  
                 if (argw >= 0 && argw <= 0x3ffff) {  
                         SLJIT_ASSERT(get_immediate(argw & 0x3fc00));  
                         EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00)));  
                         argw &= 0x3ff;  
                         EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, argw >> 2));  
                         return SLJIT_SUCCESS;  
                 }  
                 if (argw < 0 && argw >= -0x3ffff) {  
                         argw = -argw;  
                         SLJIT_ASSERT(get_immediate(argw & 0x3fc00));  
                         EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00)));  
                         argw &= 0x3ff;  
                         EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG1, fpu_reg, argw >> 2));  
                         return SLJIT_SUCCESS;  
                 }  
2051          }          }
2052    
2053          if (arg & 0xf0) {          if (compiler->cache_arg == arg) {
2054                  EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7)));                  tmp = argw - compiler->cache_argw;
2055                  EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, 0));                  if (!(tmp & ~0x3fc))
2056                  return SLJIT_SUCCESS;                          return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, tmp >> 2));
2057                    if (!(-tmp & ~0x3fc))
2058                            return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG3, reg, -tmp >> 2));
2059                    if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) {
2060                            FAIL_IF(compiler->error);
2061                            compiler->cache_argw = argw;
2062                            return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0));
2063                    }
2064          }          }
2065    
2066          if (compiler->cache_arg == arg && ((argw - compiler->cache_argw) & 0x3) == 0) {          if (arg & 0xf) {
2067                  if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= 0x3ff) {                  if (emit_set_delta(compiler, TMP_REG1, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) {
2068                          EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, (argw - compiler->cache_argw) >> 2));                          FAIL_IF(compiler->error);
2069                          return SLJIT_SUCCESS;                          return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0));
2070                  }                  }
2071                  if (((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= 0x3ff) {                  imm = get_imm(argw & ~0x3fc);
2072                          EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG3, fpu_reg, (compiler->cache_argw - argw) >> 2));                  if (imm) {
2073                          return SLJIT_SUCCESS;                          EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, imm));
2074                            return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2));
2075                    }
2076                    imm = get_imm(-argw & ~0x3fc);
2077                    if (imm) {
2078                            argw = -argw;
2079                            EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, imm));
2080                            return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2));
2081                  }                  }
2082          }          }
2083    
# Line 2077  static int emit_fpu_data_transfer(struct Line 2090  static int emit_fpu_data_transfer(struct
2090          else          else
2091                  FAIL_IF(load_immediate(compiler, TMP_REG3, argw));                  FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
2092    
2093          EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, 0));          return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0));
         return SLJIT_SUCCESS;  
2094  }  }
2095    
2096  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
2097          int dst, sljit_w dstw,          sljit_si dst, sljit_sw dstw,
2098          int src, sljit_w srcw)          sljit_si src, sljit_sw srcw)
2099  {  {
2100          int dst_fr;          sljit_si dst_fr;
2101    
2102          CHECK_ERROR();          CHECK_ERROR();
2103          check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);          check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2104            SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error);
2105    
2106          compiler->cache_arg = 0;          compiler->cache_arg = 0;
2107          compiler->cache_argw = 0;          compiler->cache_argw = 0;
2108            op ^= SLJIT_SINGLE_OP;
2109    
2110          if (GET_OPCODE(op) == SLJIT_FCMP) {          if (GET_OPCODE(op) == SLJIT_CMPD) {
2111                  if (dst > SLJIT_FLOAT_REG4) {                  if (dst > SLJIT_FLOAT_REG6) {
2112                          FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw));                          FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw));
2113                          dst = TMP_FREG1;                          dst = TMP_FREG1;
2114                  }                  }
2115                  if (src > SLJIT_FLOAT_REG4) {                  if (src > SLJIT_FLOAT_REG6) {
2116                          FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw));                          FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw));
2117                          src = TMP_FREG2;                          src = TMP_FREG2;
2118                  }                  }
2119                  EMIT_INSTRUCTION(VCMP_F64 | (dst << 12) | src);                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, dst, src, 0));
2120                  EMIT_INSTRUCTION(VMRS);                  EMIT_INSTRUCTION(VMRS);
2121                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
2122          }          }
2123    
2124          dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;          dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst;
2125    
2126          if (src > SLJIT_FLOAT_REG4) {          if (src > SLJIT_FLOAT_REG6) {
2127                  FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw));                  FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_fr, src, srcw));
2128                  src = dst_fr;                  src = dst_fr;
2129          }          }
2130    
2131          switch (op) {          switch (GET_OPCODE(op)) {
2132                  case SLJIT_FMOV:                  case SLJIT_MOVD:
2133                          if (src != dst_fr && dst_fr != TMP_FREG1)                          if (src != dst_fr && dst_fr != TMP_FREG1)
2134                                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F64, dst_fr, src, 0));                                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0));
2135                          break;                          break;
2136                  case SLJIT_FNEG:                  case SLJIT_NEGD:
2137                          EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F64, dst_fr, src, 0));                          EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0));
2138                          break;                          break;
2139                  case SLJIT_FABS:                  case SLJIT_ABSD:
2140                          EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F64, dst_fr, src, 0));                          EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0));
2141                          break;                          break;
2142          }          }
2143    
2144          if (dst_fr == TMP_FREG1) {          if (dst_fr == TMP_FREG1) {
2145                  if (op == SLJIT_FMOV)                  if (GET_OPCODE(op) == SLJIT_MOVD)
2146                          dst_fr = src;                          dst_fr = src;
2147                  FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 0, dst, dstw));                  FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_fr, dst, dstw));
2148          }          }
2149    
2150          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2151  }  }
2152    
2153  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
2154          int dst, sljit_w dstw,          sljit_si dst, sljit_sw dstw,
2155          int src1, sljit_w src1w,          sljit_si src1, sljit_sw src1w,
2156          int src2, sljit_w src2w)          sljit_si src2, sljit_sw src2w)
2157  {  {
2158          int dst_fr;          sljit_si dst_fr;
2159    
2160          CHECK_ERROR();          CHECK_ERROR();
2161          check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);          check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2162    
2163          compiler->cache_arg = 0;          compiler->cache_arg = 0;
2164          compiler->cache_argw = 0;          compiler->cache_argw = 0;
2165            op ^= SLJIT_SINGLE_OP;
2166    
2167          dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;          dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst;
2168    
2169          if (src2 > SLJIT_FLOAT_REG4) {          if (src2 > SLJIT_FLOAT_REG6) {
2170                  FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));                  FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w));
2171                  src2 = TMP_FREG2;                  src2 = TMP_FREG2;
2172          }          }
2173    
2174          if (src1 > SLJIT_FLOAT_REG4) {          if (src1 > SLJIT_FLOAT_REG6) {
2175                  FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));                  FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w));
2176                  src1 = TMP_FREG1;                  src1 = TMP_FREG1;
2177          }          }
2178    
2179          switch (op) {          switch (GET_OPCODE(op)) {
2180          case SLJIT_FADD:          case SLJIT_ADDD:
2181                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F64, dst_fr, src2, src1));                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1));
2182                  break;                  break;
2183    
2184          case SLJIT_FSUB:          case SLJIT_SUBD:
2185                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F64, dst_fr, src2, src1));                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1));
2186                  break;                  break;
2187    
2188          case SLJIT_FMUL:          case SLJIT_MULD:
2189                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F64, dst_fr, src2, src1));                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1));
2190                  break;                  break;
2191    
2192          case SLJIT_FDIV:          case SLJIT_DIVD:
2193                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F64, dst_fr, src2, src1));                  EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1));
2194                  break;                  break;
2195          }          }
2196    
2197          if (dst_fr == TMP_FREG1)          if (dst_fr == TMP_FREG1)
2198                  FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw));                  FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw));
2199    
2200          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2201  }  }
2202    
2203    #undef FPU_LOAD
2204    #undef EMIT_FPU_DATA_TRANSFER
2205    #undef EMIT_FPU_OPERATION
2206    
2207  /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
2208  /*  Other instructions                                                   */  /*  Other instructions                                                   */
2209  /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
2210    
2211  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
2212  {  {
2213          CHECK_ERROR();          CHECK_ERROR();
2214          check_sljit_emit_fast_enter(compiler, dst, dstw);          check_sljit_emit_fast_enter(compiler, dst, dstw);
# Line 2209  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2228  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2228          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2229  }  }
2230    
2231  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
2232  {  {
2233          CHECK_ERROR();          CHECK_ERROR();
2234          check_sljit_emit_fast_return(compiler, src, srcw);          check_sljit_emit_fast_return(compiler, src, srcw);
# Line 2236  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2255  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2255  /*  Conditional instructions                                             */  /*  Conditional instructions                                             */
2256  /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
2257    
2258  static sljit_uw get_cc(int type)  static sljit_uw get_cc(sljit_si type)
2259  {  {
2260          switch (type) {          switch (type) {
2261          case SLJIT_C_EQUAL:          case SLJIT_C_EQUAL:
# Line 2306  SLJIT_API_FUNC_ATTRIBUTE struct sljit_la Line 2325  SLJIT_API_FUNC_ATTRIBUTE struct sljit_la
2325          return label;          return label;
2326  }  }
2327    
2328  SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)  SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
2329  {  {
2330          struct sljit_jump *jump;          struct sljit_jump *jump;
2331    
# Line 2347  SLJIT_API_FUNC_ATTRIBUTE struct sljit_ju Line 2366  SLJIT_API_FUNC_ATTRIBUTE struct sljit_ju
2366          return jump;          return jump;
2367  }  }
2368    
2369  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
2370  {  {
2371          struct sljit_jump *jump;          struct sljit_jump *jump;
2372    
# Line 2386  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2405  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2405          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2406  }  }
2407    
2408  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)  SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_cond_value(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si type)
2409  {  {
2410          int reg;          sljit_si reg;
2411          sljit_uw cc;          sljit_uw cc;
2412    
2413          CHECK_ERROR();          CHECK_ERROR();
# Line 2425  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2444  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2444          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2445  }  }
2446    
2447  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
2448  {  {
2449          struct sljit_const *const_;          struct sljit_const *const_;
2450          int reg;          sljit_si reg;
2451    
2452          CHECK_ERROR_PTR();          CHECK_ERROR_PTR();
2453          check_sljit_emit_const(compiler, dst, dstw, init_value);          check_sljit_emit_const(compiler, dst, dstw, init_value);
# Line 2458  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_ Line 2477  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_
2477          inline_set_jump_addr(addr, new_addr, 1);          inline_set_jump_addr(addr, new_addr, 1);
2478  }  }
2479    
2480  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
2481  {  {
2482          inline_set_const(addr, new_constant, 1);          inline_set_const(addr, new_constant, 1);
2483  }  }

Legend:
Removed from v.1194  
changed lines
  Added in v.1195

  ViewVC Help
Powered by ViewVC 1.1.5