1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

tool/instruction.rb: move logics to templates

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59636 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-08-22 04:22:01 +00:00
parent 1f89414c20
commit 7735c1f5fe
8 changed files with 155 additions and 206 deletions

View file

@ -14,8 +14,10 @@
#define BIN(n) YARVINSN_##n #define BIN(n) YARVINSN_##n
enum ruby_vminsn_type { enum ruby_vminsn_type {
<%= insns %> % @insns.each do |insn|
VM_INSTRUCTION_SIZE = <%= @insns.size %> BIN(<%=insn.name%>),
% end
VM_INSTRUCTION_SIZE
}; };
#define ASSERT_VM_INSTRUCTION_SIZE(array) \ #define ASSERT_VM_INSTRUCTION_SIZE(array) \

View file

@ -9,29 +9,39 @@
or tool/insns2vm.rb or tool/insns2vm.rb
*/ */
<%= insn_type_chars %> % TYPE_CHARS.each do |t, c|
#define <%=t%> '<%=c%>'
% end
static const char *const insn_name_info[] = { static const char *const insn_name_info[] = {
<%= insn_names %> % @insns.each do |insn|
"<%= insn.name %>",
% end
}; };
ASSERT_VM_INSTRUCTION_SIZE(insn_name_info); ASSERT_VM_INSTRUCTION_SIZE(insn_name_info);
static const char *const insn_operand_info[] = { static const char *const insn_operand_info[] = {
<%= operands_info %> % @insns.each do |insn|
"<% insn.opes.each {|type, _| %><%=TYPE_CHARS.fetch(op2typesig(type))%><%}%>",
% end
}; };
ASSERT_VM_INSTRUCTION_SIZE(insn_operand_info); ASSERT_VM_INSTRUCTION_SIZE(insn_operand_info);
static const int insn_len_info[] = { static const int insn_len_info[] = {
<%= operands_num_info %> % @insns.each do |insn|
<%= insn.opes.size + 1 %>,
% end
}; };
ASSERT_VM_INSTRUCTION_SIZE(insn_len_info); ASSERT_VM_INSTRUCTION_SIZE(insn_len_info);
#ifdef USE_INSN_RET_NUM #ifdef USE_INSN_RET_NUM
static const int insn_stack_push_num_info[] = { static const int insn_stack_push_num_info[] = {
<%= stack_num_info %> % @insns.each do |insn|
<%= insn.rets.size %>,
% end
}; };
ASSERT_VM_INSTRUCTION_SIZE(insn_stack_push_num_info); ASSERT_VM_INSTRUCTION_SIZE(insn_stack_push_num_info);
@ -41,12 +51,16 @@ ASSERT_VM_INSTRUCTION_SIZE(insn_stack_push_num_info);
static int static int
insn_stack_increase(int depth, int insn, VALUE *opes) insn_stack_increase(int depth, int insn, VALUE *opes)
{ {
switch(insn){ switch (insn) {
<%= stack_increase %> % @insns.each do |insn|
default: case BIN(<%= insn.name %>): {
rb_bug("insn_sp_increase: unreachable"); <%= insn.sp_increase_c_expr %>
} }
return 0; % end
default:
rb_bug("insn_sp_increase: unreachable");
}
return 0;
} }
#endif #endif
@ -55,37 +69,37 @@ insn_stack_increase(int depth, int insn, VALUE *opes)
static int static int
insn_len(VALUE insn) insn_len(VALUE insn)
{ {
return insn_len_info[(int)insn]; return insn_len_info[(int)insn];
} }
static const char * static const char *
insn_name(VALUE insn) insn_name(VALUE insn)
{ {
return insn_name_info[(int)insn]; return insn_name_info[(int)insn];
} }
static const char * static const char *
insn_op_types(VALUE insn) insn_op_types(VALUE insn)
{ {
return insn_operand_info[(int)insn]; return insn_operand_info[(int)insn];
} }
static int static int
insn_op_type(VALUE insn, long pos) insn_op_type(VALUE insn, long pos)
{ {
int len = insn_len(insn) - 1; int len = insn_len(insn) - 1;
if(pos < len){ if (pos < len) {
return insn_operand_info[(int)insn][pos]; return insn_operand_info[(int)insn][pos];
} }
else{ else{
return 0; return 0;
} }
} }
#ifdef USE_INSN_RET_NUM #ifdef USE_INSN_RET_NUM
static int static int
insn_ret_num(VALUE insn) insn_ret_num(VALUE insn)
{ {
return insn_stack_push_num_info[(int)insn]; return insn_stack_push_num_info[(int)insn];
} }
#endif #endif

View file

