From 11b00882d8ddbf207c31565a51030408c8fd646b Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Thu, 29 Nov 2012 13:17:28 +0100 Subject: [PATCH] be: Replace generate_emitter.pl by generate_emitter_new.pl. --- Makefile | 3 +- ir/Makefile.am | 1 - ir/be/scripts/generate_emitter.pl | 195 ++++++++++-------------- ir/be/scripts/generate_emitter_new.pl | 208 -------------------------- vc2005/libfirm.vcproj | 4 - win32/vc2010/firm.vcxproj | 1 - win32/vc2010/firm.vcxproj.filters | 12 -- 7 files changed, 83 insertions(+), 341 deletions(-) delete mode 100755 ir/be/scripts/generate_emitter_new.pl diff --git a/Makefile b/Makefile index b5f27dd57..3929e5dc3 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,6 @@ firm: $(libfirm_dll) backends = amd64 arm ia32 sparc TEMPLATE EMITTER_GENERATOR = $(srcdir)ir/be/scripts/generate_emitter.pl -EMITTER_GENERATOR2 = $(srcdir)ir/be/scripts/generate_emitter_new.pl REGALLOC_IF_GENERATOR = $(srcdir)ir/be/scripts/generate_regalloc_if.pl OPCODES_GENERATOR = $(srcdir)ir/be/scripts/generate_new_opcodes.pl @@ -112,7 +111,7 @@ $(1)_GEN_HEADERS = $(1)_SPEC = ir/be/$(1)/$(1)_spec.pl -$$(srcdir)ir/be/$(1)/gen_$(1)_emitter.h $$(srcdir)ir/be/$(1)/gen_$(1)_emitter.c: $$($(1)_SPEC) $$(EMITTER_GENERATOR) $(EMITTER_GENERATOR2) +$$(srcdir)ir/be/$(1)/gen_$(1)_emitter.h $$(srcdir)ir/be/$(1)/gen_$(1)_emitter.c: $$($(1)_SPEC) $$(EMITTER_GENERATOR) @echo GEN $$@ $(Q)$$(EMITTER_GENERATOR) $$($(1)_SPEC) $$(srcdir)ir/be/$(1) $(1)_SOURCES += ir/be/$(1)/gen_$(1)_emitter.c diff --git a/ir/Makefile.am b/ir/Makefile.am index e4a53f85b..e2846ef6c 100644 --- a/ir/Makefile.am +++ b/ir/Makefile.am @@ -413,7 +413,6 @@ EXTRA_DIST = \ ir/gen_irnode.c.inl \ ir/gen_irdump.c.inl \ adt/hashset.c.inl \ - be/scripts/generate_emitter_new.pl \ be/scripts/generate_emitter.pl \ be/scripts/generate_new_opcodes.pl \ be/scripts/generate_regalloc_if.pl diff --git a/ir/be/scripts/generate_emitter.pl b/ir/be/scripts/generate_emitter.pl index 12c780bde..8f1181aca 100755 --- a/ir/be/scripts/generate_emitter.pl +++ b/ir/be/scripts/generate_emitter.pl @@ -22,23 +22,18 @@ # This script generates C code which emits assembler code for the # assembler ir nodes. It takes a "emit" key from the node specification # and substitutes lines starting with . with a corresponding fprintf(). -# Creation: 2005/11/07 use strict; use Data::Dumper; -use File::Basename; -my $myname = $0; our $specfile = $ARGV[0]; our $target_dir = $ARGV[1]; our $arch; -our $comment_string = "/*"; -our $comment_string_end = "*/" ; our %nodes; -our $new_emit_syntax = 1; - -# include spec file +our %emit_templates; +our $finish_line_template = "be_emit_finish_line_gas(node);"; +our $indent_line_func; my $return; @@ -50,18 +45,6 @@ unless ($return = do $specfile) { } use strict "subs"; -if ($new_emit_syntax) { - my $newscript = dirname($myname) . "/generate_emitter_new.pl"; - unless ($return = do "$newscript") { - die "Fatal error: couldn't parse $newscript: $@" if $@; - die "Fatal error: couldn't do $newscript: $!" unless defined $return; - die "Fatal error: couldn't run $newscript" unless $return; - } - exit; -} - -my $comment_string_quoted = quotemeta($comment_string); - my $target_c = $target_dir."/gen_".$arch."_emitter.c"; my $target_h = $target_dir."/gen_".$arch."_emitter.h"; @@ -70,105 +53,84 @@ my @obst_func; # stack for the emit functions my @obst_register; # stack for emitter register code my $line; +sub create_emitter { + my $result = shift; + my $indent = shift; + my $template = shift; + our %emit_templates; + our $arch; + + if (!defined($indent_line_func)) { + $template = "\\t" . $template; + } else { + push(@{$result}, "${indent}${indent_line_func};\n"); + } + + my @tokens = ($template =~ m/(?:[^%]|%%)+|\%[a-zA-Z_][a-zA-Z0-9_]*|%\./g); + for (@tokens) { + SWITCH: { + if (/%\./) { last SWITCH; } + if (/^%([^%]+)/) { + if(defined($emit_templates{$1})) { + push(@{$result}, "${indent}$emit_templates{$1}\n"); + } else { + print "Warning: No emit_template defined for '$1'\n"; + push(@{$result}, "${indent}$1(node);\n"); + } + last SWITCH; + } + $_ =~ s/%%/%/g; + if (length($_) == 1) { + push(@{$result}, "${indent}be_emit_char('$_');\n"); + } else { + push(@{$result}, "${indent}be_emit_cstring(\"$_\");\n"); + } + } + } + push(@{$result}, "${indent}${finish_line_template}\n"); +} + + + foreach my $op (keys(%nodes)) { my %n = %{ $nodes{"$op"} }; # skip this node description if no emit information is available next if (!defined($n{"emit"})); - $line = "static void emit_".$arch."_".$op."(const ir_node *n, $arch\_emit_env_t *env)"; + $line = "static void emit_${arch}_${op}(const ir_node *node)"; - push(@obst_register, " BE_EMIT($op);\n"); + push(@obst_register, " ${arch}_register_emitter(op_${arch}_${op}, emit_${arch}_${op});\n"); if($n{"emit"} eq "") { - push(@obst_func, $line." {\n"); + push(@obst_func, $line."\n"); + push(@obst_func, "{\n"); + push(@obst_func, "\t(void) node;\n"); push(@obst_func, "}\n\n"); next; } - push(@obst_func, $line." {\n FILE *F = env->out;\n"); - push(@obst_func, " char cmd_buf[256], cmnt_buf[256];\n"); - push(@obst_func, " const lc_arg_env_t *arg_env = $arch\_get_arg_env();\n\n"); + push(@obst_func, $line."\n"); + push(@obst_func, "{\n"); + my @emit = split(/\n/, $n{"emit"}); foreach my $template (@emit) { # substitute only lines, starting with a '.' - if ($template =~ /^(\d*)\.\s*/) { - my $indent = " "; # default indent is 2 spaces - - $indent = " " x $1 if ($1 && $1 > 0); - # remove indent, dot and trailing spaces - $template =~ s/^\d*\.\s*//; - my $fmt = $template; - my $cnt = 0; - my $buf = 'cmd_buf'; - - push(@obst_func, $indent."cmnt_buf[0] = '\\0';\n"); - foreach $template (split(/$comment_string_quoted/, $fmt, 2)) { - my @params; - my $res = ""; - $cnt++; - - $template =~ s/(\\t)*$//; - - if ($cnt == 2) { - # add the comment begin string - $res .= $comment_string; - $buf = "cmnt_buf"; - } - - # substitute all format parameter - while ($template =~ /(\%\%)|\%([ASDX])(\d)|\%([COM])|\%(\w+)/) { - $res .= $`; # get everything before the match - - if ($1) { - $res .= "%%"; - } - elsif ($2 && $2 eq "S") { - push(@params, "n"); - $res .= "%".$3."S"; # substitute %Sx with %xS - } - elsif ($2 && $2 eq "D") { - push(@params, "n"); - $res .= "%".$3."D"; # substitute %Dx with %xD - } - elsif ($2 && $2 eq "X") { - push(@params, "n"); - $res .= "%".$3."X"; # substitute %Xx with %xX - } - elsif ($2 && $2 eq "A") { - push(@params, "get_irn_n(n, ".($3 - 1).")"); - $res .= "%+F"; - } - elsif ($4) { - push(@params, "n"); - $res .= "%".$4; - } - elsif ($5) { # backend provided function to call, has to return a string - push(@params, $5."(n, env)"); - $res .= "\%s"; - } - - $template = $'; # scan everything after the match - } - $res .= $template; # get the remaining string - - my $parm = ""; - $parm = ", ".join(", ", @params) if (@params); - - push(@obst_func, $indent.'lc_esnprintf(arg_env, '.$buf.', 256, "'.$res.'"'.$parm.');'."\n"); - } - push(@obst_func, $indent.'lc_efprintf(arg_env, F, "\t%-35s %-60s '.$comment_string.' %+F (%+G) '.$comment_string_end.'\n", cmd_buf, cmnt_buf, n, n);'."\n"); - } - else { - push(@obst_func, $template,"\n"); + if ($template eq '') { + # nothing + } elsif ($template =~ /^(\s*)\.\s*(.*)/) { + my $indent = "\t$1"; + create_emitter(\@obst_func, $indent, $2); + } else { + push(@obst_func, "\t${arch}_emitf(node, \"$template\");\n"); } } push(@obst_func, "}\n\n"); } -open(OUT, ">$target_h") || die("Fatal error: Could not open $target_h, reason: $!\n"); +open(OUT, ">$target_h") || die("Could not open $target_h, reason: $!\n"); my $creation_time = localtime(time()); @@ -187,9 +149,9 @@ print OUT<$target_c") || die("Fatal error: Could not open $target_c, reason: $!\n"); +open(OUT, ">$target_c") || die("Could not open $target_c, reason: $!\n"); $creation_time = localtime(time()); print OUT< +#include #include "irnode.h" #include "irop_t.h" #include "irprog_t.h" +#include "beemitter.h" -#include "gen_$arch\_emitter.h" -#include "$arch\_new_nodes.h" +#include "gen_${arch}_emitter.h" +#include "${arch}_new_nodes.h" +#include "${arch}_emitter.h" EOF print OUT @obst_func; print OUT<ops.generic == NULL); + op->ops.generic = (op_func)func; +} + /** * Enters the emitter functions for handled nodes into the generic * pointer of an opcode. */ -void $arch\_register_spec_emitters(void) { - -#define BE_EMIT(a) op_$arch\_##a->ops.generic = (op_func)emit_$arch\_##a - - /* generated emitter functions */ +void $arch\_register_spec_emitters(void) +{ EOF print OUT @obst_register; print OUT<$target_h") || die("Could not open $target_h, reason: $!\n"); - -my $creation_time = localtime(time()); - -my $tmp = uc($arch); - -print OUT<$target_c") || die("Could not open $target_c, reason: $!\n"); - -$creation_time = localtime(time()); - -print OUT< -#include - -#include "irnode.h" -#include "irop_t.h" -#include "irprog_t.h" -#include "beemitter.h" - -#include "gen_${arch}_emitter.h" -#include "${arch}_new_nodes.h" -#include "${arch}_emitter.h" - -EOF - -print OUT @obst_func; - -print OUT<ops.generic == NULL); - op->ops.generic = (op_func)func; -} - -/** - * Enters the emitter functions for handled nodes into the generic - * pointer of an opcode. - */ -void $arch\_register_spec_emitters(void) -{ -EOF - -print OUT @obst_register; - -print OUT< - - diff --git a/win32/vc2010/firm.vcxproj b/win32/vc2010/firm.vcxproj index 34e769970..76607c12c 100644 --- a/win32/vc2010/firm.vcxproj +++ b/win32/vc2010/firm.vcxproj @@ -722,7 +722,6 @@ $(FirmRoot)\ir\be\scripts\generate_machine.pl %(FullPath) $(FirmRoot)\ir\be\TEMP - diff --git a/win32/vc2010/firm.vcxproj.filters b/win32/vc2010/firm.vcxproj.filters index 9c09f7d50..4eeaec5fd 100644 --- a/win32/vc2010/firm.vcxproj.filters +++ b/win32/vc2010/firm.vcxproj.filters @@ -1869,9 +1869,6 @@ scripts - - ir\be\scripts - ir\be\scripts @@ -3579,9 +3576,6 @@ ir\be\scripts - - ir\be\scripts - ir\be\scripts @@ -5250,9 +5244,6 @@ ir\be\scripts - - ir\be\scripts - ir\be\scripts @@ -6918,9 +6909,6 @@ ir\be\scripts - - ir\be\scripts - ir\be\scripts -- 2.20.1