Commit 11b00882 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

be: Replace generate_emitter.pl by generate_emitter_new.pl.

parent 0a8dac2b
......@@ -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
......
......@@ -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
......
......@@ -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<<EOF;
#define FIRM_BE_${tmp}_GEN_${tmp}_EMITTER_H
#include "irnode.h"
#include "$arch\_emitter.h"
#include "${arch}_emitter.h"
void $arch\_register_spec_emitters(void);
void ${arch}_register_spec_emitters(void);
#endif
......@@ -197,51 +159,58 @@ EOF
close(OUT);
open(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<<EOF;
/**
* \@file
* \@brief Generated functions to emit code for assembler ir nodes.
* \@note DO NOT EDIT THIS FILE, your changes will be lost.
* Edit $specfile instead.
* created by: $0 $specfile $target_dir
* \@date $creation_time
* \@brief Generated functions to emit code for assembler ir nodes.
* \@note DO NOT EDIT THIS FILE, your changes will be lost.
* Edit $specfile instead.
* created by: $0 $specfile $target_dir
* \@date $creation_time
*/
#include "config.h"
#include <stdio.h>
#include <assert.h>
#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<<EOF;
typedef void (*emit_func)(const ir_node *node);
static void ${arch}_register_emitter(ir_op *op, emit_func func)
{
assert(op->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<<EOF;
#undef BE_EMIT
}
EOF
......
#!/usr/bin/perl -w
#
# Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
#
# This file is part of libFirm.
#
# This file may be distributed and/or modified under the terms of the
# GNU General Public License version 2 as published by the Free Software
# Foundation and appearing in the file LICENSE.GPL included in the
# packaging of this file.
#
# Licensees holding valid libFirm Professional Edition licenses may use
# this file in accordance with the libFirm Commercial License.
# Agreement provided with the Software.
#
# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE.
#
# 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().
use strict;
use Data::Dumper;
our $specfile;
our $target_dir;
our $arch;
our %nodes;
our %emit_templates;
our $finish_line_template = "be_emit_finish_line_gas(node);";
our $indent_line_func;
my $target_c = $target_dir."/gen_".$arch."_emitter.c";
my $target_h = $target_dir."/gen_".$arch."_emitter.h";
# stacks for output
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 *node)";
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, "{\n");
push(@obst_func, "\t(void) node;\n");
push(@obst_func, "}\n\n");
next;
}
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 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("Could not open $target_h, reason: $!\n");
my $creation_time = localtime(time());
my $tmp = uc($arch);
print OUT<<EOF;
/**
* \@file
* \@brief Function prototypes for the emitter functions.
* \@note DO NOT EDIT THIS FILE, your changes will be lost.
* Edit $specfile instead.
* created by: $0 $specfile $target_dir
* \@date $creation_time
*/
#ifndef FIRM_BE_${tmp}_GEN_${tmp}_EMITTER_H
#define FIRM_BE_${tmp}_GEN_${tmp}_EMITTER_H
#include "irnode.h"
#include "${arch}_emitter.h"
void ${arch}_register_spec_emitters(void);
#endif
EOF
close(OUT);
open(OUT, ">$target_c") || die("Could not open $target_c, reason: $!\n");
$creation_time = localtime(time());
print OUT<<EOF;
/**
* \@file
* \@brief Generated functions to emit code for assembler ir nodes.
* \@note DO NOT EDIT THIS FILE, your changes will be lost.
* Edit $specfile instead.
* created by: $0 $specfile $target_dir
* \@date $creation_time
*/
#include "config.h"
#include <stdio.h>
#include <assert.h>
#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<<EOF;
typedef void (*emit_func)(const ir_node *node);
static void ${arch}_register_emitter(ir_op *op, emit_func func)
{
assert(op->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<<EOF;
}
EOF
close(OUT);
......@@ -1878,10 +1878,6 @@
RelativePath="..\ir\be\scripts\generate_emitter.pl"
>
</File>
<File
RelativePath="..\ir\be\scripts\generate_emitter_new.pl"
>
</File>
<File
RelativePath="..\ir\be\scripts\generate_machine.pl"
>
......
......@@ -722,7 +722,6 @@ $(FirmRoot)\ir\be\scripts\generate_machine.pl %(FullPath) $(FirmRoot)\ir\be\TEMP
<None Include="$(FirmRoot)\scripts\spec_util.py"/>
<None Include="$(FirmRoot)\scripts\statev_sql.py"/>
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter.pl"/>
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter_new.pl"/>
<None Include="$(FirmRoot)\ir\be\scripts\generate_machine.pl"/>
<None Include="$(FirmRoot)\ir\be\scripts\generate_new_opcodes.pl"/>
<None Include="$(FirmRoot)\ir\be\scripts\generate_regalloc_if.pl"/>
......
......@@ -1869,9 +1869,6 @@
<None Include="$(FirmRoot)\scripts\statev_sql.py">
<Filter>scripts</Filter>
</None>
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter_new.pl">
<Filter>ir\be\scripts</Filter>
</None>
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter.pl">
<Filter>ir\be\scripts</Filter>
</None>
......@@ -3579,9 +3576,6 @@
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter.pl">
<Filter>ir\be\scripts</Filter>
</None>
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter_new.pl">
<Filter>ir\be\scripts</Filter>
</None>
<None Include="$(FirmRoot)\ir\be\scripts\generate_machine.pl">
<Filter>ir\be\scripts</Filter>
</None>
......@@ -5250,9 +5244,6 @@
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter.pl">
<Filter>ir\be\scripts</Filter>
</None>
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter_new.pl">
<Filter>ir\be\scripts</Filter>
</None>
<None Include="$(FirmRoot)\ir\be\scripts\generate_machine.pl">
<Filter>ir\be\scripts</Filter>
</None>
......@@ -6918,9 +6909,6 @@
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter.pl">
<Filter>ir\be\scripts</Filter>
</None>
<None Include="$(FirmRoot)\ir\be\scripts\generate_emitter_new.pl">
<Filter>ir\be\scripts</Filter>
</None>
<None Include="$(FirmRoot)\ir\be\scripts\generate_machine.pl">
<Filter>ir\be\scripts</Filter>
</None>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment