Example #1
0
  static void fixnum_compare(MathOperation op, JITOperations& ops, Inliner& i) {
    Value* lint = ops.cast_int(i.recv());
    Value* rint = ops.cast_int(i.arg(0));

    Value* anded = BinaryOperator::CreateAnd(lint, rint, "fixnums_anded",
                                             ops.current_block());

    Value* fix_mask = ConstantInt::get(ops.NativeIntTy, TAG_FIXNUM_MASK);
    Value* fix_tag  = ConstantInt::get(ops.NativeIntTy, TAG_FIXNUM);

    Value* masked = BinaryOperator::CreateAnd(anded, fix_mask, "masked",
                                              ops.current_block());

    Value* cmp = ops.create_equal(masked, fix_tag, "is_fixnum");

    BasicBlock* push = ops.new_block("push_le");
    BasicBlock* send = i.failure();

    ops.create_conditional_branch(push, send, cmp);

    ops.set_block(push);

    Value* performed = 0;

    switch(op) {
    case cEqual:
      performed = ops.b().CreateICmpEQ(lint, rint, "fixnum.eq");
      break;
    case cLessThan:
      performed = ops.b().CreateICmpSLT(lint, rint, "fixnum.lt");
      break;
    case cLessThanEqual:
      performed = ops.b().CreateICmpSLE(lint, rint, "fixnum.le");
      break;
    case cGreaterThan:
      performed = ops.b().CreateICmpSGT(lint, rint, "fixnum.gt");
      break;
    case cGreaterThanEqual:
      performed = ops.b().CreateICmpSGE(lint, rint, "fixnum.ge");
      break;
    default:
      abort();
    }

    Value* le = ops.b().CreateSelect(
                   performed,
                   ops.constant(Qtrue),
                   ops.constant(Qfalse));

    i.use_send_for_failure();
    i.exception_safe();
    i.set_result(ops.as_obj(le));
  }
Example #2
0
  static void object_equal(Class* klass, JITOperations& ops, Inliner& i) {
    Value* self = i.recv();

    ops.check_class(self, klass, i.failure());

    Value* cmp = ops.create_equal(self, i.arg(0), "idenity_equal");
    Value* imm_value = SelectInst::Create(cmp, ops.constant(Qtrue),
          ops.constant(Qfalse), "select_bool", ops.current_block());

    i.exception_safe();
    i.set_result(imm_value);
  }
Example #3
0
  static void symbol_s_eqq(JITOperations& ops, Inliner& i) {
    Value* sym_mask = ConstantInt::get(ops.state()->IntPtrTy, TAG_SYMBOL_MASK);
    Value* sym_tag  = ConstantInt::get(ops.state()->IntPtrTy, TAG_SYMBOL);

    Value* lint = ops.cast_int(i.arg(0));
    Value* masked = ops.b().CreateAnd(lint, sym_mask, "masked");

    Value* cmp = ops.b().CreateICmpEQ(masked, sym_tag, "is_symbol");

    Value* imm_value = ops.b().CreateSelect(cmp,
        ops.constant(Qtrue), ops.constant(Qfalse), "is_symbol");

    i.exception_safe();
    i.set_result(imm_value);
  }
Example #4
0
  static void float_compare(MathOperation op, Class* klass,
      JITOperations& ops, Inliner& i)
  {
    Value* self = i.recv();
    ops.check_class(self, klass, i.failure());

    // Support compare against Floats and Fixnums inline
    BasicBlock* do_compare = ops.new_block("float_compare");
    BasicBlock* check_fix =  ops.new_block("check_fixnum");

    Value* arg = i.arg(0);
    ops.check_class(arg, klass, check_fix);

    Value* farg =  ops.b().CreateBitCast(arg, ops.state()->ptr_type("Float"),
        "arg_float");

    Value* unboxed_rhs = ops.b().CreateLoad(
        ops.b().CreateConstGEP2_32(farg,  0, 1, "arg.value_pos"), "farg");

    BasicBlock* unboxed_block = ops.current_block();

    ops.b().CreateBr(do_compare);

    ops.set_block(check_fix);
    ops.verify_guard(ops.check_is_fixnum(arg), i.failure());
    Value* converted_rhs = ops.b().CreateUIToFP(
        ops.fixnum_to_native(arg), unboxed_rhs->getType());

    BasicBlock* converted_block = ops.current_block();

    ops.b().CreateBr(do_compare);

    ops.set_block(do_compare);

    do_compare->moveAfter(converted_block);

    PHINode* rhs = ops.b().CreatePHI(converted_rhs->getType(), "float_rhs");
    rhs->addIncoming(unboxed_rhs, unboxed_block);
    rhs->addIncoming(converted_rhs, converted_block);

    Value* fself = ops.b().CreateBitCast(self, ops.state()->ptr_type("Float"),
        "self_float");
    Value* lhs = ops.b().CreateLoad(
        ops.b().CreateConstGEP2_32(fself, 0, 1, "self.value_pos"), "fself");

    Value* performed = 0;

    switch(op) {
    case cEqual:
      performed = ops.b().CreateFCmpUEQ(lhs, rhs, "float.eq");
      break;
    case cLessThan:
      performed = ops.b().CreateFCmpULT(lhs, rhs, "float.lt");
      break;
    case cLessThanEqual:
      performed = ops.b().CreateFCmpULE(lhs, rhs, "float.le");
      break;
    case cGreaterThan:
      performed = ops.b().CreateFCmpUGT(lhs, rhs, "float.gt");
      break;
    case cGreaterThanEqual:
      performed = ops.b().CreateFCmpUGE(lhs, rhs, "float.ge");
      break;
    default:
      abort();
    }

    Value* imm_value = ops.b().CreateSelect(performed,
            ops.constant(Qtrue), ops.constant(Qfalse), "select_bool");

    i.exception_safe();
    i.set_result(imm_value);
  }