aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine
diff options
context:
space:
mode:
Diffstat (limited to 'qtmips_machine')
-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
6 files changed, 95 insertions, 6 deletions
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;