3 # This script generates C code which emits assembler code for the
4 # assembler ir nodes. It takes a "emit" key from the node specification
5 # and substitutes lines starting with . with a corresponding fprintf().
18 our $finish_line_template = "be_emit_finish_line_gas(emit, node);";
20 my $target_c = $target_dir."/gen_".$arch."_emitter.c";
21 my $target_h = $target_dir."/gen_".$arch."_emitter.h";
24 my @obst_func; # stack for the emit functions
25 my @obst_register; # stack for emitter register code
35 my @tokens = ($template =~ m/[^\%]+|\%[a-zA-Z_][a-zA-Z0-9_]*|\%./g);
36 push(@{$result}, "${indent}be_emit_char(emit, '\t');\n");
39 if (/%\./) { last SWITCH; }
40 if (/%%/) { push(@{$result}, "${indent}be_emit_char(emit, '%');\n"); last SWITCH; }
42 if(defined($emit_templates{$1})) {
43 push(@{$result}, "${indent}$emit_templates{$1}\n");
45 print "Warning: No emit_template defined for '$1'\n";
46 push(@{$result}, "${indent}$1(emit, node);\n");
50 push(@{$result}, "${indent}be_emit_cstring(emit, \"$_\");\n");
53 push(@{$result}, "${indent}${finish_line_template}\n");
58 foreach my $op (keys(%nodes)) {
59 my %n = %{ $nodes{"$op"} };
61 # skip this node description if no emit information is available
62 next if (!defined($n{"emit"}));
64 $line = "static void emit_${arch}_${op}(${arch}_emit_env_t *env, const ir_node *node)";
66 push(@obst_register, " BE_EMIT($op);\n");
68 if($n{"emit"} eq "") {
69 push(@obst_func, $line." {\n");
70 push(@obst_func, "}\n\n");
74 push(@obst_func, $line." {\n");
75 push(@obst_func, "\tbe_emit_env_t *emit = env->emit;\n");
77 my @emit = split(/\n/, $n{"emit"});
79 foreach my $template (@emit) {
80 # substitute only lines, starting with a '.'
81 if ($template =~ /^(\s*)\.\s*(.*)/) {
83 create_emitter(\@obst_func, $indent, $2);
85 push(@obst_func, "\t$template\n");
89 push(@obst_func, "}\n\n");
92 open(OUT, ">$target_h") || die("Could not open $target_h, reason: $!\n");
94 my $creation_time = localtime(time());
99 #ifndef _GEN_$tmp\_EMITTER_H_
100 #define _GEN_$tmp\_EMITTER_H_
103 * Function prototypes for the emitter functions.
104 * DO NOT EDIT THIS FILE, your changes will be lost.
105 * Edit $specfile instead.
106 * created by: $0 $specfile $target_dir
107 * date: $creation_time
111 #include "${arch}_emitter.h"
113 void ${arch}_register_spec_emitters(void);
115 #endif /* _GEN_$tmp\_EMITTER_H_ */
121 open(OUT, ">$target_c") || die("Could not open $target_c, reason: $!\n");
123 $creation_time = localtime(time());
127 * Generated functions to emit code for assembler ir nodes.
128 * DO NOT EDIT THIS FILE, your changes will be lost.
129 * Edit $specfile instead.
130 * created by: $0 $specfile $target_dir
131 * date: $creation_time
141 #include "irprog_t.h"
143 #include "gen_${arch}_emitter.h"
144 #include "${arch}_new_nodes.h"
145 #include "${arch}_emitter.h"
149 print OUT @obst_func;
153 * Enters the emitter functions for handled nodes into the generic
154 * pointer of an opcode.
156 void $arch\_register_spec_emitters(void) {
158 #define BE_EMIT(a) op_$arch\_##a->ops.generic = (op_func)emit_$arch\_##a
160 /* generated emitter functions */
163 print OUT @obst_register;