aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-14 21:11:03 +0200
committerEugen Wissner <belka@caraus.de>2026-09-14 21:11:03 +0200
commit52c8ca2c06da93c8d14e80a256e8996c1fa1e885 (patch)
tree3579cffe682bb2d2270e5d892f26ae3c197880e6 /gcc
parent49e6a0518eb6b7b09938b562ef270028337508bf (diff)
downloadelna-52c8ca2c06da93c8d14e80a256e8996c1fa1e885.tar.gz
Implement volatile operations
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gcc/elna-generic.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc
index ed75fa4..3b43f5e 100644
--- a/gcc/gcc/elna-generic.cc
+++ b/gcc/gcc/elna-generic.cc
@@ -92,6 +92,46 @@ namespace elna::gcc
}
}
+ // Volatile-qualifying the pointee is what carries the guarantee into
+ // GIMPLE; the flags on the reference itself mirror what the C front end
+ // sets when it dereferences a volatile pointer.
+ tree generic_visitor::build_volatile_reference(location_t location,
+ boot::expression& pointer, const boot::type& accessed)
+ {
+ pointer.accept(this);
+
+ tree pointee = get_inner_alias(accessed, this->symbols);
+ tree qualified = build_qualified_type(pointee, TYPE_QUALS(pointee) | TYPE_QUAL_VOLATILE);
+ tree address = fold_convert_loc(location, build_pointer_type(qualified),
+ prepare_rvalue(this->current_expression));
+ tree reference = build_simple_mem_ref_loc(location, address);
+
+ TREE_THIS_VOLATILE(reference) = 1;
+ TREE_SIDE_EFFECTS(reference) = 1;
+
+ return reference;
+ }
+
+ void generic_visitor::build_volatile_load_builtin(location_t call_location,
+ boot::procedure_call *call)
+ {
+ this->current_expression = build_volatile_reference(call_location,
+ *call->arguments.at(0), call->type_decoration);
+ }
+
+ void generic_visitor::build_volatile_store_builtin(location_t call_location,
+ boot::procedure_call *call)
+ {
+ tree target = build_volatile_reference(call_location,
+ *call->arguments.at(0), call->argument_types.at(1));
+
+ call->arguments.at(1)->accept(this);
+ tree value = prepare_rvalue(this->current_expression);
+
+ this->current_expression = build2_loc(call_location, MODIFY_EXPR, void_type_node,
+ target, value);
+ }
+
bool generic_visitor::build_builtin_procedures(boot::procedure_call *call)
{
const location_t call_location = get_location(&call->position());
@@ -103,6 +143,16 @@ namespace elna::gcc
build_assert_builtin(call_location, call->arguments);
return true;
}
+ if (named_call->name == "volatile_load")
+ {
+ build_volatile_load_builtin(call_location, call);
+ return true;
+ }
+ if (named_call->name == "volatile_store")
+ {
+ build_volatile_store_builtin(call_location, call);
+ return true;
+ }
}
return false;
}