Inline-Lua

 view release on metacpan or  search on metacpan

ffi/target/release/build/mlua-sys-6a99a2ae50f12319/out/luajit-build/build/src/vm_arm.dasc  view on Meta::CPAN


/* Generate the code for a single instruction. */
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
{
  int vk = 0;
  |=>defop:

  switch (op) {

  /* -- Comparison ops ---------------------------------------------------- */

  /* Remember: all ops branch for a true comparison, fall through otherwise. */

  case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
    |  // RA = src1*8, RC = src2, JMP with RC = target
    |   lsl RC, RC, #3
    |  ldrd CARG12, [RA, BASE]!
    |    ldrh RB, [PC, #2]
    |   ldrd CARG34, [RC, BASE]!
    |    add PC, PC, #4
    |    add RB, PC, RB, lsl #2
    |  checktp CARG2, LJ_TISNUM
    |  bne >3
    |  checktp CARG4, LJ_TISNUM
    |  bne >4
    |  cmp CARG1, CARG3
    if (op == BC_ISLT) {
      |  sublt PC, RB, #0x20000
    } else if (op == BC_ISGE) {
      |  subge PC, RB, #0x20000
    } else if (op == BC_ISLE) {
      |  suble PC, RB, #0x20000
    } else {
      |  subgt PC, RB, #0x20000
    }
    |1:
    |  ins_next
    |
    |3: // CARG12 is not an integer.
    |.if FPU
    |   vldr d0, [RA]
    |  bhi ->vmeta_comp
    |  // d0 is a number.
    |  checktp CARG4, LJ_TISNUM
    |   vldr d1, [RC]
    |  blo >5
    |  bhi ->vmeta_comp
    |  // d0 is a number, CARG3 is an integer.
    |  vmov s4, CARG3
    |  vcvt.f64.s32 d1, s4
    |  b >5
    |4:  // CARG1 is an integer, CARG34 is not an integer.
    |   vldr d1, [RC]
    |  bhi ->vmeta_comp
    |  // CARG1 is an integer, d1 is a number.
    |  vmov s4, CARG1
    |  vcvt.f64.s32 d0, s4
    |5:  // d0 and d1 are numbers.
    |  vcmp.f64 d0, d1
    |  vmrs
    |  // To preserve NaN semantics GE/GT branch on unordered, but LT/LE don't.
    if (op == BC_ISLT) {
      |  sublo PC, RB, #0x20000
    } else if (op == BC_ISGE) {
      |  subhs PC, RB, #0x20000
    } else if (op == BC_ISLE) {
      |  subls PC, RB, #0x20000
    } else {
      |  subhi PC, RB, #0x20000
    }
    |  b <1
    |.else
    |  bhi ->vmeta_comp
    |  // CARG12 is a number.
    |  checktp CARG4, LJ_TISNUM
    |  movlo RA, RB			// Save RB.
    |  blo >5
    |  bhi ->vmeta_comp
    |  // CARG12 is a number, CARG3 is an integer.
    |  mov CARG1, CARG3
    |  mov RC, RA
    |  mov RA, RB			// Save RB.
    |  bl extern __aeabi_i2d
    |  mov CARG3, CARG1
    |  mov CARG4, CARG2
    |  ldrd CARG12, [RC]		// Restore first operand.
    |  b >5
    |4:  // CARG1 is an integer, CARG34 is not an integer.
    |  bhi ->vmeta_comp
    |  // CARG1 is an integer, CARG34 is a number.
    |  mov RA, RB			// Save RB.
    |  bl extern __aeabi_i2d
    |  ldrd CARG34, [RC]		// Restore second operand.
    |5:  // CARG12 and CARG34 are numbers.
    |  bl extern __aeabi_cdcmple
    |  // To preserve NaN semantics GE/GT branch on unordered, but LT/LE don't.
    if (op == BC_ISLT) {
      |  sublo PC, RA, #0x20000
    } else if (op == BC_ISGE) {
      |  subhs PC, RA, #0x20000
    } else if (op == BC_ISLE) {
      |  subls PC, RA, #0x20000
    } else {
      |  subhi PC, RA, #0x20000
    }
    |  b <1
    |.endif
    break;

  case BC_ISEQV: case BC_ISNEV:
    vk = op == BC_ISEQV;
    |  // RA = src1*8, RC = src2, JMP with RC = target
    |   lsl RC, RC, #3
    |  ldrd CARG12, [RA, BASE]!
    |    ldrh RB, [PC, #2]
    |   ldrd CARG34, [RC, BASE]!
    |    add PC, PC, #4
    |    add RB, PC, RB, lsl #2
    |  checktp CARG2, LJ_TISNUM
    |  cmnls CARG4, #-LJ_TISNUM
    if (vk) {
      |  bls ->BC_ISEQN_Z
    } else {
      |  bls ->BC_ISNEN_Z
    }
    |  // Either or both types are not numbers.
    |.if FFI
    |  checktp CARG2, LJ_TCDATA
    |  checktpne CARG4, LJ_TCDATA
    |  beq ->vmeta_equal_cd
    |.endif
    |  cmp CARG2, CARG4			// Compare types.
    |  bne >2				// Not the same type?
    |  checktp CARG2, LJ_TISPRI
    |  bhs >1				// Same type and primitive type?
    |
    |  // Same types and not a primitive type. Compare GCobj or pvalue.
    |  cmp CARG1, CARG3
    if (vk) {
      |  bne >3				// Different GCobjs or pvalues?
      |1:  // Branch if same.
      |  sub PC, RB, #0x20000
      |2:  // Different.
      |  ins_next
      |3:
      |  checktp CARG2, LJ_TISTABUD
      |  bhi <2				// Different objects and not table/ud?
    } else {
      |  beq >1				// Same GCobjs or pvalues?
      |  checktp CARG2, LJ_TISTABUD
      |  bhi >2				// Different objects and not table/ud?
    }
    |  // Different tables or userdatas. Need to check __eq metamethod.
    |  // Field metatable must be at same offset for GCtab and GCudata!
    |  ldr TAB:RA, TAB:CARG1->metatable
    |  cmp TAB:RA, #0



( run in 1.485 second using v1.01-cache-2.11-cpan-39bf76dae61 )