And now, with the patch

Michael
-- 
Michael Fischer                         7.5 million years to run
[EMAIL PROTECTED]                        printf "%d", 0x2a;
                                                -- deep thought 
diff -ur parrot/Configure.pl dispatcher-11-04/Configure.pl
--- parrot/Configure.pl Fri Nov  2 07:11:15 2001
+++ dispatcher-11-04/Configure.pl       Sun Nov  4 12:26:21 2001
@@ -91,6 +91,8 @@
        numlow =>       '(~0xfff)',
        strlow =>       '(~0xfff)',
        pmclow =>       '(~0xfff)',
+
+        do_op_t =>      'func',
        
        platform =>     'linux',
        cp =>           'cp',
@@ -118,6 +120,16 @@
 prompt("How big would you like integers to be?", 'iv');
 prompt("And your floats?", 'nv');
 prompt("What is your native opcode type?", 'opcode_t');
+prompt("Opcode dispatch by switch or function ('switch' or 'goto' or 'func')",
+        'do_op_t');
+
+if ($c{do_opt_t} eq 'goto' and $c{cc} !~ /gcc/i ) {
+        my $not_portable =  "
+'goto' opcode dispatch available only with gcc (for now).
+Please rerun and select either 'func' or 'switch'. Sorry\n";
+        die $not_portable;
+}
+
 
 unless( $c{debugging} ) {
        $c{ld_debug} = ' ';
diff -ur parrot/Makefile.in dispatcher-11-04/Makefile.in
--- parrot/Makefile.in  Fri Nov  2 07:11:15 2001
+++ dispatcher-11-04/Makefile.in        Sun Nov  4 12:26:15 2001
@@ -29,6 +29,7 @@
 PERL = ${perl}
 TEST_PROG = test_prog${exe}
 PDUMP = pdump${exe}
+DO_OP_T = ${do_op_t}
 
 .c$(O):
        $(CC) $(CFLAGS) ${ld_out}$@ -c $<
@@ -104,13 +105,13 @@
 core_ops$(O): $(H_FILES) core_ops.c
 
 core_ops.c $(INC)/oplib/core_ops.h: core.ops ops2c.pl
-       $(PERL) ops2c.pl core.ops
+       $(PERL) ops2c.pl -t $(DO_OP_T) core.ops
 
 vtable.ops: make_vtable_ops.pl
        $(PERL) make_vtable_ops.pl > vtable.ops
 
 vtable_ops.c $(INC)/oplib/vtable_ops.h: vtable.ops ops2c.pl
-       $(PERL) ops2c.pl vtable.ops
+       $(PERL) ops2c.pl -t $(DO_OP_T) vtable.ops
 
 $(INC)/config.h: Configure.pl config_h.in
        $(PERL) Configure.pl
diff -ur parrot/interpreter.c dispatcher-11-04/interpreter.c
--- parrot/interpreter.c        Fri Oct 26 14:58:02 2001
+++ dispatcher-11-04/interpreter.c      Sun Nov  4 12:26:32 2001
@@ -11,7 +11,6 @@
  */
 
 #include "parrot/parrot.h"
-#include "parrot/interp_guts.h"
 #include "parrot/oplib/core_ops.h"
 #include "parrot/runops_cores.h"
 
diff -ur parrot/ops2c.pl dispatcher-11-04/ops2c.pl
--- parrot/ops2c.pl     Wed Oct 17 20:21:03 2001
+++ dispatcher-11-04/ops2c.pl   Sun Nov  4 12:26:39 2001
@@ -1,15 +1,26 @@
 #! /usr/bin/perl -w
+
+#  vim: expandtab shiftwidth=4 ts=4:
 #
 # ops2c.pl
 #
-# Generate a C header and source file from the operation definitions in
+# Generate a C header and source file from the operation definitions in,
 # an .ops file.
 #
 
 use strict;
 use Parrot::OpsFile;
+use Getopt::Std;
+
+use vars qw($opt_t);
+getopts('t:');
 
+die "You didn't specifiy how you want DO_OP written!\n
+Use the -t ['func' | 'switch' | 'goto' ] flag, please\n" 
+unless $opt_t eq 'func' or $opt_t eq 'switch' or $opt_t eq 'goto';
 
+my $dispatch = $opt_t;
+  
 #
 # Process command-line argument:
 #
@@ -106,19 +117,49 @@
 #
 
 my @op_funcs;
+
+my %switch;
+my %goto;
+
 my $index = 0;
 
+my @switch_source_subs = (                            
+    \&map_ret_abs_switch,
+    \&map_ret_rel_switch,
+    \&map_arg_switch,
+    \&map_res_abs_switch,
+    \&map_res_rel_switch
+    );    
+my @goto_source_subs = (
+    \&map_ret_abs_goto,   
+    \&map_ret_rel_goto,   
+    \&map_arg_switch,
+    \&map_res_abs_goto,
+    \&map_res_rel_goto
+    );
+my @func_source_subs = (
+    \&map_ret_abs,
+    \&map_ret_rel,
+    \&map_arg,
+    \&map_res_abs,
+    \&map_res_rel);    
+
 foreach my $op ($ops->ops) {
     my $func_name  = $op->func_name;
     my $arg_types  = "opcode_t *, struct Parrot_Interp *";
     my $prototype  = "opcode_t * $func_name ($arg_types)";
     my $args       = "opcode_t cur_opcode[], struct Parrot_Interp * interpreter";
     my $definition = "opcode_t *\n$func_name ($args)";
-    my $source     = $op->source(\&map_ret_abs, \&map_ret_rel, \&map_arg, 
\&map_res_abs, \&map_res_rel);
-
+    my $source     = $op->source(@func_source_subs);
+    my $sw_source  = $op->source(@switch_source_subs);
+    my $gt_source  = $op->source(@goto_source_subs);
     print HEADER "$prototype;\n";
     print SOURCE sprintf("  %-22s /* %6ld */\n", "$func_name,", $index++);
 
+    my $idx = $op->{CODE};
+    $switch{$idx} = "{\n$sw_source}\n";
+    $goto{$func_name}   = "{\n$gt_source\ngoto *goto_map[*pc];\n}\n\n";    
+    
     push @op_funcs, "$definition {\n$source}\n\n";
 }
 
@@ -139,6 +180,82 @@
 
 print SOURCE @op_funcs;
 
+#
+# if we are working on core.ops, worry about switch/goto
+# if we are working on vtable, skip it...
+#
+
+if ( $file !~ /vtable/ ) {
+
+    #my $do_op_header = "include/parrot/do_op.h";
+    my $do_op_header = "include/parrot/do_op.h";
+
+    open DO_OP_H, ">$do_op_header"
+        or die "Couldn't write to $do_op_header: $!\n";
+
+    print DO_OP_H <<END;
+$preamble
+#ifndef DO_OP_H
+#define DO_OP_H
+
+#include <math.h>
+#include<sys/time.h>
+END
+
+    if ($dispatch eq 'switch' ) {
+
+        print DO_OP_H "#define DO_OP(pc,interpreter) do { \\\n";
+        print DO_OP_H "switch(*pc) {  \\\n";
+
+        for my $label (sort {$a <=> $b} keys %switch) {
+            $switch{$label} =~ s/\n/  \\\n/g;
+            # stupid way cur_opcode survives in bsr_i and bsr_ic
+            $switch{$label} =~ s/cur_opcode/pc/;
+            print DO_OP_H "case $label: \\\n", "$switch{$label}";    
+        }
+
+        print DO_OP_H "} \\\n";
+        print DO_OP_H "} while(0);\n"
+    }
+
+    elsif ($dispatch eq 'goto') {
+        print DO_OP_H "void goto_op_dispatch(opcode_t * pc, struct Parrot_Interp * 
+interpreter)\n{\n";
+        print DO_OP_H "\n";
+        
+        print DO_OP_H "const static void * goto_map[] = {\n";
+        for my $label (keys %goto) {
+           print DO_OP_H "&&" . "$label,\n";
+        }    
+        print DO_OP_H "};\n"; # close the array
+        
+        # print goto setup
+        print DO_OP_H "while (1) {\n\n";
+        print DO_OP_H "goto *goto_map[*pc];\n";
+
+        for my $label (keys %goto) {
+            print DO_OP_H "$label:\n";
+            # stupid way cur_opcode survives in bsr_i and bsr_ic
+            $goto{$label} =~ s/cur_opcode/pc/;
+            print DO_OP_H "$goto{$label}\n";
+            # map funcs should turn 'returns' into pc += 4, etc.
+            # print DO_OP_H "goto *goto_map[*pc];\n";
+        }
+        # close the function
+        print DO_OP_H "} /* end while(1) */ \n} /* end goto_op_dispatch */\n\n";
+         
+       print DO_OP_H "#define DO_OP(pc,interpreter) 
+goto_op_dispatch((pc),(interpreter))\n";
+        
+    }
+    else { # regular function pointer dispatch
+        print DO_OP_H "
+        #define DO_OP(PC,INTERP) PC = ((INTERP->opcode_funcs)[*PC])(PC,INTERP);
+        ";
+    }
+
+    print DO_OP_H "#endif /* DO_OP_H */\n";
+    close DO_OP_H;
+
+} # end if ( we are doing core.ops )
 
 #
 # Op Info Table:
@@ -190,24 +307,45 @@
 #
 # map_ret_abs()
 #
-
 sub map_ret_abs
 {
   my ($addr) = @_;
   return "return $addr";
 }
 
+sub map_ret_abs_switch
+{
+    my ($addr) = @_;
+    return "pc = $addr;\nbreak;\n";     
+}
+
+sub map_ret_abs_goto
+{
+    my ($addr) = @_;
+    return "pc = $addr;\n";     
+}
 
 #
 # map_ret_rel()
 #
-
 sub map_ret_rel
 {
   my ($offset) = @_;
   return "return cur_opcode + $offset";
 }
 
+sub map_ret_rel_switch
+{
+    my ($offset) = @_;
+    return "pc += $offset;\nbreak;\n";    
+}
+
+sub map_ret_rel_goto
+{
+    my ($offset) = @_;
+    return "pc += $offset;\n";    
+}
+
 
 #
 # map_arg()
@@ -236,26 +374,67 @@
   return sprintf($arg_maps{$type}, $num);
 }
 
+sub map_arg_switch
+{
+  my ($type, $num) = @_;
+
+  my %arg_maps = (
+    'op' => "pc[%ld]",
+
+    'i'  => "interpreter->int_reg->registers[pc[%ld]]",
+    'n'  => "interpreter->num_reg->registers[pc[%ld]]",
+    'p'  => "interpreter->pmc_reg->registers[pc[%ld]]",
+    's'  => "interpreter->string_reg->registers[pc[%ld]]",
+  
+    'ic' => "pc[%ld]",
+    'nc' => "interpreter->code->const_table->constants[pc[%ld]]->number",
+    'pc' => "%ld /* ERROR: Don't know how to handle PMC constants yet! */",
+    'sc' => "interpreter->code->const_table->constants[pc[%ld]]->string",
+  );
 
+  die "Unrecognized type '$type' for num '$num'" unless exists $arg_maps{$type};
+  return sprintf($arg_maps{$type}, $num);
+}
 #
 # map_res_rel()
 #
-
 sub map_res_rel
 {
   my ($offset) = @_;
   return "interpreter->resume_addr = cur_opcode + $offset";
 }
 
+sub map_res_rel_switch
+{
+  my ($offset) = @_;
+  return "interpreter->resume_addr =  pc + $offset;\nbreak;\n";
+}
+
+
+sub map_res_rel_goto
+{
+  my ($offset) = @_;
+  return "interpreter->resume_addr =  pc + $offset;\n";
+}
+
 
 #
 # map_res_abs()
 #
-
 sub map_res_abs
 {
   my ($addr) = @_;
   return "interpreter->resume_addr = $addr";
 }
 
+sub map_res_abs_swich
+{
+  my ($addr) = @_;
+  return "interpreter->resume_addr = $addr;\nbreak;\n";
+}
 
+sub map_res_abs_goto
+{
+  my ($addr) = @_;
+  return "interpreter->resume_addr = $addr;\n";
+}
diff -ur parrot/runops_cores.c dispatcher-11-04/runops_cores.c
--- parrot/runops_cores.c       Thu Oct 18 21:43:00 2001
+++ dispatcher-11-04/runops_cores.c     Sun Nov  4 12:26:27 2001
@@ -12,7 +12,7 @@
 
 #include "parrot/runops_cores.h"
 
-#include "parrot/interp_guts.h"
+#include "parrot/do_op.h"
 
 const runops_core_f runops_cores[8] = {
   runops_t0p0b0_core,

Reply via email to