@ -9,6 +9,6 @@
or tool/insns2vm.rb or tool/insns2vm.rb
*/ */
<%= defs %> % @insns.each_with_index do |insn, i|
rb_define_const(mYarvInsns, "I<%=insn.name%>", INT2FIX(<%=i%>));
% end

View file

@ -13,18 +13,42 @@
*/ */
static INSN * static INSN *
insn_operands_unification(INSN *insnobj){ insn_operands_unification(INSN *insnobj)
{
#ifdef OPT_OPERANDS_UNIFICATION #ifdef OPT_OPERANDS_UNIFICATION
/* optimize rule */ /* optimize rule */
switch(insnobj->insn_id){ switch(insnobj->insn_id){
% opt_insns_map.each do |originsn, optinsns|
case BIN(<%=originsn.name%>):
% optinsns.each {|opti|
if (
% opti.defopes.each_with_index {|opinfo, i|
% next if opinfo[1] == '*'
insnobj->operands[<%=i%>] == <%=val_as_type(opinfo)%> &&
% }
1) {
% idx = 0
% opti.defopes.each_with_index {|opinfo, n|
% if opinfo[1] == '*'
% if idx != n
insnobj->operands[<%=idx%>] = insnobj->operands[<%=n%>];
% end
% idx += 1
% end
% }
insnobj->insn_id = BIN(<%=opti.name%>);
insnobj->operand_size = <%=idx%>;
break;
}
% }
break;
% end
<%= rule %> default:
/* do nothing */;
default: break;
/* do nothing */; }
break;
}
#endif #endif
return insnobj; return insnobj;
} }

View file

@ -27,9 +27,40 @@
UNIFIED_insn_nameB, ...}; UNIFIED_insn_nameB, ...};
*/ */
<%= unif_insns_each %> % unif_insns_data = @insns.find_all {|insn| !insn.is_sc}.map do |insn|
<%= unif_insns %> % size = insn.unifs.size
<%= unif_insns_data %> % if size > 0
% name = "UNIFIED_#{insn.name}"
% insn.unifs.sort_by{|unif| -unif[1].size}.each_with_index do |(uni_insn, uni_insns), i|
% uni_insns = uni_insns[1..-1]
static const int <%=name%>_<%=i%>[] = {
BIN(<%=uni_insn.name%>), <%=uni_insns.size + 2%>,
<% uni_insns.map{|e| -%>
BIN(<%=e.name%>),<% -%>
% }
};
% end
static const int *const <%=name%>[] = {(int *)<%=size+1%>,
% size.times do |e|
<%=name%>_<%=e%>,
% end
};
% name
% end
% end
static const int *const *const unified_insns_data[] = {<%#-%>
% unif_insns_data.each_with_index do |insn, i|
% if (i%8).zero?
<% -%>
% end
<%=insn || "0"%>,<%#-%>
% end
};
#undef GET_INSN_NAME #undef GET_INSN_NAME

View file

@ -11,19 +11,23 @@
If you want to fix something, you must edit 'insns.def' If you want to fix something, you must edit 'insns.def'
*/ */
<%=
line = 15 % line = _erbout.count("\n") + 1
vm_body.gsub(/\n|__CURRENT_LINE__|__CURRENT_FILE__/){ % @insns.each do |insn|
e = $& <%
line += 1
make_insn_def(insn).split(/(__CURRENT_LINE__|__CURRENT_FILE__)/).each {|e|
%><%=
case e case e
when '__CURRENT_LINE__' when '__CURRENT_LINE__'
line.to_s line.to_s
when '__CURRENT_FILE__' when '__CURRENT_FILE__'
"vm.inc" "vm.inc"
else else
line += 1 line += e.count("\n")
e e
end end
%><%
} }
%> %>
% end

View file

@ -13,7 +13,9 @@
*/ */
static const void *const insns_address_table[] = { static const void *const insns_address_table[] = {
<%= insns_table %> % @insns.each do |insn|
LABEL_PTR(<%=insn.name%>),
% end
}; };
ASSERT_VM_INSTRUCTION_SIZE(insns_address_table); ASSERT_VM_INSTRUCTION_SIZE(insns_address_table);

View file

@ -648,6 +648,10 @@ class RubyVM
@insns.use_const? @insns.use_const?
end end
def template(name)
ERB.new(vpath.read("template/#{name}"), nil, '%-')
end
def build_string def build_string
@lines = [] @lines = []
yield yield
@ -676,13 +680,7 @@ class RubyVM
class VmBodyGenerator < SourceCodeGenerator class VmBodyGenerator < SourceCodeGenerator
# vm.inc # vm.inc
def generate def generate
vm_body = '' template('vm.inc.tmpl').result(binding)
@insns.each{|insn|
vm_body << "\n"
vm_body << make_insn_def(insn)
}
src = vpath.read('template/vm.inc.tmpl')
ERB.new(src).result(binding)
end end
def generate_from_insnname insnname def generate_from_insnname insnname
@ -912,20 +910,7 @@ class RubyVM
# vmtc.inc # vmtc.inc
class VmTCIncGenerator < SourceCodeGenerator class VmTCIncGenerator < SourceCodeGenerator
def generate def generate
template('vmtc.inc.tmpl').result(binding)
insns_table = build_string do
@insns.each{|insn|
commit " LABEL_PTR(#{insn.name}),"
}
end
insn_end_table = build_string do
@insns.each{|insn|
commit " ELABEL_PTR(#{insn.name}),\n"
}
end
ERB.new(vpath.read('template/vmtc.inc.tmpl')).result(binding)
end end
end end
@ -933,7 +918,7 @@ class RubyVM
# insns_info.inc # insns_info.inc
class InsnsInfoIncGenerator < SourceCodeGenerator class InsnsInfoIncGenerator < SourceCodeGenerator
def generate def generate
insns_info_inc template('insns_info.inc.tmpl').result(binding)
end end
### ###
@ -988,52 +973,14 @@ class RubyVM
'TS_FUNCPTR' => 'F', 'TS_FUNCPTR' => 'F',
} }
# insns_info.inc def max_length(array)
def insns_info_inc max = 0
# insn_type_chars array.each do |i|
insn_type_chars = TYPE_CHARS.map{|t, c| if (n = i.length) > max
"#define #{t} '#{c}'" max = n
}.join("\n") end
end
# insn_names max
insn_names = ''
@insns.each{|insn|
insn_names << " \"#{insn.name}\",\n"
}
# operands info
operands_info = ''
operands_num_info = ''
@insns.each{|insn|
opes = insn.opes
operands_info << ' '
ot = opes.map{|type, var|
TYPE_CHARS.fetch(op2typesig(type))
}
operands_info << "\"#{ot.join}\"" << ",\n"
num = opes.size + 1
operands_num_info << " #{num},\n"
}
# stack num
stack_num_info = ''
@insns.each{|insn|
num = insn.rets.size
stack_num_info << " #{num},\n"
}
# stack increase
stack_increase = ''
@insns.each{|insn|
stack_increase << <<-EOS
case BIN(#{insn.name}):{
#{insn.sp_increase_c_expr}
}
EOS
}
ERB.new(vpath.read('template/insns_info.inc.tmpl')).result(binding)
end end
end end
@ -1041,15 +988,7 @@ class RubyVM
# insns.inc # insns.inc
class InsnsIncGenerator < SourceCodeGenerator class InsnsIncGenerator < SourceCodeGenerator
def generate def generate
i=0 template('insns.inc.tmpl').result(binding)
insns = build_string do
@insns.each{|insn|
commit " %-30s = %d," % ["BIN(#{insn.name})", i]
i+=1
}
end
ERB.new(vpath.read('template/insns.inc.tmpl')).result(binding)
end end
end end
@ -1057,15 +996,7 @@ class RubyVM
# minsns.inc # minsns.inc
class MInsnsIncGenerator < SourceCodeGenerator class MInsnsIncGenerator < SourceCodeGenerator
def generate def generate
i=0 template('minsns.inc.tmpl').result(binding)
defs = build_string do
@insns.each{|insn|
commit " rb_define_const(mYarvInsns, %-30s, INT2FIX(%d));" %
["\"I#{insn.name}\"", i]
i+=1
}
end
ERB.new(vpath.read('template/minsns.inc.tmpl')).result(binding)
end end
end end
@ -1103,8 +1034,7 @@ class RubyVM
# optinsn.inc # optinsn.inc
def optinsn_inc def optinsn_inc
rule = '' opt_insns_map = Hash.new{[]}
opt_insns_map = Hash.new{|h, k| h[k] = []}
@insns.each{|insn| @insns.each{|insn|
next if insn.defopes.size == 0 next if insn.defopes.size == 0
@ -1112,46 +1042,17 @@ class RubyVM
next if /^UNIFIED/ =~ insn.name.to_s next if /^UNIFIED/ =~ insn.name.to_s
originsn = insn.orig originsn = insn.orig
opt_insns_map[originsn] << insn opt_insns_map[originsn] <<= insn
} }
rule = build_string do opt_insns_map.each_value do |optinsns|
opt_insns_map.each{|originsn, optinsns| sorted = optinsns.sort_by {|opti|
commit "case BIN(#{originsn.name}):" opti.defopes.find_all{|e| e[1] == '*'}.size
optinsns.sort_by{|opti|
opti.defopes.find_all{|e| e[1] == '*'}.size
}.each{|opti|
commit " if("
i = 0
commit " " + opti.defopes.map{|opinfo|
i += 1
next if opinfo[1] == '*'
"insnobj->operands[#{i-1}] == #{val_as_type(opinfo)}"
}.compact.join('&& ')
commit " ){"
idx = 0
n = 0
opti.defopes.each{|opinfo|
if opinfo[1] == '*'
if idx != n
commit " insnobj->operands[#{idx}] = insnobj->operands[#{n}];"
end
idx += 1
else
# skip
end
n += 1
}
commit " insnobj->insn_id = BIN(#{opti.name});"
commit " insnobj->operand_size = #{idx};"
commit " break;\n }\n"
}
commit " break;";
} }
optinsns.replace(sorted)
end end
ERB.new(vpath.read('template/optinsn.inc.tmpl')).result(binding) template('optinsn.inc.tmpl').result(binding)
end end
end end
@ -1159,36 +1060,7 @@ class RubyVM
# optunifs.inc # optunifs.inc
class OptUnifsIncGenerator < SourceCodeGenerator class OptUnifsIncGenerator < SourceCodeGenerator
def generate def generate
unif_insns_each = '' template('optunifs.inc.tmpl').result(binding)
unif_insns = ''
unif_insns_data = []
insns = @insns.find_all{|insn| !insn.is_sc}
insns.each{|insn|
size = insn.unifs.size
if size > 0
insn.unifs.sort_by{|unif| -unif[1].size}.each_with_index{|unif, i|
uni_insn, uni_insns = *unif
uni_insns = uni_insns[1..-1]
unif_insns_each << "static const int UNIFIED_#{insn.name}_#{i}[] = {" +
" BIN(#{uni_insn.name}), #{uni_insns.size + 2},\n " +
uni_insns.map{|e| "BIN(#{e.name})"}.join(", ") + "};\n"
}
else
end
if size > 0
unif_insns << "static const int *const UNIFIED_#{insn.name}[] = {(int *)#{size+1},\n"
unif_insns << (0...size).map{|e| " UNIFIED_#{insn.name}_#{e}"}.join(",\n") + "};\n"
unif_insns_data << " UNIFIED_#{insn.name}"
else
unif_insns_data << " 0"
end
}
unif_insns_data = "static const int *const *const unified_insns_data[] = {\n" +
unif_insns_data.join(",\n") + "};\n"
ERB.new(vpath.read('template/optunifs.inc.tmpl')).result(binding)
end end
end end
@ -1212,7 +1084,7 @@ class RubyVM
" SCS_#{InstructionsLoader.complement_name(insn.nextsc).upcase}" + " SCS_#{InstructionsLoader.complement_name(insn.nextsc).upcase}" +
(verbose? ? " /* #{insn.name} */" : '') (verbose? ? " /* #{insn.name} */" : '')
}.join(",\n") }.join(",\n")
ERB.new(vpath.read('template/opt_sc.inc.tmpl')).result(binding) template('opt_sc.inc.tmpl').result(binding)
end end
end end
@ -1224,7 +1096,7 @@ class RubyVM
@insns.each_with_index{|insn, i| @insns.each_with_index{|insn, i|
insn_id2no << " :#{insn.name} => #{i},\n" insn_id2no << " :#{insn.name} => #{i},\n"
} }
ERB.new(vpath.read('template/yasmdata.rb.tmpl')).result(binding) template('yasmdata.rb').result(binding)
end end
end end
@ -1251,8 +1123,8 @@ class RubyVM
d << "*** #{insn.name}\n" d << "*** #{insn.name}\n"
d << "\n" d << "\n"
d << insn.comm[lang] + "\n\n" d << insn.comm[lang] << "\n\n"
d << ":instruction sequence: 0x%02x #{seq}\n" % i d << ":instruction sequence: 0x%02x " % i << seq << "\n"
d << ":stack: #{before} => #{after}\n\n" d << ":stack: #{before} => #{after}\n\n"
i+=1 i+=1
} }
@ -1261,12 +1133,12 @@ class RubyVM
def desc_ja def desc_ja
d = desc :j d = desc :j
ERB.new(vpath.read('template/yarvarch.ja')).result(binding) template('yarvarch.ja').result(binding)
end end
def desc_en def desc_en
d = desc :e d = desc :e
ERB.new(vpath.read('template/yarvarch.en')).result(binding) template('yarvarch.en').result(binding)
end end
end end