diff options
| -rw-r--r-- | qtmips_asm/qtmips_asm.pro | 9 | ||||
| -rw-r--r-- | qtmips_asm/simpleasm.cpp | 285 | ||||
| -rw-r--r-- | qtmips_asm/simpleasm.h | 83 | ||||
| -rw-r--r-- | qtmips_gui/mainwindow.cpp | 208 | ||||
| -rw-r--r-- | qtmips_machine/instruction.cpp | 19 | ||||
| -rw-r--r-- | qtmips_machine/instruction.h | 10 | ||||
| -rw-r--r-- | qtmips_machine/qtmipsmachine.cpp | 10 | ||||
| -rw-r--r-- | qtmips_machine/qtmipsmachine.h | 1 | ||||
| -rw-r--r-- | qtmips_machine/symboltable.cpp | 6 | ||||
| -rw-r--r-- | qtmips_machine/symboltable.h | 2 | 
10 files changed, 420 insertions, 213 deletions
| diff --git a/qtmips_asm/qtmips_asm.pro b/qtmips_asm/qtmips_asm.pro index d096961..ed42c10 100644 --- a/qtmips_asm/qtmips_asm.pro +++ b/qtmips_asm/qtmips_asm.pro @@ -6,6 +6,9 @@ CONFIG += c++11  TEMPLATE = lib  CONFIG += staticlib +INCLUDEPATH += $$PWD/../qtmips_machine $$PWD/../qtmips_osemu +DEPENDPATH += $$PWD/../qtmips_machine +  LIBS += -lelf  QMAKE_CXXFLAGS += -std=c++0x  QMAKE_CXXFLAGS_DEBUG += -ggdb @@ -14,8 +17,10 @@ DEFINES += QTMIPS_MACHINE_LIBRARY  DEFINES += QT_DEPRECATED_WARNINGS  SOURCES += \ -    fixmatheval.cpp +    fixmatheval.cpp \ +    simpleasm.cpp  HEADERS += \      fixmatheval.h \ -    messagetype.h +    messagetype.h \ +    simpleasm.h diff --git a/qtmips_asm/simpleasm.cpp b/qtmips_asm/simpleasm.cpp new file mode 100644 index 0000000..15d50b2 --- /dev/null +++ b/qtmips_asm/simpleasm.cpp @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + *   B35APO - Computer Architectures + *   https://cw.fel.cvut.cz/wiki/courses/b35apo + * + *   B4M35PAP - Advanced Computer Architectures + *   https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019      Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University        (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA  02110-1301, USA. + * + ******************************************************************************/ + +#include <QObject> + +#include "simpleasm.h" + +using namespace fixmatheval; + + +SymbolTableDb::SymbolTableDb(machine::SymbolTable *symtab) { +    this->symtab = symtab; +} + +bool SymbolTableDb::getValue(fixmatheval::FmeValue &value, QString name) { +    std::uint32_t val; +    if (!symtab->name_to_value(val, name)) +        return false; +    value = val; +    return true; +} + +void SymbolTableDb::setSymbol(QString name, std::uint32_t value, std::uint32_t size, +          unsigned char info, unsigned char other) { +    symtab->set_symbol(name, value, size, info, other); +} + + +std::uint64_t SimpleAsm::string_to_uint64(QString str, int base, +                                      int *chars_taken) { +    int i; +    std::int64_t val; +    char *p, *r; +    char cstr[str.count() + 1]; +    for (i = 0; i < str.count(); i++) +        cstr[i] = str.at(i).toLatin1(); +    cstr[i] = 0; +    p = cstr; +    val = std::strtoll(p, &r, base); +    if (chars_taken != nullptr) +        *chars_taken = r - p; +    return val; +} + +SimpleAsm::SimpleAsm(QObject *parent) : Super(parent) { +    clear(); +} + +SimpleAsm::~SimpleAsm() { +    clear(); +} + +void SimpleAsm::clear() { +    symtab = nullptr; +    mem = nullptr; +    while (!reloc.isEmpty()) { +        delete reloc.takeFirst(); +    } +    error_occured = false; +    fatal_occured = false; +} + +void SimpleAsm::setup(machine::MemoryAccess *mem, SymbolTableDb *symtab, +                      std::uint32_t address) { +    this->mem = mem; +    this->symtab = symtab; +    this->address = address; +} + +bool SimpleAsm::process_line(QString line, QString filename, +                             int line_number, QString *error_ptr) { +    QString error; +    int pos; +    QString label = ""; +    pos = line.indexOf("#"); +    if (pos >= 0) +        line.truncate(pos); +    pos = line.indexOf(";"); +    if (pos >= 0) +        line.truncate(pos); +    pos = line.indexOf("//"); +    if (pos >= 0) +        line.truncate(pos); +    line = line.simplified(); +    pos = line.indexOf(":"); +    if (pos >= 0) { +        label = line.mid(0, pos); +        line = line.mid(pos + 1).trimmed(); +        symtab->setSymbol(label, address, 4); +    } +    if (line.isEmpty()) +        return true; +    int k = 0, l; +    while (k < line.count()) { +        if (!line.at(k).isSpace()) +            break; +        k++; +    } +    l = k; +    while (l < line.count()) { +        if (!line.at(l).isLetterOrNumber() && !(line.at(l) == '.')) +            break; +        l++; +    } +    QString op = line.mid(k, l - k).toUpper(); +    if ((op == ".DATA") || (op == ".TEXT") || +        (op == ".GLOBL") || (op == ".END") || +        (op == ".ENT")) { +        return true; +    } +    if (op == ".ORG") { +        bool ok; +        fixmatheval::FmeExpression expression; +        fixmatheval::FmeValue value; +        ok = expression.parse(line.mid(op.size()), error); +        if (ok) +            ok = expression.eval(value, symtab, error); +        if (!ok) { +            error = tr("line %1 .orig %2 parse error.") +                    .arg(QString::number(line_number), line); +            emit report_message(messagetype::ERROR, filename, line_number, 0, error, ""); +            error_occured = true; +            fatal_occured = true; +            if (error_ptr != nullptr) +                *error_ptr = error; +            return false; +        } +        address = value; +        return true; +    } +    if ((op == ".EQU") || (op == ".SET")) { +        QStringList operands = line.mid(op.size()).split(","); +        if ((operands.count() > 2) || (operands.count() < 1)) { +            error = tr("line %1 .set or .equ incorrect arguments number.") +                    .arg(QString::number(line_number)); +            emit report_message(messagetype::ERROR, filename, line_number, 0, error, ""); +            error_occured = true; +            if (error_ptr != nullptr) +                *error_ptr = error; +            return false; +        } +        QString name = operands.at(0).trimmed(); +        if ((name == "noat") || (name == "noreored")) +            return true; +        bool ok; +        fixmatheval::FmeValue value = 1; +        if (operands.count() > 1) { +            fixmatheval::FmeExpression expression; +            ok = expression.parse(operands.at(1), error); +            if (ok) +                ok = expression.eval(value, symtab, error); +            if (!ok) { +                error = tr("line %1 .set or .equ %2 parse error.") +                           .arg(QString::number(line_number), operands.at(1)); +                emit report_message(messagetype::ERROR, filename, line_number, 0, error, ""); +                error_occured = true; +                if (error_ptr != nullptr) +                    *error_ptr = error; +                return false; +            } +        } +        symtab->setSymbol(name, value, 0); +        return true; +    } +    if (op == ".WORD") { +        foreach (QString s, line.mid(op.size()).split(",")) { +            s = s.simplified(); +            std::uint32_t val = 0; +            int chars_taken; +            val = string_to_uint64(s, 0, &chars_taken); +            if (chars_taken != s.size()) { +                val = 0; +                reloc.append(new machine::RelocExpression(address, s, 0, +                             -0xffffffff, 0xffffffff, 0, 32, 0, filename, line_number, 0)); +            } +            if (fatal_occured) +                mem->write_word(address, val); +            address += 4; +        } +        return true; +    } + +    std::uint32_t inst[2] = {0, 0}; +    ssize_t size = machine::Instruction::code_from_string(inst, 8, line, error, +                                             address, &reloc, filename, line_number, true); +    if (size < 0) { +        error = tr("line %1 instruction %2 parse error - %3.") +                .arg(QString::number(line_number), line, error); +        emit report_message(messagetype::ERROR, filename, line_number, 0, error, ""); +        error_occured = true; +        if (error_ptr != nullptr) +            *error_ptr = error; +        return false; +    } +    std::uint32_t *p = inst; +    for (ssize_t l = 0; l < size; l += 4) { +        if (!fatal_occured) +            mem->write_word(address, *(p++)); +        address += 4; +    } +    return true; +} + +bool SimpleAsm::finish(QString *error_ptr) { +    bool error_reported = false; +    foreach(machine::RelocExpression *r, reloc) { +        QString error; +        fixmatheval::FmeExpression expression; +        if (!expression.parse(r->expression, error)) { +            error = tr("expression parse error %1 at line %2, expression %3.") +                    .arg(error, QString::number(r->line), expression.dump()); +            emit report_message(messagetype::ERROR, r->filename, r->line, 0, error, ""); +            if (error_ptr != nullptr && !error_reported) +                *error_ptr = error; +            error_occured = true; +            error_reported = true; +        } else { +            fixmatheval::FmeValue value; +            if (!expression.eval(value, symtab, error)) { +                error = tr("expression evalution error %1 at line %2 , expression %3.") +                        .arg(error, QString::number(r->line), expression.dump()); +                emit report_message(messagetype::ERROR, r->filename, r->line, 0, error, ""); +                if (error_ptr != nullptr && !error_reported) +                    *error_ptr = error; +                error_occured = true; +                error_reported = true; +            } else { +                if (false) +                    emit report_message(messagetype::INFO, r->filename, r->line, 0, +                                   expression.dump() + " -> " + QString::number(value), ""); +                machine::Instruction inst(mem->read_word(r->location, true)); +                if (!inst.update(value, r)) { +                    error = tr("instruction update error %1 at line %2, expression %3 -> value %4.") +                            .arg(error, QString::number(r->line), expression.dump(), QString::number(value)); +                    emit report_message(messagetype::ERROR, r->filename, r->line, 0, error, ""); +                    if (error_ptr != nullptr && !error_reported) +                        *error_ptr = error; +                    error_occured = true; +                    error_reported = true; +                } +                if (!fatal_occured) +                    mem->write_word(r->location, inst.data()); +            } +        } +    } +    while (!reloc.isEmpty()) { +        delete reloc.takeFirst(); +    } + +    emit mem->external_change_notify(mem, 0, 0xffffffff, true); + +    return !error_occured; +} diff --git a/qtmips_asm/simpleasm.h b/qtmips_asm/simpleasm.h new file mode 100644 index 0000000..773aa39 --- /dev/null +++ b/qtmips_asm/simpleasm.h @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + *   B35APO - Computer Architectures + *   https://cw.fel.cvut.cz/wiki/courses/b35apo + * + *   B4M35PAP - Advanced Computer Architectures + *   https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019      Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University        (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA  02110-1301, USA. + * + ******************************************************************************/ + +#ifndef  SIMPLEASM_H +#define  SIMPLEASM_H + +#include  <QString> +#include "fixmatheval.h" +#include "qtmipsmachine.h" +#include "messagetype.h" + +class SymbolTableDb : public fixmatheval::FmeSymbolDb { +public: +    SymbolTableDb(machine::SymbolTable *symtab); +    virtual bool getValue(fixmatheval::FmeValue &value, QString name) override; +    void setSymbol(QString name, std::uint32_t value, std::uint32_t size, +              unsigned char info = 0, unsigned char other = 0); +private: +    machine::SymbolTable *symtab; +}; + +class SimpleAsm : public QObject { +    Q_OBJECT + +    using Super = QObject; + +signals: +    void report_message(messagetype::Type type, QString file, int line, +                                   int column, QString text, QString hint); + +public: +    SimpleAsm(QObject *parent = nullptr); +    ~SimpleAsm(); +public: +    static std::uint64_t string_to_uint64(QString str, int base, +                                          int *chars_taken = nullptr); +    void clear(); +    void setup(machine::MemoryAccess *mem, SymbolTableDb *symtab, std::uint32_t address); +    bool process_line(QString line, QString filename = "", +                      int line_number = 0, QString *error_ptr = nullptr); +    bool finish(QString *error_ptr = nullptr); +private: +    bool error_occured; +    bool fatal_occured; +    SymbolTableDb *symtab; +    machine::MemoryAccess *mem; +    machine::RelocExpressionList reloc; +    std::uint32_t address; +}; + +#endif /*SIMPLEASM_H*/ diff --git a/qtmips_gui/mainwindow.cpp b/qtmips_gui/mainwindow.cpp index 0498ff3..87549d2 100644 --- a/qtmips_gui/mainwindow.cpp +++ b/qtmips_gui/mainwindow.cpp @@ -50,6 +50,7 @@  #include "fontsize.h"  #include "gotosymboldialog.h"  #include "fixmatheval.h" +#include "simpleasm.h"  #ifdef __EMSCRIPTEN__  #include <QFileInfo> @@ -691,45 +692,9 @@ void MainWindow::message_selected(messagetype::Type type, QString file, int line          central_window->setCurrentWidget(editor);  } -class SymbolTableDb : public fixmatheval::FmeSymbolDb { -public: -    SymbolTableDb(const machine::SymbolTable *symtab); -    virtual bool getValue(fixmatheval::FmeValue &value, QString name) override; -private: -    const machine::SymbolTable *symtab; -}; - -SymbolTableDb::SymbolTableDb(const machine::SymbolTable *symtab) { -    this->symtab = symtab; -} - -bool SymbolTableDb::getValue(fixmatheval::FmeValue &value, QString name) { -    std::uint32_t val; -    if (!symtab->name_to_value(val, name)) -        return false; -    value = val; -    return true; -} - -static std::uint64_t string_to_uint64(QString str, int base, -                                      int *chars_taken = nullptr) { -    int i; -    std::int64_t val; -    char *p, *r; -    char cstr[str.count() + 1]; -    for (i = 0; i < str.count(); i++) -        cstr[i] = str.at(i).toLatin1(); -    cstr[i] = 0; -    p = cstr; -    val = std::strtoll(p, &r, base); -    if (chars_taken != nullptr) -        *chars_taken = r - p; -    return val; -} -  void MainWindow::compile_source() { -    SymbolTableDb symtab(machine->symbol_table(true)); -    int error_line = 0; +    SymbolTableDb symtab(machine->symbol_table_rw(true)); +    bool error_occured;      if (current_srceditor == nullptr)          return;      if (machine == nullptr) { @@ -745,169 +710,24 @@ void MainWindow::compile_source() {      machine->cache_sync();      SrcEditor *editor = current_srceditor;      QTextDocument *doc = editor->document(); -    std::uint32_t address = 0x80020000; -    machine::RelocExpressionList reloc;      emit clear_messages(); +    SimpleAsm sasm; + +    connect(&sasm, SIGNAL(report_message(messagetype::Type,QString,int,int,QString,QString)), +            this, SIGNAL(report_message(messagetype::Type,QString,int,int,QString,QString))); + +    sasm.setup(mem, &symtab, 0x80020000);      int ln = 1;      for ( QTextBlock block = doc->begin(); block.isValid(); block = block.next(), ln++) { -        QString error; -        int pos; -        QString label = "";          QString line = block.text(); -        pos = line.indexOf("#"); -        if (pos >= 0) -            line.truncate(pos); -        pos = line.indexOf(";"); -        if (pos >= 0) -            line.truncate(pos); -        pos = line.indexOf("//"); -        if (pos >= 0) -            line.truncate(pos); -        line = line.simplified(); -        pos = line.indexOf(":"); -        if (pos >= 0) { -            label = line.mid(0, pos); -            line = line.mid(pos + 1).trimmed(); -            machine->set_symbol(label, address, 4); -        } -        if (line.isEmpty()) -            continue; -        int k = 0, l; -        while (k < line.count()) { -            if (!line.at(k).isSpace()) -                break; -            k++; -        } -        l = k; -        while (l < line.count()) { -            if (!line.at(l).isLetterOrNumber() && !(line.at(l) == '.')) -                break; -            l++; -        } -        QString op = line.mid(k, l - k).toUpper(); -        if ((op == ".DATA") || (op == ".TEXT") || -            (op == ".GLOBL") || (op == ".END") || -            (op == ".ENT")) { -            continue; -        } -        if (op == ".ORG") { -            bool ok; -            fixmatheval::FmeExpression expression; -            fixmatheval::FmeValue value; -            ok = expression.parse(line.mid(op.size()), error); -            if (ok) -                ok = expression.eval(value, &symtab, error); -            if (!ok) { -                error_line = ln; -                emit report_message(messagetype::ERROR, filename, ln, 0, -                               tr("line %1 .orig %2 parse error.") -                               .arg(QString::number(ln), line), ""); -                break; -            } -            address = value; -            continue; -        } -        if ((op == ".EQU") || (op == ".SET")) { -            QStringList operands = line.mid(op.size()).split(","); -            if ((operands.count() > 2) || (operands.count() < 1)) { -                error_line = ln; -                emit report_message(messagetype::ERROR, filename, ln, 0, -                               tr("line %1 .set or .equ incorrect arguments number.") -                               .arg(QString::number(ln)), ""); -                continue; -            } -            QString name = operands.at(0).trimmed(); -            if ((name == "noat") || (name == "noreored")) -                continue; -            bool ok; -            fixmatheval::FmeValue value = 1; -            if (operands.count() > 1) { -                fixmatheval::FmeExpression expression; -                ok = expression.parse(operands.at(1), error); -                if (ok) -                    ok = expression.eval(value, &symtab, error); -                if (!ok) { -                    error_line = ln; -                    emit report_message(messagetype::ERROR, filename, ln, 0, -                                  tr("line %1 .set or .equ %2 parse error.") -                                  .arg(QString::number(ln), operands.at(1)), ""); -                    continue; -                } -            } -            machine->set_symbol(name, value, 0); -            continue; -        } -        if (op == ".WORD") { -            foreach (QString s, line.mid(op.size()).split(",")) { -                s = s.simplified(); -                std::uint32_t val = 0; -                int chars_taken; -                val = string_to_uint64(s, 0, &chars_taken); -                if (chars_taken != s.size()) { -                    val = 0; -                    reloc.append(new machine::RelocExpression(address, s, 0, -                                 -0xffffffff, 0xffffffff, 0, 32, 0, ln, 0)); -                } -                mem->write_word(address, val); -                address += 4; -            } -            continue; -        } - -        std::uint32_t inst[2] = {0, 0}; -        ssize_t size = machine::Instruction::code_from_string(inst, 8, line, error, -                                                 address, &reloc, ln, true); -        if (size < 0) { -            error_line = ln; -            emit report_message(messagetype::ERROR, filename, ln, 0, -                              tr("line %1 instruction %2 parse error - %3.") -                              .arg(QString::number(ln), line, error), ""); -            continue; -        } -        std::uint32_t *p = inst; -        for (ssize_t l = 0; l < size; l += 4) { -            mem->write_word(address, *(p++)); -            address += 4; -        } +        if (!sasm.process_line(line, filename, ln)) +            error_occured = true;      } -    foreach(machine::RelocExpression *r, reloc) { -        QString error; -        fixmatheval::FmeExpression expression; -        if (!expression.parse(r->expression, error)) { -            error_line = r->line; -            emit report_message(messagetype::ERROR, filename, ln, 0, -                                tr("expression parse error %1 at line %2, expression %3.") -                                .arg(error, QString::number(r->line), expression.dump()), ""); -        } else { -            fixmatheval::FmeValue value; -            if (!expression.eval(value, &symtab, error)) { -                error_line = r->line; -                emit report_message(messagetype::ERROR, filename, ln, 0, -                               tr("expression evalution error %1 at line %2 , expression %3.") -                               .arg(error, QString::number(r->line), expression.dump()), ""); -            } else { -                if (false) -                    emit report_message(messagetype::INFO, filename, ln, 0, -                                   expression.dump() + " -> " + QString::number(value), ""); -                machine::Instruction inst(mem->read_word(r->location, true)); -                if (!inst.update(value, r)) { -                    error_line = r->line; -                    emit report_message(messagetype::ERROR, filename, ln, 0, -                                   tr("instruction update error %1 at line %2, expression %3 -> value %4.") -                                   .arg(error, QString::number(r->line), expression.dump(), QString::number(value)), ""); -                } -                mem->write_word(r->location, inst.data()); -            } -        } -    } -    while (!reloc.isEmpty()) { -        delete reloc.takeFirst(); -    } - -    emit mem->external_change_notify(mem, 0, 0xffffffff, true); +    if (!sasm.finish()) +        error_occured = true; -    if (error_line != 0) +    if (error_occured)          show_messages();  } diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index b30901f..547c666 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -1111,7 +1111,7 @@ static int parse_reg_from_string(QString str, uint *chars_taken = nullptr)  static void reloc_append(RelocExpressionList *reloc, QString fl, uint32_t inst_addr,                      std::int64_t offset, const ArgumentDesc *adesc, uint *chars_taken = nullptr, -                    int line = 0, int options = 0) { +                    QString filename = "", int line = 0, int options = 0) {      uint bits = IMF_SUB_GET_BITS(adesc->loc);      uint shift = IMF_SUB_GET_SHIFT(adesc->loc);      QString expression = ""; @@ -1130,7 +1130,7 @@ static void reloc_append(RelocExpressionList *reloc, QString fl, uint32_t inst_a      }      reloc->append(new RelocExpression(inst_addr, expression, offset, -                  adesc->min, adesc->max, shift, bits, adesc->shift, line, options)); +                  adesc->min, adesc->max, shift, bits, adesc->shift, filename, line, options));      if (chars_taken != nullptr) {          *chars_taken = i;      } @@ -1141,7 +1141,7 @@ static void reloc_append(RelocExpressionList *reloc, QString fl, uint32_t inst_a  ssize_t Instruction::code_from_string(std::uint32_t *code, size_t buffsize,                         QString inst_base, QStringList &inst_fields, QString &error,                         std::uint32_t inst_addr, RelocExpressionList *reloc, -                       int line, bool pseudo_opt, int options) +                       QString filename, int line, bool pseudo_opt, int options)  {      const char *err = "unknown instruction";      if (str_to_instruction_code_map.isEmpty()) @@ -1236,7 +1236,7 @@ ssize_t Instruction::code_from_string(std::uint32_t *code, size_t buffsize,                          need_reloc = true;                      }                      if (need_reloc && (reloc != nullptr)) { -                        reloc_append(reloc, fl, inst_addr, val, adesc, &chars_taken, line, options); +                        reloc_append(reloc, fl, inst_addr, val, adesc, &chars_taken, filename, line, options);                          val = 0;                      }                      break; @@ -1263,7 +1263,7 @@ ssize_t Instruction::code_from_string(std::uint32_t *code, size_t buffsize,                          need_reloc = true;                      }                      if (need_reloc && (reloc != nullptr)) { -                        reloc_append(reloc, fl, inst_addr, val, adesc, &chars_taken, line, options); +                        reloc_append(reloc, fl, inst_addr, val, adesc, &chars_taken, filename, line, options);                          val = 0;                      }                      break; @@ -1328,14 +1328,14 @@ ssize_t Instruction::code_from_string(std::uint32_t *code, size_t buffsize,      } else if (pseudo_opt) {          if (((inst_base == "LA") || (inst_base == "LI")) && (inst_fields.size() == 2)) {              if(code_from_string(code, buffsize, "LUI", inst_fields, error, -                             inst_addr, reloc, line, false, +                             inst_addr, reloc, filename, line, false,                               CFS_OPTION_SILENT_MASK + 16) < 0) {                  error = QString("error in LUI element of " + inst_base);                  return -1;              }              inst_fields.insert(1, inst_fields.at(0));              if (code_from_string(code + 1, buffsize - 4, "ORI", inst_fields, error, -                             inst_addr + 4, reloc, line, false, +                             inst_addr + 4, reloc, filename, line, false,                               CFS_OPTION_SILENT_MASK + 0) < 0) {                  error = QString("error in ORI element of " + inst_base);                  return -1; @@ -1353,7 +1353,8 @@ ssize_t Instruction::code_from_string(std::uint32_t *code, size_t buffsize,  ssize_t Instruction::code_from_string(std::uint32_t *code, size_t buffsize,                         QString str, QString &error, std::uint32_t inst_addr, -                       RelocExpressionList *reloc, int line, bool pseudo_opt, int options) +                       RelocExpressionList *reloc, QString filename, int line, +                       bool pseudo_opt, int options)  {      int k = 0, l;      while (k < str.count()) { @@ -1379,7 +1380,7 @@ ssize_t Instruction::code_from_string(std::uint32_t *code, size_t buffsize,      }      return code_from_string(code, buffsize, inst_base, inst_fields, error, inst_addr, -                            reloc, line, pseudo_opt, options); +                            reloc, filename, line, pseudo_opt, options);  }  bool Instruction::update(std::int64_t val, RelocExpression *relocexp) { diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h index b07a0e8..2ecd0c4 100644 --- a/qtmips_machine/instruction.h +++ b/qtmips_machine/instruction.h @@ -78,8 +78,8 @@ enum InstructionFlags {  struct RelocExpression {      inline RelocExpression(std::int32_t location, QString expression, std::int64_t offset, std::int64_t min, -                           std::int64_t max, unsigned lsb_bit, unsigned bits, unsigned shift, int line, -                           int options) { +                           std::int64_t max, unsigned lsb_bit, unsigned bits, unsigned shift, +                           QString filename, int line, int options) {          this->location = location;          this->expression = expression;          this->offset = offset; @@ -88,6 +88,7 @@ struct RelocExpression {          this->lsb_bit = lsb_bit;          this->bits = bits;          this->shift = shift; +        this->filename = filename;          this->line = line;          this->options = options;      } @@ -99,6 +100,7 @@ struct RelocExpression {      unsigned      lsb_bit;      unsigned      bits;      unsigned      shift; +    QString       filename;      int           line;      int           options;  }; @@ -152,11 +154,11 @@ public:                             QString inst_base, QStringList &inst_fields, QString &error,                             std::uint32_t inst_addr = 0,                             RelocExpressionList *reloc = nullptr, -                           int line = 0, bool pseudo_opt = false, int options = 0); +                           QString filename = "", int line = 0, bool pseudo_opt = false, int options = 0);      static ssize_t code_from_string(std::uint32_t *code, size_t buffsize,                             QString str, QString &error, std::uint32_t inst_addr = 0, -                           RelocExpressionList *reloc = nullptr, +                           RelocExpressionList *reloc = nullptr, QString filename = "",                             int line = 0, bool pseudo_opt = false, int options = 0);      bool update(std::int64_t val, RelocExpression *relocexp); diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp index e838429..b726bba 100644 --- a/qtmips_machine/qtmipsmachine.cpp +++ b/qtmips_machine/qtmipsmachine.cpp @@ -193,7 +193,6 @@ void QtMipsMachine::cache_sync() {          cch_data->sync();  } -  const PhysAddrSpace *QtMipsMachine::physical_address_space() {      return physaddrspace;  } @@ -214,19 +213,22 @@ LcdDisplay *QtMipsMachine::peripheral_lcd_display() {      return perip_lcd_display;  } -const SymbolTable *QtMipsMachine::symbol_table(bool create) { +SymbolTable *QtMipsMachine::symbol_table_rw(bool create) {      if (create && (symtab == nullptr))          symtab = new SymbolTable;      return symtab;  } +const SymbolTable *QtMipsMachine::symbol_table(bool create) { +    return symbol_table_rw(create); +} +  void QtMipsMachine::set_symbol(QString name, std::uint32_t value,                                 std::uint32_t size, unsigned char info,                                 unsigned char other) {      if (symtab == nullptr)          symtab = new SymbolTable; -    symtab->remove_symbol(name); -    symtab->add_symbol(name, value, size, info, other); +    symtab->set_symbol(name, value, size, info, other);  }  const Core *QtMipsMachine::core() { diff --git a/qtmips_machine/qtmipsmachine.h b/qtmips_machine/qtmipsmachine.h index e5bbdb3..7092ec3 100644 --- a/qtmips_machine/qtmipsmachine.h +++ b/qtmips_machine/qtmipsmachine.h @@ -77,6 +77,7 @@ public:      PeripSpiLed *peripheral_spi_led();      LcdDisplay *peripheral_lcd_display();      const SymbolTable *symbol_table(bool create = false); +    SymbolTable *symbol_table_rw(bool create = false);      void set_symbol(QString name, std::uint32_t value, std::uint32_t size,                      unsigned char info = 0, unsigned char other = 0);      const Core *core(); diff --git a/qtmips_machine/symboltable.cpp b/qtmips_machine/symboltable.cpp index d26491f..987b35f 100644 --- a/qtmips_machine/symboltable.cpp +++ b/qtmips_machine/symboltable.cpp @@ -75,6 +75,12 @@ void SymbolTable::remove_symbol(QString name) {      delete p_ste;  } +void SymbolTable::set_symbol(QString name, std::uint32_t value, std::uint32_t size, +          unsigned char info, unsigned char other) { +    remove_symbol(name); +    add_symbol(name, value, size, info, other); +} +  bool SymbolTable::name_to_value(std::uint32_t &value, QString name) const {      SymbolTableEntry *p_ste = map_name_to_symbol.value(name);      if (p_ste == nullptr) { diff --git a/qtmips_machine/symboltable.h b/qtmips_machine/symboltable.h index 0c33ac3..ece92a9 100644 --- a/qtmips_machine/symboltable.h +++ b/qtmips_machine/symboltable.h @@ -65,6 +65,8 @@ public:      void add_symbol(QString name, std::uint32_t value, std::uint32_t size,                unsigned char info = 0, unsigned char other = 0); +    void set_symbol(QString name, std::uint32_t value, std::uint32_t size, +              unsigned char info = 0, unsigned char other = 0);      void remove_symbol(QString name);      QStringList *names() const;  public slots: | 
