static void fixnum_or(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_bit_or"); BasicBlock* send = i.failure(); ops.create_conditional_branch(push, send, cmp); ops.set_block(push); Value* ored = BinaryOperator::CreateOr(lint, rint, "fixnums_ored", ops.current_block()); i.exception_safe(); i.set_result(ops.as_obj(ored)); }
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)); }
static void fixnum_neg(JITOperations& ops, Inliner& i) { BasicBlock* use_send = i.failure(); BasicBlock* inlined = ops.new_block("fixnum_neg"); Value* self = i.recv(); Value* cmp = ops.check_if_fixnum(self); ops.create_conditional_branch(inlined, use_send, cmp); ops.set_block(inlined); Value* native = ops.fixnum_strip(self); Value* neg = BinaryOperator::CreateSub( ops.Zero, native, "to_neg", ops.current_block()); Value* more = BinaryOperator::CreateShl(neg, ops.One, "shl", ops.current_block()); Value* tagged = BinaryOperator::CreateOr(more, ops.One, "or", ops.current_block()); i.exception_safe(); i.set_result(ops.as_obj(tagged)); }