about summary refs log tree commit diff stats
path: root/subx/018jump_disp32.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-03-12 18:56:55 -0700
committerKartik Agaram <vc@akkartik.com>2019-03-12 19:14:12 -0700
commit4a943d4ed313eff001504c2b5c472266e86a38af (patch)
treea5757233a8c81b303a808f251180c7344071ed51 /subx/018jump_disp32.cc
parent43711b0e9f18e0225ce14687fb6ea0902aa6fc61 (diff)
downloadmu-4a943d4ed313eff001504c2b5c472266e86a38af.tar.gz
5001 - drop the :(scenario) DSL
I've been saying for a while[1][2][3] that adding extra abstractions makes
things harder for newcomers, and adding new notations doubly so. And then
I notice this DSL in my own backyard. Makes me feel like a hypocrite.

[1] https://news.ycombinator.com/item?id=13565743#13570092
[2] https://lobste.rs/s/to8wpr/configuration_files_are_canary_warning
[3] https://lobste.rs/s/mdmcdi/little_languages_by_jon_bentley_1986#c_3miuf2

The implementation of the DSL was also highly hacky:

a) It was happening in the tangle/ tool, but was utterly unrelated to tangling
layers.

b) There were several persnickety constraints on the different kinds of
lines and the specific order they were expected in. I kept finding bugs
where the translator would silently do the wrong thing. Or the error messages
sucked, and readers may be stuck looking at the generated code to figure
out what happened. Fixing error messages would require a lot more code,
which is one of my arguments against DSLs in the first place: they may
be easy to implement, but they're hard to design to go with the grain of
the underlying platform. They require lots of iteration. Is that effort
worth prioritizing in this project?

On the other hand, the DSL did make at least some readers' life easier,
the ones who weren't immediately put off by having to learn a strange syntax.
There were fewer quotes to parse, fewer backslash escapes.

Anyway, since there are also people who dislike having to put up with strange
syntaxes, we'll call that consideration a wash and tear this DSL out.

---

This commit was sheer drudgery. Hopefully it won't need to be redone with
a new DSL because I grow sick of backslashes.
Diffstat (limited to 'subx/018jump_disp32.cc')
-rw-r--r--subx/018jump_disp32.cc424
1 files changed, 254 insertions, 170 deletions
diff --git a/subx/018jump_disp32.cc b/subx/018jump_disp32.cc
index c86cd2df..836146ee 100644
--- a/subx/018jump_disp32.cc
+++ b/subx/018jump_disp32.cc
@@ -5,16 +5,22 @@
 :(before "End Initialize Op Names")
 put_new(Name, "e9", "jump disp32 bytes away (jmp)");
 
