From 863a42d3607f6e5bf48d33b5e7993ba183e79898 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 1 Jul 2018 00:01:13 -0700 Subject: [PATCH] 4303 - subx: first real transform We'll see if this is useful. Mostly just stretching our legs. --- subx/010core.cc | 2 +- subx/022transform_immediate.cc | 68 ++++++++++++++++++++++++++++++++-- subx/ex1.2.subx | 14 +++++++ 3 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 subx/ex1.2.subx diff --git a/subx/010core.cc b/subx/010core.cc index f8dcdf20..1dc9f16f 100644 --- a/subx/010core.cc +++ b/subx/010core.cc @@ -100,7 +100,7 @@ End_of_program = 0; // of its bytes, and run it void run(string text_bytes) { // Begin run() For Scenarios - cerr << text_bytes << '\n'; +//? cerr << text_bytes << '\n'; load_program(text_bytes, 1); // tests always assume a starting address of 1 EIP = 1; // preserve null pointer while (EIP < End_of_program) diff --git a/subx/022transform_immediate.cc b/subx/022transform_immediate.cc index 65ff95ce..bdbdd77e 100644 --- a/subx/022transform_immediate.cc +++ b/subx/022transform_immediate.cc @@ -1,19 +1,74 @@ +:(scenario translate_immediate_constants) +# opcode ModR/M SIB displacement immediate +# instruction mod, reg, Reg/Mem bits scale, index, base +# 1-3 bytes 0/1 byte 0/1 byte 0/1/2/4 bytes 0/1/2/4 bytes + bb 42/imm32 ++translate: converting '42/imm32' to '2a 00 00 00' ++run: copy imm32 0x0000002a to EBX + +#: we don't have a testable instruction using 8-bit immediates yet, so can't run this instruction +:(scenarios transform) +:(scenario translate_imm8) + cd 128/imm8 ++translate: converting '128/imm8' to '80' +:(scenarios run) + :(before "End One-time Setup") -Transform.push_back(skip_whitespace_and_comments); +Transform.push_back(transform_immediate); :(code) -void skip_whitespace_and_comments(const string& input, string& output) { - cerr << "running compiler phase\n"; +void transform_immediate(const string& input, string& output) { istringstream in(input); in >> std::noskipws; ostringstream out; while (has_data(in)) { string word = next_word(in); - out << word << ' '; + if (word.find("/imm") == string::npos) + out << word << ' '; + else { + string output = transform_immediate(word); + trace("translate") << "converting '" << word << "' to '" << output << "'" << end(); + out << output << ' '; + } } out.str().swap(output); } +string transform_immediate(const string& word) { + istringstream in(word); // 'word' is guaranteed to have no whitespace + string data = slurp_until(in, '/'); + istringstream in2(data); + int value = 0; + in2 >> value; + ostringstream out; + string type = next_word(in); + if (type == "imm32") emit_octets(value, 4, out); + else if (type == "imm8") emit_octets(value, 1, out); + else raise << "unknown immediate tag /" << type << '\n' << end(); + return out.str(); +} + +void emit_octets(int value, int num_octets, ostream& out) { + for (int i = 0; i < num_octets; ++i) { + if (i > 0) out << ' '; + out << HEXBYTE << (value & 0xff); + value = value >> 8; + } +} + +string slurp_until(istream& in, char delim) { + ostringstream out; + char c; + while (in >> c) { + if (c == delim) { + // drop the delim + break; + } + out << c; + } + return out.str(); +} + string next_word(istream& in) { skip_whitespace_and_comments(in); string result; @@ -37,3 +92,8 @@ void skip_comment(istream& in) { in >> c; } while (c != '\n'); } + +// helper +void transform(string/*copy*/ in) { + perform_all_transforms(in); +} diff --git a/subx/ex1.2.subx b/subx/ex1.2.subx new file mode 100644 index 00000000..c12c1902 --- /dev/null +++ b/subx/ex1.2.subx @@ -0,0 +1,14 @@ +## first program: same as https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html +# +# To run: +# $ subx translate ex1.2.subx ex1 +# $ subx run ex1 + +# opcode ModR/M SIB displacement immediate +# instruction mod, reg, Reg/Mem bits scale, index, base +# 1-3 bytes 0/1 byte 0/1 byte 0/1/2/4 bytes 0/1/2/4 bytes + bb 42/imm32 + 05 1/imm32 + cd 128/imm8 + +# vim:ft=subx