mirror of
https://github.com/ruby/ruby.git
synced 2025-08-25 14:05:02 +02:00
Implement opt_and and opt_or
This commit is contained in:
parent
67cc53214c
commit
bc50b0475a
Notes:
git
2023-03-06 07:30:03 +00:00
4 changed files with 118 additions and 5 deletions
|
@ -121,6 +121,16 @@ module RubyVM::MJIT
|
||||||
mod_rm: ModRM[mod: Mod11, reg: 4, rm: dst_reg],
|
mod_rm: ModRM[mod: Mod11, reg: 4, rm: dst_reg],
|
||||||
imm: imm8(src_imm),
|
imm: imm8(src_imm),
|
||||||
)
|
)
|
||||||
|
# AND r64, r/m64 (Mod 01: [reg]+disp8)
|
||||||
|
in [Symbol => dst_reg, [Symbol => src_reg, Integer => src_disp]] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_disp)
|
||||||
|
# REX.W + 23 /r
|
||||||
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
|
insn(
|
||||||
|
prefix: REX_W,
|
||||||
|
opcode: 0x23,
|
||||||
|
mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
|
||||||
|
disp: imm8(src_disp),
|
||||||
|
)
|
||||||
else
|
else
|
||||||
raise NotImplementedError, "and: not-implemented operands: #{dst.inspect}, #{src.inspect}"
|
raise NotImplementedError, "and: not-implemented operands: #{dst.inspect}, #{src.inspect}"
|
||||||
end
|
end
|
||||||
|
@ -545,6 +555,23 @@ module RubyVM::MJIT
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def or(dst, src)
|
||||||
|
case [dst, src]
|
||||||
|
# OR r64, r/m64 (Mod 01: [reg]+disp8)
|
||||||
|
in [Symbol => dst_reg, [Symbol => src_reg, Integer => src_disp]] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_disp)
|
||||||
|
# REX.W + 0B /r
|
||||||
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
|
insn(
|
||||||
|
prefix: REX_W,
|
||||||
|
opcode: 0x0b,
|
||||||
|
mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
|
||||||
|
disp: imm8(src_disp),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
raise NotImplementedError, "or: not-implemented operands: #{dst.inspect}, #{src.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def push(src)
|
def push(src)
|
||||||
case src
|
case src
|
||||||
# PUSH r64
|
# PUSH r64
|
||||||
|
|
|
@ -23,7 +23,7 @@ module RubyVM::MJIT
|
||||||
asm.incr_counter(:mjit_insns_count)
|
asm.incr_counter(:mjit_insns_count)
|
||||||
asm.comment("Insn: #{insn.name}")
|
asm.comment("Insn: #{insn.name}")
|
||||||
|
|
||||||
# 36/101
|
# 38/101
|
||||||
case insn.name
|
case insn.name
|
||||||
when :nop then nop(jit, ctx, asm)
|
when :nop then nop(jit, ctx, asm)
|
||||||
# getlocal
|
# getlocal
|
||||||
|
@ -105,8 +105,8 @@ module RubyVM::MJIT
|
||||||
when :opt_gt then opt_gt(jit, ctx, asm)
|
when :opt_gt then opt_gt(jit, ctx, asm)
|
||||||
when :opt_ge then opt_ge(jit, ctx, asm)
|
when :opt_ge then opt_ge(jit, ctx, asm)
|
||||||
when :opt_ltlt then opt_ltlt(jit, ctx, asm)
|
when :opt_ltlt then opt_ltlt(jit, ctx, asm)
|
||||||
# opt_and
|
when :opt_and then opt_and(jit, ctx, asm)
|
||||||
# opt_or
|
when :opt_or then opt_or(jit, ctx, asm)
|
||||||
when :opt_aref then opt_aref(jit, ctx, asm)
|
when :opt_aref then opt_aref(jit, ctx, asm)
|
||||||
# opt_aset
|
# opt_aset
|
||||||
# opt_aset_with
|
# opt_aset_with
|
||||||
|
@ -648,8 +648,84 @@ module RubyVM::MJIT
|
||||||
opt_send_without_block(jit, ctx, asm)
|
opt_send_without_block(jit, ctx, asm)
|
||||||
end
|
end
|
||||||
|
|
||||||
# opt_and
|
# @param jit [RubyVM::MJIT::JITState]
|
||||||
# opt_or
|
# @param ctx [RubyVM::MJIT::Context]
|
||||||
|
# @param asm [RubyVM::MJIT::Assembler]
|
||||||
|
def opt_and(jit, ctx, asm)
|
||||||
|
unless jit.at_current_insn?
|
||||||
|
defer_compilation(jit, ctx, asm)
|
||||||
|
return EndBlock
|
||||||
|
end
|
||||||
|
|
||||||
|
if two_fixnums_on_stack?(jit)
|
||||||
|
# Create a side-exit to fall back to the interpreter
|
||||||
|
# Note: we generate the side-exit before popping operands from the stack
|
||||||
|
side_exit = side_exit(jit, ctx)
|
||||||
|
|
||||||
|
unless Invariants.assume_bop_not_redefined(jit, C.INTEGER_REDEFINED_OP_FLAG, C.BOP_AND)
|
||||||
|
return CantCompile
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check that both operands are fixnums
|
||||||
|
guard_two_fixnums(jit, ctx, asm, side_exit)
|
||||||
|
|
||||||
|
# Get the operands and destination from the stack
|
||||||
|
arg1 = ctx.stack_pop(1)
|
||||||
|
arg0 = ctx.stack_pop(1)
|
||||||
|
|
||||||
|
asm.comment('bitwise and')
|
||||||
|
asm.mov(:rax, arg0)
|
||||||
|
asm.and(:rax, arg1)
|
||||||
|
|
||||||
|
# Push the return value onto the stack
|
||||||
|
dst = ctx.stack_push
|
||||||
|
asm.mov(dst, :rax)
|
||||||
|
|
||||||
|
KeepCompiling
|
||||||
|
else
|
||||||
|
opt_send_without_block(jit, ctx, asm)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @param jit [RubyVM::MJIT::JITState]
|
||||||
|
# @param ctx [RubyVM::MJIT::Context]
|
||||||
|
# @param asm [RubyVM::MJIT::Assembler]
|
||||||
|
def opt_or(jit, ctx, asm)
|
||||||
|
unless jit.at_current_insn?
|
||||||
|
defer_compilation(jit, ctx, asm)
|
||||||
|
return EndBlock
|
||||||
|
end
|
||||||
|
|
||||||
|
if two_fixnums_on_stack?(jit)
|
||||||
|
# Create a side-exit to fall back to the interpreter
|
||||||
|
# Note: we generate the side-exit before popping operands from the stack
|
||||||
|
side_exit = side_exit(jit, ctx)
|
||||||
|
|
||||||
|
unless Invariants.assume_bop_not_redefined(jit, C.INTEGER_REDEFINED_OP_FLAG, C.BOP_OR)
|
||||||
|
return CantCompile
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check that both operands are fixnums
|
||||||
|
guard_two_fixnums(jit, ctx, asm, side_exit)
|
||||||
|
|
||||||
|
# Get the operands and destination from the stack
|
||||||
|
asm.comment('bitwise or')
|
||||||
|
arg1 = ctx.stack_pop(1)
|
||||||
|
arg0 = ctx.stack_pop(1)
|
||||||
|
|
||||||
|
# Do the bitwise or arg0 | arg1
|
||||||
|
asm.mov(:rax, arg0)
|
||||||
|
asm.or(:rax, arg1)
|
||||||
|
|
||||||
|
# Push the return value onto the stack
|
||||||
|
dst = ctx.stack_push
|
||||||
|
asm.mov(dst, :rax)
|
||||||
|
|
||||||
|
KeepCompiling
|
||||||
|
else
|
||||||
|
opt_send_without_block(jit, ctx, asm)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# @param jit [RubyVM::MJIT::JITState]
|
# @param jit [RubyVM::MJIT::JITState]
|
||||||
# @param ctx [RubyVM::MJIT::Context]
|
# @param ctx [RubyVM::MJIT::Context]
|
||||||
|
|
|
@ -329,6 +329,10 @@ module RubyVM::MJIT # :nodoc: all
|
||||||
Primitive.cexpr! %q{ UINT2NUM(ARRAY_REDEFINED_OP_FLAG) }
|
Primitive.cexpr! %q{ UINT2NUM(ARRAY_REDEFINED_OP_FLAG) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def C.BOP_AND
|
||||||
|
Primitive.cexpr! %q{ UINT2NUM(BOP_AND) }
|
||||||
|
end
|
||||||
|
|
||||||
def C.BOP_AREF
|
def C.BOP_AREF
|
||||||
Primitive.cexpr! %q{ UINT2NUM(BOP_AREF) }
|
Primitive.cexpr! %q{ UINT2NUM(BOP_AREF) }
|
||||||
end
|
end
|
||||||
|
@ -357,6 +361,10 @@ module RubyVM::MJIT # :nodoc: all
|
||||||
Primitive.cexpr! %q{ UINT2NUM(BOP_MOD) }
|
Primitive.cexpr! %q{ UINT2NUM(BOP_MOD) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def C.BOP_OR
|
||||||
|
Primitive.cexpr! %q{ UINT2NUM(BOP_OR) }
|
||||||
|
end
|
||||||
|
|
||||||
def C.BOP_PLUS
|
def C.BOP_PLUS
|
||||||
Primitive.cexpr! %q{ UINT2NUM(BOP_PLUS) }
|
Primitive.cexpr! %q{ UINT2NUM(BOP_PLUS) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -348,6 +348,7 @@ generator = BindingGenerator.new(
|
||||||
VM_ENV_DATA_INDEX_SPECVAL
|
VM_ENV_DATA_INDEX_SPECVAL
|
||||||
],
|
],
|
||||||
UINT: %w[
|
UINT: %w[
|
||||||
|
BOP_AND
|
||||||
BOP_AREF
|
BOP_AREF
|
||||||
BOP_GE
|
BOP_GE
|
||||||
BOP_GT
|
BOP_GT
|
||||||
|
@ -355,6 +356,7 @@ generator = BindingGenerator.new(
|
||||||
BOP_LT
|
BOP_LT
|
||||||
BOP_MINUS
|
BOP_MINUS
|
||||||
BOP_MOD
|
BOP_MOD
|
||||||
|
BOP_OR
|
||||||
BOP_PLUS
|
BOP_PLUS
|
||||||
ARRAY_REDEFINED_OP_FLAG
|
ARRAY_REDEFINED_OP_FLAG
|
||||||
HASH_REDEFINED_OP_FLAG
|
HASH_REDEFINED_OP_FLAG
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue