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
enum ruby_vminsn_type {
<%= insns %>
VM_INSTRUCTION_SIZE = <%= @insns.size %>
% @insns.each do |insn|
BIN(<%=insn.name%>),
% end
VM_INSTRUCTION_SIZE
};
#define ASSERT_VM_INSTRUCTION_SIZE(array) \

View file

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

View file

@ -9,6 +9,6 @@
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 *
insn_operands_unification(INSN *insnobj){
insn_operands_unification(INSN *insnobj)
{
#ifdef OPT_OPERANDS_UNIFICATION
/* optimize rule */
switch(insnobj->insn_id){
/* optimize rule */
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 */;
break;
}
default:
/* do nothing */;
break;
}
#endif
return insnobj;
return insnobj;
}

View file

@ -27,9 +27,40 @@
UNIFIED_insn_nameB, ...};
*/
<%= unif_insns_each %>
<%= unif_insns %>
<%= unif_insns_data %>
% unif_insns_data = @insns.find_all {|insn| !insn.is_sc}.map do |insn|
% size = insn.unifs.size
% 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

View file

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

View file

@ -13,7 +13,9 @@
*/
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);

View file

@ -648,6 +648,10 @@ class RubyVM
@insns.use_const?
end
def template(name)
ERB.new(vpath.read("template/#{name}"), nil, '%-')
end
def build_string
@lines = []
yield
@ -676,13 +680,7 @@ class RubyVM
class VmBodyGenerator < SourceCodeGenerator
# vm.inc
def generate
vm_body = ''
@insns.each{|insn|
vm_body << "\n"
vm_body << make_insn_def(insn)
}
src = vpath.read('template/vm.inc.tmpl')
ERB.new(src).result(binding)
template('vm.inc.tmpl').result(binding)
end
def generate_from_insnname insnname
@ -912,20 +910,7 @@ class RubyVM
# vmtc.inc
class VmTCIncGenerator < SourceCodeGenerator
def generate
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)
template('vmtc.inc.tmpl').result(binding)
end
end
@ -933,7 +918,7 @@ class RubyVM
# insns_info.inc
class InsnsInfoIncGenerator < SourceCodeGenerator
def generate
insns_info_inc
template('insns_info.inc.tmpl').result(binding)
end
###
@ -988,52 +973,14 @@ class RubyVM
'TS_FUNCPTR' => 'F',
}
# insns_info.inc
def insns_info_inc
# insn_type_chars
insn_type_chars = TYPE_CHARS.map{|t, c|
"#define #{t} '#{c}'"
}.join("\n")
# insn_names
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)
def max_length(array)
max = 0
array.each do |i|
if (n = i.length) > max
max = n
end
end
max
end
end
@ -1041,15 +988,7 @@ class RubyVM
# insns.inc
class InsnsIncGenerator < SourceCodeGenerator
def generate
i=0
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)
template('insns.inc.tmpl').result(binding)
end
end
@ -1057,15 +996,7 @@ class RubyVM
# minsns.inc
class MInsnsIncGenerator < SourceCodeGenerator
def generate
i=0
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)
template('minsns.inc.tmpl').result(binding)
end
end
@ -1103,8 +1034,7 @@ class RubyVM
# optinsn.inc
def optinsn_inc
rule = ''
opt_insns_map = Hash.new{|h, k| h[k] = []}
opt_insns_map = Hash.new{[]}
@insns.each{|insn|
next if insn.defopes.size == 0
@ -1112,46 +1042,17 @@ class RubyVM
next if /^UNIFIED/ =~ insn.name.to_s
originsn = insn.orig
opt_insns_map[originsn] << insn
opt_insns_map[originsn] <<= insn
}
rule = build_string do
opt_insns_map.each{|originsn, optinsns|
commit "case BIN(#{originsn.name}):"
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;";
opt_insns_map.each_value do |optinsns|
sorted = optinsns.sort_by {|opti|
opti.defopes.find_all{|e| e[1] == '*'}.size
}
optinsns.replace(sorted)
end
ERB.new(vpath.read('template/optinsn.inc.tmpl')).result(binding)
template('optinsn.inc.tmpl').result(binding)
end
end
@ -1159,36 +1060,7 @@ class RubyVM
# optunifs.inc
class OptUnifsIncGenerator < SourceCodeGenerator
def generate
unif_insns_each = ''
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)
template('optunifs.inc.tmpl').result(binding)
end
end
@ -1212,7 +1084,7 @@ class RubyVM
" SCS_#{InstructionsLoader.complement_name(insn.nextsc).upcase}" +
(verbose? ? " /* #{insn.name} */" : '')
}.join(",\n")
ERB.new(vpath.read('template/opt_sc.inc.tmpl')).result(binding)
template('opt_sc.inc.tmpl').result(binding)
end
end
@ -1224,7 +1096,7 @@ class RubyVM
@insns.each_with_index{|insn, i|
insn_id2no << " :#{insn.name} => #{i},\n"
}
ERB.new(vpath.read('template/yasmdata.rb.tmpl')).result(binding)
template('yasmdata.rb').result(binding)
end
end
@ -1251,8 +1123,8 @@ class RubyVM
d << "*** #{insn.name}\n"
d << "\n"
d << insn.comm[lang] + "\n\n"
d << ":instruction sequence: 0x%02x #{seq}\n" % i
d << insn.comm[lang] << "\n\n"
d << ":instruction sequence: 0x%02x " % i << seq << "\n"
d << ":stack: #{before} => #{after}\n\n"
i+=1
}
@ -1261,12 +1133,12 @@ class RubyVM
def desc_ja
d = desc :j
ERB.new(vpath.read('template/yarvarch.ja')).result(binding)
template('yarvarch.ja').result(binding)
end
def desc_en
d = desc :e
ERB.new(vpath.read('template/yarvarch.en')).result(binding)
template('yarvarch.en').result(binding)
end
end