aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-07-01 18:37:54 +0200
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-07-01 18:37:54 +0200
commitb62686b24fbb65d0810475e24aba7a5c4ee3e05e (patch)
tree1071883f7f678d112126e6c934a4b9af4709619e
parent2db0208ed333e0bf232e396c1789085781f50d66 (diff)
downloadqtmips-b62686b24fbb65d0810475e24aba7a5c4ee3e05e.tar.gz
qtmips-b62686b24fbb65d0810475e24aba7a5c4ee3e05e.tar.bz2
qtmips-b62686b24fbb65d0810475e24aba7a5c4ee3e05e.zip
Minimal prototype of integrated assembler.
The labels are parsed and stored into symbol table but expressions dependent on symbols values are not evaluated. Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r--qtmips_gui/MainWindow.ui15
-rw-r--r--qtmips_gui/mainwindow.cpp57
-rw-r--r--qtmips_gui/mainwindow.h2
-rw-r--r--qtmips_gui/programmodel.cpp3
-rw-r--r--qtmips_machine/instruction.cpp41
-rw-r--r--qtmips_machine/instruction.h28
-rw-r--r--qtmips_machine/qtmipsmachine.cpp19
-rw-r--r--qtmips_machine/qtmipsmachine.h3
-rw-r--r--qtmips_machine/symboltable.cpp9
-rw-r--r--qtmips_machine/symboltable.h1
10 files changed, 171 insertions, 7 deletions
diff --git a/qtmips_gui/MainWindow.ui b/qtmips_gui/MainWindow.ui
index 3202726..92fa695 100644
--- a/qtmips_gui/MainWindow.ui
+++ b/qtmips_gui/MainWindow.ui
@@ -101,6 +101,7 @@
<addaction name="separator"/>
<addaction name="actionRestart"/>
<addaction name="actionShow_Symbol"/>
+ <addaction name="actionCompileSource"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
@@ -239,6 +240,20 @@
<string>Ctrl+C</string>
</property>
</action>
+ <action name="actionCompileSource">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Compile Source</string>
+ </property>
+ <property name="toolTip">
+ <string>Compile source and update memory</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+C</string>
+ </property>
+ </action>
<action name="actionExit">
<property name="icon">
<iconset resource="icons.qrc">
diff --git a/qtmips_gui/mainwindow.cpp b/qtmips_gui/mainwindow.cpp
index 241a623..8a7956f 100644
--- a/qtmips_gui/mainwindow.cpp
+++ b/qtmips_gui/mainwindow.cpp
@@ -41,6 +41,8 @@
#include <QFile>
#include <QFileInfo>
#include <QMessageBox>
+#include <QTextDocument>
+#include <iostream>
#include "mainwindow.h"
#include "aboutdialog.h"
@@ -107,6 +109,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
connect(ui->actionSave, SIGNAL(triggered(bool)), this, SLOT(save_source()));
connect(ui->actionSaveAs, SIGNAL(triggered(bool)), this, SLOT(save_source_as()));
connect(ui->actionClose, SIGNAL(triggered(bool)), this, SLOT(close_source()));
+ connect(ui->actionCompileSource, SIGNAL(triggered(bool)), this, SLOT(compile_source()));
connect(ui->actionShow_Symbol, SIGNAL(triggered(bool)), this, SLOT(show_symbol_dialog()));
connect(ui->actionRegisters, SIGNAL(triggered(bool)), this, SLOT(show_registers()));
connect(ui->actionProgram_memory, SIGNAL(triggered(bool)), this, SLOT(show_program()));
@@ -458,10 +461,12 @@ void MainWindow::setCurrentSrcEditor(SrcEditor *srceditor) {
ui->actionSave->setEnabled(false);
ui->actionSaveAs->setEnabled(false);
ui->actionClose->setEnabled(false);
+ ui->actionCompileSource->setEnabled(false);
} else {
ui->actionSave->setEnabled(true);
ui->actionSaveAs->setEnabled(true);
ui->actionClose->setEnabled(true);
+ ui->actionCompileSource->setEnabled(true);
}
}
@@ -540,3 +545,55 @@ void MainWindow::close_source() {
central_window->removeTab(idx);
delete editor;
}
+
+void MainWindow::compile_source() {
+ if (current_srceditor == nullptr)
+ return;
+ if (machine == nullptr) {
+ QMessageBox::critical(this, "QtMips Error", tr("No machine to store program."));
+ return;
+ }
+ machine::MemoryAccess *mem = machine->physical_address_space_rw();
+ if (mem == nullptr) {
+ QMessageBox::critical(this, "QtMips Error", tr("No physical addresspace to store program."));
+ return;
+ }
+ machine->cache_sync();
+ SrcEditor *editor = current_srceditor;
+ QTextDocument *doc = editor->document();
+ std::uint32_t address = 0x80020000;
+ machine::RelocExpressionList reloc;
+
+ int ln = 1;
+ bool ok;
+ for ( QTextBlock block = doc->begin(); block.isValid(); block = block.next(), ln++) {
+ 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);
+ 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);
+ }
+ machine::Instruction inst;
+ inst = machine::Instruction::from_string(line, &ok, address, &reloc);
+ mem->write_word(address, inst.data());
+ address += 4;
+ }
+ foreach(machine::RelocExpression *r, reloc) {
+ QString e = r->expression;
+
+
+ delete r;
+ }
+
+ emit mem->external_change_notify(mem, 0, 0xffffffff, true);
+}
diff --git a/qtmips_gui/mainwindow.h b/qtmips_gui/mainwindow.h
index b051309..f75d31e 100644
--- a/qtmips_gui/mainwindow.h
+++ b/qtmips_gui/mainwindow.h
@@ -77,6 +77,7 @@ public slots:
void save_source();
void save_source_as();
void close_source();
+ void compile_source();
void show_registers();
void show_program();
void show_memory();
@@ -124,7 +125,6 @@ private:
bool coreview_shown;
SrcEditor *current_srceditor;
-
QActionGroup *speed_group;
QSettings *settings;
diff --git a/qtmips_gui/programmodel.cpp b/qtmips_gui/programmodel.cpp
index 9098ab1..64dffb8 100644
--- a/qtmips_gui/programmodel.cpp
+++ b/qtmips_gui/programmodel.cpp
@@ -176,6 +176,9 @@ void ProgramModel::setup(machine::QtMipsMachine *machine) {
stage_addr[i] = machine::STAGEADDR_NONE;
if (machine != nullptr)
connect(machine, SIGNAL(post_tick()), this, SLOT(check_for_updates()));
+ if (mem_access() != nullptr)
+ connect(mem_access(), SIGNAL(external_change_notify(const MemoryAccess*,std::uint32_t,std::uint32_t,bool)),
+ this, SLOT(check_for_updates()));
emit update_all();
}
diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp
index d210ad9..d7ff37a 100644
--- a/qtmips_machine/instruction.cpp
+++ b/qtmips_machine/instruction.cpp
@@ -1039,7 +1039,34 @@ static int parse_reg_from_string(QString str, uint *chars_taken = nullptr)
return res;
}
-Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr) {
+static void reloc_append(RelocExpressionList *reloc, QString fl, uint32_t inst_addr,
+ std::int64_t offset, const ArgumentDesc *adesc, uint *chars_taken = nullptr) {
+ uint bits = IMF_SUB_GET_BITS(adesc->loc);
+ uint shift = IMF_SUB_GET_SHIFT(adesc->loc);
+ QString expression = "";
+ QString allowed_operators = "+-/*";
+ int i = 0;
+ for (; i < fl.size(); i++) {
+ QChar ch = fl.at(i);
+ if (ch.isSpace())
+ continue;
+ if (ch.isLetterOrNumber())
+ expression.append(ch);
+ else if (allowed_operators.indexOf(ch) >= 0)
+ expression.append(ch);
+ else
+ break;
+ }
+
+ reloc->append(new RelocExpression(inst_addr, expression, offset,
+ adesc->min, adesc->max, shift, bits, adesc->shift));
+ if (chars_taken != nullptr) {
+ *chars_taken = i;
+ }
+}
+
+Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr,
+ RelocExpressionList *reloc) {
std::uint32_t code;
bool ok = false;
@@ -1151,7 +1178,7 @@ Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr)
FALLTROUGH
case 'o':
case 'n':
- {
+ if(fl.at(0).isDigit() || (reloc == nullptr)) {
int i;
// Qt functions are limited, toLongLong would be usable
// but does not return information how many characters
@@ -1167,20 +1194,26 @@ Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr)
else
val += std::strtoull(p, &r, 0);
chars_taken = r - p;
+ } else {
+ reloc_append(reloc, fl, val, inst_addr, adesc, &chars_taken);
+ val = 0;
}
break;
case 'a':
- {
+ val -= (inst_addr + 4) & 0xf0000000;
+ if(fl.at(0).isDigit() || (reloc == nullptr)) {
int i;
char cstr[fl.count() + 1];
for (i = 0; i < fl.count(); i++)
cstr[i] = fl.at(i).toLatin1();
cstr[i] = 0;
p = cstr;
- val -= (inst_addr + 4) & 0xf0000000;
val += std::strtoull(p, &r, 0);
chars_taken = r - p;
break;
+ } else {
+ reloc_append(reloc, fl, val, inst_addr, adesc, &chars_taken);
+ val = 0;
}
}
if (chars_taken <= 0) {
diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h
index f86d10c..f721835 100644
--- a/qtmips_machine/instruction.h
+++ b/qtmips_machine/instruction.h
@@ -38,6 +38,7 @@
#include <QObject>
#include <QString>
+#include <QVector>
#include "machinedefs.h"
@@ -74,6 +75,30 @@ enum InstructionFlags {
IMF_STOP_IF = 1L<<23, /**< Stop instruction fetch until instruction processed */
};
+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) {
+ this->location = location;
+ this->expression = expression;
+ this->offset = offset;
+ this->min = min;
+ this->max = max;
+ this->lsb_bit = lsb_bit;
+ this->bits = bits;
+ this->shift = shift;
+ }
+ 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;
+};
+
+typedef QVector<RelocExpression *> RelocExpressionList;
+
class Instruction {
public:
Instruction();
@@ -117,7 +142,8 @@ public:
QString to_str(std::int32_t inst_addr = 0) const;
- static Instruction from_string(QString str, bool *pok = nullptr, std::uint32_t inst_addr = 0);
+ static Instruction from_string(QString str, bool *pok = nullptr,
+ std::uint32_t inst_addr = 0, RelocExpressionList *reloc = nullptr);
private:
std::uint32_t dt;
};
diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp
index 8299ddf..68eeeca 100644
--- a/qtmips_machine/qtmipsmachine.cpp
+++ b/qtmips_machine/qtmipsmachine.cpp
@@ -186,7 +186,15 @@ Cache *QtMipsMachine::cache_data_rw() {
return cch_data;
}
-const PhysAddrSpace *QtMipsMachine::physical_address_space() {
+void QtMipsMachine::cache_sync() {
+ if (cch_program != nullptr)
+ cch_program->sync();
+ if (cch_data != nullptr)
+ cch_data->sync();
+}
+
+
+const PhysAddrSpace *QtMipsMachine::physical_address_space() {
return physaddrspace;
}
@@ -210,6 +218,15 @@ const SymbolTable *QtMipsMachine::symbol_table() {
return symtab;
}
+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);
+}
+
const Core *QtMipsMachine::core() {
return cr;
}
diff --git a/qtmips_machine/qtmipsmachine.h b/qtmips_machine/qtmipsmachine.h
index 03cdad9..ef96e09 100644
--- a/qtmips_machine/qtmipsmachine.h
+++ b/qtmips_machine/qtmipsmachine.h
@@ -70,12 +70,15 @@ public:
const Cache *cache_program();
const Cache *cache_data();
Cache *cache_data_rw();
+ void cache_sync();
const PhysAddrSpace *physical_address_space();
PhysAddrSpace *physical_address_space_rw();
SerialPort *serial_port();
PeripSpiLed *peripheral_spi_led();
LcdDisplay *peripheral_lcd_display();
const SymbolTable *symbol_table();
+ void set_symbol(QString name, std::uint32_t value, std::uint32_t size,
+ unsigned char info = 0, unsigned char other = 0);
const Core *core();
const CoreSingle *core_singe();
const CorePipelined *core_pipelined();
diff --git a/qtmips_machine/symboltable.cpp b/qtmips_machine/symboltable.cpp
index f22acaa..d26491f 100644
--- a/qtmips_machine/symboltable.cpp
+++ b/qtmips_machine/symboltable.cpp
@@ -66,6 +66,15 @@ void SymbolTable::add_symbol(QString name, std::uint32_t value, std::uint32_t si
map_name_to_symbol.insert(name, p_ste);
}
+void SymbolTable::remove_symbol(QString name) {
+ SymbolTableEntry *p_ste = map_name_to_symbol.value(name);
+ if (p_ste == nullptr)
+ return;
+ map_name_to_symbol.remove(name);
+ map_value_to_symbol.remove(p_ste->value, p_ste);
+ delete p_ste;
+}
+
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 174917c..0c33ac3 100644
--- a/qtmips_machine/symboltable.h
+++ b/qtmips_machine/symboltable.h
@@ -65,6 +65,7 @@ public:
void add_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:
bool name_to_value(std::uint32_t &value, QString name) const;