-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Literal support #207
Merged
slavek-kucera
merged 60 commits into
eclipse-che4z:development
from
slavek-kucera:feat_literal_support
Dec 10, 2021
Merged
Changes from 59 commits
Commits
Show all changes
60 commits
Select commit
Hold shift + click to select a range
10b5e5c
prep for richer mach attributes
slavek-kucera 6f14d54
fix reference to nullptr
slavek-kucera 78d1e36
specialize is_similar for std pointer-like objects
slavek-kucera 7bb8eec
...
slavek-kucera c7c6c65
fix: Current location counter changes between individual DC/DS operands
slavek-kucera dd42bc0
literals (WIP)
slavek-kucera afb7251
stateless loctr expressions
slavek-kucera 533147b
Final all the things
slavek-kucera 4fd0551
WIP
slavek-kucera c05fcd2
remove confusing alias
slavek-kucera 8664ac2
adjust literal collection
slavek-kucera 9124c60
refactoring of dependency evaluation context
slavek-kucera 5034466
order pending literal pool elements
slavek-kucera 3196a50
...
slavek-kucera f02f223
refactor data definition visitor
slavek-kucera 941bee6
test for occurences in literals and location counter detection
slavek-kucera 94b7087
a few literal tests
slavek-kucera 90334f6
cleanup
slavek-kucera 22535a1
no nested literals
slavek-kucera 8c71440
test for nested literals
slavek-kucera cfa3d11
wip - issue with adding literal alias while generating pool
slavek-kucera ad993f3
refactor dep solver
slavek-kucera 60b1a38
cleanup messages
slavek-kucera 3e53164
fix duplicate literal handling
slavek-kucera b5912cb
support literals in mach_expr_data_attr
slavek-kucera 9e8c188
attribute support for literals in machine expressions
slavek-kucera d0ff28f
WIP - ca sets not working
slavek-kucera 3b2b3fb
basic support for literal attributes in ca statements
slavek-kucera 1d4f750
fix missing literal registration
slavek-kucera aff24e1
fixes
slavek-kucera 9d8186d
implement LTORG
slavek-kucera 39414dd
fixes
slavek-kucera 59ce91b
enhance is_similar
slavek-kucera 5208786
implement literal comparison
slavek-kucera 0b91259
test for similar literals
slavek-kucera 022c67f
unconditionally examine all operands
slavek-kucera 78fd035
incomplete fix for CR LF in strings
slavek-kucera 92dca17
CA self def term support
slavek-kucera 93b4eda
test for literal occurence in CA context
slavek-kucera 182a0f0
...
slavek-kucera d2980b2
code smells
slavek-kucera 7d17d4e
keep literal range
slavek-kucera 1d98719
literal dependency evaluation
slavek-kucera 97bf2f9
include processing stack in diagnostics from literals
slavek-kucera 6379ade
reladdr literal reference should trigger halfword alignment
slavek-kucera 67b280d
...
slavek-kucera 47d80e6
...
slavek-kucera 7e0a364
do not create the private section until needed
slavek-kucera dc8206c
tests
slavek-kucera 2689e2d
fix cache issue related to reladdr transformation
slavek-kucera 6aa3379
fix data definition extension parsing
slavek-kucera 0d609b6
fix handling of private sections
slavek-kucera 29329ad
fix attribute lookahead on expressions
slavek-kucera 1ec8e76
review suggestions
slavek-kucera 8de34c0
split ordinary_assembly_dependency_solver
slavek-kucera 3cfa9e1
add test for bad literal attributes
slavek-kucera edcbaef
...
slavek-kucera 1c17faa
run DC-like check when generating literal pool
slavek-kucera 14846db
handle zero-length literals better
slavek-kucera dfea704
reladdr transform mask for mnemonics
slavek-kucera File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/* | ||
* Copyright (c) 2021 Broadcom. | ||
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Broadcom, Inc. - initial API and implementation | ||
*/ | ||
|
||
#include "literal_pool.h" | ||
|
||
#include <algorithm> | ||
#include <functional> | ||
|
||
#include "context/ordinary_assembly/ordinary_assembly_context.h" | ||
#include "context/ordinary_assembly/postponed_statement.h" | ||
#include "diagnosable_ctx.h" | ||
#include "ebcdic_encoding.h" | ||
#include "hlasm_context.h" | ||
#include "processing/statement.h" | ||
#include "semantics/operand_impls.h" | ||
|
||
namespace hlasm_plugin::parser_library::context { | ||
|
||
id_index literal_pool::add_literal(const std::string& literal_text, | ||
const std::shared_ptr<const expressions::data_definition>& dd, | ||
range r, | ||
size_t unique_id, | ||
std::optional<address> loctr, | ||
bool align_on_halfword) | ||
{ | ||
unique_id = dd->references_loctr ? unique_id : 0; | ||
if (auto lit = get_literal(m_current_literal_pool_generation, dd, unique_id)) | ||
return lit; | ||
|
||
auto [it, inserted] = m_literals.try_emplace( | ||
literal_id { m_current_literal_pool_generation, unique_id, dd }, literal_text, std::move(r), std::move(loctr)); | ||
// even if we end up inserting a duplicate | ||
// we need to try to insert const expressions::data_definition->iterator relation | ||
// because a single literal may be referenced by independent data_definitions | ||
m_literals_genmap.try_emplace(literal_id { m_current_literal_pool_generation, unique_id, dd }, it); | ||
// but we should not try to put logical duplicates on the pending queue | ||
if (inserted) | ||
{ | ||
m_pending_literals.emplace_back(it); | ||
it->second.stack = hlasm_ctx.processing_stack(); | ||
} | ||
it->second.align_on_halfword |= align_on_halfword; | ||
|
||
return &it->second.text; | ||
} | ||
|
||
id_index literal_pool::get_literal( | ||
size_t generation, const std::shared_ptr<const expressions::data_definition>& dd, size_t unique_id) const | ||
{ | ||
unique_id = dd->references_loctr ? unique_id : 0; | ||
auto it = m_literals_genmap.find(literal_id { generation, unique_id, dd }); | ||
if (it == m_literals_genmap.end()) | ||
return nullptr; | ||
return &it->second->second.text; | ||
} | ||
|
||
|
||
class literal_pool::literal_postponed_statement : public context::postponed_statement, | ||
public processing::resolved_statement | ||
{ | ||
const literal_pool::literal_details* details; | ||
semantics::operands_si op; | ||
processing::op_code op_code; | ||
|
||
static const semantics::remarks_si empty_remarks; | ||
static const semantics::label_si empty_label; | ||
static const semantics::instruction_si empty_instr; | ||
static const processing::processing_format dc_format; | ||
|
||
public: | ||
literal_postponed_statement(const std::shared_ptr<const expressions::data_definition>& dd, | ||
const literal_pool::literal_details& details, | ||
id_storage& ids) | ||
: details(&details) | ||
, op(details.r, {}) | ||
, op_code(ids.add("DC"), instruction_type::ASM) | ||
{ | ||
op.value.push_back(std::make_unique<semantics::data_def_operand>(dd, details.r)); | ||
} | ||
const processing_stack_t& location_stack() const override { return details->stack; } | ||
const processing::resolved_statement* resolved_stmt() const override { return this; } | ||
const processing::op_code& opcode_ref() const override { return op_code; } | ||
processing::processing_format format_ref() const override { return dc_format; } | ||
const semantics::operands_si& operands_ref() const override { return op; } | ||
const semantics::remarks_si& remarks_ref() const override { return empty_remarks; } | ||
const range& stmt_range_ref() const override { return details->r; } | ||
const semantics::label_si& label_ref() const override { return empty_label; } | ||
const semantics::instruction_si& instruction_ref() const override { return empty_instr; } | ||
std::pair<const diagnostic_op*, const diagnostic_op*> diagnostics() const override { return {}; }; | ||
}; | ||
const semantics::remarks_si literal_pool::literal_postponed_statement::empty_remarks({}, {}); | ||
const semantics::label_si literal_pool::literal_postponed_statement::empty_label(range {}); | ||
const semantics::instruction_si literal_pool::literal_postponed_statement::empty_instr(range {}); | ||
const processing::processing_format literal_pool::literal_postponed_statement::dc_format( | ||
processing::processing_kind::ORDINARY, processing::processing_form::ASM, processing::operand_occurence::PRESENT); | ||
|
||
void literal_pool::generate_pool(dependency_solver& solver, const diagnosable_ctx& diags) | ||
{ | ||
ordinary_assembly_context& ord_ctx = hlasm_ctx.ord_ctx; | ||
|
||
if (m_pending_literals.empty()) | ||
return; | ||
|
||
for (auto& [it, size, alignment] : m_pending_literals) | ||
{ | ||
const auto& lit = it->first.lit; | ||
if (!lit->access_data_def_type()) // unknown type | ||
continue; | ||
|
||
size = (semantics::data_def_operand::get_operand_value(*lit, solver).get_length() + 7) / 8; | ||
if (size == 0) | ||
continue; | ||
|
||
auto top_alignment = size | 16; // 16B length alignment is the top | ||
alignment = (~top_alignment & top_alignment - 1) + 1; | ||
} | ||
|
||
std::stable_sort(m_pending_literals.begin(), m_pending_literals.end(), [](const auto& l, const auto& r) { | ||
return l.alignment > r.alignment; | ||
}); | ||
|
||
constexpr auto sectalign = doubleword; | ||
ord_ctx.align(sectalign); | ||
|
||
for (const auto& [it, size, alignment] : m_pending_literals) | ||
{ | ||
const auto& lit_key = it->first; | ||
const auto& lit = lit_key.lit; | ||
const auto& lit_val = it->second; | ||
|
||
if (!lit->access_data_def_type()) // unknown type | ||
continue; | ||
|
||
// TODO: warn on align > sectalign | ||
|
||
bool cycle_ok = ord_ctx.create_symbol(&lit_val.text, | ||
ord_ctx.align(lit_val.align_on_halfword ? halfword : no_align), | ||
symbol_attributes(symbol_origin::DAT, | ||
ebcdic_encoding::a2e[(unsigned char)lit->get_type_attribute()], | ||
lit->get_length_attribute(solver)), | ||
{}); | ||
|
||
if (size == 0) | ||
{ | ||
diags.add_diagnostic(diagnostic_op::error_D031(it->second.r)); | ||
continue; | ||
} | ||
|
||
ord_ctx.reserve_storage_area(size, no_align); | ||
|
||
if (!cycle_ok) | ||
diags.add_diagnostic(diagnostic_op::error_E033(it->second.r)); | ||
else if (lit->get_dependencies(solver).contains_dependencies()) | ||
{ | ||
auto adder = ord_ctx.symbol_dependencies.add_dependencies( | ||
std::make_unique<literal_postponed_statement>(lit, lit_val, hlasm_ctx.ids()), | ||
{ lit_val.loctr, lit_key.generation, lit_key.unique_id }); | ||
adder.add_dependency(); | ||
adder.finish(); | ||
} | ||
else | ||
{ | ||
auto ddt = lit->access_data_def_type(); | ||
if (!ddt) // unknown type | ||
continue; | ||
|
||
auto ddo = semantics::data_def_operand::get_operand_value(*lit, solver); | ||
ddt->check_DC(ddo, diagnostic_collector(&diags, lit_val.stack)); | ||
} | ||
} | ||
|
||
m_pending_literals.clear(); | ||
++m_current_literal_pool_generation; | ||
} | ||
|
||
bool literal_pool::literal_id::is_similar(const literal_id& ld) const noexcept | ||
{ | ||
return generation == ld.generation && unique_id == ld.unique_id && utils::is_similar(lit, ld.lit); | ||
} | ||
|
||
size_t literal_pool::literal_definition_hasher::operator()(const literal_id& ld) const noexcept | ||
{ | ||
return ld.lit->hash() ^ ld.generation ^ ld.unique_id; | ||
} | ||
|
||
} // namespace hlasm_plugin::parser_library::context |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* | ||
* Copyright (c) 2021 Broadcom. | ||
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Broadcom, Inc. - initial API and implementation | ||
*/ | ||
|
||
#ifndef HLASMPLUGIN_PARSERLIBRARY_LITERAL_POOL_H | ||
#define HLASMPLUGIN_PARSERLIBRARY_LITERAL_POOL_H | ||
|
||
#include <unordered_map> | ||
#include <unordered_set> | ||
|
||
#include "expressions/data_definition.h" | ||
#include "id_storage.h" | ||
#include "location.h" | ||
#include "processing_context.h" | ||
#include "utils/similar.h" | ||
|
||
namespace hlasm_plugin::parser_library::context { | ||
class hlasm_context; | ||
|
||
class literal_pool | ||
{ | ||
struct literal_id | ||
{ | ||
size_t generation; | ||
size_t unique_id; | ||
std::shared_ptr<const expressions::data_definition> lit; | ||
|
||
bool is_similar(const literal_id&) const noexcept; | ||
}; | ||
struct literal_details | ||
{ | ||
std::string text; | ||
range r; | ||
std::optional<address> loctr; | ||
processing_stack_t stack; | ||
bool align_on_halfword = false; | ||
|
||
literal_details(std::string text, range r, std::optional<address> loctr) | ||
: text(std::move(text)) | ||
, r(r) | ||
, loctr(std::move(loctr)) | ||
{} | ||
|
||
literal_details(std::string text, range r, std::optional<address> loctr, processing_stack_t stack) | ||
: text(std::move(text)) | ||
, r(r) | ||
, loctr(std::move(loctr)) | ||
, stack(std::move(stack)) | ||
{} | ||
}; | ||
class literal_postponed_statement; | ||
struct literal_definition_hasher | ||
{ | ||
size_t operator()(const literal_id&) const noexcept; | ||
}; | ||
size_t m_current_literal_pool_generation = 0; | ||
|
||
struct literal_id_helper | ||
{ | ||
size_t operator()(const literal_id& p) const noexcept | ||
{ | ||
return std::hash<size_t>()(p.generation) ^ std::hash<size_t>()(p.unique_id) | ||
^ std::hash<const expressions::data_definition*>()(p.lit.get()); | ||
} | ||
bool operator()(const literal_id& l, const literal_id& r) const noexcept | ||
{ | ||
return l.lit == r.lit && l.generation == r.generation && l.unique_id == r.unique_id; | ||
} | ||
}; | ||
|
||
std::unordered_map<literal_id, literal_details, literal_definition_hasher, decltype(utils::is_similar)> m_literals; | ||
std::unordered_map<literal_id, decltype(m_literals)::const_iterator, literal_id_helper, literal_id_helper> | ||
m_literals_genmap; | ||
|
||
struct pending_literal | ||
{ | ||
decltype(m_literals)::const_iterator literal; | ||
size_t size = 0; | ||
size_t alignment = 0; | ||
|
||
explicit pending_literal(decltype(m_literals)::const_iterator l) noexcept | ||
: literal(l) | ||
{} | ||
}; | ||
|
||
std::vector<pending_literal> m_pending_literals; | ||
|
||
hlasm_context& hlasm_ctx; | ||
|
||
public: | ||
explicit literal_pool(hlasm_context& hlasm_ctx) | ||
: hlasm_ctx(hlasm_ctx) | ||
{} | ||
|
||
id_index add_literal(const std::string& literal_text, | ||
const std::shared_ptr<const expressions::data_definition>& dd, | ||
range r, | ||
size_t unique_id, | ||
std::optional<address> loctr, | ||
bool align_on_halfword); | ||
id_index get_literal( | ||
size_t generation, const std::shared_ptr<const expressions::data_definition>& dd, size_t unique_id) const; | ||
|
||
void generate_pool(dependency_solver& solver, const diagnosable_ctx& diags); | ||
size_t current_generation() const { return m_current_literal_pool_generation; } | ||
|
||
// testing | ||
size_t get_pending_count() const { return m_pending_literals.size(); } | ||
}; | ||
|
||
} // namespace hlasm_plugin::parser_library::context | ||
|
||
#endif |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am reasonably sure that this should never really happen, but not 100%.