From b62686b24fbb65d0810475e24aba7a5c4ee3e05e Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Mon, 1 Jul 2019 18:37:54 +0200 Subject: 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 --- qtmips_machine/instruction.cpp | 41 ++++++++++++++++++++++++++++++++++++---- qtmips_machine/instruction.h | 28 ++++++++++++++++++++++++++- qtmips_machine/qtmipsmachine.cpp | 19 ++++++++++++++++++- qtmips_machine/qtmipsmachine.h | 3 +++ qtmips_machine/symboltable.cpp | 9 +++++++++ qtmips_machine/symboltable.h | 1 + 6 files changed, 95 insertions(+), 6 deletions(-) (limited to 'qtmips_machine') 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 #include +#include #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 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; -- cgit v1.2.3