summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ruby_vm/mjit/assembler.rb17
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb42
-rw-r--r--mjit_c.rb4
-rwxr-xr-xtool/mjit/bindgen.rb1
4 files changed, 60 insertions, 4 deletions
diff --git a/lib/ruby_vm/mjit/assembler.rb b/lib/ruby_vm/mjit/assembler.rb
index f2cd90a789..5f2873b09f 100644
--- a/lib/ruby_vm/mjit/assembler.rb
+++ b/lib/ruby_vm/mjit/assembler.rb
@@ -101,6 +101,23 @@ module RubyVM::MJIT
end
end
+ def and(dst, src)
+ case [dst, src]
+ # AND r/m64, imm8 (Mod 11: reg)
+ in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm8?(src_imm)
+ # REX.W + 83 /4 ib
+ # MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
+ insn(
+ prefix: REX_W,
+ opcode: 0x83,
+ mod_rm: ModRM[mod: Mod11, reg: 4, rm: dst_reg],
+ imm: imm8(src_imm),
+ )
+ else
+ raise NotImplementedError, "and: not-implemented operands: #{dst.inspect}, #{src.inspect}"
+ end
+ end
+
# @param addr [Integer]
def call(addr)
# CALL rel32
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index b30f1e7988..43fd1e9648 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -17,7 +17,7 @@ module RubyVM::MJIT
asm.incr_counter(:mjit_insns_count)
asm.comment("Insn: #{insn.name}")
- # 14/101
+ # 15/101
case insn.name
when :nop then nop(jit, ctx, asm)
# getlocal
@@ -115,6 +115,7 @@ module RubyVM::MJIT
# opt_invokebuiltin_delegate
# opt_invokebuiltin_delegate_leave
when :getlocal_WC_0 then getlocal_WC_0(jit, ctx, asm)
+ when :getlocal_WC_1 then getlocal_WC_1(jit, ctx, asm)
# setlocal_WC_0
# setlocal_WC_1
when :putobject_INT2FIX_0_ then putobject_INT2FIX_0_(jit, ctx, asm)
@@ -516,12 +517,31 @@ module RubyVM::MJIT
asm.mov(:rax, [:rax, -idx * C.VALUE.size])
# Push it to the stack
- asm.mov([SP, C.VALUE.size * ctx.stack_size], :rax)
- ctx.stack_push(1)
+ stack_top = ctx.stack_push
+ asm.mov(stack_top, :rax)
+ KeepCompiling
+ end
+
+ # @param jit [RubyVM::MJIT::JITState]
+ # @param ctx [RubyVM::MJIT::Context]
+ # @param asm [RubyVM::MJIT::Assembler]
+ def getlocal_WC_1(jit, ctx, asm)
+ # Get operands
+ idx = jit.operand(0)
+ level = 1
+
+ # Get EP
+ ep_reg = jit_get_ep(asm, level)
+
+ # Get a local variable
+ asm.mov(:rax, [ep_reg, -idx * C.VALUE.size])
+
+ # Push it to the stack
+ stack_top = ctx.stack_push
+ asm.mov(stack_top, :rax)
KeepCompiling
end
- # getlocal_WC_1
# setlocal_WC_0
# setlocal_WC_1
@@ -611,6 +631,20 @@ module RubyVM::MJIT
asm.jnz(side_exit(jit, ctx))
end
+ # vm_get_ep
+ # @param jit [RubyVM::MJIT::JITState]
+ # @param ctx [RubyVM::MJIT::Context]
+ # @param asm [RubyVM::MJIT::Assembler]
+ def jit_get_ep(asm, level)
+ asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:ep)])
+ level.times do
+ # GET_PREV_EP: ep[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03
+ asm.mov(:rax, [:rax, C.VALUE.size * C.VM_ENV_DATA_INDEX_SPECVAL])
+ asm.and(:rax, ~0x03)
+ end
+ return :rax
+ end
+
# vm_getivar
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
diff --git a/mjit_c.rb b/mjit_c.rb
index 1c37185713..74a6c48abe 100644
--- a/mjit_c.rb
+++ b/mjit_c.rb
@@ -283,6 +283,10 @@ module RubyVM::MJIT # :nodoc: all
Primitive.cexpr! %q{ INT2NUM(NOT_COMPILED_STACK_SIZE) }
end
+ def C.VM_ENV_DATA_INDEX_SPECVAL
+ Primitive.cexpr! %q{ INT2NUM(VM_ENV_DATA_INDEX_SPECVAL) }
+ end
+
def C.BOP_LT
Primitive.cexpr! %q{ UINT2NUM(BOP_LT) }
end
diff --git a/tool/mjit/bindgen.rb b/tool/mjit/bindgen.rb
index 32c2417bef..83d85844cc 100755
--- a/tool/mjit/bindgen.rb
+++ b/tool/mjit/bindgen.rb
@@ -345,6 +345,7 @@ generator = BindingGenerator.new(
values: {
INT: %w[
NOT_COMPILED_STACK_SIZE
+ VM_ENV_DATA_INDEX_SPECVAL
],
UINT: %w[
BOP_LT