about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-07-01 00:01:13 -0700
committerKartik Agaram <vc@akkartik.com>2018-07-01 00:04:11 -0700
commit863a42d3607f6e5bf48d33b5e7993ba183e79898 (patch)
tree502949d4122461cb775d722cf722a7f17ea65aa4
parentfc5b5e3704c43f55ac19646e51d78d1b8141850b (diff)
downloadmu-863a42d3607f6e5bf48d33b5e7993ba183e79898.tar.gz
4303 - subx: first real transform
We'll see if this is useful. Mostly just stretching our legs.
-rw-r--r--subx/010core.cc2
-rw-r--r--subx/022transform_immediate.cc68
-rw-r--r--subx/ex1.2.subx14
3 files changed, 79 insertions, 5 deletions
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