aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-07-17 19:48:43 +0200
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-07-17 19:48:43 +0200
commit139dcf818566f9f2a48d95cdab9ad9e2ac7c7978 (patch)
tree2003660ee71cd5df7e830ca8084c8e3ea8f6ab96 /qtmips_gui
parentda53e0174a90636c2a9469ef63b0aaa981f7bae3 (diff)
downloadqtmips-139dcf818566f9f2a48d95cdab9ad9e2ac7c7978.tar.gz
qtmips-139dcf818566f9f2a48d95cdab9ad9e2ac7c7978.tar.bz2
qtmips-139dcf818566f9f2a48d95cdab9ad9e2ac7c7978.zip
Simple assembler moved to separate class which is independent on Qt GUI API.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_gui')
-rw-r--r--qtmips_gui/mainwindow.cpp208
1 files changed, 14 insertions, 194 deletions
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();
}