diff --git a/src/cpp/common/assembler_state.h b/src/cpp/common/assembler_state.h index f12146597..5fc6c2c1e 100644 --- a/src/cpp/common/assembler_state.h +++ b/src/cpp/common/assembler_state.h @@ -113,6 +113,7 @@ class assembler_state : public std::enable_shared_from_this std::vector m_labellist; std::map> m_dependent_labelmap; std::set m_opt_opcodes; + bool m_is_save_restore_op = false; // True when currently serializing a save/restore op inline std::string gen_label_name(bool makeunique, const std::shared_ptr data) { return makeunique ? data->get_file() + ":" + data->get_operation()->get_name() : data->get_operation()->get_name(); @@ -159,6 +160,7 @@ class assembler_state : public std::enable_shared_from_this std::map& m_ctrlpkt_id_map; HEADER_ACCESS_GET_SET(offset_type, pos); + HEADER_ACCESS_GET_SET(bool, is_save_restore_op); void printstate() const; diff --git a/src/cpp/encoder/aie2ps/aie2ps_encoder.cpp b/src/cpp/encoder/aie2ps/aie2ps_encoder.cpp index 57d250874..5160f609b 100644 --- a/src/cpp/encoder/aie2ps/aie2ps_encoder.cpp +++ b/src/cpp/encoder/aie2ps/aie2ps_encoder.cpp @@ -10,24 +10,6 @@ namespace aiebu { -void -aie2ps_encoder:: -fill_scratchpad(std::shared_ptr padwriter, const std::map>& scratchpads) -{ - for (const auto& pad : scratchpads) - { - const auto& content = pad.second->get_content(); - if (content.size()) - { - assert((void("Pad content size and size doesnt match\n"), content.size() == pad.second->get_size())); - padwriter->write_bytes(content); - } else { - auto size = pad.second->get_size(); - std::vector zeros(size, 0x00); - padwriter->write_bytes(zeros); - } - } -} void aie2ps_encoder:: @@ -66,16 +48,10 @@ process(std::shared_ptr input) // for each colnum encode each page for (const auto& coldata: totalcoldata) { - auto colnum = coldata.first; for (auto& lpage : coldata.second->m_pages) page_writer(lpage, coldata.second->m_scratchpad, coldata.second->m_labelpageindex, ctrlpkt_id_map, optimizatiom_level); - if (coldata.second->m_scratchpad.size()) { - auto padwriter = std::make_shared(get_PadSectionName(colnum), code_section::data); - fill_scratchpad(padwriter, coldata.second->m_scratchpad); - twriter.push_back(padwriter); - } for (const auto& pair : ctrlpkt_id_map) { auto ctrlpktwriter = std::make_shared(pair.second, code_section::data); @@ -180,6 +156,7 @@ page_writer(page& lpage, std::map> if (text->isOpcode()) { page_state->set_pos(textwriter->tell() - offset); + page_state->set_is_save_restore_op(text->get_is_save_restore()); // Track if this is save/restore op std::vector ret = (*m_isa)[name]->serializer(text->get_operation()->get_args()) ->serialize(page_state, tsym, colnum, pagenum); textwriter->write_bytes(ret); @@ -218,6 +195,15 @@ page_writer(page& lpage, std::map> for (auto& arg : spad.second) { offset = page_state->parse_num_arg(arg); + // Log patch information + log_info() << "Patching scratchpad: label=" << spad.first + << ", arg=" << arg + << ", offset=" << offset + << ", base=" << page_state->m_scratchpad[spad.first.substr(1)]->get_base() + << ", offset=" << page_state->m_scratchpad[spad.first.substr(1)]->get_offset() + << ", patch=" << (page_state->m_scratchpad[spad.first.substr(1)]->get_base() + + page_state->m_scratchpad[spad.first.substr(1)]->get_offset()) + << std::endl; patch57(textwriter, datawriter, offset + static_cast(page_header.size()), page_state->m_scratchpad[spad.first.substr(1)]->get_base() + page_state->m_scratchpad[spad.first.substr(1)]->get_offset()); } @@ -243,6 +229,12 @@ patch57(const std::shared_ptr textwriter, std::shared_ptrread_word(offset + 2*4); // NOLINT uint64_t bd8 = datawriter->read_word(offset + 8*4); // NOLINT uint64_t arg = ((bd8 & 0x1FF) << 48) + ((bd2 & 0xFFFF) << 32) + (bd1 & 0xFFFFFFFF); // NOLINT + // Add log for debugging patching + log_info() << "aie2ps_encoder::patch57: offset=" << offset + << ", patch=0x" << std::hex << patch + << ", arg=0x" << std::hex << arg + << ", after patch=0x" << std::hex << patch + arg + << std::dec << std::endl; patch = arg + patch; datawriter->write_word_at(offset + 1*4, patch & 0xFFFFFFFF); // NOLINT datawriter->write_word_at(offset + 2*4, ((patch >> 32) & 0xFFFF) | (bd2 & 0xFFFF0000)); // NOLINT diff --git a/src/cpp/encoder/aie4/aie4_encoder.h b/src/cpp/encoder/aie4/aie4_encoder.h index 1c9b98bf1..551fb222e 100644 --- a/src/cpp/encoder/aie4/aie4_encoder.h +++ b/src/cpp/encoder/aie4/aie4_encoder.h @@ -10,6 +10,7 @@ #include "writer.h" #include "aie2ps_preprocessed_output.h" #include "ops.h" +#include "common/logger.h" #include "specification/aie2ps/isa.h" namespace aiebu { @@ -38,6 +39,13 @@ class aie4_encoder : public aie2ps_encoder uint64_t bd0 = datawriter->read_word(offset); uint64_t bd1 = datawriter->read_word(offset + 1*4); // NOLINT uint64_t arg = (bd1 & 0xFFFFFFFF) + ((bd0 & 0x1FFFFFF) << 32); // NOLINT + + // Add log for debugging patching + log_info() << "aie4_encoder::patch57: offset=" << offset + << ", patch=0x" << std::hex << patch + << ", arg=0x" << std::hex << arg + << ", after patch=0x" << std::hex << patch + arg + << std::dec << std::endl; patch = arg + patch; datawriter->write_word_at(offset + 1*4, patch & 0xFFFFFFFF); // NOLINT datawriter->write_word_at(offset, (((patch >> 32) & 0x1FFFFFF) | (bd0 & 0xFE000000))); // NOLINT diff --git a/src/cpp/ops/ops.cpp b/src/cpp/ops/ops.cpp index 50539ce54..e91110607 100644 --- a/src/cpp/ops/ops.cpp +++ b/src/cpp/ops/ops.cpp @@ -105,6 +105,8 @@ serialize(std::shared_ptr state, std::vector& symbols, { if (state->m_ctrlpkt_id_map.find(val) != state->m_ctrlpkt_id_map.end()) sval = state->m_ctrlpkt_id_map[val]; + else if (val == offset_type_marker && state->get_is_save_restore_op()) + sval = "scratch-pad-mem"; // For save/restore routine, use "scratch-pad-mem" as arg name else if (val == offset_type_marker) sval = "control-code-" + std::to_string(colnum); diff --git a/src/cpp/preprocessor/aie2ps/aie2ps_preprocessor.h b/src/cpp/preprocessor/aie2ps/aie2ps_preprocessor.h index 2c9e3f75f..a3fcd3124 100644 --- a/src/cpp/preprocessor/aie2ps/aie2ps_preprocessor.h +++ b/src/cpp/preprocessor/aie2ps/aie2ps_preprocessor.h @@ -127,11 +127,11 @@ class aie2ps_preprocessor: public preprocessor toutput->set_ctrlpkt_id_map(ctrlpkt_id_map); toutput->set_annotations(parser->get_annotations()); + offset_type preemption_scratchpad = 0; for (auto col: collist) { std::vector pages; int relative_page_index = 0; - int pad_size = 0; auto& label_page_index = parser->getcollabelpageindex(col); auto& scratchpad = parser->getcolscratchpad(col); auto& coldata = parser->get_col_asmdata(col); @@ -148,10 +148,8 @@ class aie2ps_preprocessor: public preprocessor for (auto& pad : scratchpad) { - pad_size = (((pad_size + 3) >> 2) << 2); // round off to next multiple of 4 - pad.second->set_offset(pad_size); - pad.second->set_base(PAGE_SIZE * relative_page_index); - pad_size += pad.second->get_size(); + pad.second->set_offset(preemption_scratchpad); + preemption_scratchpad += pad.second->get_size(); } toutput->set_coldata(col, pages, scratchpad, label_page_index, tinput->get_control_packet_index()); diff --git a/src/cpp/preprocessor/asm/asm_parser.cpp b/src/cpp/preprocessor/asm/asm_parser.cpp index 26dd3fd27..403525453 100644 --- a/src/cpp/preprocessor/asm/asm_parser.cpp +++ b/src/cpp/preprocessor/asm/asm_parser.cpp @@ -109,7 +109,7 @@ std::vector asm_parser:: get_col_list() { - // get col list + // get col list (sorted order since unordered_map doesn't preserve insertion order) std::vector keys; std::transform( @@ -117,6 +117,7 @@ get_col_list() m_col.end(), std::back_inserter(keys), [](const std::unordered_map::value_type &pair){return pair.first;}); + std::sort(keys.begin(), keys.end()); return keys; } @@ -223,7 +224,7 @@ parse_lines(const std::vector& data, std::string& file) } else insert_col_asmdata(std::make_shared(std::make_shared(sm[1].str(), ""), operation_type::label, code_section::unknown, 0, - (uint32_t)-1, linenumber, line, file)); + (uint32_t)-1, linenumber, line, file, is_save_restore_routine())); continue; } // check for operation @@ -307,7 +308,7 @@ parse_lines(const std::vector& data, std::string& file) insert_col_asmdata(std::make_shared(std::make_shared(op_name, arg_str), operation_type::op, code_section::unknown, 0, (uint32_t)-1, - linenumber, line, file)); + linenumber, line, file, is_save_restore_routine())); if (!op_name.compare("eof")) set_data_state(true); } @@ -991,12 +992,14 @@ asm_parser::inject_hintmap_save_restore(int col, m_current_col = col; set_data_state(false); + set_save_restore_routine(true); // Mark as save/restore routine parse_lines(save_chars, save_file_mod); pop_data_state(); set_data_state(false); parse_lines(restore_chars, restore_file_mod); pop_data_state(); + set_save_restore_routine(false); // Clear save/restore routine flag } // --------------------------------------------------------------------------- @@ -1120,12 +1123,14 @@ asm_parser::inject_default_save_restore(int col, m_current_col = col; set_data_state(false); + set_save_restore_routine(true); // Mark as save/restore routine parse_lines(save_chars, save_file_mod); pop_data_state(); set_data_state(false); parse_lines(restore_chars, restore_file_mod); pop_data_state(); + set_save_restore_routine(false); // Clear save/restore routine flag } // --------------------------------------------------------------------------- @@ -1377,8 +1382,13 @@ operate(std::shared_ptr parserptr, const smatch& sm) m_parserptr = parserptr; verify_match(sm, error::error_code::invalid_asm, ".setpad directive requires arguments\n"); - std::vector args = splitoption(sm[2].str().c_str(), ','); + // .setpad should only be part of save/restore routines + if (!m_parserptr->should_skip_setpad_in_save_restore()) { + log_warn() << "Warning: Directive \"" << sm[0].str() << "\" found outside save/restore routine for target: " + << m_parserptr->get_target_type() << "\n"; + } + std::vector args = splitoption(sm[2].str().c_str(), ','); add_scratchpad(args[0], args[1]); } diff --git a/src/cpp/preprocessor/asm/asm_parser.h b/src/cpp/preprocessor/asm/asm_parser.h index 3cde90a4c..e3d09efee 100644 --- a/src/cpp/preprocessor/asm/asm_parser.h +++ b/src/cpp/preprocessor/asm/asm_parser.h @@ -196,14 +196,15 @@ class asm_data std::string m_line; std::string m_file; int m_annotation_index = -1; + bool m_is_save_restore = false; // True if this instruction is from save/restore routine public: asm_data() = default; asm_data(std::shared_ptr op, operation_type optype, code_section sec, offset_type size, uint32_t pgnum, - uint32_t ln, std::string line, std::string file) + uint32_t ln, std::string line, std::string file, bool is_save_restore = false) :m_op(op), m_optype(optype), m_section(sec), m_size(size), - m_pagenum(pgnum), m_linenumber(ln), m_line(line), m_file(file) {} + m_pagenum(pgnum), m_linenumber(ln), m_line(line), m_file(file), m_is_save_restore(is_save_restore) {} asm_data( asm_data* a) { @@ -215,6 +216,7 @@ class asm_data a->m_linenumber = m_linenumber; a->m_line = m_line; a->m_file = m_file; + a->m_is_save_restore = m_is_save_restore; } HEADER_ACCESS_GET_SET(code_section, section); @@ -223,6 +225,7 @@ class asm_data HEADER_ACCESS_GET_SET(uint32_t, linenumber); HEADER_ACCESS_GET_SET(std::string, file); HEADER_ACCESS_GET_SET(std::string, line); + HEADER_ACCESS_GET_SET(bool, is_save_restore); bool isLabel() { return m_optype == operation_type::label; } bool isOpcode() { return m_optype == operation_type::op; } bool isAnnotation() { return m_optype == operation_type::annotation; } @@ -346,6 +349,7 @@ class asm_parser: public std::enable_shared_from_this std::map> m_preempt_hintmaps; // group -> vector of hintmap_labels (multiple PREEMPT opcodes per group) std::map> m_hintmap_labels; // hintmap_label -> (save_label, restore_label) std::set m_preempt_without_hintmap; // groups that have PREEMPT opcodes without hintmaps + bool m_is_save_restore_routine = false; // True when parsing save/restore routine files // One unique scratchpad region: all hintmap labels that share the same scratchbase+size struct hintmap_group_entry { @@ -425,6 +429,20 @@ class asm_parser: public std::enable_shared_from_this bool is_multi_column_mode() const { return m_preempt_labels.size() > 1; } + // Check if currently parsing save/restore routine + bool is_save_restore_routine() const { return m_is_save_restore_routine; } + void set_save_restore_routine(bool val) { m_is_save_restore_routine = val; } + + // Check if we should skip setpad for this target in save/restore routine + bool should_skip_setpad_in_save_restore() const { + return m_is_save_restore_routine; + } + + // Check if we should use scratch-pad section for save/restore APPLY_OFFSET_57 + //bool should_use_scratchpad_section_for_save_restore() const { + // return m_is_save_restore_routine; + //} + // Record preempt label for current group (called when PREEMPT opcode is hit) // Label naming: save_N / restore_N where N = index (group/2 + 1) // group 0 -> save_1, group 2 -> save_2, group 4 -> save_3 diff --git a/test/aie4-ctrlcode/1col_preempt/gold.md5 b/test/aie4-ctrlcode/1col_preempt/gold.md5 index 3d0b35379..372841ad6 100644 --- a/test/aie4-ctrlcode/1col_preempt/gold.md5 +++ b/test/aie4-ctrlcode/1col_preempt/gold.md5 @@ -1 +1 @@ -96b00cbda9f5061f2cfef83b22c2e01d +7605802954688a5e7d1fff4198e6ef59