summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDaniel Biester <danielbiester@icloud.com>2020-07-14 08:07:38 +0200
committerDaniel Biester <danielbiester@icloud.com>2020-07-14 08:07:38 +0200
commit63d81cc5318385e1cab48b7fb5c24968188aba61 (patch)
tree70e8f34a5c4f9d138470e4d08eee10c9ee0a5742
parent8f0c94f0f5401615afcfede9f8fd7e6abea3ca0a (diff)
Add opcode argument to function attribute special_instruction.
m---------libfirm0
-rw-r--r--src/ast/attribute.c19
-rw-r--r--src/ast/entity_t.h1
-rw-r--r--src/firm/ast2firm.c2
4 files changed, 19 insertions, 3 deletions
diff --git a/libfirm b/libfirm
-Subproject f9a9fc7dc7c74ead22e15b1be6ce6f990219f45
+Subproject ff1714068c0390a52da7f2230ce744e55f4047c
diff --git a/src/ast/attribute.c b/src/ast/attribute.c
index 2af5bcf..6b42462 100644
--- a/src/ast/attribute.c
+++ b/src/ast/attribute.c
@@ -243,6 +243,17 @@ static void handle_attribute_visibility(const attribute_t *attribute,
}
}
+static void handle_attribute_special_instruction(const attribute_t *attribute, entity_t *entity)
+{
+ int si_opcode = 0;
+ if (attribute->a.arguments) {
+ attribute_argument_t *argument = attribute->a.arguments;
+ si_opcode = fold_expression_to_int(argument->v.expression);
+ }
+ assert(entity->kind == ENTITY_FUNCTION);
+ entity->function.si_opcode = si_opcode & 0x1F;
+}
+
static void warn_arguments(const attribute_t *attribute)
{
if (attribute->a.arguments == NULL)
@@ -367,9 +378,6 @@ void handle_entity_attributes(const attribute_t *attributes, entity_t *entity)
case ATTRIBUTE_GNU_LEAF: modifiers |= DM_LEAF; break;
case ATTRIBUTE_GNU_GNU_INLINE: modifiers |= DM_GNU_INLINE; break;
- case ATTRIBUTE_ICORE_SPECIAL_INSTRUCTION:
- modifiers |= DM_SPECIAL_INSTRUCTION; break;
-
case ATTRIBUTE_MS_DLLIMPORT: modifiers |= DM_DLLIMPORT; break;
case ATTRIBUTE_MS_DLLEXPORT: modifiers |= DM_DLLEXPORT; break;
case ATTRIBUTE_MS_NAKED: modifiers |= DM_NAKED; break;
@@ -391,6 +399,11 @@ void handle_entity_attributes(const attribute_t *attributes, entity_t *entity)
handle_attribute_asm(attribute, entity);
break;
+ case ATTRIBUTE_ICORE_SPECIAL_INSTRUCTION:
+ modifiers |= DM_SPECIAL_INSTRUCTION;
+ handle_attribute_special_instruction(attribute, entity);
+ break;
+
case ATTRIBUTE_GNU_VISIBILITY:
handle_attribute_visibility(attribute, entity);
break;
diff --git a/src/ast/entity_t.h b/src/ast/entity_t.h
index 8d4002c..4e4b0a6 100644
--- a/src/ast/entity_t.h
+++ b/src/ast/entity_t.h
@@ -223,6 +223,7 @@ struct function_t {
scope_t parameters;
statement_t *body;
symbol_t *actual_name; /**< gnu extension __REDIRECT */
+ unsigned si_opcode; /**< value from attribute((special_instruction())) */
union {
symbol_t *symbol;
entity_t *entity;
diff --git a/src/firm/ast2firm.c b/src/firm/ast2firm.c
index 1b39f26..4992221 100644
--- a/src/firm/ast2firm.c
+++ b/src/firm/ast2firm.c
@@ -704,6 +704,8 @@ static ir_entity *get_function_entity(function_t *const function)
handle_decl_modifiers(irentity, (entity_t*)function);
+ set_entity_si_opcode(irentity, function->si_opcode);
+
if (function->body != NULL && function_is_inline_only(function))
add_entity_linkage(irentity, IR_LINKAGE_NO_CODEGEN);