4303 - subx: first real transform

We'll see if this is useful. Mostly just stretching our legs.
This commit is contained in:
Kartik Agaram 2018-07-01 00:01:13 -07:00
parent fc5b5e3704
commit 863a42d360
3 changed files with 79 additions and 5 deletions

View File

@ -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)

View File

@ -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);
}

14
subx/ex1.2.subx Normal file
View File

@ -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