diff --git a/lib/mjit/codegen.rb b/lib/mjit/codegen.rb index b04cb7b2fe..6ebefde860 100644 --- a/lib/mjit/codegen.rb +++ b/lib/mjit/codegen.rb @@ -16,13 +16,18 @@ module RubyVM::MJIT # @param asm [RubyVM::MJIT::X86Assembler] def leave(ctx, asm) assert_eq!(ctx.stack_size, 1) + # TODO: Check interrupts - # pop the current frame (ec->cfp++) + # Pop the current frame (ec->cfp++) asm.add(:rsi, C.rb_control_frame_t.size) # rsi = cfp + 1 asm.mov([:rdi, C.rb_execution_context_t.offsetof(:cfp)], :rsi) # ec->cfp = rsi - # return a value + # Return a value asm.mov(:rax, [:rbx]) + + # Restore callee-saved registers + asm.pop(:rbx) + asm.ret EndBlock end diff --git a/lib/mjit/x86_assembler.rb b/lib/mjit/x86_assembler.rb index be65644650..c6c0cc2e19 100644 --- a/lib/mjit/x86_assembler.rb +++ b/lib/mjit/x86_assembler.rb @@ -37,7 +37,7 @@ module RubyVM::MJIT imm: imm8(src_imm), ) else - raise NotImplementedError, "add: not-implemented input: #{dst.inspect}, #{src.inspect}" + raise NotImplementedError, "add: not-implemented operands: #{dst.inspect}, #{src.inspect}" end end @@ -102,7 +102,31 @@ module RubyVM::MJIT disp: src_offset, ) else - raise NotImplementedError, "mov: not-implemented input: #{dst.inspect}, #{src.inspect}" + raise NotImplementedError, "mov: not-implemented operands: #{dst.inspect}, #{src.inspect}" + end + end + + def push(src) + case src + # PUSH r64 + in Symbol => src_reg if r64?(src_reg) + # 50+rd + # O: Operand 1: opcode + rd (r) + insn(opcode: 0x50 + reg_code(src_reg)) + else + raise NotImplementedError, "push: not-implemented operands: #{src.inspect}" + end + end + + def pop(dst) + case dst + # POP r64 + in Symbol => dst_reg if r64?(dst_reg) + # 58+ rd + # O: Operand 1: opcode + rd (r) + insn(opcode: 0x58 + reg_code(dst_reg)) + else + raise NotImplementedError, "pop: not-implemented operands: #{dst.inspect}" end end diff --git a/lib/ruby_vm/mjit/compiler.rb b/lib/ruby_vm/mjit/compiler.rb index ff0003c8bf..8a5614c081 100644 --- a/lib/ruby_vm/mjit/compiler.rb +++ b/lib/ruby_vm/mjit/compiler.rb @@ -58,8 +58,16 @@ module RubyVM::MJIT # ec: rdi # cfp: rsi + # + # Callee-saved: rbx, rsp, rbp, r12, r13, r14, r15 + # Caller-saved: rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11 + # # @param asm [RubyVM::MJIT::X86Assembler] def compile_prologue(asm) + # Save callee-saved registers used by JITed code + asm.push(:rbx) + + # Load sp to a register asm.mov(:rbx, [:rsi, C.rb_control_frame_t.offsetof(:sp)]) # rbx = cfp->sp end @@ -103,6 +111,9 @@ module RubyVM::MJIT asm.mov([:rsi, C.rb_control_frame_t.offsetof(:sp)], :rbx) # cfp->sp = rbx end + # Restore callee-saved registers + asm.pop(:rbx) + asm.mov(:rax, Qundef) asm.ret end @@ -115,6 +126,7 @@ module RubyVM::MJIT C.dump_disasm(from, to).each do |address, mnemonic, op_str| puts " 0x#{"%p" % address}: #{mnemonic} #{op_str}" end + puts end end end