-:(scenario jump_disp32)
-== 0x1
-# op  ModR/M  SIB   displacement  immediate
-  e9                05 00 00 00               # skip 1 instruction
-  05                              00 00 00 01
-  05                              00 00 00 02
-+run: 0x00000001 opcode: e9
-+run: jump 5
-+run: 0x0000000b opcode: 05
--run: 0x00000006 opcode: 05
+:(code)
+void test_jump_disp32() {
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  e9                   05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: e9\n"
+      "run: jump 5\n"
+      "run: 0x0000000b opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000006 opcode: 05");
+}
 
 :(before "End Single-Byte Opcodes")
 case 0xe9: {  // jump disp32
@@ -29,17 +35,23 @@ case 0xe9: {  // jump disp32
 :(before "End Initialize Op Names")
 put_new(Name_0f, "84", "jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)");
 
-:(scenario je_disp32_success)
-% ZF = true;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 84                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: jump 5
-+run: 0x0000000c opcode: 05
--run: 0x00000007 opcode: 05
+:(code)
+void test_je_disp32_success() {
+  ZF = true;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 84                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: jump 5\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
+}
 
 :(before "End Two-Byte Opcodes Starting With 0f")
 case 0x84: {  // jump disp32 if ZF
@@ -51,34 +63,46 @@ case 0x84: {  // jump disp32 if ZF
   break;
 }
 
-:(scenario je_disp32_fail)
-% ZF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 84                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: 0x00000007 opcode: 05
-+run: 0x0000000c opcode: 05
--run: jump 5
+:(code)
+void test_je_disp32_fail() {
+  ZF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 84                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: 0x00000007 opcode: 05\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
+}
 
 //:: jump if not equal/not zero
 
 :(before "End Initialize Op Names")
 put_new(Name_0f, "85", "jump disp32 bytes away if not equal, if ZF is not set (jcc/jnz/jne)");
 
-:(scenario jne_disp32_success)
-% ZF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 85                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: jump 5
-+run: 0x0000000c opcode: 05
--run: 0x00000007 opcode: 05
+:(code)
+void test_jne_disp32_success() {
+  ZF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 85                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: jump 5\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
+}
 
 :(before "End Two-Byte Opcodes Starting With 0f")
 case 0x85: {  // jump disp32 unless ZF
@@ -90,36 +114,48 @@ case 0x85: {  // jump disp32 unless ZF
   break;
 }
 
-:(scenario jne_disp32_fail)
-% ZF = true;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 85                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: 0x00000007 opcode: 05
-+run: 0x0000000c opcode: 05
--run: jump 5
+:(code)
+void test_jne_disp32_fail() {
+  ZF = true;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 85                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: 0x00000007 opcode: 05\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
+}
 
 //:: jump if greater
 
 :(before "End Initialize Op Names")
 put_new(Name_0f, "8f", "jump disp32 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)");
 
-:(scenario jg_disp32_success)
-% ZF = false;
-% SF = false;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8f                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: jump 5
-+run: 0x0000000c opcode: 05
--run: 0x00000007 opcode: 05
+:(code)
+void test_jg_disp32_success() {
+  ZF = false;
+  SF = false;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8f                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: jump 5\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
+}
 
 :(before "End Two-Byte Opcodes Starting With 0f")
 case 0x8f: {  // jump disp32 if !SF and !ZF
@@ -131,37 +167,49 @@ case 0x8f: {  // jump disp32 if !SF and !ZF
   break;
 }
 
-:(scenario jg_disp32_fail)
-% ZF = false;
-% SF = true;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8f                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: 0x00000007 opcode: 05
-+run: 0x0000000c opcode: 05
--run: jump 5
+:(code)
+void test_jg_disp32_fail() {
+  ZF = false;
+  SF = true;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8f                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: 0x00000007 opcode: 05\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
+}
 
 //:: jump if greater or equal
 
 :(before "End Initialize Op Names")
 put_new(Name_0f, "8d", "jump disp32 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)");
 
-:(scenario jge_disp32_success)
-% SF = false;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8d                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: jump 5
-+run: 0x0000000c opcode: 05
--run: 0x00000007 opcode: 05
+:(code)
+void test_jge_disp32_success() {
+  SF = false;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8d                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: jump 5\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
+}
 
 :(before "End Two-Byte Opcodes Starting With 0f")
 case 0x8d: {  // jump disp32 if !SF
@@ -173,37 +221,49 @@ case 0x8d: {  // jump disp32 if !SF
   break;
 }
 
-:(scenario jge_disp32_fail)
-% SF = true;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8d                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: 0x00000007 opcode: 05
-+run: 0x0000000c opcode: 05
--run: jump 5
+:(code)
+void test_jge_disp32_fail() {
+  SF = true;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8d                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: 0x00000007 opcode: 05\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
+}
 
 //:: jump if lesser
 
 :(before "End Initialize Op Names")
 put_new(Name_0f, "8c", "jump disp32 bytes away if lesser, if SF != OF (jcc/jl/jnge)");
 
-:(scenario jl_disp32_success)
-% ZF = false;
-% SF = true;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8c                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: jump 5
-+run: 0x0000000c opcode: 05
--run: 0x00000007 opcode: 05
+:(code)
+void test_jl_disp32_success() {
+  ZF = false;
+  SF = true;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8c                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: jump 5\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
+}
 
 :(before "End Two-Byte Opcodes Starting With 0f")
 case 0x8c: {  // jump disp32 if SF and !ZF
@@ -215,52 +275,70 @@ case 0x8c: {  // jump disp32 if SF and !ZF
   break;
 }
 
-:(scenario jl_disp32_fail)
-% ZF = false;
-% SF = false;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8c                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: 0x00000007 opcode: 05
-+run: 0x0000000c opcode: 05
--run: jump 5
+:(code)
+void test_jl_disp32_fail() {
+  ZF = false;
+  SF = false;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8c                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: 0x00000007 opcode: 05\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
+}
 
 //:: jump if lesser or equal
 
 :(before "End Initialize Op Names")
 put_new(Name_0f, "8e", "jump disp32 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)");
 
-:(scenario jle_disp32_equal)
-% ZF = true;
-% SF = false;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8e                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: jump 5
-+run: 0x0000000c opcode: 05
--run: 0x00000007 opcode: 05
-
-:(scenario jle_disp32_lesser)
-% ZF = false;
-% SF = true;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8e                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: jump 5
-+run: 0x0000000c opcode: 05
--run: 0x00000007 opcode: 05
+:(code)
+void test_jle_disp32_equal() {
+  ZF = true;
+  SF = false;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8e                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: jump 5\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
+}
+
+:(code)
+void test_jle_disp32_lesser() {
+  ZF = false;
+  SF = true;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8e                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: jump 5\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05");
+}
 
 :(before "End Two-Byte Opcodes Starting With 0f")
 case 0x8e: {  // jump disp32 if SF or ZF
@@ -272,16 +350,22 @@ case 0x8e: {  // jump disp32 if SF or ZF
   break;
 }
 
-:(scenario jle_disp32_greater)
-% ZF = false;
-% SF = false;
-% OF = false;
-== 0x1
-# op      ModR/M  SIB   displacement  immediate
-  0f 8e                 05 00 00 00               # skip 1 instruction
-  05                                  00 00 00 01
-  05                                  00 00 00 02
-+run: 0x00000001 opcode: 0f
-+run: 0x00000007 opcode: 05
-+run: 0x0000000c opcode: 05
--run: jump 5
+:(code)
+void test_jle_disp32_greater() {
+  ZF = false;
+  SF = false;
+  OF = false;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  0f 8e                05 00 00 00               \n"  // skip 1 instruction
+      "  05                                 00 00 00 01 \n"
+      "  05                                 00 00 00 02 \n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: 0x00000001 opcode: 0f\n"
+      "run: 0x00000007 opcode: 05\n"
+      "run: 0x0000000c opcode: 05\n"
+  );
+  CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
+}