#! /usr/bin/env perl # # This file is part of libFirm. # Copyright (C) 2014 University of Karlsruhe. # # This script generates C code which emits assembler code for the # assembler ir nodes. It takes a "emit" key from the node specification # and generates ${arch}_emitf() calls for them. use strict; use warnings; our $specfile = $ARGV[0]; our $target_dir = $ARGV[1]; our $arch; our %nodes; unless (my $return = do "${specfile}") { die "Fatal error: couldn't parse $specfile: $@" if $@; die "Fatal error: couldn't do $specfile: $!" unless defined $return; die "Fatal error: couldn't run $specfile" unless $return; } # buffers for output my $obst_func = ""; # buffer for the emit functions my $obst_register = ""; # buffer for emitter register code my $obst_register_binary = ""; # buffer for emitter register code foreach my $op (sort(keys(%nodes))) { my $n = $nodes{$op}; my $emit = $n->{emit}; if (!defined($emit) && defined($n->{template})) { $emit = $n->{template}->{emit}; } if (defined($emit)) { my $emit_func; if ($emit eq "") { $emit_func = "be_emit_nothing"; } else { $emit_func = "emit_${arch}_$op"; $obst_func .= "static void $emit_func(ir_node const *const node)\n"; $obst_func .= "{\n"; my $name = $n->{name} // lc($op); $emit =~ s/{name}/$name/g; $emit =~ s/\n/\\n/g; $obst_func .= "\t${arch}_emitf(node, \"$emit\");\n"; $obst_func .= "}\n\n"; } $obst_register .= "\tbe_set_emitter(op_${arch}_$op, $emit_func);\n"; } my $encode = $n->{encode}; if (defined($encode)) { my $emit_func; if ($encode eq "") { $emit_func = "be_emit_nothing"; } else { $emit_func = "enc_${arch}_$op"; $obst_func .= "static void $emit_func(ir_node const *const node)\n"; $obst_func .= "{\n"; $obst_func .= "\t(void)node; /* avoid potential warning */\n"; $obst_func .= "\t${encode};\n"; $obst_func .= "}\n\n"; } $obst_register_binary .= "\tbe_set_emitter(op_${arch}_$op, $emit_func);\n"; } } my $creation_time = localtime(time()); sub create_with_header { my ($name, $brief) = @_; open(my $out, ">", $name) // die("Could not open $name, reason: $!\n"); print $out <