From ad8368234bf59eb46fbc0cfff5b7322a7efac964 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20W=C3=BCrdig?= Date: Tue, 8 Nov 2005 17:00:49 +0000 Subject: [PATCH] generate emitter functions from spec --- ir/be/scripts/generate_emitter.pl | 135 ++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100755 ir/be/scripts/generate_emitter.pl diff --git a/ir/be/scripts/generate_emitter.pl b/ir/be/scripts/generate_emitter.pl new file mode 100755 index 000000000..dc4274ceb --- /dev/null +++ b/ir/be/scripts/generate_emitter.pl @@ -0,0 +1,135 @@ +#!/usr/bin/perl -w + +# 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 +# $Id$ + +use strict; +use Data::Dumper; + +my $specfile = $ARGV[0]; +my $target_dir = $ARGV[1]; + +my $target_c = $target_dir."/emitter_gen.c"; +my $target_h = $target_dir."/emitter_gen.h"; + +our $arch; +our %nodes; + +# include spec file + +my $return; + +no strict "subs"; +unless ($return = do $specfile) { + warn "couldn't parse $specfile: $@" if $@; + warn "couldn't do $specfile: $!" unless defined $return; + warn "couldn't run $specfile" unless $return; +} +use strict "subs"; + +# stacks for output +my @obst_func; # stack for the emit functions +my @obst_header; # stack for the function prototypes + +my $line; + +foreach my $op (keys(%nodes)) { + my %n = %{ $nodes{"$op"} }; + + # skip this node description if no emit information is available + next if (!$n{"emit"} || length($n{"emit"}) < 1); + + $line = "void emit_".$arch."_".$op."(FILE *F, ir_node *n)"; + push(@obst_header, $line.";\n"); + push(@obst_func, $line." {\n"); + + my @emit = split(/\n/, $n{"emit"}); + + foreach(@emit) { + # substitute only lines, starting with a '.' + if (/^(\d*)\.\s*/) { + my @params; + my $regkind; + my $indent = " "; # default indent is 2 spaces + + $indent = " " x $1 if ($1 && $1 > 0); + # remove indent, dot and trailing spaces + s/^\d*\.\s*//; + # substitute all format parameter + while (/%(([sd])(\d)|([co]))/) { + if ($4 && $4 eq "c") { + push(@params, "node_const_to_str(n)"); + } + elsif ($4 && $4 eq "o") { + push(@params, "node_offset_to_str(n)"); + } + else { + $regkind = ($2 eq "s" ? "source" : "dest"); + push(@params, "get_".$regkind."_reg(n, $3)"); + } + s/%$1/%%\%s/; + } + my $parm = ""; + $parm = ", ".join(", ", @params) if (@params); + push(@obst_func, $indent.'fprintf(F, "\t'.$_.'\n"'.$parm.');'."\n"); + } + else { + push(@obst_func, $_,"\n"); + } + } + push(@obst_func, "}\n\n"); +} + +open(OUT, ">$target_h") || die("Could not open $target_h, reason: $!\n"); + +my $creation_time = localtime(time()); + +print OUT<$target_c") || die("Could not open $target_c, reason: $!\n"); + +$creation_time = localtime(time()); + +print OUT< + +#include "irnode.h" +#include "emitter_gen.h" +#include "emitter.h" + +EOF + +print OUT @obst_func; + +close(OUT); -- 2.20.1