aboutsummaryrefslogtreecommitdiffstats
path: root/tool/ruby_vm/views/_mjit_compile_insn_body.erb
diff options
context:
space:
mode:
Diffstat (limited to 'tool/ruby_vm/views/_mjit_compile_insn_body.erb')
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn_body.erb38
1 files changed, 34 insertions, 4 deletions
diff --git a/tool/ruby_vm/views/_mjit_compile_insn_body.erb b/tool/ruby_vm/views/_mjit_compile_insn_body.erb
index 24c07d590b..b209786525 100644
--- a/tool/ruby_vm/views/_mjit_compile_insn_body.erb
+++ b/tool/ruby_vm/views/_mjit_compile_insn_body.erb
@@ -17,9 +17,6 @@
% #
% expand_simple_macros = lambda do |arg_expr|
% arg_expr.dup.tap do |expr|
-% # For `opt_xxx`'s fallbacks.
-% expr.gsub!(/\bDISPATCH_ORIGINAL_INSN\([^)]+\);/, 'return Qundef; /* cancel JIT */')
-%
% # For `leave`. We can't proceed next ISeq in the same JIT function.
% expr.gsub!(/^(?<indent>\s*)RESTORE_REGS\(\);\n/) do
% indent = Regexp.last_match[:indent]
@@ -42,7 +39,9 @@
% #
% # Expand dynamic macro here (only JUMP for now)
% #
-% if line =~ /\A\s+JUMP\((?<dest>[^)]+)\);\s+\z/
+% # TODO: support combination of following macros in the same line
+% case line
+% when /\A\s+JUMP\((?<dest>[^)]+)\);\s+\z/
% dest = Regexp.last_match[:dest]
%
% if insn.name == 'opt_case_dispatch' # special case... TODO: use another macro to avoid checking name
@@ -68,7 +67,38 @@
next_pos = pos + insn_len(insn) + (unsigned int)<%= dest %>;
fprintf(f, " goto label_%d;\n", next_pos);
% end
+% when /\A\s+DISPATCH_ORIGINAL_INSN\([^)]+\);\s+\z/
+% # For `opt_xxx`'s fallbacks.
+ if (status->local_stack_p) {
+ fprintf(f, " reg_cfp->sp = (VALUE *)reg_cfp->bp + %d;\n", b->stack_size + 1);
+ }
+ fprintf(f, " goto cancel;\n");
% else
+% if insn.handles_frame?
+% # If insn.handles_frame? is true, cfp->sp might be changed inside insns (like vm_caller_setup_arg_block)
+% # and thus we need to use cfp->sp, even when local_stack_p is TRUE. When insn.handles_frame? is true,
+% # cfp->sp should be available too because _mjit_compile_pc_and_sp.erb sets it.
fprintf(f, <%= to_cstr.call(line) %>);
+% else
+% # If local_stack_p is TRUE and insn.handles_frame? is false, stack values are only available in local variables
+% # for stack. So we need to replace those macros if local_stack_p is TRUE here.
+% case line
+% when /\bGET_SP\(\)/
+% # reg_cfp->sp
+ fprintf(f, <%= to_cstr.call(line.sub(/\bGET_SP\(\)/, '%s')) %>, (status->local_stack_p ? "(stack + stack_size)" : "GET_SP()"));
+% when /\bSTACK_ADDR_FROM_TOP\((?<num>[^)]+)\)/
+% # #define STACK_ADDR_FROM_TOP(n) (GET_SP()-(n))
+% num = Regexp.last_match[:num]
+ fprintf(f, <%= to_cstr.call(line.sub(/\bSTACK_ADDR_FROM_TOP\(([^)]+)\)/, '%s')) %>,
+ (status->local_stack_p ? "stack + (stack_size - (<%= num %>))" : "STACK_ADDR_FROM_TOP(<%= num %>)"));
+% when /\bTOPN\((?<num>[^)]+)\)/
+% # #define TOPN(n) (*(GET_SP()-(n)-1))
+% num = Regexp.last_match[:num]
+ fprintf(f, <%= to_cstr.call(line.sub(/\bTOPN\(([^)]+)\)/, '%s')) %>,
+ (status->local_stack_p ? "*(stack + (stack_size - (<%= num %>) - 1))" : "TOPN(<%= num %>)"));
+% else
+ fprintf(f, <%= to_cstr.call(line) %>);
+% end
+% end
% end
% end