diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-07-27 10:35:49 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-07-27 10:35:49 -0700 |
commit | 29426e5d765f10e10aeb3d5380a3fa91bd2bfed9 (patch) | |
tree | a96ef7fe00ad36ad0ec6baf25eece0e58ae6bc62 | |
parent | 3f4bbe9e5fd1389720c7adb5577edf2dc01d51e9 (diff) | |
download | mu-29426e5d765f10e10aeb3d5380a3fa91bd2bfed9.tar.gz |
4435 - make instruction packing less strict
Now it will pass labels straight through. But we may get more confusing error messages in later passes in some situations.
-rw-r--r-- | subx/023check_operand_sizes.cc | 2 | ||||
-rw-r--r-- | subx/024pack_instructions.cc | 25 |
2 files changed, 26 insertions, 1 deletions
diff --git a/subx/023check_operand_sizes.cc b/subx/023check_operand_sizes.cc index 158b1465..048cc28a 100644 --- a/subx/023check_operand_sizes.cc +++ b/subx/023check_operand_sizes.cc @@ -57,7 +57,7 @@ int32_t parse_int(const string& s) { istringstream in(s); int32_t result = 0; in >> std::hex >> result; - if (!in) { + if (!in || !in.eof()) { raise << "not a number: " << s << '\n' << end(); return 0; } diff --git a/subx/024pack_instructions.cc b/subx/024pack_instructions.cc index bbaa7369..62d47d22 100644 --- a/subx/024pack_instructions.cc +++ b/subx/024pack_instructions.cc @@ -145,6 +145,10 @@ void add_imm_bytes(const line& in, line& out) { void emit_hex_bytes(line& out, const word& w, int num) { assert(num <= 4); + if (!is_hex_int(w.data)) { + out.words.push_back(w); + return; + } uint32_t val = static_cast<uint32_t>(parse_int(w.data)); for (int i = 0; i < num; ++i) { out.words.push_back(hex_byte_text(val & 0xff)); @@ -152,6 +156,14 @@ void emit_hex_bytes(line& out, const word& w, int num) { } } +bool is_hex_int(const string& s) { + if (s.empty()) return false; + size_t pos = 0; + if (s.at(0) == '-' || s.at(0) == '+') pos++; + if (s.substr(pos, pos+2) == "0x") pos += 2; + return s.find_first_not_of("0123456789abcdefABCDEF", pos) == string::npos; +} + word hex_byte_text(uint8_t val) { ostringstream out; out << HEXBYTE << NUM(val); @@ -187,3 +199,16 @@ void transform(const string& text_bytes) { +translate: packing instruction 'bb 0x2a/imm32' +translate: instruction after packing: 'bb 2a 00 00 00' +run: copy imm32 0x0000002a to EBX + +:(scenarios transform) +:(scenario pack_silently_ignores_non_hex) +== 0x1 +# instruction effective address operand displacement immediate +# op subop mod rm32 base index scale r32 +# 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes + bb foo/imm32 # copy foo to EBX ++translate: packing instruction 'bb foo/imm32' +# no change (we're just not printing metadata to the trace) ++translate: instruction after packing: 'bb foo' +$error: 0 +:(scenarios run) |