summaryrefslogtreecommitdiff
path: root/template/insns_info.inc.tmpl
diff options
context:
space:
mode:
Diffstat (limited to 'template/insns_info.inc.tmpl')
-rw-r--r--template/insns_info.inc.tmpl134
1 files changed, 134 insertions, 0 deletions
diff --git a/template/insns_info.inc.tmpl b/template/insns_info.inc.tmpl
new file mode 100644
index 0000000000..546368d984
--- /dev/null
+++ b/template/insns_info.inc.tmpl
@@ -0,0 +1,134 @@
+/** -*-c-*-
+ This file contains instruction information for yarv instruction sequence.
+
+ ----
+ This file is auto generated by insns2vm.rb
+ DO NOT TOUCH!
+
+ If you want to fix something, you must edit 'template/insns_info.inc.tmpl'
+ or tool/insns2vm.rb
+ */
+
+% TYPE_CHARS.each do |t, c|
+#define <%=t%> '<%=c%>'
+% end
+
+extern const struct rb_vm_insn_name_info rb_vm_insn_name_info_base;
+extern const unsigned short rb_vm_insn_name_info_offset[];
+extern const char rb_vm_insn_operand_info[][8];
+extern const unsigned short rb_vm_insn_stack_push_num_info[];
+#define insn_name_info (const char *)&rb_vm_insn_name_info_base+rb_vm_insn_name_info_offset
+#define insn_operand_info rb_vm_insn_operand_info
+#define rb_vm_insn_stack_push_num_info insn_stack_push_num_info
+
+#ifdef RUBY_VM_INSNS_INFO
+const unsigned short rb_vm_insn_name_info_offset[] = {
+% insn_name_length = @insns.inject(0) do |ofs, insn|
+ <%= ofs %>,
+% ofs + insn.name.size + 1
+% end
+};
+
+ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_name_info_offset);
+
+% n = 100
+const struct rb_vm_insn_name_info {
+% @insns.each_with_index do |insn, i|
+% if (i % n) == 0
+ struct {
+% end
+ char L<%=i%n%>[<%= insn.name.size+1 %>];
+% if (i % n) == n - 1 or i == @insns.size - 1
+ } S<%=i / n%>;
+% end
+% end
+} rb_vm_insn_name_info_base = {
+% @insns.each_with_index do |insn, i|
+% if (i % n) == 0
+ {
+% end
+ "<%= insn.name %>",
+% if (i % n) == n - 1 or i == @insns.size - 1
+ },
+% end
+% end
+};
+
+const char rb_vm_insn_operand_info[][8] = {
+% @insns.each do |insn|
+ "\<%= (insn.opes.size+1).to_s(8) %>""<%
+ insn.opes.each {|type, _|
+ %><%=TYPE_CHARS.fetch(op2typesig(type))%><%
+ }%>",
+% end
+};
+
+ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_operand_info);
+
+#ifdef USE_INSN_RET_NUM
+const unsigned short rb_vm_insn_stack_push_num_info[] = {
+% @insns.each do |insn|
+ <%= insn.rets.size %>,
+% end
+};
+
+ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_stack_push_num_info);
+#endif
+#endif
+
+#ifdef USE_INSN_STACK_INCREASE
+static int
+insn_stack_increase(int depth, int insn, VALUE *opes)
+{
+ 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
+
+/* some utilities */
+
+static int
+insn_len(VALUE insn)
+{
+ return (unsigned char)insn_operand_info[(int)insn][0];
+}
+
+static const char *
+insn_name(VALUE insn)
+{
+ return insn_name_info[(int)insn];
+}
+
+static const char *
+insn_op_types(VALUE insn)
+{
+ return insn_operand_info[(int)insn]+1;
+}
+
+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+1];
+ }
+ else{
+ return 0;
+ }
+}
+
+#ifdef USE_INSN_RET_NUM
+static int
+insn_ret_num(VALUE insn)
+{
+ return insn_stack_push_num_info[(int)insn];
+}
+#endif