aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-07-02 12:22:05 +0200
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-07-02 12:22:05 +0200
commitcf97513e757cdd25e6b1dd1fd584e4ec13d93cb1 (patch)
tree2fa12b7e17d460e3b9f39f024fcab863653b6823 /qtmips_machine
parentb62686b24fbb65d0810475e24aba7a5c4ee3e05e (diff)
downloadqtmips-cf97513e757cdd25e6b1dd1fd584e4ec13d93cb1.tar.gz
qtmips-cf97513e757cdd25e6b1dd1fd584e4ec13d93cb1.tar.bz2
qtmips-cf97513e757cdd25e6b1dd1fd584e4ec13d93cb1.zip
Evaluation of symbolic expressions in assembler added.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_machine')
-rw-r--r--qtmips_machine/instruction.cpp24
-rw-r--r--qtmips_machine/instruction.h7
2 files changed, 20 insertions, 11 deletions
diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp
index d7ff37a..99ca26b 100644
--- a/qtmips_machine/instruction.cpp
+++ b/qtmips_machine/instruction.cpp
@@ -1040,7 +1040,8 @@ 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) {
+ std::int64_t offset, const ArgumentDesc *adesc, uint *chars_taken = nullptr,
+ int line = 0) {
uint bits = IMF_SUB_GET_BITS(adesc->loc);
uint shift = IMF_SUB_GET_SHIFT(adesc->loc);
QString expression = "";
@@ -1059,22 +1060,20 @@ 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));
+ adesc->min, adesc->max, shift, bits, adesc->shift, line));
if (chars_taken != nullptr) {
*chars_taken = i;
}
}
Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr,
- RelocExpressionList *reloc) {
+ RelocExpressionList *reloc, int line) {
std::uint32_t code;
bool ok = false;
if (str_to_instruction_code_map.isEmpty())
instruction_from_string_build_base();
- str = str.toUpper();
-
QString inst_base = "";
QVector<QString> inst_fields(0);
bool prev_white = true;
@@ -1104,7 +1103,7 @@ Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr,
error = true;
break;
}
- inst_base = str.mid(l, k - l);
+ inst_base = str.mid(l, k - l).toUpper();
} else {
if ((field && !comma) || (!field && comma)) {
error = true;
@@ -1195,7 +1194,7 @@ Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr,
val += std::strtoull(p, &r, 0);
chars_taken = r - p;
} else {
- reloc_append(reloc, fl, val, inst_addr, adesc, &chars_taken);
+ reloc_append(reloc, fl, inst_addr, val, adesc, &chars_taken, line);
val = 0;
}
break;
@@ -1212,7 +1211,7 @@ Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr,
chars_taken = r - p;
break;
} else {
- reloc_append(reloc, fl, val, inst_addr, adesc, &chars_taken);
+ reloc_append(reloc, fl, val, inst_addr, adesc, &chars_taken, line);
val = 0;
}
}
@@ -1257,9 +1256,16 @@ Instruction Instruction::from_string(QString str, bool *pok, uint32_t inst_addr,
return Instruction(code);
}
- if (str == "NOP")
+ if (str.toUpper() == "NOP")
ok = true;
if (pok != nullptr)
*pok = ok;
return Instruction(0);
}
+
+bool Instruction::update(std::int64_t val, RelocExpression *relocexp) {
+ std::int64_t mask = ((1 << relocexp->bits) - 1) << relocexp->lsb_bit;
+ dt &= ~ mask;
+ dt |= (((val + relocexp->offset) >> relocexp->shift) << relocexp->lsb_bit) & mask;
+ return true;
+}
diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h
index f721835..d55b079 100644
--- a/qtmips_machine/instruction.h
+++ b/qtmips_machine/instruction.h
@@ -77,7 +77,7 @@ 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) {
+ std::int64_t max, unsigned lsb_bit, unsigned bits, unsigned shift, int line) {
this->location = location;
this->expression = expression;
this->offset = offset;
@@ -86,6 +86,7 @@ struct RelocExpression {
this->lsb_bit = lsb_bit;
this->bits = bits;
this->shift = shift;
+ this->line = line;
}
std::int32_t location;
QString expression;
@@ -95,6 +96,7 @@ struct RelocExpression {
unsigned lsb_bit;
unsigned bits;
unsigned shift;
+ int line;
};
typedef QVector<RelocExpression *> RelocExpressionList;
@@ -143,7 +145,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, RelocExpressionList *reloc = nullptr);
+ std::uint32_t inst_addr = 0, RelocExpressionList *reloc = nullptr, int line = 0);
+ bool update(std::int64_t val, RelocExpression *relocexp);
private:
std::uint32_t dt;
};