4303 - subx: first real transform
We'll see if this is useful. Mostly just stretching our legs.
This commit is contained in:
parent
fc5b5e3704
commit
863a42d360
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue