summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChristoph Mallon <mallon@cs.uni-saarland.de>2015-06-09 07:33:11 +0200
committerChristoph Mallon <christoph.mallon@gmx.de>2019-04-05 21:05:50 +0200
commit3ec27c3c9a1e7d3addca3d7c0d7723e24765d3ec (patch)
treed7836558a01caa9e77a3de3bcf4018e20e81ff4e
parent45f3ce90844e9f6efb3815cb4ab98b1971f55aa0 (diff)
Support 'asm goto'.
-rw-r--r--NEWS.md1
m---------libfirm0
-rw-r--r--src/firm/ast2firm.c34
-rw-r--r--src/parser/parser.c2
4 files changed, 36 insertions, 1 deletions
diff --git a/NEWS.md b/NEWS.md
index 613b056..b097862 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -20,6 +20,7 @@ cparser 1.22.1 (2016-01-23)
* Accept asm qualifiers in arbitrary order
* Accept (and ignore) the asm qualifier `inline`
* The target triple can also be set by prefixing the executable name, e.g. `x86_64-unknown-elf-cparser`
+* Support `asm goto`; even allow output constraints, which gcc and clang do not
* Bugfixes
cparser 1.22.0 (2015-12-31)
diff --git a/libfirm b/libfirm
-Subproject 80146aaacf50c17449e07b8aac0000e5267aed5
+Subproject b405d397f43ac08df63dd838152b0301f6c201a
diff --git a/src/firm/ast2firm.c b/src/firm/ast2firm.c
index 1559f6e..fdf0063 100644
--- a/src/firm/ast2firm.c
+++ b/src/firm/ast2firm.c
@@ -4546,6 +4546,14 @@ typedef struct out_info {
ir_node *proj;
} out_info;
+static void asm_make_target(ir_node *const asmn, unsigned const pos)
+{
+ ir_node *const proj = new_Proj(asmn, mode_X, pos);
+ ir_node *const in[] = { proj };
+ ir_node *const block = new_Block(ARRAY_SIZE(in), in);
+ set_cur_block(block);
+}
+
static void asm_set_values(out_info const *const outs)
{
for (size_t i = 0, n = ARR_LEN(outs); i < n; ++i) {
@@ -4653,6 +4661,19 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
ARR_APP1(ir_asm_constraint, constraints, constraint);
}
+ {
+ size_t label_pos = pn_ASM_first_out + ARR_LEN(outs);
+ for (entity_t const *l = statement->labels; l; l = l->base.next) {
+ ir_asm_constraint const c = {
+ .in_pos = -1,
+ .out_pos = label_pos++,
+ .constraint = NULL,
+ .mode = mode_X,
+ };
+ ARR_APP1(ir_asm_constraint, constraints, c);
+ }
+ }
+
ir_node *mem = needs_memory ? get_store() : new_NoMem();
size_t const n_ins = ARR_LEN(ins);
@@ -4661,6 +4682,8 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
ir_cons_flags flags = cons_none;
if (!statement->is_volatile)
flags |= cons_floats;
+ if (statement->labels)
+ flags |= cons_throws_exception;
/* create asm node */
dbg_info *dbgi = get_dbg_info(&statement->base.pos);
@@ -4681,6 +4704,17 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
outs[i].proj = new_Proj(node, mode, out_pos++);
}
+ entity_t const *l = statement->labels;
+ if (l) {
+ for (; l; l = l->base.next) {
+ asm_make_target(node, out_pos++);
+ asm_set_values(outs);
+ jump_to_label(l->asm_label.label);
+ }
+
+ asm_make_target(node, pn_ASM_X_regular);
+ }
+
asm_set_values(outs);
DEL_ARR_F(constraints);
diff --git a/src/parser/parser.c b/src/parser/parser.c
index 4252a56..37486d9 100644
--- a/src/parser/parser.c
+++ b/src/parser/parser.c
@@ -9365,7 +9365,7 @@ check_duplicate:
"assembler statement with labels should be 'asm goto'");
parse_asm_labels(&asm_statement->labels);
if (asm_statement->labels)
- errorf(&statement->base.pos, "'asm goto' not supported");
+ asm_statement->is_volatile = true;
} else if (asm_goto)
warningf(WARN_OTHER, &statement->base.pos,
"'asm goto' without labels");