summaryrefslogtreecommitdiffhomepage
path: root/ir/be/beemitter.c
diff options
context:
space:
mode:
authorChristoph Mallon <mallon@cs.uni-saarland.de>2015-02-16 08:10:31 +0100
committerChristoph Mallon <mallon@cs.uni-saarland.de>2015-04-29 08:20:07 +0200
commit94dd895c50855ae5200bf0876ce04f530e829f67 (patch)
tree6f1c87827915b354a845563ff01957f836323d55 /ir/be/beemitter.c
parent156f217b7b36650af73177714f62a6f49374e3d3 (diff)
be: Factorise the code to emit an asm node and use a callback for each backend to output the operands.
Diffstat (limited to 'ir/be/beemitter.c')
-rw-r--r--ir/be/beemitter.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/ir/be/beemitter.c b/ir/be/beemitter.c
index b3dbff5..6c550e2 100644
--- a/ir/be/beemitter.c
+++ b/ir/be/beemitter.c
@@ -9,6 +9,9 @@
* @author Matthias Braun
* @date 12.03.2007
*/
+#include <ctype.h>
+
+#include "bediagnostic.h"
#include "bedwarf.h"
#include "beemitter.h"
#include "benode.h"
@@ -103,3 +106,47 @@ void be_emit_node(ir_node const *const node)
DEBUG_ONLY(if (!emit) panic("no emit handler for node %+F (%+G, graph %+F)", node, node, get_irn_irg(node));)
emit(node);
}
+
+void be_emit_asm(ir_node const *const asmn, ident *const text, unsigned const n_operands, be_emit_asm_operand_func *const emit_asm_operand)
+{
+ be_emit_cstring("#APP");
+ be_emit_finish_line_gas(asmn);
+
+ char const *s = get_id_str(text);
+ if (s[0] != '\t')
+ be_emit_char('\t');
+
+ char const *last = s;
+ while ((s = strchr(s, '%'))) {
+ be_emit_string_len(last, s - last);
+ ++s; /* Skip '%'. */
+ switch (*s) {
+ case '%':
+ be_emit_char(*s++);
+ break;
+
+ default: {
+ char const modifier = isalpha((unsigned char)*s) ? *s++ : '\0';
+ unsigned pos;
+ int p;
+ if (sscanf(s, "%u%n", &pos, &p) == 1) {
+ s += p;
+ if (pos < n_operands) {
+ emit_asm_operand(asmn, modifier, pos);
+ } else {
+ be_errorf(asmn, "asm operand number '%u' out of range", pos);
+ }
+ } else {
+ be_errorf(asmn, "could not parse asm operand number");
+ }
+ break;
+ }
+ }
+
+ last = s;
+ }
+ be_emit_string(last);
+
+ be_emit_cstring("\n#NO_APP\n");
+ be_emit_write_line();
+}