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:
parent
1f89414c20
commit
7735c1f5fe
8 changed files with 155 additions and 206 deletions
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue