diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-09-14 21:11:03 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-09-14 21:11:03 +0200 |
| commit | 52c8ca2c06da93c8d14e80a256e8996c1fa1e885 (patch) | |
| tree | 3579cffe682bb2d2270e5d892f26ae3c197880e6 /gcc | |
| parent | 49e6a0518eb6b7b09938b562ef270028337508bf (diff) | |
| download | elna-52c8ca2c06da93c8d14e80a256e8996c1fa1e885.tar.gz | |
Implement volatile operations
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/gcc/elna-generic.cc | 50 |
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; } |
