From 2d0c3b3e68ef76cf9e78bedac231c08b33277566 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 7 Jun 2020 23:59:08 -0700 Subject: 6502 --- html/018jump_disp32.cc.html | 106 +- html/apps/browse.mu.html | 254 +- html/apps/mu.subx.html | 29626 +++++++++++++++++++++--------------------- 3 files changed, 15233 insertions(+), 14753 deletions(-) (limited to 'html') diff --git a/html/018jump_disp32.cc.html b/html/018jump_disp32.cc.html index d8a41776..dad97deb 100644 --- a/html/018jump_disp32.cc.html +++ b/html/018jump_disp32.cc.html @@ -15,12 +15,12 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } -.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; } +.SpecialChar { color: #d70000; } .Comment { color: #005faf; } .Delimiter { color: #c000c0; } -.Special { color: #d70000; } .Identifier { color: #af5f00; } .Constant { color: #008787; } +.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; } .SalientComment { color: #0000af; } --> @@ -62,7 +62,7 @@ if ('onhashchange' in window) { 3 //:: jump 4 5 :(before "End Initialize Op Names") - 6 put_new(Name, "e9", "jump disp32 bytes away (jmp)"); + 6 put_new(Name, "e9", "jump disp32 bytes away (jmp)"); 7 8 :(code) 9 void test_jump_disp32() { @@ -73,18 +73,18 @@ if ('onhashchange' in window) { 14 " 05 00 00 00 01 \n" 15 " 05 00 00 00 02 \n" 16 ); - 17 CHECK_TRACE_CONTENTS( + 17 CHECK_TRACE_CONTENTS( 18 "run: 0x00000001 opcode: e9\n" 19 "run: jump 5\n" 20 "run: 0x0000000b opcode: 05\n" 21 ); - 22 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000006 opcode: 05"); + 22 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000006 opcode: 05"); 23 } 24 25 :(before "End Single-Byte Opcodes") 26 case 0xe9: { // jump disp32 27 const int32_t offset = next32(); - 28 trace(Callstack_depth+1, "run") << "jump " << offset << end(); + 28 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 29 EIP += offset; 30 break; 31 } @@ -92,7 +92,7 @@ if ('onhashchange' in window) { 33 //:: jump if equal/zero 34 35 :(before "End Initialize Op Names") - 36 put_new(Name_0f, "84", "jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)"); + 36 put_new(Name_0f, "84", "jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)"); 37 38 :(code) 39 void test_je_disp32_success() { @@ -104,19 +104,19 @@ if ('onhashchange' in window) { 45 " 05 00 00 00 01 \n" 46 " 05 00 00 00 02 \n" 47 ); - 48 CHECK_TRACE_CONTENTS( + 48 CHECK_TRACE_CONTENTS( 49 "run: 0x00000001 opcode: 0f\n" 50 "run: jump 5\n" 51 "run: 0x0000000c opcode: 05\n" 52 ); - 53 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); + 53 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); 54 } 55 56 :(before "End Two-Byte Opcodes Starting With 0f") 57 case 0x84: { // jump disp32 if ZF 58 const int32_t offset = next32(); 59 if (ZF) { - 60 trace(Callstack_depth+1, "run") << "jump " << offset << end(); + 60 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 61 EIP += offset; 62 } 63 break; @@ -132,18 +132,18 @@ if ('onhashchange' in window) { 73 " 05 00 00 00 01 \n" 74 " 05 00 00 00 02 \n" 75 ); - 76 CHECK_TRACE_CONTENTS( + 76 CHECK_TRACE_CONTENTS( 77 "run: 0x00000001 opcode: 0f\n" 78 "run: 0x00000007 opcode: 05\n" 79 "run: 0x0000000c opcode: 05\n" 80 ); - 81 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); + 81 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); 82 } 83 84 //:: jump if not equal/not zero 85 86 :(before "End Initialize Op Names") - 87 put_new(Name_0f, "85", "jump disp32 bytes away if not equal, if ZF is not set (jcc/jnz/jne)"); + 87 put_new(Name_0f, "85", "jump disp32 bytes away if not equal, if ZF is not set (jcc/jnz/jne)"); 88 89 :(code) 90 void test_jne_disp32_success() { @@ -155,19 +155,19 @@ if ('onhashchange' in window) { 96 " 05 00 00 00 01 \n" 97 " 05 00 00 00 02 \n" 98 ); - 99 CHECK_TRACE_CONTENTS( + 99 CHECK_TRACE_CONTENTS( 100 "run: 0x00000001 opcode: 0f\n" 101 "run: jump 5\n" 102 "run: 0x0000000c opcode: 05\n" 103 ); -104 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +104 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); 105 } 106 107 :(before "End Two-Byte Opcodes Starting With 0f") 108 case 0x85: { // jump disp32 if !ZF 109 const int32_t offset = next32(); 110 if (!ZF) { -111 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +111 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 112 EIP += offset; 113 } 114 break; @@ -183,19 +183,19 @@ if ('onhashchange' in window) { 124 " 05 00 00 00 01 \n" 125 " 05 00 00 00 02 \n" 126 ); -127 CHECK_TRACE_CONTENTS( +127 CHECK_TRACE_CONTENTS( 128 "run: 0x00000001 opcode: 0f\n" 129 "run: 0x00000007 opcode: 05\n" 130 "run: 0x0000000c opcode: 05\n" 131 ); -132 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +132 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); 133 } 134 135 //:: jump if greater 136 137 :(before "End Initialize Op Names") -138 put_new(Name_0f, "8f", "jump disp32 bytes away if greater (signed), if ZF is unset and SF == OF (jcc/jg/jnle)"); -139 put_new(Name_0f, "87", "jump disp32 bytes away if greater (unsigned), if ZF is unset and CF is unset (jcc/ja/jnbe)"); +138 put_new(Name_0f, "8f", "jump disp32 bytes away if greater (signed), if ZF is unset and SF == OF (jcc/jg/jnle)"); +139 put_new(Name_0f, "87", "jump disp32 bytes away if greater (unsigned), if ZF is unset and CF is unset (jcc/ja/jnbe)"); 140 141 :(code) 142 void test_jg_disp32_success() { @@ -209,27 +209,27 @@ if ('onhashchange' in window) { 150 " 05 00 00 00 01 \n" 151 " 05 00 00 00 02 \n" 152 ); -153 CHECK_TRACE_CONTENTS( +153 CHECK_TRACE_CONTENTS( 154 "run: 0x00000001 opcode: 0f\n" 155 "run: jump 5\n" 156 "run: 0x0000000c opcode: 05\n" 157 ); -158 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +158 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); 159 } 160 161 :(before "End Two-Byte Opcodes Starting With 0f") 162 case 0x8f: { // jump disp32 if !SF and !ZF 163 const int32_t offset = next32(); 164 if (!ZF && SF == OF) { -165 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +165 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 166 EIP += offset; 167 } 168 break; 169 } 170 case 0x87: { // jump disp32 if !CF and !ZF -171 const int32_t offset = next(); +171 const int32_t offset = next32(); 172 if (!CF && !ZF) { -173 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +173 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 174 EIP += offset; 175 } 176 break; @@ -247,19 +247,19 @@ if ('onhashchange' in window) { 188 " 05 00 00 00 01 \n" 189 " 05 00 00 00 02 \n" 190 ); -191 CHECK_TRACE_CONTENTS( +191 CHECK_TRACE_CONTENTS( 192 "run: 0x00000001 opcode: 0f\n" 193 "run: 0x00000007 opcode: 05\n" 194 "run: 0x0000000c opcode: 05\n" 195 ); -196 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +196 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); 197 } 198 199 //:: jump if greater or equal 200 201 :(before "End Initialize Op Names") -202 put_new(Name_0f, "8d", "jump disp32 bytes away if greater or equal (signed), if SF == OF (jcc/jge/jnl)"); -203 put_new(Name_0f, "83", "jump disp32 bytes away if greater or equal (unsigned), if CF is unset (jcc/jae/jnb)"); +202 put_new(Name_0f, "8d", "jump disp32 bytes away if greater or equal (signed), if SF == OF (jcc/jge/jnl)"); +203 put_new(Name_0f, "83", "jump disp32 bytes away if greater or equal (unsigned), if CF is unset (jcc/jae/jnb)"); 204 205 :(code) 206 void test_jge_disp32_success() { @@ -272,19 +272,19 @@ if ('onhashchange' in window) { 213 " 05 00 00 00 01 \n" 214 " 05 00 00 00 02 \n" 215 ); -216 CHECK_TRACE_CONTENTS( +216 CHECK_TRACE_CONTENTS( 217 "run: 0x00000001 opcode: 0f\n" 218 "run: jump 5\n" 219 "run: 0x0000000c opcode: 05\n" 220 ); -221 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +221 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); 222 } 223 224 :(before "End Two-Byte Opcodes Starting With 0f") 225 case 0x8d: { // jump disp32 if !SF 226 const int32_t offset = next32(); 227 if (SF == OF) { -228 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +228 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 229 EIP += offset; 230 } 231 break; @@ -292,7 +292,7 @@ if ('onhashchange' in window) { 233 case 0x83: { // jump disp32 if !CF 234 const int32_t offset = next32(); 235 if (!CF) { -236 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +236 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 237 EIP += offset; 238 } 239 break; @@ -309,19 +309,19 @@ if ('onhashchange' in window) { 250 " 05 00 00 00 01 \n" 251 " 05 00 00 00 02 \n" 252 ); -253 CHECK_TRACE_CONTENTS( +253 CHECK_TRACE_CONTENTS( 254 "run: 0x00000001 opcode: 0f\n" 255 "run: 0x00000007 opcode: 05\n" 256 "run: 0x0000000c opcode: 05\n" 257 ); -258 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +258 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); 259 } 260 261 //:: jump if lesser 262 263 :(before "End Initialize Op Names") -264 put_new(Name_0f, "8c", "jump disp32 bytes away if lesser (signed), if SF != OF (jcc/jl/jnge)"); -265 put_new(Name_0f, "82", "jump disp32 bytes away if lesser (unsigned), if CF is set (jcc/jb/jnae)"); +264 put_new(Name_0f, "8c", "jump disp32 bytes away if lesser (signed), if SF != OF (jcc/jl/jnge)"); +265 put_new(Name_0f, "82", "jump disp32 bytes away if lesser (unsigned), if CF is set (jcc/jb/jnae)"); 266 267 :(code) 268 void test_jl_disp32_success() { @@ -335,19 +335,19 @@ if ('onhashchange' in window) { 276 " 05 00 00 00 01 \n" 277 " 05 00 00 00 02 \n" 278 ); -279 CHECK_TRACE_CONTENTS( +279 CHECK_TRACE_CONTENTS( 280 "run: 0x00000001 opcode: 0f\n" 281 "run: jump 5\n" 282 "run: 0x0000000c opcode: 05\n" 283 ); -284 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +284 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); 285 } 286 287 :(before "End Two-Byte Opcodes Starting With 0f") 288 case 0x8c: { // jump disp32 if SF and !ZF 289 const int32_t offset = next32(); 290 if (SF != OF) { -291 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +291 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 292 EIP += offset; 293 } 294 break; @@ -355,7 +355,7 @@ if ('onhashchange' in window) { 296 case 0x82: { // jump disp32 if CF 297 const int32_t offset = next32(); 298 if (CF) { -299 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +299 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 300 EIP += offset; 301 } 302 break; @@ -373,19 +373,19 @@ if ('onhashchange' in window) { 314 " 05 00 00 00 01 \n" 315 " 05 00 00 00 02 \n" 316 ); -317 CHECK_TRACE_CONTENTS( +317 CHECK_TRACE_CONTENTS( 318 "run: 0x00000001 opcode: 0f\n" 319 "run: 0x00000007 opcode: 05\n" 320 "run: 0x0000000c opcode: 05\n" 321 ); -322 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +322 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); 323 } 324 325 //:: jump if lesser or equal 326 327 :(before "End Initialize Op Names") -328 put_new(Name_0f, "8e", "jump disp32 bytes away if lesser or equal (signed), if ZF is set or SF != OF (jcc/jle/jng)"); -329 put_new(Name_0f, "86", "jump disp32 bytes away if lesser or equal (unsigned), if ZF is set or CF is set (jcc/jbe/jna)"); +328 put_new(Name_0f, "8e", "jump disp32 bytes away if lesser or equal (signed), if ZF is set or SF != OF (jcc/jle/jng)"); +329 put_new(Name_0f, "86", "jump disp32 bytes away if lesser or equal (unsigned), if ZF is set or CF is set (jcc/jbe/jna)"); 330 331 :(code) 332 void test_jle_disp32_equal() { @@ -399,12 +399,12 @@ if ('onhashchange' in window) { 340 " 05 00 00 00 01 \n" 341 " 05 00 00 00 02 \n" 342 ); -343 CHECK_TRACE_CONTENTS( +343 CHECK_TRACE_CONTENTS( 344 "run: 0x00000001 opcode: 0f\n" 345 "run: jump 5\n" 346 "run: 0x0000000c opcode: 05\n" 347 ); -348 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +348 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); 349 } 350 351 :(code) @@ -419,19 +419,19 @@ if ('onhashchange' in window) { 360 " 05 00 00 00 01 \n" 361 " 05 00 00 00 02 \n" 362 ); -363 CHECK_TRACE_CONTENTS( +363 CHECK_TRACE_CONTENTS( 364 "run: 0x00000001 opcode: 0f\n" 365 "run: jump 5\n" 366 "run: 0x0000000c opcode: 05\n" 367 ); -368 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +368 CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); 369 } 370 371 :(before "End Two-Byte Opcodes Starting With 0f") 372 case 0x8e: { // jump disp32 if SF or ZF 373 const int32_t offset = next32(); 374 if (ZF || SF != OF) { -375 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +375 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 376 EIP += offset; 377 } 378 break; @@ -439,7 +439,7 @@ if ('onhashchange' in window) { 380 case 0x86: { // jump disp32 if ZF or CF 381 const int32_t offset = next32(); 382 if (ZF || CF) { -383 trace(Callstack_depth+1, "run") << "jump " << offset << end(); +383 trace(Callstack_depth+1, "run") << "jump " << offset << end(); 384 EIP += offset; 385 } 386 break; @@ -457,12 +457,12 @@ if ('onhashchange' in window) { 398 " 05 00 00 00 01 \n" 399 " 05 00 00 00 02 \n" 400 ); -401 CHECK_TRACE_CONTENTS( +401 CHECK_TRACE_CONTENTS( 402 "run: 0x00000001 opcode: 0f\n" 403 "run: 0x00000007 opcode: 05\n" 404 "run: 0x0000000c opcode: 05\n" 405 ); -406 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +406 CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); 407 } diff --git a/html/apps/browse.mu.html b/html/apps/browse.mu.html index a6fcc4cd..ede38500 100644 --- a/html/apps/browse.mu.html +++ b/html/apps/browse.mu.html @@ -65,15 +65,15 @@ if ('onhashchange' in window) { 7 # Press 'q' to quit. All other keys scroll down. 8 9 fn main args: (addr array (addr array byte)) -> exit-status/ebx: int { - 10 var filename/eax: (addr array byte) <- first-arg args - 11 var file/esi: (addr buffered-file) <- load-file filename + 10 var filename/eax: (addr array byte) <- first-arg args + 11 var file/esi: (addr buffered-file) <- load-file filename 12 enable-screen-grid-mode 13 var nrows/eax: int <- copy 0 14 var ncols/ecx: int <- copy 0 15 nrows, ncols <- screen-size 16 enable-keyboard-immediate-mode 17 { - 18 render file, nrows, ncols + 18 render file, nrows, ncols 19 var key/eax: byte <- read-key 20 compare key, 0x71 # 'q' 21 loop-if-!= @@ -83,102 +83,158 @@ if ('onhashchange' in window) { 25 exit-status <- copy 0 26 } 27 - 28 # decide how to lay out pages on screen - 29 fn render in: (addr buffered-file), nrows: int, ncols: int { - 30 # Fit multiple pages on screen on separate columns, each wide enough to read - 31 # comfortably. - 32 # Pages are separated horizontally by a 'page margin'. Among other reasons, - 33 # this allows the odd line to bleed out on the right if necessary. - 34 # - 35 # hardcoded parameters: - 36 # top-margin - 37 # page-margin - 38 # text-width - 39 var toprow/eax: int <- copy 2 # top-margin - 40 var botrow/ecx: int <- copy nrows - 41 var leftcol/edx: int <- copy 5 # page-margin - 42 var rightcol/ebx: int <- copy leftcol - 43 rightcol <- add 0x40 # text-width = 64 characters - 44 { - 45 compare rightcol, ncols - 46 break-if->= - 47 render-page in, toprow, leftcol, botrow, rightcol - 48 leftcol <- copy rightcol - 49 leftcol <- add 5 # page-margin - 50 rightcol <- copy leftcol - 51 rightcol <- add 0x40 # text-width - 52 loop - 53 } - 54 } - 55 - 56 fn render-page in: (addr buffered-file), toprow: int, leftcol: int, botrow: int, rightcol: int { - 57 clear toprow, leftcol, botrow, rightcol - 58 # render screen rows - 59 var row/ecx: int <- copy toprow - 60 $line-loop: { - 61 compare row, botrow - 62 break-if->= - 63 var col/edx: int <- copy leftcol - 64 move-cursor row, col - 65 { - 66 compare col, rightcol - 67 break-if->= - 68 var c/eax: byte <- read-byte-buffered in - 69 compare c, 0xffffffff # EOF marker - 70 break-if-= $line-loop - 71 compare c, 0xa # newline - 72 break-if-= # no need to print newlines - 73 print-byte c - 74 col <- increment - 75 loop - 76 } - 77 row <- increment - 78 loop - 79 } - 80 } - 81 - 82 fn clear toprow: int, leftcol: int, botrow: int, rightcol: int { - 83 var row/ecx: int <- copy toprow - 84 { - 85 compare row, botrow - 86 break-if->= - 87 var col/edx: int <- copy leftcol - 88 move-cursor row, col - 89 { - 90 compare col, rightcol - 91 break-if->= - 92 print-string " " - 93 col <- increment - 94 loop - 95 } - 96 row <- increment - 97 loop - 98 } - 99 } -100 -101 fn first-arg args-on-stack: (addr array (addr array byte)) -> out/eax: (addr array byte) { -102 var args/eax: (addr array (addr array byte)) <- copy args-on-stack -103 var result/eax: (addr addr array byte) <- index args, 1 -104 out <- copy *result -105 } -106 -107 fn load-file filename: (addr array byte) -> out/esi: (addr buffered-file) { -108 var result: (handle buffered-file) -109 { -110 var tmp1/eax: (addr handle buffered-file) <- address result -111 open filename, 0, tmp1 -112 } -113 var tmp2/eax: (addr buffered-file) <- lookup result -114 out <- copy tmp2 -115 } -116 -117 fn dump in: (addr buffered-file) { -118 var c/eax: byte <- read-byte-buffered in -119 compare c, 0xffffffff # EOF marker -120 break-if-= -121 print-byte c -122 loop -123 } + 28 type render-state { + 29 current-state: int # enum 0: normal, 1: bold + 30 } + 31 + 32 # decide how to lay out pages on screen + 33 fn render in: (addr buffered-file), nrows: int, ncols: int { + 34 # Fit multiple pages on screen on separate columns, each wide enough to read + 35 # comfortably. + 36 # Pages are separated horizontally by a 'page margin'. Among other reasons, + 37 # this allows the odd line to bleed out on the right if necessary. + 38 # + 39 # hardcoded parameters: + 40 # top-margin + 41 # page-margin + 42 # page-width + 43 var _r: render-state + 44 var r/edi: (addr render-state) <- address _r + 45 var toprow/eax: int <- copy 2 # top-margin + 46 var botrow/ecx: int <- copy nrows + 47 var leftcol/edx: int <- copy 5 # page-margin + 48 var rightcol/ebx: int <- copy leftcol + 49 rightcol <- add 0x40 # page-width = 64 characters + 50 start-color 0xec, 7 # 236 = darkish gray + 51 { + 52 compare rightcol, ncols + 53 break-if->= + 54 render-page in, toprow, leftcol, botrow, rightcol, r + 55 leftcol <- copy rightcol + 56 leftcol <- add 5 # page-margin + 57 rightcol <- copy leftcol + 58 rightcol <- add 0x40 # page-width + 59 loop + 60 } + 61 } + 62 + 63 fn render-page in: (addr buffered-file), toprow: int, leftcol: int, botrow: int, rightcol: int, r: (addr render-state) { + 64 clear toprow, leftcol, botrow, rightcol + 65 # render screen rows + 66 var row/ecx: int <- copy toprow + 67 $line-loop: { + 68 compare row, botrow + 69 break-if->= + 70 var col/edx: int <- copy leftcol + 71 move-cursor row, col + 72 { + 73 compare col, rightcol + 74 break-if->= + 75 var c/eax: byte <- read-byte-buffered in + 76 compare c, 0xffffffff # EOF marker + 77 break-if-= $line-loop + 78 update-attributes c, r + 79 compare c, 0xa # newline + 80 break-if-= # no need to print newlines + 81 print-byte c + 82 col <- increment + 83 loop + 84 } + 85 row <- increment + 86 loop + 87 } + 88 } + 89 + 90 fn update-attributes c: byte, _r: (addr render-state) { + 91 var r/edi: (addr render-state) <- copy _r + 92 var state/esi: (addr int) <- get r, current-state + 93 $update-attributes:check-state: { + 94 compare *state, 0 # normal + 95 { + 96 break-if-!= + 97 compare c, 0x2a # '*' + 98 { + 99 break-if-!= +100 # r->current-state == 0 && c == '*' +101 start-bold +102 copy-to *state, 1 +103 break $update-attributes:check-state +104 } +105 compare c, 0x5f # '_' +106 { +107 break-if-!= +108 # r->current-state == 0 && c == '_' +109 start-bold +110 copy-to *state, 1 +111 break $update-attributes:check-state +112 } +113 break $update-attributes:check-state +114 } +115 { +116 break-if-= +117 compare c, 0x2a # '*' +118 { +119 break-if-!= +120 # r->current-state == 1 && c == '*' +121 reset-formatting +122 copy-to *state, 0 +123 break $update-attributes:check-state +124 } +125 compare c, 0x5f # '_' +126 { +127 break-if-!= +128 # r->current-state == 1 && c == '_' +129 reset-formatting +130 copy-to *state, 0 +131 break $update-attributes:check-state +132 } +133 break $update-attributes:check-state +134 } +135 } +136 } +137 +138 fn clear toprow: int, leftcol: int, botrow: int, rightcol: int { +139 var row/ecx: int <- copy toprow +140 { +141 compare row, botrow +142 break-if->= +143 var col/edx: int <- copy leftcol +144 move-cursor row, col +145 { +146 compare col, rightcol +147 break-if->= +148 print-string " " +149 col <- increment +150 loop +151 } +152 row <- increment +153 loop +154 } +155 } +156 +157 fn first-arg args-on-stack: (addr array (addr array byte)) -> out/eax: (addr array byte) { +158 var args/eax: (addr array (addr array byte)) <- copy args-on-stack +159 var result/eax: (addr addr array byte) <- index args, 1 +160 out <- copy *result +161 } +162 +163 fn load-file filename: (addr array byte) -> out/esi: (addr buffered-file) { +164 var result: (handle buffered-file) +165 { +166 var tmp1/eax: (addr handle buffered-file) <- address result +167 open filename, 0, tmp1 +168 } +169 var tmp2/eax: (addr buffered-file) <- lookup result +170 out <- copy tmp2 +171 } +172 +173 fn dump in: (addr buffered-file) { +174 var c/eax: byte <- read-byte-buffered in +175 compare c, 0xffffffff # EOF marker +176 break-if-= +177 print-byte c +178 loop +179 } diff --git a/html/apps/mu.subx.html b/html/apps/mu.subx.html index d6d57b25..816aa562 100644 --- a/html/apps/mu.subx.html +++ b/html/apps/mu.subx.html @@ -417,1190 +417,1190 @@ if ('onhashchange' in window) { 355 Stmt-var-size: # (addr int) 356 0x14/imm32 357 - 358 # Types are expressed as trees (s-expressions) of type-ids (ints). - 359 # However, there's no need for singletons, so we can assume (int) == int - 360 # - if x->right == nil, x is an atom - 361 # - x->left contains either a pointer to a pair, or an atomic type-id directly. - 362 - 363 Tree-is-atom: # boolean - 364 0/imm32 - 365 # if left-is-atom? - 366 Tree-value: # type-id - 367 4/imm32 - 368 # unless left-is-atom? - 369 Tree-left: # (addr tree type-id) - 370 4/imm32 - 371 Tree-right: # (addr tree type-id) - 372 0xc/imm32 - 373 # - 374 Tree-size: # (addr int) - 375 0x14/imm32 - 376 - 377 # Types - 378 - 379 # TODO: heap allocations here can't be reclaimed - 380 Type-id: # (stream (addr array byte)) - 381 0x1c/imm32/write - 382 0/imm32/read - 383 0x100/imm32/size - 384 # data - 385 "literal"/imm32 # 0: value is just the name - 386 "int"/imm32 # 1 - 387 "addr"/imm32 # 2 - 388 "array"/imm32 # 3 - 389 "handle"/imm32 # 4 - 390 "boolean"/imm32 # 5 - 391 "constant"/imm32 # 6: like a literal, but value is an int in Var-offset - 392 "offset"/imm32 # 7: (offset T) is guaranteed to be a 32-bit multiple of size-of(T) - 393 0/imm32 - 394 # 0x20 - 395 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 396 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 397 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 398 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 399 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 400 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 401 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 402 - 403 # == Type definitions - 404 # Program->types contains some typeinfo for each type definition. - 405 # Types contain vars with types, but can't specify registers. - 406 Typeinfo-id: # type-id - 407 0/imm32 - 408 Typeinfo-fields: # (handle table (handle array byte) (handle typeinfo-entry)) - 409 4/imm32 - 410 # Total size must be >= 0 - 411 # During parsing it may take on two additional values: - 412 # -2: not yet initialized - 413 # -1: in process of being computed - 414 # See populate-mu-type-sizes for details. - 415 Typeinfo-total-size-in-bytes: # int - 416 0xc/imm32 - 417 Typeinfo-next: # (handle typeinfo) - 418 0x10/imm32 - 419 Typeinfo-size: # (addr int) - 420 0x18/imm32 - 421 - 422 # Each entry in the typeinfo->fields table has a pointer to a string and a - 423 # pointer to a typeinfo-entry. - 424 Typeinfo-fields-row-size: # (addr int) - 425 0x10/imm32 - 426 - 427 # typeinfo-entry objects have information about a field in a single record type - 428 # - 429 # each field of a type is represented using two var's: - 430 # 1. the input var: expected type of the field; convenient for creating using parse-var-with-type - 431 # 2. the output var: a constant containing the byte offset; convenient for code-generation - 432 # computing the output happens after parsing; in the meantime we preserve the - 433 # order of fields in the 'index' field. - 434 Typeinfo-entry-input-var: # (handle var) - 435 0/imm32 - 436 Typeinfo-entry-index: # int - 437 8/imm32 - 438 Typeinfo-entry-output-var: # (handle var) - 439 0xc/imm32 - 440 Typeinfo-entry-size: # (addr int) - 441 0x14/imm32 - 442 - 443 == code - 444 - 445 Entry: - 446 # . prologue - 447 89/<- %ebp 4/r32/esp - 448 (new-segment *Heap-size Heap) - 449 # if (argv[1] == "test') run-tests() - 450 { - 451 # if (argc <= 1) break - 452 81 7/subop/compare *ebp 1/imm32 - 453 7e/jump-if-<= break/disp8 - 454 # if (argv[1] != "test") break - 455 (kernel-string-equal? *(ebp+8) "test") # => eax - 456 3d/compare-eax-and 0/imm32/false - 457 74/jump-if-= break/disp8 - 458 # - 459 (run-tests) - 460 # syscall(exit, *Num-test-failures) - 461 8b/-> *Num-test-failures 3/r32/ebx - 462 eb/jump $mu-main:end/disp8 - 463 } - 464 # otherwise convert Stdin - 465 (convert-mu Stdin Stdout) - 466 (flush Stdout) - 467 # syscall(exit, 0) - 468 bb/copy-to-ebx 0/imm32 - 469 $mu-main:end: - 470 b8/copy-to-eax 1/imm32/exit - 471 cd/syscall 0x80/imm8 - 472 - 473 convert-mu: # in: (addr buffered-file), out: (addr buffered-file) - 474 # . prologue - 475 55/push-ebp - 476 89/<- %ebp 4/r32/esp - 477 # initialize global data structures - 478 c7 0/subop/copy *Next-block-index 1/imm32 - 479 c7 0/subop/copy *Type-id 0x1c/imm32 # stream-write - 480 c7 0/subop/copy *_Program-functions 0/imm32 - 481 c7 0/subop/copy *_Program-functions->payload 0/imm32 - 482 c7 0/subop/copy *_Program-types 0/imm32 - 483 c7 0/subop/copy *_Program-types->payload 0/imm32 - 484 # - 485 (parse-mu *(ebp+8)) - 486 (populate-mu-type-sizes) - 487 #? (dump-typeinfos "=== typeinfos\n") - 488 (check-mu-types) - 489 (emit-subx *(ebp+0xc)) - 490 $convert-mu:end: - 491 # . epilogue - 492 89/<- %esp 5/r32/ebp - 493 5d/pop-to-ebp - 494 c3/return - 495 - 496 test-convert-empty-input: - 497 # empty input => empty output - 498 # . prologue - 499 55/push-ebp - 500 89/<- %ebp 4/r32/esp - 501 # setup - 502 (clear-stream _test-input-stream) - 503 (clear-stream $_test-input-buffered-file->buffer) - 504 (clear-stream _test-output-stream) - 505 (clear-stream $_test-output-buffered-file->buffer) - 506 # - 507 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 508 (flush _test-output-buffered-file) - 509 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input") - 510 # . epilogue - 511 89/<- %esp 5/r32/ebp - 512 5d/pop-to-ebp - 513 c3/return - 514 - 515 test-convert-function-skeleton: - 516 # . prologue - 517 55/push-ebp - 518 89/<- %ebp 4/r32/esp - 519 # setup - 520 (clear-stream _test-input-stream) - 521 (clear-stream $_test-input-buffered-file->buffer) - 522 (clear-stream _test-output-stream) - 523 (clear-stream $_test-output-buffered-file->buffer) - 524 # - 525 (write _test-input-stream "fn foo {\n") - 526 (write _test-input-stream "}\n") - 527 # convert - 528 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 529 (flush _test-output-buffered-file) - 530 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 536 # check output - 537 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0") - 538 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-skeleton/1") - 539 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2") - 540 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3") - 541 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-skeleton/4") - 542 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5") - 543 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6") - 544 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7") - 545 # . epilogue - 546 89/<- %esp 5/r32/ebp - 547 5d/pop-to-ebp - 548 c3/return - 549 - 550 test-convert-multiple-function-skeletons: - 551 # . prologue - 552 55/push-ebp - 553 89/<- %ebp 4/r32/esp - 554 # setup - 555 (clear-stream _test-input-stream) - 556 (clear-stream $_test-input-buffered-file->buffer) - 557 (clear-stream _test-output-stream) - 558 (clear-stream $_test-output-buffered-file->buffer) - 559 # - 560 (write _test-input-stream "fn foo {\n") - 561 (write _test-input-stream "}\n") - 562 (write _test-input-stream "fn bar {\n") - 563 (write _test-input-stream "}\n") - 564 # convert - 565 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 566 (flush _test-output-buffered-file) - 567 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 573 # check first function - 574 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0") - 575 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/1") - 576 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2") - 577 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3") - 578 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/4") - 579 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5") - 580 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6") - 581 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7") - 582 # check second function - 583 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10") - 584 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/11") - 585 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12") - 586 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13") - 587 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/14") - 588 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15") - 589 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16") - 590 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17") - 591 # . epilogue - 592 89/<- %esp 5/r32/ebp - 593 5d/pop-to-ebp - 594 c3/return - 595 - 596 test-convert-function-with-arg: - 597 # . prologue - 598 55/push-ebp - 599 89/<- %ebp 4/r32/esp - 600 # setup - 601 (clear-stream _test-input-stream) - 602 (clear-stream $_test-input-buffered-file->buffer) - 603 (clear-stream _test-output-stream) - 604 (clear-stream $_test-output-buffered-file->buffer) - 605 # - 606 (write _test-input-stream "fn foo n: int {\n") - 607 (write _test-input-stream "}\n") - 608 # convert - 609 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 610 (flush _test-output-buffered-file) - 611 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 617 # check output - 618 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0") - 619 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg/1") - 620 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2") - 621 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3") - 622 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg/4") - 623 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5") - 624 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6") - 625 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7") - 626 # . epilogue - 627 89/<- %esp 5/r32/ebp - 628 5d/pop-to-ebp - 629 c3/return - 630 - 631 test-convert-function-with-arg-and-body: - 632 # . prologue - 633 55/push-ebp - 634 89/<- %ebp 4/r32/esp - 635 # setup - 636 (clear-stream _test-input-stream) - 637 (clear-stream $_test-input-buffered-file->buffer) - 638 (clear-stream _test-output-stream) - 639 (clear-stream $_test-output-buffered-file->buffer) - 640 # - 641 (write _test-input-stream "fn foo n: int {\n") - 642 (write _test-input-stream " increment n\n") - 643 (write _test-input-stream "}\n") - 644 # convert - 645 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 646 (flush _test-output-buffered-file) - 647 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 653 # check output - 654 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0") - 655 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg-and-body/1") - 656 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2") - 657 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3") - 658 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4") - 659 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5") - 660 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6") - 661 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7") - 662 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8") - 663 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg-and-body/9") - 664 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10") - 665 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11") - 666 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12") - 667 # . epilogue - 668 89/<- %esp 5/r32/ebp - 669 5d/pop-to-ebp - 670 c3/return - 671 - 672 test-convert-function-distinguishes-args: - 673 # . prologue - 674 55/push-ebp - 675 89/<- %ebp 4/r32/esp - 676 # setup - 677 (clear-stream _test-input-stream) - 678 (clear-stream $_test-input-buffered-file->buffer) - 679 (clear-stream _test-output-stream) - 680 (clear-stream $_test-output-buffered-file->buffer) - 681 # - 682 (write _test-input-stream "fn foo a: int, b: int {\n") - 683 (write _test-input-stream " increment b\n") - 684 (write _test-input-stream "}\n") - 685 # convert - 686 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 687 (flush _test-output-buffered-file) - 688 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 694 # check output - 695 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0") - 696 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-distinguishes-args/1") - 697 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2") - 698 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3") - 699 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4") - 700 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5") - 701 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6") - 702 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7") - 703 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8") - 704 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-distinguishes-args/9") - 705 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10") - 706 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11") - 707 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12") - 708 # . epilogue - 709 89/<- %esp 5/r32/ebp - 710 5d/pop-to-ebp - 711 c3/return - 712 - 713 test-convert-function-returns-result: - 714 # . prologue - 715 55/push-ebp - 716 89/<- %ebp 4/r32/esp - 717 # setup - 718 (clear-stream _test-input-stream) - 719 (clear-stream $_test-input-buffered-file->buffer) - 720 (clear-stream _test-output-stream) - 721 (clear-stream $_test-output-buffered-file->buffer) - 722 # - 723 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") - 724 (write _test-input-stream " result <- copy a\n") - 725 (write _test-input-stream " result <- increment\n") - 726 (write _test-input-stream "}\n") - 727 # convert - 728 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 729 (flush _test-output-buffered-file) - 730 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 736 # check output - 737 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-returns-result/0") - 738 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-returns-result/1") - 739 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-returns-result/2") - 740 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-returns-result/3") - 741 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-returns-result/4") - 742 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-returns-result/5") - 743 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-returns-result/6") - 744 (check-next-stream-line-equal _test-output-stream " 40/increment-eax" "F - test-convert-function-returns-result/7") - 745 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-returns-result/8") - 746 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-returns-result/9") - 747 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-returns-result/10") - 748 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-returns-result/11") - 749 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-returns-result/12") - 750 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-returns-result/13") - 751 # . epilogue - 752 89/<- %esp 5/r32/ebp - 753 5d/pop-to-ebp - 754 c3/return - 755 - 756 test-convert-function-with-literal-arg: - 757 # . prologue - 758 55/push-ebp - 759 89/<- %ebp 4/r32/esp - 760 # setup - 761 (clear-stream _test-input-stream) - 762 (clear-stream $_test-input-buffered-file->buffer) - 763 (clear-stream _test-output-stream) - 764 (clear-stream $_test-output-buffered-file->buffer) - 765 # - 766 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") - 767 (write _test-input-stream " result <- copy a\n") - 768 (write _test-input-stream " result <- add 1\n") - 769 (write _test-input-stream "}\n") - 770 # convert - 771 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 772 (flush _test-output-buffered-file) - 773 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 779 # check output - 780 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0") - 781 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg/1") - 782 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2") - 783 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3") - 784 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4") - 785 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5") - 786 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/6") - 787 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/7") - 788 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/8") - 789 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/9") - 790 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg/10") - 791 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/11") - 792 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/12") - 793 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/13") - 794 # . epilogue - 795 89/<- %esp 5/r32/ebp - 796 5d/pop-to-ebp - 797 c3/return - 798 - 799 test-convert-function-with-literal-arg-2: - 800 # . prologue - 801 55/push-ebp - 802 89/<- %ebp 4/r32/esp - 803 # setup - 804 (clear-stream _test-input-stream) - 805 (clear-stream $_test-input-buffered-file->buffer) - 806 (clear-stream _test-output-stream) - 807 (clear-stream $_test-output-buffered-file->buffer) - 808 # - 809 (write _test-input-stream "fn foo a: int, b: int -> result/ebx: int {\n") - 810 (write _test-input-stream " result <- copy a\n") - 811 (write _test-input-stream " result <- add 1\n") - 812 (write _test-input-stream "}\n") - 813 # convert - 814 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 815 (flush _test-output-buffered-file) - 816 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 822 # check output - 823 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0") - 824 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg-2/1") - 825 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2") - 826 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3") - 827 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4") - 828 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5") - 829 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/6") - 830 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/7") - 831 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/8") - 832 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/9") - 833 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg-2/10") - 834 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/11") - 835 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/12") - 836 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/13") - 837 # . epilogue - 838 89/<- %esp 5/r32/ebp - 839 5d/pop-to-ebp - 840 c3/return - 841 - 842 test-convert-function-call-with-literal-arg: - 843 # . prologue - 844 55/push-ebp - 845 89/<- %ebp 4/r32/esp - 846 # setup - 847 (clear-stream _test-input-stream) - 848 (clear-stream $_test-input-buffered-file->buffer) - 849 (clear-stream _test-output-stream) - 850 (clear-stream $_test-output-buffered-file->buffer) - 851 # - 852 (write _test-input-stream "fn main -> result/ebx: int {\n") - 853 (write _test-input-stream " result <- do-add 3 4\n") - 854 (write _test-input-stream "}\n") - 855 (write _test-input-stream "fn do-add a: int, b: int -> result/ebx: int {\n") - 856 (write _test-input-stream " result <- copy a\n") - 857 (write _test-input-stream " result <- add b\n") - 858 (write _test-input-stream "}\n") - 859 # convert - 860 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 861 (flush _test-output-buffered-file) - 862 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 868 # check output - 869 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0") - 870 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/1") - 871 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2") - 872 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3") - 873 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4") - 874 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5") - 875 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/6") - 876 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/7") - 877 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/8") - 878 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/9") - 879 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/10") - 880 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/11") - 881 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/12") - 882 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/13") - 883 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/14") - 884 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/15") - 885 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/16") - 886 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/17") - 887 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/18") - 888 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/19") - 889 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/20") - 890 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/21") - 891 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/22") - 892 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/23") - 893 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/24") - 894 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/25") - 895 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/26") - 896 # . epilogue - 897 89/<- %esp 5/r32/ebp - 898 5d/pop-to-ebp - 899 c3/return - 900 - 901 test-convert-function-with-local-var-in-mem: - 902 # . prologue - 903 55/push-ebp - 904 89/<- %ebp 4/r32/esp - 905 # setup - 906 (clear-stream _test-input-stream) - 907 (clear-stream $_test-input-buffered-file->buffer) - 908 (clear-stream _test-output-stream) - 909 (clear-stream $_test-output-buffered-file->buffer) - 910 # - 911 (write _test-input-stream "fn foo {\n") - 912 (write _test-input-stream " var x: int\n") - 913 (write _test-input-stream " increment x\n") - 914 (write _test-input-stream "}\n") - 915 # convert - 916 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 917 (flush _test-output-buffered-file) - 918 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 924 # check output - 925 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0") - 926 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1") - 927 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2") - 928 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3") - 929 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4") - 930 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5") - 931 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6") - 932 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7") - 933 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem/8") - 934 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9") - 935 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10") - 936 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11") - 937 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12") - 938 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13") - 939 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14") - 940 # . epilogue - 941 89/<- %esp 5/r32/ebp - 942 5d/pop-to-ebp - 943 c3/return - 944 - 945 test-convert-function-with-local-var-with-compound-type-in-mem: - 946 # . prologue - 947 55/push-ebp - 948 89/<- %ebp 4/r32/esp - 949 # setup - 950 (clear-stream _test-input-stream) - 951 (clear-stream $_test-input-buffered-file->buffer) - 952 (clear-stream _test-output-stream) - 953 (clear-stream $_test-output-buffered-file->buffer) - 954 # - 955 (write _test-input-stream "fn foo {\n") - 956 (write _test-input-stream " var x: (addr int)\n") - 957 (write _test-input-stream " copy-to x, 0\n") - 958 (write _test-input-stream "}\n") - 959 # convert - 960 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 961 (flush _test-output-buffered-file) - 962 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 968 # check output - 969 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0") - 970 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1") - 971 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2") - 972 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/3") - 973 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4") - 974 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5") - 975 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/6") - 976 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy *(ebp+0xfffffffc) 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/7") - 977 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/8") - 978 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9") - 979 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10") - 980 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11") - 981 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/12") - 982 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/13") - 983 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14") - 984 # . epilogue - 985 89/<- %esp 5/r32/ebp - 986 5d/pop-to-ebp - 987 c3/return - 988 - 989 test-convert-function-with-local-var-in-reg: - 990 # . prologue - 991 55/push-ebp - 992 89/<- %ebp 4/r32/esp - 993 # setup - 994 (clear-stream _test-input-stream) - 995 (clear-stream $_test-input-buffered-file->buffer) - 996 (clear-stream _test-output-stream) - 997 (clear-stream $_test-output-buffered-file->buffer) - 998 # - 999 (write _test-input-stream "fn foo {\n") - 1000 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1001 (write _test-input-stream " x <- increment\n") - 1002 (write _test-input-stream "}\n") - 1003 # convert - 1004 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1005 (flush _test-output-buffered-file) - 1006 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1012 # check output - 1013 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0") - 1014 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1") - 1015 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2") - 1016 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3") - 1017 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4") - 1018 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5") - 1019 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6") - 1020 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7") - 1021 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8") - 1022 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9") - 1023 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10") - 1024 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11") - 1025 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12") - 1026 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13") - 1027 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14") - 1028 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15") - 1029 # . epilogue - 1030 89/<- %esp 5/r32/ebp - 1031 5d/pop-to-ebp - 1032 c3/return - 1033 - 1034 test-convert-function-with-second-local-var-in-same-reg: - 1035 # . prologue - 1036 55/push-ebp - 1037 89/<- %ebp 4/r32/esp - 1038 # setup - 1039 (clear-stream _test-input-stream) - 1040 (clear-stream $_test-input-buffered-file->buffer) - 1041 (clear-stream _test-output-stream) - 1042 (clear-stream $_test-output-buffered-file->buffer) - 1043 # - 1044 (write _test-input-stream "fn foo {\n") - 1045 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1046 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1047 (write _test-input-stream " y <- increment\n") - 1048 (write _test-input-stream "}\n") - 1049 # convert - 1050 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1051 (flush _test-output-buffered-file) - 1052 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1058 # check output - 1059 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0") - 1060 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1") - 1061 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2") - 1062 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-second-local-var-in-same-reg/3") - 1063 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4") - 1064 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5") - 1065 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/6") - 1066 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/7") - 1067 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/8") - 1068 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9") - 1069 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/10") - 1070 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11") - 1071 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12") - 1072 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13") - 1073 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-second-local-var-in-same-reg/14") - 1074 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15") - 1075 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16") - 1076 # . epilogue - 1077 89/<- %esp 5/r32/ebp - 1078 5d/pop-to-ebp - 1079 c3/return - 1080 - 1081 test-convert-function-with-local-var-dereferenced: - 1082 # . prologue - 1083 55/push-ebp - 1084 89/<- %ebp 4/r32/esp - 1085 # setup - 1086 (clear-stream _test-input-stream) - 1087 (clear-stream $_test-input-buffered-file->buffer) - 1088 (clear-stream _test-output-stream) - 1089 (clear-stream $_test-output-buffered-file->buffer) - 1090 # - 1091 (write _test-input-stream "fn foo {\n") - 1092 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") - 1093 (write _test-input-stream " increment *x\n") - 1094 (write _test-input-stream "}\n") - 1095 # convert - 1096 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1097 (flush _test-output-buffered-file) - 1098 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1104 # check output - 1105 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0") - 1106 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1") - 1107 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2") - 1108 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3") - 1109 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4") - 1110 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5") - 1111 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6") - 1112 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7") - 1113 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8") - 1114 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9") - 1115 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10") - 1116 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11") - 1117 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12") - 1118 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13") - 1119 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14") - 1120 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15") - 1121 # . epilogue - 1122 89/<- %esp 5/r32/ebp - 1123 5d/pop-to-ebp - 1124 c3/return - 1125 - 1126 test-convert-compare-register-with-literal: - 1127 # . prologue - 1128 55/push-ebp - 1129 89/<- %ebp 4/r32/esp - 1130 # setup - 1131 (clear-stream _test-input-stream) - 1132 (clear-stream $_test-input-buffered-file->buffer) - 1133 (clear-stream _test-output-stream) - 1134 (clear-stream $_test-output-buffered-file->buffer) - 1135 # - 1136 (write _test-input-stream "fn foo {\n") - 1137 (write _test-input-stream " var x/ecx: int <- copy 0\n") - 1138 (write _test-input-stream " compare x, 0\n") - 1139 (write _test-input-stream "}\n") - 1140 # convert - 1141 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1142 (flush _test-output-buffered-file) - 1143 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1149 # check output - 1150 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0") - 1151 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1") - 1152 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2") - 1153 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3") - 1154 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4") - 1155 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5") - 1156 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") - 1157 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7") - 1158 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8") - 1159 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") - 1160 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10") - 1161 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11") - 1162 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12") - 1163 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13") - 1164 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14") - 1165 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15") - 1166 # . epilogue - 1167 89/<- %esp 5/r32/ebp - 1168 5d/pop-to-ebp - 1169 c3/return - 1170 - 1171 test-convert-function-with-local-var-in-block: - 1172 # . prologue - 1173 55/push-ebp - 1174 89/<- %ebp 4/r32/esp - 1175 # setup - 1176 (clear-stream _test-input-stream) - 1177 (clear-stream $_test-input-buffered-file->buffer) - 1178 (clear-stream _test-output-stream) - 1179 (clear-stream $_test-output-buffered-file->buffer) - 1180 # - 1181 (write _test-input-stream "fn foo {\n") - 1182 (write _test-input-stream " {\n") - 1183 (write _test-input-stream " var x: int\n") - 1184 (write _test-input-stream " increment x\n") - 1185 (write _test-input-stream " }\n") - 1186 (write _test-input-stream "}\n") - 1187 # convert - 1188 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1189 (flush _test-output-buffered-file) - 1190 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1196 # check output - 1197 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0") - 1198 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1") - 1199 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2") - 1200 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3") - 1201 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4") - 1202 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5") - 1203 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6") - 1204 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7") - 1205 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8") - 1206 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9") - 1207 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-block/10") - 1208 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11") - 1209 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12") - 1210 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13") - 1211 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14") - 1212 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15") - 1213 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16") - 1214 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17") - 1215 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18") - 1216 # . epilogue - 1217 89/<- %esp 5/r32/ebp - 1218 5d/pop-to-ebp - 1219 c3/return - 1220 - 1221 test-convert-function-with-local-var-in-named-block: - 1222 # . prologue - 1223 55/push-ebp - 1224 89/<- %ebp 4/r32/esp - 1225 # setup - 1226 (clear-stream _test-input-stream) - 1227 (clear-stream $_test-input-buffered-file->buffer) - 1228 (clear-stream _test-output-stream) - 1229 (clear-stream $_test-output-buffered-file->buffer) - 1230 # - 1231 (write _test-input-stream "fn foo {\n") - 1232 (write _test-input-stream " $bar: {\n") - 1233 (write _test-input-stream " var x: int\n") - 1234 (write _test-input-stream " increment x\n") - 1235 (write _test-input-stream " }\n") - 1236 (write _test-input-stream "}\n") - 1237 # convert - 1238 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1239 (flush _test-output-buffered-file) - 1240 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1246 # check output - 1247 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0") - 1248 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1") - 1249 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2") - 1250 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3") - 1251 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4") - 1252 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5") - 1253 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6") - 1254 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7") - 1255 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8") - 1256 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-named-block/9") - 1257 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-named-block/10") - 1258 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11") - 1259 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12") - 1260 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13") - 1261 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14") - 1262 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15") - 1263 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16") - 1264 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17") - 1265 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18") - 1266 # . epilogue - 1267 89/<- %esp 5/r32/ebp - 1268 5d/pop-to-ebp - 1269 c3/return - 1270 - 1271 test-always-shadow-outermost-reg-vars-in-function: - 1272 # . prologue - 1273 55/push-ebp - 1274 89/<- %ebp 4/r32/esp - 1275 # setup - 1276 (clear-stream _test-input-stream) - 1277 (clear-stream $_test-input-buffered-file->buffer) - 1278 (clear-stream _test-output-stream) - 1279 (clear-stream $_test-output-buffered-file->buffer) - 1280 # - 1281 (write _test-input-stream "fn foo {\n") - 1282 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1283 (write _test-input-stream "}\n") - 1284 # convert - 1285 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1286 (flush _test-output-buffered-file) - 1287 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1293 # check output - 1294 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0") - 1295 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1") - 1296 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2") - 1297 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3") - 1298 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4") - 1299 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5") - 1300 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") - 1301 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8") - 1302 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") - 1303 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12") - 1304 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13") - 1305 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14") - 1306 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15") - 1307 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16") - 1308 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17") - 1309 # . epilogue - 1310 89/<- %esp 5/r32/ebp - 1311 5d/pop-to-ebp - 1312 c3/return - 1313 - 1314 _pending-test-clobber-dead-local: - 1315 # . prologue - 1316 55/push-ebp - 1317 89/<- %ebp 4/r32/esp - 1318 # setup - 1319 (clear-stream _test-input-stream) - 1320 (clear-stream $_test-input-buffered-file->buffer) - 1321 (clear-stream _test-output-stream) - 1322 (clear-stream $_test-output-buffered-file->buffer) - 1323 # - 1324 (write _test-input-stream "fn foo {\n") - 1325 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1326 (write _test-input-stream " {\n") - 1327 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1328 (write _test-input-stream " }\n") - 1329 (write _test-input-stream "}\n") - 1330 # convert - 1331 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1332 (flush _test-output-buffered-file) - 1333 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1339 # check output - 1340 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-clobber-dead-local/0") - 1341 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-clobber-dead-local/1") - 1342 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-clobber-dead-local/2") - 1343 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-clobber-dead-local/3") - 1344 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/4") - 1345 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-clobber-dead-local/5") - 1346 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-clobber-dead-local/6") - 1347 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-clobber-dead-local/7") - 1348 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/8") - 1349 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-clobber-dead-local/9") - 1350 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-clobber-dead-local/10") # no push/pop here - 1351 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/11") - 1352 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-clobber-dead-local/12") - 1353 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-clobber-dead-local/13") - 1354 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/14") - 1355 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-clobber-dead-local/15") - 1356 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-clobber-dead-local/16") - 1357 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-clobber-dead-local/17") - 1358 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-clobber-dead-local/18") - 1359 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-clobber-dead-local/19") - 1360 # . epilogue - 1361 89/<- %esp 5/r32/ebp - 1362 5d/pop-to-ebp - 1363 c3/return - 1364 - 1365 test-shadow-live-local: - 1366 # . prologue - 1367 55/push-ebp - 1368 89/<- %ebp 4/r32/esp - 1369 # setup - 1370 (clear-stream _test-input-stream) - 1371 (clear-stream $_test-input-buffered-file->buffer) - 1372 (clear-stream _test-output-stream) - 1373 (clear-stream $_test-output-buffered-file->buffer) - 1374 # - 1375 (write _test-input-stream "fn foo {\n") - 1376 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1377 (write _test-input-stream " {\n") - 1378 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1379 (write _test-input-stream " }\n") - 1380 (write _test-input-stream " x <- increment\n") - 1381 (write _test-input-stream "}\n") - 1382 # convert - 1383 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1384 (flush _test-output-buffered-file) - 1385 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1391 # check output - 1392 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-local/0") - 1393 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-local/1") - 1394 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-local/2") - 1395 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-local/3") - 1396 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/4") - 1397 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-local/5") - 1398 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/6") - 1399 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-local/7") - 1400 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/8") - 1401 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-local/9") - 1402 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/10") - 1403 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-local/11") - 1404 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/12") - 1405 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/13") - 1406 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-local/14") - 1407 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-local/15") - 1408 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/16") - 1409 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/17") - 1410 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-local/18") - 1411 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-local/19") - 1412 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-local/20") - 1413 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-local/21") - 1414 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-local/21") - 1415 # . epilogue - 1416 89/<- %esp 5/r32/ebp - 1417 5d/pop-to-ebp - 1418 c3/return - 1419 - 1420 test-do-not-spill-same-register-in-block: - 1421 # . prologue - 1422 55/push-ebp - 1423 89/<- %ebp 4/r32/esp - 1424 # setup - 1425 (clear-stream _test-input-stream) - 1426 (clear-stream $_test-input-buffered-file->buffer) - 1427 (clear-stream _test-output-stream) - 1428 (clear-stream $_test-output-buffered-file->buffer) - 1429 # - 1430 (write _test-input-stream "fn foo {\n") - 1431 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1432 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1433 (write _test-input-stream " y <- increment\n") - 1434 (write _test-input-stream "}\n") - 1435 # convert - 1436 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1437 (flush _test-output-buffered-file) - 1438 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1444 # check output - 1445 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0") - 1446 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1") - 1447 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2") - 1448 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3") - 1449 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4") - 1450 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5") - 1451 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6") - 1452 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7") - 1453 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8") - 1454 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9") - 1455 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10") - 1456 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11") - 1457 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12") - 1458 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13") - 1459 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14") - 1460 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15") - 1461 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16") - 1462 # . epilogue - 1463 89/<- %esp 5/r32/ebp - 1464 5d/pop-to-ebp - 1465 c3/return - 1466 - 1467 test-spill-different-register-in-block: - 1468 # . prologue - 1469 55/push-ebp - 1470 89/<- %ebp 4/r32/esp - 1471 # setup - 1472 (clear-stream _test-input-stream) - 1473 (clear-stream $_test-input-buffered-file->buffer) - 1474 (clear-stream _test-output-stream) - 1475 (clear-stream $_test-output-buffered-file->buffer) - 1476 # - 1477 (write _test-input-stream "fn foo {\n") - 1478 (write _test-input-stream " var x/eax: int <- copy 3\n") - 1479 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1480 (write _test-input-stream " y <- increment\n") - 1481 (write _test-input-stream "}\n") - 1482 # convert - 1483 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1484 (flush _test-output-buffered-file) - 1485 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1491 # check output - 1492 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0") - 1493 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1") - 1494 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2") - 1495 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3") - 1496 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4") - 1497 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5") - 1498 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6") - 1499 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7") - 1500 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8") - 1501 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9") - 1502 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10") - 1503 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11") - 1504 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12") - 1505 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13") - 1506 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14") - 1507 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15") - 1508 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16") - 1509 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17") - 1510 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18") - 1511 # . epilogue - 1512 89/<- %esp 5/r32/ebp - 1513 5d/pop-to-ebp - 1514 c3/return - 1515 - 1516 test-shadow-live-output: - 1517 # . prologue - 1518 55/push-ebp - 1519 89/<- %ebp 4/r32/esp - 1520 # setup - 1521 (clear-stream _test-input-stream) - 1522 (clear-stream $_test-input-buffered-file->buffer) - 1523 (clear-stream _test-output-stream) - 1524 (clear-stream $_test-output-buffered-file->buffer) - 1525 # - 1526 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 1527 (write _test-input-stream " x <- copy 3\n") - 1528 (write _test-input-stream " {\n") - 1529 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1530 (write _test-input-stream " }\n") - 1531 (write _test-input-stream " x <- increment\n") - 1532 (write _test-input-stream "}\n") - 1533 # convert - 1534 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1535 (flush _test-output-buffered-file) - 1536 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1542 # check output - 1543 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-output/0") - 1544 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-output/1") - 1545 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-output/2") - 1546 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-output/3") - 1547 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/4") - 1548 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-output/5") - 1549 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-output/7") # no push because it's an output reg - 1550 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/8") - 1551 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-output/9") - 1552 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-output/10") - 1553 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-output/11") - 1554 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-output/12") - 1555 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/13") - 1556 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-output/14") - 1557 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-output/15") - 1558 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/17") - 1559 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-output/18") - 1560 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-output/19") - 1561 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-output/20") - 1562 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-output/21") - 1563 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-output/21") - 1564 # . epilogue - 1565 89/<- %esp 5/r32/ebp - 1566 5d/pop-to-ebp - 1567 c3/return - 1568 - 1569 _pending-test-local-clobbered-by-output: - 1570 # also doesn't spill - 1571 # . prologue - 1572 55/push-ebp - 1573 89/<- %ebp 4/r32/esp - 1574 # setup - 1575 (clear-stream _test-input-stream) - 1576 (clear-stream $_test-input-buffered-file->buffer) - 1577 (clear-stream _test-output-stream) - 1578 (clear-stream $_test-output-buffered-file->buffer) - 1579 # - 1580 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 1581 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1582 (write _test-input-stream " x <- copy y\n") - 1583 (write _test-input-stream "}\n") - 1584 # convert - 1585 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1586 (flush _test-output-buffered-file) - 1587 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1593 # check output - 1594 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-local-clobbered-by-output/0") - 1595 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-local-clobbered-by-output/1") - 1596 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-local-clobbered-by-output/2") - 1597 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-local-clobbered-by-output/3") - 1598 (check-next-stream-line-equal _test-output-stream " {" "F - test-local-clobbered-by-output/4") - 1599 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-local-clobbered-by-output/5") - 1600 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-local-clobbered-by-output/6") - 1601 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-local-clobbered-by-output/7") - 1602 (check-next-stream-line-equal _test-output-stream " }" "F - test-local-clobbered-by-output/8") - 1603 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-local-clobbered-by-output/9") - 1604 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-local-clobbered-by-output/10") - 1605 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-local-clobbered-by-output/11") - 1606 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-local-clobbered-by-output/12") - 1607 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-local-clobbered-by-output/13") - 1608 # . epilogue - 1609 89/<- %esp 5/r32/ebp - 1610 5d/pop-to-ebp - 1611 c3/return - 1612 - 1613 test-convert-function-with-branches-in-block: - 1614 # . prologue - 1615 55/push-ebp - 1616 89/<- %ebp 4/r32/esp - 1617 # setup - 1618 (clear-stream _test-input-stream) - 1619 (clear-stream $_test-input-buffered-file->buffer) - 1620 (clear-stream _test-output-stream) - 1621 (clear-stream $_test-output-buffered-file->buffer) - 1622 # - 1623 (write _test-input-stream "fn foo x: int {\n") - 1624 (write _test-input-stream " {\n") - 1625 (write _test-input-stream " break-if->=\n") - 1626 (write _test-input-stream " loop-if-addr<\n") - 1627 (write _test-input-stream " increment x\n") - 1628 (write _test-input-stream " loop\n") - 1629 (write _test-input-stream " }\n") - 1630 (write _test-input-stream "}\n") - 1631 # convert - 1632 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1633 (flush _test-output-buffered-file) - 1634 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1640 # check output - 1641 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") - 1642 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") - 1643 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") - 1644 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") - 1645 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") - 1646 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") - 1647 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") - 1648 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") - 1649 (check-next-stream-line-equal _test-output-stream " 0f 8d/jump-if->= break/disp32" "F - test-convert-function-with-branches-in-block/8") - 1650 (check-next-stream-line-equal _test-output-stream " 0f 82/jump-if-addr< loop/disp32" "F - test-convert-function-with-branches-in-block/9") - 1651 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/10") - 1652 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/11") - 1653 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/12") - 1654 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/13") - 1655 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/14") - 1656 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/15") - 1657 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/16") - 1658 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/17") - 1659 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/18") - 1660 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/19") + 358 # A live-var is a var augmented with information needed for tracking live + 359 # variables. + 360 Live-var-value: # (handle var) + 361 0/imm32 + 362 Live-var-register-spilled: # boolean; only used if value is in a register, and only during code-gen + 363 8/imm32 + 364 Live-var-size: # (addr int) + 365 0xc/imm32 + 366 + 367 # Types are expressed as trees (s-expressions) of type-ids (ints). + 368 # However, there's no need for singletons, so we can assume (int) == int + 369 # - if x->right == nil, x is an atom + 370 # - x->left contains either a pointer to a pair, or an atomic type-id directly. + 371 + 372 Tree-is-atom: # boolean + 373 0/imm32 + 374 # if left-is-atom? + 375 Tree-value: # type-id + 376 4/imm32 + 377 # unless left-is-atom? + 378 Tree-left: # (addr tree type-id) + 379 4/imm32 + 380 Tree-right: # (addr tree type-id) + 381 0xc/imm32 + 382 # + 383 Tree-size: # (addr int) + 384 0x14/imm32 + 385 + 386 # Types + 387 + 388 # TODO: heap allocations here can't be reclaimed + 389 Type-id: # (stream (addr array byte)) + 390 0x1c/imm32/write + 391 0/imm32/read + 392 0x100/imm32/size + 393 # data + 394 "literal"/imm32 # 0: value is just the name + 395 "int"/imm32 # 1 + 396 "addr"/imm32 # 2 + 397 "array"/imm32 # 3 + 398 "handle"/imm32 # 4 + 399 "boolean"/imm32 # 5 + 400 "constant"/imm32 # 6: like a literal, but value is an int in Var-offset + 401 "offset"/imm32 # 7: (offset T) is guaranteed to be a 32-bit multiple of size-of(T) + 402 0/imm32 + 403 # 0x20 + 404 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 405 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 406 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 407 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 408 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 409 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 410 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 411 + 412 # == Type definitions + 413 # Program->types contains some typeinfo for each type definition. + 414 # Types contain vars with types, but can't specify registers. + 415 Typeinfo-id: # type-id + 416 0/imm32 + 417 Typeinfo-fields: # (handle table (handle array byte) (handle typeinfo-entry)) + 418 4/imm32 + 419 # Total size must be >= 0 + 420 # During parsing it may take on two additional values: + 421 # -2: not yet initialized + 422 # -1: in process of being computed + 423 # See populate-mu-type-sizes for details. + 424 Typeinfo-total-size-in-bytes: # int + 425 0xc/imm32 + 426 Typeinfo-next: # (handle typeinfo) + 427 0x10/imm32 + 428 Typeinfo-size: # (addr int) + 429 0x18/imm32 + 430 + 431 # Each entry in the typeinfo->fields table has a pointer to a string and a + 432 # pointer to a typeinfo-entry. + 433 Typeinfo-fields-row-size: # (addr int) + 434 0x10/imm32 + 435 + 436 # typeinfo-entry objects have information about a field in a single record type + 437 # + 438 # each field of a type is represented using two var's: + 439 # 1. the input var: expected type of the field; convenient for creating using parse-var-with-type + 440 # 2. the output var: a constant containing the byte offset; convenient for code-generation + 441 # computing the output happens after parsing; in the meantime we preserve the + 442 # order of fields in the 'index' field. + 443 Typeinfo-entry-input-var: # (handle var) + 444 0/imm32 + 445 Typeinfo-entry-index: # int + 446 8/imm32 + 447 Typeinfo-entry-output-var: # (handle var) + 448 0xc/imm32 + 449 Typeinfo-entry-size: # (addr int) + 450 0x14/imm32 + 451 + 452 == code + 453 + 454 Entry: + 455 # . prologue + 456 89/<- %ebp 4/r32/esp + 457 (new-segment *Heap-size Heap) + 458 # if (argv[1] == "test') run-tests() + 459 { + 460 # if (argc <= 1) break + 461 81 7/subop/compare *ebp 1/imm32 + 462 7e/jump-if-<= break/disp8 + 463 # if (argv[1] != "test") break + 464 (kernel-string-equal? *(ebp+8) "test") # => eax + 465 3d/compare-eax-and 0/imm32/false + 466 74/jump-if-= break/disp8 + 467 # + 468 (run-tests) + 469 # syscall(exit, *Num-test-failures) + 470 8b/-> *Num-test-failures 3/r32/ebx + 471 eb/jump $mu-main:end/disp8 + 472 } + 473 # otherwise convert Stdin + 474 (convert-mu Stdin Stdout) + 475 (flush Stdout) + 476 # syscall(exit, 0) + 477 bb/copy-to-ebx 0/imm32 + 478 $mu-main:end: + 479 b8/copy-to-eax 1/imm32/exit + 480 cd/syscall 0x80/imm8 + 481 + 482 convert-mu: # in: (addr buffered-file), out: (addr buffered-file) + 483 # . prologue + 484 55/push-ebp + 485 89/<- %ebp 4/r32/esp + 486 # initialize global data structures + 487 c7 0/subop/copy *Next-block-index 1/imm32 + 488 c7 0/subop/copy *Type-id 0x1c/imm32 # stream-write + 489 c7 0/subop/copy *_Program-functions 0/imm32 + 490 c7 0/subop/copy *_Program-functions->payload 0/imm32 + 491 c7 0/subop/copy *_Program-types 0/imm32 + 492 c7 0/subop/copy *_Program-types->payload 0/imm32 + 493 # + 494 (parse-mu *(ebp+8)) + 495 (populate-mu-type-sizes) + 496 #? (dump-typeinfos "=== typeinfos\n") + 497 (check-mu-types) + 498 (emit-subx *(ebp+0xc)) + 499 $convert-mu:end: + 500 # . epilogue + 501 89/<- %esp 5/r32/ebp + 502 5d/pop-to-ebp + 503 c3/return + 504 + 505 test-convert-empty-input: + 506 # empty input => empty output + 507 # . prologue + 508 55/push-ebp + 509 89/<- %ebp 4/r32/esp + 510 # setup + 511 (clear-stream _test-input-stream) + 512 (clear-stream $_test-input-buffered-file->buffer) + 513 (clear-stream _test-output-stream) + 514 (clear-stream $_test-output-buffered-file->buffer) + 515 # + 516 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 517 (flush _test-output-buffered-file) + 518 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input") + 519 # . epilogue + 520 89/<- %esp 5/r32/ebp + 521 5d/pop-to-ebp + 522 c3/return + 523 + 524 test-convert-function-skeleton: + 525 # . prologue + 526 55/push-ebp + 527 89/<- %ebp 4/r32/esp + 528 # setup + 529 (clear-stream _test-input-stream) + 530 (clear-stream $_test-input-buffered-file->buffer) + 531 (clear-stream _test-output-stream) + 532 (clear-stream $_test-output-buffered-file->buffer) + 533 # + 534 (write _test-input-stream "fn foo {\n") + 535 (write _test-input-stream "}\n") + 536 # convert + 537 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 538 (flush _test-output-buffered-file) + 539 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 545 # check output + 546 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0") + 547 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-skeleton/1") + 548 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2") + 549 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3") + 550 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-skeleton/4") + 551 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5") + 552 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6") + 553 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7") + 554 # . epilogue + 555 89/<- %esp 5/r32/ebp + 556 5d/pop-to-ebp + 557 c3/return + 558 + 559 test-convert-multiple-function-skeletons: + 560 # . prologue + 561 55/push-ebp + 562 89/<- %ebp 4/r32/esp + 563 # setup + 564 (clear-stream _test-input-stream) + 565 (clear-stream $_test-input-buffered-file->buffer) + 566 (clear-stream _test-output-stream) + 567 (clear-stream $_test-output-buffered-file->buffer) + 568 # + 569 (write _test-input-stream "fn foo {\n") + 570 (write _test-input-stream "}\n") + 571 (write _test-input-stream "fn bar {\n") + 572 (write _test-input-stream "}\n") + 573 # convert + 574 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 575 (flush _test-output-buffered-file) + 576 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 582 # check first function + 583 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0") + 584 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/1") + 585 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2") + 586 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3") + 587 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/4") + 588 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5") + 589 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6") + 590 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7") + 591 # check second function + 592 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10") + 593 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/11") + 594 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12") + 595 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13") + 596 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/14") + 597 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15") + 598 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16") + 599 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17") + 600 # . epilogue + 601 89/<- %esp 5/r32/ebp + 602 5d/pop-to-ebp + 603 c3/return + 604 + 605 test-convert-function-with-arg: + 606 # . prologue + 607 55/push-ebp + 608 89/<- %ebp 4/r32/esp + 609 # setup + 610 (clear-stream _test-input-stream) + 611 (clear-stream $_test-input-buffered-file->buffer) + 612 (clear-stream _test-output-stream) + 613 (clear-stream $_test-output-buffered-file->buffer) + 614 # + 615 (write _test-input-stream "fn foo n: int {\n") + 616 (write _test-input-stream "}\n") + 617 # convert + 618 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 619 (flush _test-output-buffered-file) + 620 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 626 # check output + 627 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0") + 628 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg/1") + 629 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2") + 630 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3") + 631 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg/4") + 632 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5") + 633 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6") + 634 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7") + 635 # . epilogue + 636 89/<- %esp 5/r32/ebp + 637 5d/pop-to-ebp + 638 c3/return + 639 + 640 test-convert-function-with-arg-and-body: + 641 # . prologue + 642 55/push-ebp + 643 89/<- %ebp 4/r32/esp + 644 # setup + 645 (clear-stream _test-input-stream) + 646 (clear-stream $_test-input-buffered-file->buffer) + 647 (clear-stream _test-output-stream) + 648 (clear-stream $_test-output-buffered-file->buffer) + 649 # + 650 (write _test-input-stream "fn foo n: int {\n") + 651 (write _test-input-stream " increment n\n") + 652 (write _test-input-stream "}\n") + 653 # convert + 654 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 655 (flush _test-output-buffered-file) + 656 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 662 # check output + 663 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0") + 664 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg-and-body/1") + 665 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2") + 666 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3") + 667 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4") + 668 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5") + 669 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6") + 670 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7") + 671 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8") + 672 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg-and-body/9") + 673 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10") + 674 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11") + 675 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12") + 676 # . epilogue + 677 89/<- %esp 5/r32/ebp + 678 5d/pop-to-ebp + 679 c3/return + 680 + 681 test-convert-function-distinguishes-args: + 682 # . prologue + 683 55/push-ebp + 684 89/<- %ebp 4/r32/esp + 685 # setup + 686 (clear-stream _test-input-stream) + 687 (clear-stream $_test-input-buffered-file->buffer) + 688 (clear-stream _test-output-stream) + 689 (clear-stream $_test-output-buffered-file->buffer) + 690 # + 691 (write _test-input-stream "fn foo a: int, b: int {\n") + 692 (write _test-input-stream " increment b\n") + 693 (write _test-input-stream "}\n") + 694 # convert + 695 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 696 (flush _test-output-buffered-file) + 697 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 703 # check output + 704 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0") + 705 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-distinguishes-args/1") + 706 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2") + 707 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3") + 708 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4") + 709 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5") + 710 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6") + 711 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7") + 712 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8") + 713 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-distinguishes-args/9") + 714 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10") + 715 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11") + 716 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12") + 717 # . epilogue + 718 89/<- %esp 5/r32/ebp + 719 5d/pop-to-ebp + 720 c3/return + 721 + 722 test-convert-function-returns-result: + 723 # . prologue + 724 55/push-ebp + 725 89/<- %ebp 4/r32/esp + 726 # setup + 727 (clear-stream _test-input-stream) + 728 (clear-stream $_test-input-buffered-file->buffer) + 729 (clear-stream _test-output-stream) + 730 (clear-stream $_test-output-buffered-file->buffer) + 731 # + 732 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") + 733 (write _test-input-stream " result <- copy a\n") + 734 (write _test-input-stream " result <- increment\n") + 735 (write _test-input-stream "}\n") + 736 # convert + 737 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 738 (flush _test-output-buffered-file) + 739 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 745 # check output + 746 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-returns-result/0") + 747 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-returns-result/1") + 748 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-returns-result/2") + 749 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-returns-result/3") + 750 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-returns-result/4") + 751 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-returns-result/5") + 752 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-returns-result/6") + 753 (check-next-stream-line-equal _test-output-stream " 40/increment-eax" "F - test-convert-function-returns-result/7") + 754 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-returns-result/8") + 755 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-returns-result/9") + 756 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-returns-result/10") + 757 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-returns-result/11") + 758 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-returns-result/12") + 759 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-returns-result/13") + 760 # . epilogue + 761 89/<- %esp 5/r32/ebp + 762 5d/pop-to-ebp + 763 c3/return + 764 + 765 test-convert-function-with-literal-arg: + 766 # . prologue + 767 55/push-ebp + 768 89/<- %ebp 4/r32/esp + 769 # setup + 770 (clear-stream _test-input-stream) + 771 (clear-stream $_test-input-buffered-file->buffer) + 772 (clear-stream _test-output-stream) + 773 (clear-stream $_test-output-buffered-file->buffer) + 774 # + 775 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") + 776 (write _test-input-stream " result <- copy a\n") + 777 (write _test-input-stream " result <- add 1\n") + 778 (write _test-input-stream "}\n") + 779 # convert + 780 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 781 (flush _test-output-buffered-file) + 782 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 788 # check output + 789 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0") + 790 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg/1") + 791 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2") + 792 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3") + 793 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4") + 794 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5") + 795 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/6") + 796 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/7") + 797 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/8") + 798 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/9") + 799 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg/10") + 800 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/11") + 801 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/12") + 802 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/13") + 803 # . epilogue + 804 89/<- %esp 5/r32/ebp + 805 5d/pop-to-ebp + 806 c3/return + 807 + 808 test-convert-function-with-literal-arg-2: + 809 # . prologue + 810 55/push-ebp + 811 89/<- %ebp 4/r32/esp + 812 # setup + 813 (clear-stream _test-input-stream) + 814 (clear-stream $_test-input-buffered-file->buffer) + 815 (clear-stream _test-output-stream) + 816 (clear-stream $_test-output-buffered-file->buffer) + 817 # + 818 (write _test-input-stream "fn foo a: int, b: int -> result/ebx: int {\n") + 819 (write _test-input-stream " result <- copy a\n") + 820 (write _test-input-stream " result <- add 1\n") + 821 (write _test-input-stream "}\n") + 822 # convert + 823 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 824 (flush _test-output-buffered-file) + 825 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 831 # check output + 832 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0") + 833 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg-2/1") + 834 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2") + 835 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3") + 836 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4") + 837 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5") + 838 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/6") + 839 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/7") + 840 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/8") + 841 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/9") + 842 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg-2/10") + 843 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/11") + 844 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/12") + 845 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/13") + 846 # . epilogue + 847 89/<- %esp 5/r32/ebp + 848 5d/pop-to-ebp + 849 c3/return + 850 + 851 test-convert-function-call-with-literal-arg: + 852 # . prologue + 853 55/push-ebp + 854 89/<- %ebp 4/r32/esp + 855 # setup + 856 (clear-stream _test-input-stream) + 857 (clear-stream $_test-input-buffered-file->buffer) + 858 (clear-stream _test-output-stream) + 859 (clear-stream $_test-output-buffered-file->buffer) + 860 # + 861 (write _test-input-stream "fn main -> result/ebx: int {\n") + 862 (write _test-input-stream " result <- do-add 3 4\n") + 863 (write _test-input-stream "}\n") + 864 (write _test-input-stream "fn do-add a: int, b: int -> result/ebx: int {\n") + 865 (write _test-input-stream " result <- copy a\n") + 866 (write _test-input-stream " result <- add b\n") + 867 (write _test-input-stream "}\n") + 868 # convert + 869 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 870 (flush _test-output-buffered-file) + 871 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 877 # check output + 878 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0") + 879 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/1") + 880 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2") + 881 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3") + 882 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4") + 883 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5") + 884 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/6") + 885 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/7") + 886 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/8") + 887 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/9") + 888 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/10") + 889 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/11") + 890 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/12") + 891 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/13") + 892 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/14") + 893 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/15") + 894 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/16") + 895 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/17") + 896 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/18") + 897 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/19") + 898 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/20") + 899 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/21") + 900 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/22") + 901 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/23") + 902 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/24") + 903 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/25") + 904 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/26") + 905 # . epilogue + 906 89/<- %esp 5/r32/ebp + 907 5d/pop-to-ebp + 908 c3/return + 909 + 910 test-convert-function-with-local-var-in-mem: + 911 # . prologue + 912 55/push-ebp + 913 89/<- %ebp 4/r32/esp + 914 # setup + 915 (clear-stream _test-input-stream) + 916 (clear-stream $_test-input-buffered-file->buffer) + 917 (clear-stream _test-output-stream) + 918 (clear-stream $_test-output-buffered-file->buffer) + 919 # + 920 (write _test-input-stream "fn foo {\n") + 921 (write _test-input-stream " var x: int\n") + 922 (write _test-input-stream " increment x\n") + 923 (write _test-input-stream "}\n") + 924 # convert + 925 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 926 (flush _test-output-buffered-file) + 927 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 933 # check output + 934 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0") + 935 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1") + 936 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2") + 937 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3") + 938 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4") + 939 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5") + 940 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6") + 941 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7") + 942 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem/8") + 943 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9") + 944 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10") + 945 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11") + 946 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12") + 947 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13") + 948 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14") + 949 # . epilogue + 950 89/<- %esp 5/r32/ebp + 951 5d/pop-to-ebp + 952 c3/return + 953 + 954 test-convert-function-with-local-var-with-compound-type-in-mem: + 955 # . prologue + 956 55/push-ebp + 957 89/<- %ebp 4/r32/esp + 958 # setup + 959 (clear-stream _test-input-stream) + 960 (clear-stream $_test-input-buffered-file->buffer) + 961 (clear-stream _test-output-stream) + 962 (clear-stream $_test-output-buffered-file->buffer) + 963 # + 964 (write _test-input-stream "fn foo {\n") + 965 (write _test-input-stream " var x: (addr int)\n") + 966 (write _test-input-stream " copy-to x, 0\n") + 967 (write _test-input-stream "}\n") + 968 # convert + 969 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 970 (flush _test-output-buffered-file) + 971 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 977 # check output + 978 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0") + 979 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1") + 980 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2") + 981 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/3") + 982 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4") + 983 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5") + 984 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/6") + 985 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy *(ebp+0xfffffffc) 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/7") + 986 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/8") + 987 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9") + 988 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10") + 989 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11") + 990 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/12") + 991 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/13") + 992 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14") + 993 # . epilogue + 994 89/<- %esp 5/r32/ebp + 995 5d/pop-to-ebp + 996 c3/return + 997 + 998 test-convert-function-with-local-var-in-reg: + 999 # . prologue + 1000 55/push-ebp + 1001 89/<- %ebp 4/r32/esp + 1002 # setup + 1003 (clear-stream _test-input-stream) + 1004 (clear-stream $_test-input-buffered-file->buffer) + 1005 (clear-stream _test-output-stream) + 1006 (clear-stream $_test-output-buffered-file->buffer) + 1007 # + 1008 (write _test-input-stream "fn foo {\n") + 1009 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1010 (write _test-input-stream " x <- increment\n") + 1011 (write _test-input-stream "}\n") + 1012 # convert + 1013 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1014 (flush _test-output-buffered-file) + 1015 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1021 # check output + 1022 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0") + 1023 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1") + 1024 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2") + 1025 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3") + 1026 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4") + 1027 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5") + 1028 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6") + 1029 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7") + 1030 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8") + 1031 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9") + 1032 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10") + 1033 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11") + 1034 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12") + 1035 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13") + 1036 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14") + 1037 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15") + 1038 # . epilogue + 1039 89/<- %esp 5/r32/ebp + 1040 5d/pop-to-ebp + 1041 c3/return + 1042 + 1043 test-convert-function-with-second-local-var-in-same-reg: + 1044 # . prologue + 1045 55/push-ebp + 1046 89/<- %ebp 4/r32/esp + 1047 # setup + 1048 (clear-stream _test-input-stream) + 1049 (clear-stream $_test-input-buffered-file->buffer) + 1050 (clear-stream _test-output-stream) + 1051 (clear-stream $_test-output-buffered-file->buffer) + 1052 # + 1053 (write _test-input-stream "fn foo {\n") + 1054 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1055 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1056 (write _test-input-stream " y <- increment\n") + 1057 (write _test-input-stream "}\n") + 1058 # convert + 1059 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1060 (flush _test-output-buffered-file) + 1061 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1067 # check output + 1068 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0") + 1069 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1") + 1070 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2") + 1071 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-second-local-var-in-same-reg/3") + 1072 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4") + 1073 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5") + 1074 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/6") + 1075 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/7") + 1076 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/8") + 1077 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9") + 1078 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/10") + 1079 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11") + 1080 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12") + 1081 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13") + 1082 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-second-local-var-in-same-reg/14") + 1083 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15") + 1084 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16") + 1085 # . epilogue + 1086 89/<- %esp 5/r32/ebp + 1087 5d/pop-to-ebp + 1088 c3/return + 1089 + 1090 test-convert-function-with-local-var-dereferenced: + 1091 # . prologue + 1092 55/push-ebp + 1093 89/<- %ebp 4/r32/esp + 1094 # setup + 1095 (clear-stream _test-input-stream) + 1096 (clear-stream $_test-input-buffered-file->buffer) + 1097 (clear-stream _test-output-stream) + 1098 (clear-stream $_test-output-buffered-file->buffer) + 1099 # + 1100 (write _test-input-stream "fn foo {\n") + 1101 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") + 1102 (write _test-input-stream " increment *x\n") + 1103 (write _test-input-stream "}\n") + 1104 # convert + 1105 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1106 (flush _test-output-buffered-file) + 1107 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1113 # check output + 1114 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0") + 1115 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1") + 1116 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2") + 1117 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3") + 1118 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4") + 1119 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5") + 1120 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6") + 1121 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7") + 1122 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8") + 1123 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9") + 1124 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10") + 1125 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11") + 1126 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12") + 1127 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13") + 1128 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14") + 1129 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15") + 1130 # . epilogue + 1131 89/<- %esp 5/r32/ebp + 1132 5d/pop-to-ebp + 1133 c3/return + 1134 + 1135 test-convert-compare-register-with-literal: + 1136 # . prologue + 1137 55/push-ebp + 1138 89/<- %ebp 4/r32/esp + 1139 # setup + 1140 (clear-stream _test-input-stream) + 1141 (clear-stream $_test-input-buffered-file->buffer) + 1142 (clear-stream _test-output-stream) + 1143 (clear-stream $_test-output-buffered-file->buffer) + 1144 # + 1145 (write _test-input-stream "fn foo {\n") + 1146 (write _test-input-stream " var x/ecx: int <- copy 0\n") + 1147 (write _test-input-stream " compare x, 0\n") + 1148 (write _test-input-stream "}\n") + 1149 # convert + 1150 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1151 (flush _test-output-buffered-file) + 1152 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1158 # check output + 1159 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0") + 1160 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1") + 1161 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2") + 1162 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3") + 1163 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4") + 1164 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5") + 1165 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") + 1166 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7") + 1167 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8") + 1168 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") + 1169 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10") + 1170 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11") + 1171 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12") + 1172 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13") + 1173 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14") + 1174 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15") + 1175 # . epilogue + 1176 89/<- %esp 5/r32/ebp + 1177 5d/pop-to-ebp + 1178 c3/return + 1179 + 1180 test-convert-function-with-local-var-in-block: + 1181 # . prologue + 1182 55/push-ebp + 1183 89/<- %ebp 4/r32/esp + 1184 # setup + 1185 (clear-stream _test-input-stream) + 1186 (clear-stream $_test-input-buffered-file->buffer) + 1187 (clear-stream _test-output-stream) + 1188 (clear-stream $_test-output-buffered-file->buffer) + 1189 # + 1190 (write _test-input-stream "fn foo {\n") + 1191 (write _test-input-stream " {\n") + 1192 (write _test-input-stream " var x: int\n") + 1193 (write _test-input-stream " increment x\n") + 1194 (write _test-input-stream " }\n") + 1195 (write _test-input-stream "}\n") + 1196 # convert + 1197 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1198 (flush _test-output-buffered-file) + 1199 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1205 # check output + 1206 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0") + 1207 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1") + 1208 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2") + 1209 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3") + 1210 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4") + 1211 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5") + 1212 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6") + 1213 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7") + 1214 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8") + 1215 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9") + 1216 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-block/10") + 1217 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11") + 1218 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12") + 1219 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13") + 1220 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14") + 1221 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15") + 1222 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16") + 1223 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17") + 1224 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18") + 1225 # . epilogue + 1226 89/<- %esp 5/r32/ebp + 1227 5d/pop-to-ebp + 1228 c3/return + 1229 + 1230 test-convert-function-with-local-var-in-named-block: + 1231 # . prologue + 1232 55/push-ebp + 1233 89/<- %ebp 4/r32/esp + 1234 # setup + 1235 (clear-stream _test-input-stream) + 1236 (clear-stream $_test-input-buffered-file->buffer) + 1237 (clear-stream _test-output-stream) + 1238 (clear-stream $_test-output-buffered-file->buffer) + 1239 # + 1240 (write _test-input-stream "fn foo {\n") + 1241 (write _test-input-stream " $bar: {\n") + 1242 (write _test-input-stream " var x: int\n") + 1243 (write _test-input-stream " increment x\n") + 1244 (write _test-input-stream " }\n") + 1245 (write _test-input-stream "}\n") + 1246 # convert + 1247 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1248 (flush _test-output-buffered-file) + 1249 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1255 # check output + 1256 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0") + 1257 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1") + 1258 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2") + 1259 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3") + 1260 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4") + 1261 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5") + 1262 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6") + 1263 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7") + 1264 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8") + 1265 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-named-block/9") + 1266 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-named-block/10") + 1267 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11") + 1268 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12") + 1269 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13") + 1270 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14") + 1271 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15") + 1272 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16") + 1273 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17") + 1274 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18") + 1275 # . epilogue + 1276 89/<- %esp 5/r32/ebp + 1277 5d/pop-to-ebp + 1278 c3/return + 1279 + 1280 test-always-shadow-outermost-reg-vars-in-function: + 1281 # . prologue + 1282 55/push-ebp + 1283 89/<- %ebp 4/r32/esp + 1284 # setup + 1285 (clear-stream _test-input-stream) + 1286 (clear-stream $_test-input-buffered-file->buffer) + 1287 (clear-stream _test-output-stream) + 1288 (clear-stream $_test-output-buffered-file->buffer) + 1289 # + 1290 (write _test-input-stream "fn foo {\n") + 1291 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1292 (write _test-input-stream "}\n") + 1293 # convert + 1294 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1295 (flush _test-output-buffered-file) + 1296 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1302 # check output + 1303 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0") + 1304 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1") + 1305 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2") + 1306 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3") + 1307 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4") + 1308 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5") + 1309 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") + 1310 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8") + 1311 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") + 1312 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12") + 1313 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13") + 1314 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14") + 1315 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15") + 1316 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16") + 1317 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17") + 1318 # . epilogue + 1319 89/<- %esp 5/r32/ebp + 1320 5d/pop-to-ebp + 1321 c3/return + 1322 + 1323 _pending-test-clobber-dead-local: + 1324 # . prologue + 1325 55/push-ebp + 1326 89/<- %ebp 4/r32/esp + 1327 # setup + 1328 (clear-stream _test-input-stream) + 1329 (clear-stream $_test-input-buffered-file->buffer) + 1330 (clear-stream _test-output-stream) + 1331 (clear-stream $_test-output-buffered-file->buffer) + 1332 # + 1333 (write _test-input-stream "fn foo {\n") + 1334 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1335 (write _test-input-stream " {\n") + 1336 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1337 (write _test-input-stream " }\n") + 1338 (write _test-input-stream "}\n") + 1339 # convert + 1340 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1341 (flush _test-output-buffered-file) + 1342 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1348 # check output + 1349 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-clobber-dead-local/0") + 1350 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-clobber-dead-local/1") + 1351 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-clobber-dead-local/2") + 1352 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-clobber-dead-local/3") + 1353 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/4") + 1354 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-clobber-dead-local/5") + 1355 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-clobber-dead-local/6") + 1356 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-clobber-dead-local/7") + 1357 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/8") + 1358 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-clobber-dead-local/9") + 1359 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-clobber-dead-local/10") # no push/pop here + 1360 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/11") + 1361 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-clobber-dead-local/12") + 1362 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-clobber-dead-local/13") + 1363 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/14") + 1364 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-clobber-dead-local/15") + 1365 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-clobber-dead-local/16") + 1366 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-clobber-dead-local/17") + 1367 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-clobber-dead-local/18") + 1368 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-clobber-dead-local/19") + 1369 # . epilogue + 1370 89/<- %esp 5/r32/ebp + 1371 5d/pop-to-ebp + 1372 c3/return + 1373 + 1374 test-shadow-live-local: + 1375 # . prologue + 1376 55/push-ebp + 1377 89/<- %ebp 4/r32/esp + 1378 # setup + 1379 (clear-stream _test-input-stream) + 1380 (clear-stream $_test-input-buffered-file->buffer) + 1381 (clear-stream _test-output-stream) + 1382 (clear-stream $_test-output-buffered-file->buffer) + 1383 # + 1384 (write _test-input-stream "fn foo {\n") + 1385 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1386 (write _test-input-stream " {\n") + 1387 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1388 (write _test-input-stream " }\n") + 1389 (write _test-input-stream " x <- increment\n") + 1390 (write _test-input-stream "}\n") + 1391 # convert + 1392 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1393 (flush _test-output-buffered-file) + 1394 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1400 # check output + 1401 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-local/0") + 1402 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-local/1") + 1403 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-local/2") + 1404 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-local/3") + 1405 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/4") + 1406 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-local/5") + 1407 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/6") + 1408 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-local/7") + 1409 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/8") + 1410 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-local/9") + 1411 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/10") + 1412 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-local/11") + 1413 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/12") + 1414 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/13") + 1415 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-local/14") + 1416 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-local/15") + 1417 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/16") + 1418 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/17") + 1419 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-local/18") + 1420 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-local/19") + 1421 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-local/20") + 1422 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-local/21") + 1423 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-local/21") + 1424 # . epilogue + 1425 89/<- %esp 5/r32/ebp + 1426 5d/pop-to-ebp + 1427 c3/return + 1428 + 1429 test-do-not-spill-same-register-in-block: + 1430 # . prologue + 1431 55/push-ebp + 1432 89/<- %ebp 4/r32/esp + 1433 # setup + 1434 (clear-stream _test-input-stream) + 1435 (clear-stream $_test-input-buffered-file->buffer) + 1436 (clear-stream _test-output-stream) + 1437 (clear-stream $_test-output-buffered-file->buffer) + 1438 # + 1439 (write _test-input-stream "fn foo {\n") + 1440 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1441 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1442 (write _test-input-stream " y <- increment\n") + 1443 (write _test-input-stream "}\n") + 1444 # convert + 1445 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1446 (flush _test-output-buffered-file) + 1447 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1453 # check output + 1454 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0") + 1455 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1") + 1456 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2") + 1457 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3") + 1458 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4") + 1459 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5") + 1460 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6") + 1461 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7") + 1462 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8") + 1463 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9") + 1464 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10") + 1465 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11") + 1466 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12") + 1467 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13") + 1468 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14") + 1469 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15") + 1470 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16") + 1471 # . epilogue + 1472 89/<- %esp 5/r32/ebp + 1473 5d/pop-to-ebp + 1474 c3/return + 1475 + 1476 test-spill-different-register-in-block: + 1477 # . prologue + 1478 55/push-ebp + 1479 89/<- %ebp 4/r32/esp + 1480 # setup + 1481 (clear-stream _test-input-stream) + 1482 (clear-stream $_test-input-buffered-file->buffer) + 1483 (clear-stream _test-output-stream) + 1484 (clear-stream $_test-output-buffered-file->buffer) + 1485 # + 1486 (write _test-input-stream "fn foo {\n") + 1487 (write _test-input-stream " var x/eax: int <- copy 3\n") + 1488 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1489 (write _test-input-stream " y <- increment\n") + 1490 (write _test-input-stream "}\n") + 1491 # convert + 1492 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1493 (flush _test-output-buffered-file) + 1494 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1500 # check output + 1501 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0") + 1502 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1") + 1503 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2") + 1504 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3") + 1505 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4") + 1506 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5") + 1507 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6") + 1508 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7") + 1509 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8") + 1510 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9") + 1511 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10") + 1512 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11") + 1513 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12") + 1514 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13") + 1515 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14") + 1516 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15") + 1517 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16") + 1518 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17") + 1519 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18") + 1520 # . epilogue + 1521 89/<- %esp 5/r32/ebp + 1522 5d/pop-to-ebp + 1523 c3/return + 1524 + 1525 test-shadow-live-output: + 1526 # . prologue + 1527 55/push-ebp + 1528 89/<- %ebp 4/r32/esp + 1529 # setup + 1530 (clear-stream _test-input-stream) + 1531 (clear-stream $_test-input-buffered-file->buffer) + 1532 (clear-stream _test-output-stream) + 1533 (clear-stream $_test-output-buffered-file->buffer) + 1534 # + 1535 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 1536 (write _test-input-stream " x <- copy 3\n") + 1537 (write _test-input-stream " {\n") + 1538 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1539 (write _test-input-stream " }\n") + 1540 (write _test-input-stream " x <- increment\n") + 1541 (write _test-input-stream "}\n") + 1542 # convert + 1543 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1544 (flush _test-output-buffered-file) + 1545 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1551 # check output + 1552 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-output/0") + 1553 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-output/1") + 1554 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-output/2") + 1555 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-output/3") + 1556 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/4") + 1557 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-output/5") + 1558 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-output/7") # no push because it's an output reg + 1559 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/8") + 1560 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-output/9") + 1561 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-output/10") + 1562 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-output/11") + 1563 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-output/12") + 1564 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/13") + 1565 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-output/14") + 1566 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-output/15") + 1567 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/17") + 1568 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-output/18") + 1569 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-output/19") + 1570 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-output/20") + 1571 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-output/21") + 1572 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-output/21") + 1573 # . epilogue + 1574 89/<- %esp 5/r32/ebp + 1575 5d/pop-to-ebp + 1576 c3/return + 1577 + 1578 test-local-clobbered-by-output: + 1579 # also doesn't spill + 1580 # . prologue + 1581 55/push-ebp + 1582 89/<- %ebp 4/r32/esp + 1583 # setup + 1584 (clear-stream _test-input-stream) + 1585 (clear-stream $_test-input-buffered-file->buffer) + 1586 (clear-stream _test-output-stream) + 1587 (clear-stream $_test-output-buffered-file->buffer) + 1588 # + 1589 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 1590 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1591 (write _test-input-stream " x <- copy y\n") + 1592 (write _test-input-stream "}\n") + 1593 # convert + 1594 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1595 (flush _test-output-buffered-file) + 1596 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1602 # check output + 1603 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-local-clobbered-by-output/0") + 1604 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-local-clobbered-by-output/1") + 1605 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-local-clobbered-by-output/2") + 1606 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-local-clobbered-by-output/3") + 1607 (check-next-stream-line-equal _test-output-stream " {" "F - test-local-clobbered-by-output/4") + 1608 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-local-clobbered-by-output/5") + 1609 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-local-clobbered-by-output/6") + 1610 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-local-clobbered-by-output/7") + 1611 (check-next-stream-line-equal _test-output-stream " }" "F - test-local-clobbered-by-output/8") + 1612 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-local-clobbered-by-output/9") + 1613 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-local-clobbered-by-output/10") + 1614 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-local-clobbered-by-output/11") + 1615 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-local-clobbered-by-output/12") + 1616 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-local-clobbered-by-output/13") + 1617 # . epilogue + 1618 89/<- %esp 5/r32/ebp + 1619 5d/pop-to-ebp + 1620 c3/return + 1621 + 1622 test-read-output: + 1623 # also doesn't spill + 1624 # . prologue + 1625 55/push-ebp + 1626 89/<- %ebp 4/r32/esp + 1627 # setup + 1628 (clear-stream _test-input-stream) + 1629 (clear-stream $_test-input-buffered-file->buffer) + 1630 (clear-stream _test-output-stream) + 1631 (clear-stream $_test-output-buffered-file->buffer) + 1632 # + 1633 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 1634 (write _test-input-stream " x <- copy 0x34\n") + 1635 (write _test-input-stream " compare x, 0x35\n") + 1636 (write _test-input-stream "}\n") + 1637 # convert + 1638 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1639 (flush _test-output-buffered-file) + 1640 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1646 # check output + 1647 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-read-output/0") + 1648 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-read-output/1") + 1649 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-read-output/2") + 1650 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-read-output/3") + 1651 (check-next-stream-line-equal _test-output-stream " {" "F - test-read-output/4") + 1652 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-read-output/5") + 1653 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x34/imm32" "F - test-read-output/6") + 1654 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0x35/imm32" "F - test-read-output/7") + 1655 (check-next-stream-line-equal _test-output-stream " }" "F - test-read-output/8") + 1656 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-read-output/9") + 1657 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-read-output/10") + 1658 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-read-output/11") + 1659 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-read-output/12") + 1660 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-read-output/13") 1661 # . epilogue 1662 89/<- %esp 5/r32/ebp 1663 5d/pop-to-ebp 1664 c3/return 1665 - 1666 test-convert-function-with-branches-in-named-block: + 1666 test-convert-function-with-branches-in-block: 1667 # . prologue 1668 55/push-ebp 1669 89/<- %ebp 4/r32/esp @@ -1611,3276 +1611,3256 @@ if ('onhashchange' in window) { 1674 (clear-stream $_test-output-buffered-file->buffer) 1675 # 1676 (write _test-input-stream "fn foo x: int {\n") - 1677 (write _test-input-stream " $bar: {\n") - 1678 (write _test-input-stream " break-if->= $bar\n") - 1679 (write _test-input-stream " loop-if-addr< $bar\n") + 1677 (write _test-input-stream " {\n") + 1678 (write _test-input-stream " break-if->=\n") + 1679 (write _test-input-stream " loop-if-addr<\n") 1680 (write _test-input-stream " increment x\n") 1681 (write _test-input-stream " loop\n") 1682 (write _test-input-stream " }\n") 1683 (write _test-input-stream "}\n") 1684 # convert - 1685 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1685 (convert-mu _test-input-buffered-file _test-output-buffered-file) 1686 (flush _test-output-buffered-file) - 1687 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1687 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 1693 # check output - 1694 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0") - 1695 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1") - 1696 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2") - 1697 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3") - 1698 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4") - 1699 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5") - 1700 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6") - 1701 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7") - 1702 (check-next-stream-line-equal _test-output-stream " 0f 8d/jump-if->= $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/8") - 1703 (check-next-stream-line-equal _test-output-stream " 0f 82/jump-if-addr< $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/9") - 1704 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/10") - 1705 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/11") - 1706 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/12") - 1707 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/13") - 1708 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/14") - 1709 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/15") - 1710 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/16") - 1711 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/17") - 1712 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/18") - 1713 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/19") - 1714 # . epilogue - 1715 89/<- %esp 5/r32/ebp - 1716 5d/pop-to-ebp - 1717 c3/return - 1718 - 1719 test-convert-function-with-var-in-nested-block: - 1720 # . prologue - 1721 55/push-ebp - 1722 89/<- %ebp 4/r32/esp - 1723 # setup - 1724 (clear-stream _test-input-stream) - 1725 (clear-stream $_test-input-buffered-file->buffer) - 1726 (clear-stream _test-output-stream) - 1727 (clear-stream $_test-output-buffered-file->buffer) - 1728 # - 1729 (write _test-input-stream "fn foo x: int {\n") - 1730 (write _test-input-stream " {\n") - 1731 (write _test-input-stream " {\n") - 1732 (write _test-input-stream " var x: int\n") - 1733 (write _test-input-stream " increment x\n") - 1734 (write _test-input-stream " }\n") - 1735 (write _test-input-stream " }\n") - 1736 (write _test-input-stream "}\n") - 1737 # convert - 1738 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1739 (flush _test-output-buffered-file) - 1740 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1746 # check output - 1747 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0") - 1748 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1") - 1749 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2") - 1750 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3") - 1751 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4") - 1752 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5") - 1753 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6") - 1754 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7") - 1755 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8") - 1756 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9") - 1757 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10") - 1758 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11") - 1759 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-var-in-nested-block/12") - 1760 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13") - 1761 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14") - 1762 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15") - 1763 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16") - 1764 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17") - 1765 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18") - 1766 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19") - 1767 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20") - 1768 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21") - 1769 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22") - 1770 # . epilogue - 1771 89/<- %esp 5/r32/ebp - 1772 5d/pop-to-ebp - 1773 c3/return - 1774 - 1775 test-convert-function-with-multiple-vars-in-nested-blocks: - 1776 # . prologue - 1777 55/push-ebp - 1778 89/<- %ebp 4/r32/esp - 1779 # setup - 1780 (clear-stream _test-input-stream) - 1781 (clear-stream $_test-input-buffered-file->buffer) - 1782 (clear-stream _test-output-stream) - 1783 (clear-stream $_test-output-buffered-file->buffer) - 1784 # - 1785 (write _test-input-stream "fn foo x: int {\n") - 1786 (write _test-input-stream " {\n") - 1787 (write _test-input-stream " var x/eax: int <- copy 0\n") - 1788 (write _test-input-stream " {\n") - 1789 (write _test-input-stream " var y: int\n") - 1790 (write _test-input-stream " x <- add y\n") - 1791 (write _test-input-stream " }\n") - 1792 (write _test-input-stream " }\n") - 1793 (write _test-input-stream "}\n") - 1794 # convert - 1795 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1796 (flush _test-output-buffered-file) - 1797 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1803 # check output - 1804 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0") - 1805 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1") - 1806 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2") - 1807 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3") - 1808 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4") - 1809 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5") - 1810 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6") - 1811 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7") - 1812 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8") - 1813 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/9") - 1814 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10") - 1815 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11") - 1816 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12") - 1817 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/13") - 1818 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/14") - 1819 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15") - 1820 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16") - 1821 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17") - 1822 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18") - 1823 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19") - 1824 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20") - 1825 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21") - 1826 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22") - 1827 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23") - 1828 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24") - 1829 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25") - 1830 # . epilogue - 1831 89/<- %esp 5/r32/ebp - 1832 5d/pop-to-ebp - 1833 c3/return - 1834 - 1835 test-convert-function-with-branches-and-local-vars: - 1836 # A conditional 'break' after a 'var' in a block is converted into a - 1837 # nested block that performs all necessary cleanup before jumping. This - 1838 # results in some ugly code duplication. - 1839 # . prologue - 1840 55/push-ebp - 1841 89/<- %ebp 4/r32/esp - 1842 # setup - 1843 (clear-stream _test-input-stream) - 1844 (clear-stream $_test-input-buffered-file->buffer) - 1845 (clear-stream _test-output-stream) - 1846 (clear-stream $_test-output-buffered-file->buffer) - 1847 # - 1848 (write _test-input-stream "fn foo {\n") - 1849 (write _test-input-stream " {\n") - 1850 (write _test-input-stream " var x: int\n") - 1851 (write _test-input-stream " break-if->=\n") - 1852 (write _test-input-stream " increment x\n") - 1853 (write _test-input-stream " }\n") - 1854 (write _test-input-stream "}\n") - 1855 # convert - 1856 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1857 (flush _test-output-buffered-file) - 1858 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1864 # check output - 1865 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0") - 1866 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1") - 1867 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2") - 1868 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3") - 1869 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4") - 1870 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5") - 1871 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6") - 1872 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7") - 1873 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8") - 1874 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9") - 1875 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10") - 1876 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/11") - 1877 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12") - 1878 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13") - 1879 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14") - 1880 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/15") - 1881 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16") - 1882 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17") - 1883 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18") - 1884 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19") - 1885 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20") - 1886 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21") - 1887 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22") - 1888 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23") - 1889 # . epilogue - 1890 89/<- %esp 5/r32/ebp - 1891 5d/pop-to-ebp - 1892 c3/return - 1893 - 1894 test-convert-function-with-conditional-loops-and-local-vars: - 1895 # A conditional 'loop' after a 'var' in a block is converted into a nested - 1896 # block that performs all necessary cleanup before jumping. This results - 1897 # in some ugly code duplication. - 1898 # . prologue - 1899 55/push-ebp - 1900 89/<- %ebp 4/r32/esp - 1901 # setup - 1902 (clear-stream _test-input-stream) - 1903 (clear-stream $_test-input-buffered-file->buffer) - 1904 (clear-stream _test-output-stream) - 1905 (clear-stream $_test-output-buffered-file->buffer) - 1906 # - 1907 (write _test-input-stream "fn foo {\n") - 1908 (write _test-input-stream " {\n") - 1909 (write _test-input-stream " var x: int\n") - 1910 (write _test-input-stream " loop-if->=\n") - 1911 (write _test-input-stream " increment x\n") - 1912 (write _test-input-stream " }\n") - 1913 (write _test-input-stream "}\n") - 1914 # convert - 1915 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1916 (flush _test-output-buffered-file) - 1917 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1923 # check output - 1924 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0") - 1925 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1") - 1926 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2") - 1927 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3") - 1928 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4") - 1929 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5") - 1930 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6") - 1931 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7") - 1932 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8") - 1933 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9") - 1934 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/10") - 1935 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/11") - 1936 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/12") - 1937 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13") - 1938 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-conditional-loops-and-local-vars/14") - 1939 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/15") - 1940 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16") - 1941 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17") - 1942 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18") - 1943 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19") - 1944 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20") - 1945 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21") - 1946 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22") - 1947 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23") - 1948 # . epilogue - 1949 89/<- %esp 5/r32/ebp - 1950 5d/pop-to-ebp - 1951 c3/return - 1952 - 1953 test-convert-function-with-unconditional-loops-and-local-vars: - 1954 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the - 1955 # regular block cleanup. Any instructions after 'loop' are dead and - 1956 # therefore skipped. - 1957 # . prologue - 1958 55/push-ebp - 1959 89/<- %ebp 4/r32/esp - 1960 # setup - 1961 (clear-stream _test-input-stream) - 1962 (clear-stream $_test-input-buffered-file->buffer) - 1963 (clear-stream _test-output-stream) - 1964 (clear-stream $_test-output-buffered-file->buffer) - 1965 # - 1966 (write _test-input-stream "fn foo {\n") - 1967 (write _test-input-stream " {\n") - 1968 (write _test-input-stream " var x: int\n") - 1969 (write _test-input-stream " loop\n") - 1970 (write _test-input-stream " increment x\n") - 1971 (write _test-input-stream " }\n") - 1972 (write _test-input-stream "}\n") - 1973 # convert - 1974 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 1975 (flush _test-output-buffered-file) - 1976 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1982 # check output - 1983 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0") - 1984 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1") - 1985 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2") - 1986 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3") - 1987 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4") - 1988 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5") - 1989 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6") - 1990 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7") - 1991 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8") - 1992 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/9") - 1993 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10") - 1994 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc) - 1995 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11") - 1996 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12") - 1997 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13") - 1998 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14") - 1999 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15") - 2000 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16") - 2001 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17") - 2002 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18") - 2003 # . epilogue - 2004 89/<- %esp 5/r32/ebp - 2005 5d/pop-to-ebp - 2006 c3/return - 2007 - 2008 test-convert-function-with-branches-and-loops-and-local-vars: - 2009 # . prologue - 2010 55/push-ebp - 2011 89/<- %ebp 4/r32/esp - 2012 # setup - 2013 (clear-stream _test-input-stream) - 2014 (clear-stream $_test-input-buffered-file->buffer) - 2015 (clear-stream _test-output-stream) - 2016 (clear-stream $_test-output-buffered-file->buffer) - 2017 # - 2018 (write _test-input-stream "fn foo {\n") - 2019 (write _test-input-stream " {\n") - 2020 (write _test-input-stream " var x: int\n") - 2021 (write _test-input-stream " break-if->=\n") - 2022 (write _test-input-stream " increment x\n") - 2023 (write _test-input-stream " loop\n") - 2024 (write _test-input-stream " }\n") - 2025 (write _test-input-stream "}\n") - 2026 # convert - 2027 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2028 (flush _test-output-buffered-file) - 2029 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2035 # check output - 2036 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0") - 2037 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1") - 2038 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2") - 2039 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-loops-and-local-vars/3") - 2040 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4") - 2041 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5") - 2042 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6") - 2043 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7") - 2044 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8") - 2045 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9") - 2046 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/10") - 2047 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/11") - 2048 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/12") - 2049 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13") - 2050 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-loops-and-local-vars/14") - 2051 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/15") - 2052 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16") - 2053 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17") - 2054 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18") - 2055 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19") - 2056 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20") - 2057 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21") - 2058 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/22") - 2059 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23") - 2060 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24") - 2061 # . epilogue - 2062 89/<- %esp 5/r32/ebp - 2063 5d/pop-to-ebp - 2064 c3/return - 2065 - 2066 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars: - 2067 # . prologue - 2068 55/push-ebp - 2069 89/<- %ebp 4/r32/esp - 2070 # setup - 2071 (clear-stream _test-input-stream) - 2072 (clear-stream $_test-input-buffered-file->buffer) - 2073 (clear-stream _test-output-stream) - 2074 (clear-stream $_test-output-buffered-file->buffer) - 2075 # - 2076 (write _test-input-stream "fn foo {\n") - 2077 (write _test-input-stream " a: {\n") - 2078 (write _test-input-stream " var x: int\n") - 2079 (write _test-input-stream " {\n") - 2080 (write _test-input-stream " var y: int\n") - 2081 (write _test-input-stream " break-if->= a\n") - 2082 (write _test-input-stream " increment x\n") - 2083 (write _test-input-stream " loop\n") - 2084 (write _test-input-stream " }\n") - 2085 (write _test-input-stream " }\n") - 2086 (write _test-input-stream "}\n") - 2087 # convert - 2088 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2089 (flush _test-output-buffered-file) - 2090 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2096 # check output - 2097 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0") - 2098 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1") - 2099 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2") - 2100 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/3") - 2101 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4") - 2102 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5") - 2103 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6") - 2104 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7") - 2105 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/8") - 2106 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9") - 2107 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10") - 2108 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/11") - 2109 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12") - 2110 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/13") - 2111 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/14") - 2112 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/15") - 2113 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/16") - 2114 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17") - 2115 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/18") - 2116 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/19") - 2117 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/20") - 2118 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21") - 2119 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22") - 2120 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/23") - 2121 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24") - 2122 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25") - 2123 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26") - 2124 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27") - 2125 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28") - 2126 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/29") - 2127 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/30") - 2128 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31") - 2129 # . epilogue - 2130 89/<- %esp 5/r32/ebp - 2131 5d/pop-to-ebp - 2132 c3/return - 2133 - 2134 test-convert-function-with-nonlocal-unconditional-break-and-local-vars: - 2135 # . prologue - 2136 55/push-ebp - 2137 89/<- %ebp 4/r32/esp - 2138 # setup - 2139 (clear-stream _test-input-stream) - 2140 (clear-stream $_test-input-buffered-file->buffer) - 2141 (clear-stream _test-output-stream) - 2142 (clear-stream $_test-output-buffered-file->buffer) - 2143 # - 2144 (write _test-input-stream "fn foo {\n") - 2145 (write _test-input-stream " a: {\n") - 2146 (write _test-input-stream " var x: int\n") - 2147 (write _test-input-stream " {\n") - 2148 (write _test-input-stream " var y: int\n") - 2149 (write _test-input-stream " break a\n") - 2150 (write _test-input-stream " increment x\n") - 2151 (write _test-input-stream " }\n") - 2152 (write _test-input-stream " }\n") - 2153 (write _test-input-stream "}\n") - 2154 # convert - 2155 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2156 (flush _test-output-buffered-file) - 2157 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2163 # check output - 2164 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0") - 2165 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1") - 2166 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2") - 2167 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/3") - 2168 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4") - 2169 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5") - 2170 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6") - 2171 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7") - 2172 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8") - 2173 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9") - 2174 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10") - 2175 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11") - 2176 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/12") - 2177 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/13") - 2178 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/14") - 2179 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15") - 2180 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16") - 2181 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/17") - 2182 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18") - 2183 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19") - 2184 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20") - 2185 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21") - 2186 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22") - 2187 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/23") - 2188 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24") - 2189 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25") - 2190 # . epilogue - 2191 89/<- %esp 5/r32/ebp - 2192 5d/pop-to-ebp - 2193 c3/return - 2194 - 2195 test-convert-function-with-unconditional-break-and-local-vars: - 2196 # . prologue - 2197 55/push-ebp - 2198 89/<- %ebp 4/r32/esp - 2199 # setup - 2200 (clear-stream _test-input-stream) - 2201 (clear-stream $_test-input-buffered-file->buffer) - 2202 (clear-stream _test-output-stream) - 2203 (clear-stream $_test-output-buffered-file->buffer) - 2204 # - 2205 (write _test-input-stream "fn foo {\n") - 2206 (write _test-input-stream " {\n") - 2207 (write _test-input-stream " var x: int\n") - 2208 (write _test-input-stream " {\n") - 2209 (write _test-input-stream " var y: int\n") - 2210 (write _test-input-stream " break\n") - 2211 (write _test-input-stream " increment x\n") - 2212 (write _test-input-stream " }\n") - 2213 (write _test-input-stream " }\n") - 2214 (write _test-input-stream "}\n") - 2215 # convert - 2216 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2217 (flush _test-output-buffered-file) - 2218 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2224 # check output - 2225 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0") - 2226 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1") - 2227 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2") - 2228 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3") - 2229 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4") - 2230 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5") - 2231 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6") - 2232 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7") - 2233 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8") - 2234 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9") - 2235 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10") - 2236 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11") - 2237 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/12") - 2238 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13") - 2239 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14") - 2240 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/15") - 2241 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16") - 2242 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17") - 2243 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18") - 2244 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19") - 2245 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20") - 2246 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21") - 2247 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22") - 2248 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23") - 2249 # . epilogue - 2250 89/<- %esp 5/r32/ebp - 2251 5d/pop-to-ebp - 2252 c3/return - 2253 - 2254 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars: - 2255 # . prologue - 2256 55/push-ebp - 2257 89/<- %ebp 4/r32/esp - 2258 # setup - 2259 (clear-stream _test-input-stream) - 2260 (clear-stream $_test-input-buffered-file->buffer) - 2261 (clear-stream _test-output-stream) - 2262 (clear-stream $_test-output-buffered-file->buffer) - 2263 # - 2264 (write _test-input-stream "fn foo {\n") - 2265 (write _test-input-stream " a: {\n") - 2266 (write _test-input-stream " var x: int\n") - 2267 (write _test-input-stream " {\n") - 2268 (write _test-input-stream " var y: int\n") - 2269 (write _test-input-stream " loop a\n") - 2270 (write _test-input-stream " increment x\n") - 2271 (write _test-input-stream " }\n") - 2272 (write _test-input-stream " }\n") - 2273 (write _test-input-stream "}\n") - 2274 # convert - 2275 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2276 (flush _test-output-buffered-file) - 2277 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2283 # check output - 2284 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0") - 2285 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1") - 2286 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2") - 2287 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/3") - 2288 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4") - 2289 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5") - 2290 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6") - 2291 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7") - 2292 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8") - 2293 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9") - 2294 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10") - 2295 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11") - 2296 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/12") - 2297 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/13") - 2298 (check-next-stream-line-equal _test-output-stream " e9/jump a:loop/disp32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/14") - 2299 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15") - 2300 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16") - 2301 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/17") - 2302 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18") - 2303 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19") - 2304 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20") - 2305 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21") - 2306 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22") - 2307 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/23") - 2308 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24") - 2309 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25") - 2310 # . epilogue - 2311 89/<- %esp 5/r32/ebp - 2312 5d/pop-to-ebp - 2313 c3/return - 2314 - 2315 test-convert-function-with-local-array-var-in-mem: - 2316 # . prologue - 2317 55/push-ebp - 2318 89/<- %ebp 4/r32/esp - 2319 # setup - 2320 (clear-stream _test-input-stream) - 2321 (clear-stream $_test-input-buffered-file->buffer) - 2322 (clear-stream _test-output-stream) - 2323 (clear-stream $_test-output-buffered-file->buffer) - 2324 # - 2325 (write _test-input-stream "fn foo {\n") - 2326 (write _test-input-stream " var x: (array int 3)\n") - 2327 (write _test-input-stream "}\n") - 2328 # convert - 2329 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2330 (flush _test-output-buffered-file) - 2331 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2337 # check output - 2338 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0") - 2339 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1") - 2340 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2") - 2341 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3") - 2342 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4") - 2343 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5") - 2344 # define x - 2345 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7") - 2346 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8") - 2347 # reclaim x - 2348 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-function-with-local-array-var-in-mem/9") - 2349 # - 2350 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10") - 2351 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11") - 2352 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12") - 2353 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13") - 2354 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14") - 2355 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15") - 2356 # . epilogue - 2357 89/<- %esp 5/r32/ebp - 2358 5d/pop-to-ebp - 2359 c3/return - 2360 - 2361 test-convert-address: - 2362 # . prologue - 2363 55/push-ebp - 2364 89/<- %ebp 4/r32/esp - 2365 # setup - 2366 (clear-stream _test-input-stream) - 2367 (clear-stream $_test-input-buffered-file->buffer) - 2368 (clear-stream _test-output-stream) - 2369 (clear-stream $_test-output-buffered-file->buffer) - 2370 # - 2371 (write _test-input-stream "fn foo {\n") - 2372 (write _test-input-stream " var a: int\n") - 2373 (write _test-input-stream " var b/eax: (addr int) <- address a\n") - 2374 (write _test-input-stream "}\n") - 2375 # convert - 2376 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2377 (flush _test-output-buffered-file) - 2378 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2384 # check output - 2385 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0") - 2386 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1") - 2387 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2") - 2388 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3") - 2389 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4") - 2390 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5") - 2391 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6") - 2392 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7") - 2393 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8") - 2394 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9") - 2395 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10") - 2396 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11") - 2397 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12") - 2398 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13") - 2399 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14") - 2400 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15") - 2401 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16") - 2402 # . epilogue - 2403 89/<- %esp 5/r32/ebp - 2404 5d/pop-to-ebp - 2405 c3/return - 2406 - 2407 test-convert-length-of-array: - 2408 # . prologue - 2409 55/push-ebp - 2410 89/<- %ebp 4/r32/esp - 2411 # setup - 2412 (clear-stream _test-input-stream) - 2413 (clear-stream $_test-input-buffered-file->buffer) - 2414 (clear-stream _test-output-stream) - 2415 (clear-stream $_test-output-buffered-file->buffer) - 2416 # - 2417 (write _test-input-stream "fn foo a: (addr array int) {\n") - 2418 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n") - 2419 (write _test-input-stream " var c/eax: int <- length b\n") - 2420 (write _test-input-stream "}\n") - 2421 # convert - 2422 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2423 (flush _test-output-buffered-file) - 2424 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2430 # check output - 2431 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0") - 2432 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1") - 2433 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2") - 2434 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3") - 2435 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4") - 2436 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") - 2437 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") - 2438 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") - 2439 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") - 2440 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9") - 2441 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") - 2442 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") - 2443 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") - 2444 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") - 2445 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") - 2446 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") - 2447 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") - 2448 # . epilogue - 2449 89/<- %esp 5/r32/ebp - 2450 5d/pop-to-ebp - 2451 c3/return - 2452 - 2453 test-convert-length-of-array-on-stack: - 2454 # . prologue - 2455 55/push-ebp - 2456 89/<- %ebp 4/r32/esp - 2457 # setup - 2458 (clear-stream _test-input-stream) - 2459 (clear-stream $_test-input-buffered-file->buffer) - 2460 (clear-stream _test-output-stream) - 2461 (clear-stream $_test-output-buffered-file->buffer) - 2462 # - 2463 (write _test-input-stream "fn foo {\n") - 2464 (write _test-input-stream " var a: (array int 3)\n") - 2465 (write _test-input-stream " var b/eax: int <- length a\n") - 2466 (write _test-input-stream "}\n") - 2467 # convert - 2468 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2469 (flush _test-output-buffered-file) - 2470 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2476 # check output - 2477 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0") - 2478 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1") - 2479 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2") - 2480 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3") - 2481 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4") - 2482 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5") - 2483 # define x - 2484 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6") - 2485 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") - 2486 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") - 2487 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") - 2488 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10") - 2489 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") - 2490 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") - 2491 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") - 2492 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") - 2493 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") - 2494 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") - 2495 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") - 2496 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") - 2497 # . epilogue - 2498 89/<- %esp 5/r32/ebp - 2499 5d/pop-to-ebp - 2500 c3/return - 2501 - 2502 test-convert-index-into-array: - 2503 # . prologue - 2504 55/push-ebp - 2505 89/<- %ebp 4/r32/esp - 2506 # setup - 2507 (clear-stream _test-input-stream) - 2508 (clear-stream $_test-input-buffered-file->buffer) - 2509 (clear-stream _test-output-stream) - 2510 (clear-stream $_test-output-buffered-file->buffer) - 2511 # - 2512 (write _test-input-stream "fn foo {\n") - 2513 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 2514 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 2515 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 2516 (write _test-input-stream "}\n") - 2517 # convert - 2518 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2519 (flush _test-output-buffered-file) - 2520 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2526 # check output - 2527 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") - 2528 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") - 2529 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") - 2530 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") - 2531 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") - 2532 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") - 2533 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") - 2534 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") - 2535 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") - 2536 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") - 2537 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/11") - 2538 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/13") - 2539 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/14") - 2540 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/15") - 2541 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/16") - 2542 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/17") - 2543 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/18") - 2544 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/19") - 2545 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/20") - 2546 # . epilogue - 2547 89/<- %esp 5/r32/ebp - 2548 5d/pop-to-ebp - 2549 c3/return - 2550 - 2551 test-convert-index-into-array-with-literal: - 2552 # . prologue - 2553 55/push-ebp - 2554 89/<- %ebp 4/r32/esp - 2555 # setup - 2556 (clear-stream _test-input-stream) - 2557 (clear-stream $_test-input-buffered-file->buffer) - 2558 (clear-stream _test-output-stream) - 2559 (clear-stream $_test-output-buffered-file->buffer) - 2560 # - 2561 (write _test-input-stream "fn foo {\n") - 2562 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 2563 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 2564 (write _test-input-stream "}\n") - 2565 # convert - 2566 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2567 (flush _test-output-buffered-file) - 2568 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2574 # check output - 2575 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") - 2576 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") - 2577 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") - 2578 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") - 2579 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") - 2580 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") - 2581 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") - 2582 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") - 2583 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 - 2584 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") - 2585 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") - 2586 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") - 2587 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/11") - 2588 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/12") - 2589 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/13") - 2590 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/14") - 2591 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/15") - 2592 # . epilogue - 2593 89/<- %esp 5/r32/ebp - 2594 5d/pop-to-ebp - 2595 c3/return - 2596 - 2597 test-convert-index-into-array-on-stack: - 2598 # . prologue - 2599 55/push-ebp - 2600 89/<- %ebp 4/r32/esp - 2601 # setup - 2602 (clear-stream _test-input-stream) - 2603 (clear-stream $_test-input-buffered-file->buffer) - 2604 (clear-stream _test-output-stream) - 2605 (clear-stream $_test-output-buffered-file->buffer) - 2606 # - 2607 (write _test-input-stream "fn foo {\n") - 2608 (write _test-input-stream " var arr: (array int 3)\n") - 2609 (write _test-input-stream " var idx/eax: int <- copy 2\n") - 2610 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 2611 (write _test-input-stream "}\n") - 2612 # convert - 2613 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2614 (flush _test-output-buffered-file) - 2615 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2621 # check output - 2622 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") - 2623 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") - 2624 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") - 2625 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") - 2626 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") - 2627 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") - 2628 # var arr - 2629 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") - 2630 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") - 2631 # var idx - 2632 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") - 2633 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") - 2634 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc - 2635 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + eax<<0x00000002 + 0xfffffff4) 0x00000000/r32" "F - test-convert-index-into-array-on-stack/10") - 2636 # reclaim idx - 2637 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/11") - 2638 # reclaim arr - 2639 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/12") - 2640 # - 2641 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/13") - 2642 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/14") - 2643 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/15") - 2644 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/16") - 2645 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/17") - 2646 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/18") - 2647 # . epilogue - 2648 89/<- %esp 5/r32/ebp - 2649 5d/pop-to-ebp - 2650 c3/return - 2651 - 2652 test-convert-index-into-array-on-stack-with-literal: - 2653 # . prologue - 2654 55/push-ebp - 2655 89/<- %ebp 4/r32/esp - 2656 # setup - 2657 (clear-stream _test-input-stream) - 2658 (clear-stream $_test-input-buffered-file->buffer) - 2659 (clear-stream _test-output-stream) - 2660 (clear-stream $_test-output-buffered-file->buffer) - 2661 # - 2662 (write _test-input-stream "fn foo {\n") - 2663 (write _test-input-stream " var arr: (array int 3)\n") - 2664 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 2665 (write _test-input-stream "}\n") - 2666 # convert - 2667 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2668 (flush _test-output-buffered-file) - 2669 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2675 # check output - 2676 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") - 2677 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") - 2678 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") - 2679 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") - 2680 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") - 2681 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") - 2682 # var arr - 2683 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") - 2684 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") - 2685 # var x - 2686 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") - 2687 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 - 2688 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xfffffffc) 0x00000000/r32" "F - test-convert-index-into-array-on-stack-with-literal/9") - 2689 # reclaim x - 2690 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/10") - 2691 # reclaim arr - 2692 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack-with-literal/11") - 2693 # - 2694 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/12") - 2695 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/13") - 2696 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/14") - 2697 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/15") - 2698 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") - 2699 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/17") - 2700 # . epilogue - 2701 89/<- %esp 5/r32/ebp - 2702 5d/pop-to-ebp - 2703 c3/return - 2704 - 2705 test-convert-index-into-array-using-offset: - 2706 # . prologue - 2707 55/push-ebp - 2708 89/<- %ebp 4/r32/esp - 2709 # setup - 2710 (clear-stream _test-input-stream) - 2711 (clear-stream $_test-input-buffered-file->buffer) - 2712 (clear-stream _test-output-stream) - 2713 (clear-stream $_test-output-buffered-file->buffer) - 2714 # - 2715 (write _test-input-stream "fn foo {\n") - 2716 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 2717 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 2718 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 2719 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 2720 (write _test-input-stream "}\n") - 2721 # convert - 2722 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2723 (flush _test-output-buffered-file) - 2724 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2730 # check output - 2731 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") - 2732 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") - 2733 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") - 2734 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") - 2735 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") - 2736 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") - 2737 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") - 2738 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") - 2739 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") - 2740 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") - 2741 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") - 2742 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/11") - 2743 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12") - 2744 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13") - 2745 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/14") - 2746 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/15") - 2747 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/16") - 2748 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/17") - 2749 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/18") - 2750 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/19") - 2751 # . epilogue - 2752 89/<- %esp 5/r32/ebp - 2753 5d/pop-to-ebp - 2754 c3/return - 2755 - 2756 test-convert-index-into-array-using-offset-on-stack: - 2757 # . prologue - 2758 55/push-ebp - 2759 89/<- %ebp 4/r32/esp - 2760 # setup - 2761 (clear-stream _test-input-stream) - 2762 (clear-stream $_test-input-buffered-file->buffer) - 2763 (clear-stream _test-output-stream) - 2764 (clear-stream $_test-output-buffered-file->buffer) - 2765 # - 2766 (write _test-input-stream "fn foo {\n") - 2767 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 2768 (write _test-input-stream " var idx: int\n") - 2769 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 2770 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 2771 (write _test-input-stream "}\n") - 2772 # convert - 2773 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2774 (flush _test-output-buffered-file) - 2775 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2781 # check output - 2782 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") - 2783 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") - 2784 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") - 2785 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") - 2786 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") - 2787 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") - 2788 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") - 2789 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/7") - 2790 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") - 2791 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") - 2792 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10") - 2793 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset-on-stack/11") - 2794 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12") - 2795 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-using-offset-on-stack/13") - 2796 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/14") - 2797 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/15") - 2798 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/16") - 2799 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/17") - 2800 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/18") - 2801 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/19") - 2802 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/20") - 2803 # . epilogue - 2804 89/<- %esp 5/r32/ebp - 2805 5d/pop-to-ebp - 2806 c3/return - 2807 - 2808 test-convert-function-and-type-definition: - 2809 # . prologue - 2810 55/push-ebp - 2811 89/<- %ebp 4/r32/esp - 2812 # setup - 2813 (clear-stream _test-input-stream) - 2814 (clear-stream $_test-input-buffered-file->buffer) - 2815 (clear-stream _test-output-stream) - 2816 (clear-stream $_test-output-buffered-file->buffer) - 2817 # - 2818 (write _test-input-stream "fn foo a: (addr t) {\n") - 2819 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") - 2820 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") - 2821 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") - 2822 (write _test-input-stream "}\n") - 2823 (write _test-input-stream "type t {\n") - 2824 (write _test-input-stream " x: int\n") - 2825 (write _test-input-stream " y: int\n") - 2826 (write _test-input-stream "}\n") - 2827 # convert - 2828 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2829 (flush _test-output-buffered-file) - 2830 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2836 # check output - 2837 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") - 2838 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") - 2839 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") - 2840 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") - 2841 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") - 2842 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") - 2843 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") - 2844 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") - 2845 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") - 2846 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9") - 2847 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") - 2848 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13") - 2849 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14") - 2850 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/15") - 2851 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/16") - 2852 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/17") - 2853 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/18") - 2854 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/19") - 2855 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/20") - 2856 # . epilogue - 2857 89/<- %esp 5/r32/ebp - 2858 5d/pop-to-ebp - 2859 c3/return - 2860 - 2861 test-convert-function-with-local-var-with-user-defined-type: - 2862 # . prologue - 2863 55/push-ebp - 2864 89/<- %ebp 4/r32/esp - 2865 # setup - 2866 (clear-stream _test-input-stream) - 2867 (clear-stream $_test-input-buffered-file->buffer) - 2868 (clear-stream _test-output-stream) - 2869 (clear-stream $_test-output-buffered-file->buffer) - 2870 # - 2871 (write _test-input-stream "fn foo {\n") - 2872 (write _test-input-stream " var a: t\n") - 2873 (write _test-input-stream "}\n") - 2874 (write _test-input-stream "type t {\n") - 2875 (write _test-input-stream " x: int\n") - 2876 (write _test-input-stream " y: int\n") - 2877 (write _test-input-stream "}\n") - 2878 # convert - 2879 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2880 (flush _test-output-buffered-file) - 2881 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2887 # check output - 2888 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") - 2889 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") - 2890 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") - 2891 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type/3") - 2892 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") - 2893 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") - 2894 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") - 2895 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") - 2896 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/8") - 2897 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") - 2898 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") - 2899 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") - 2900 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type/12") - 2901 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") - 2902 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") - 2903 # . epilogue - 2904 89/<- %esp 5/r32/ebp - 2905 5d/pop-to-ebp - 2906 c3/return - 2907 - 2908 test-convert-function-call-with-arg-of-user-defined-type: - 2909 # . prologue - 2910 55/push-ebp - 2911 89/<- %ebp 4/r32/esp - 2912 # setup - 2913 (clear-stream _test-input-stream) - 2914 (clear-stream $_test-input-buffered-file->buffer) - 2915 (clear-stream _test-output-stream) - 2916 (clear-stream $_test-output-buffered-file->buffer) - 2917 # - 2918 (write _test-input-stream "fn f {\n") - 2919 (write _test-input-stream " var a: t\n") - 2920 (write _test-input-stream " foo a\n") - 2921 (write _test-input-stream "}\n") - 2922 (write _test-input-stream "fn foo x: t {\n") - 2923 (write _test-input-stream "}\n") - 2924 (write _test-input-stream "type t {\n") - 2925 (write _test-input-stream " x: int\n") - 2926 (write _test-input-stream " y: int\n") - 2927 (write _test-input-stream "}\n") - 2928 # convert - 2929 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2930 (flush _test-output-buffered-file) - 2931 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2937 # check output - 2938 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 2939 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 2940 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 2941 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") - 2942 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 2943 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 2944 # var a: t - 2945 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") - 2946 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") - 2947 # foo a - 2948 (check-next-stream-line-equal _test-output-stream " (foo *(ebp+0xfffffff8) *(ebp+0xfffffffc))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") - 2949 # - 2950 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/9") - 2951 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 2952 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 2953 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 2954 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") - 2955 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 2956 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 2957 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 2958 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 2959 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 2960 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") - 2961 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 2962 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") - 2963 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 2964 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 2965 # . epilogue - 2966 89/<- %esp 5/r32/ebp - 2967 5d/pop-to-ebp - 2968 c3/return - 2969 - 2970 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: - 2971 # . prologue - 2972 55/push-ebp - 2973 89/<- %ebp 4/r32/esp - 2974 # setup - 2975 (clear-stream _test-input-stream) - 2976 (clear-stream $_test-input-buffered-file->buffer) - 2977 (clear-stream _test-output-stream) - 2978 (clear-stream $_test-output-buffered-file->buffer) - 2979 # - 2980 (write _test-input-stream "fn f {\n") - 2981 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") - 2982 (write _test-input-stream " foo *a\n") - 2983 (write _test-input-stream "}\n") - 2984 (write _test-input-stream "fn foo x: t {\n") - 2985 (write _test-input-stream "}\n") - 2986 (write _test-input-stream "type t {\n") - 2987 (write _test-input-stream " x: int\n") - 2988 (write _test-input-stream " y: int\n") - 2989 (write _test-input-stream "}\n") - 2990 # convert - 2991 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 2992 (flush _test-output-buffered-file) - 2993 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 2999 # check output - 3000 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 3001 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 3002 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 3003 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") - 3004 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 3005 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 3006 # var a - 3007 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/6") - 3008 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") - 3009 # foo a - 3010 (check-next-stream-line-equal _test-output-stream " (foo *(eax+0x00000000) *(eax+0x00000004))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") - 3011 # - 3012 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9") - 3013 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 3014 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 3015 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 3016 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") - 3017 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 3018 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 3019 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 3020 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 3021 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 3022 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") - 3023 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 3024 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") - 3025 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 3026 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 3027 # . epilogue - 3028 89/<- %esp 5/r32/ebp - 3029 5d/pop-to-ebp - 3030 c3/return - 3031 - 3032 # we don't have special support for call-by-reference; just explicitly create - 3033 # a new variable with the address of the arg - 3034 test-convert-function-call-with-arg-of-user-defined-type-by-reference: - 3035 # . prologue - 3036 55/push-ebp - 3037 89/<- %ebp 4/r32/esp - 3038 # setup - 3039 (clear-stream _test-input-stream) - 3040 (clear-stream $_test-input-buffered-file->buffer) - 3041 (clear-stream _test-output-stream) - 3042 (clear-stream $_test-output-buffered-file->buffer) - 3043 # - 3044 (write _test-input-stream "fn f {\n") - 3045 (write _test-input-stream " var a: t\n") - 3046 (write _test-input-stream " var b/eax: (addr t) <- address a\n") - 3047 (write _test-input-stream " foo b\n") - 3048 (write _test-input-stream "}\n") - 3049 (write _test-input-stream "fn foo x: (addr t) {\n") - 3050 (write _test-input-stream " var x/ecx: (addr int) <- copy x\n") - 3051 (write _test-input-stream " increment *x\n") - 3052 (write _test-input-stream "}\n") - 3053 (write _test-input-stream "type t {\n") - 3054 (write _test-input-stream " x: int\n") - 3055 (write _test-input-stream " y: int\n") - 3056 (write _test-input-stream "}\n") - 3057 # convert - 3058 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3059 (flush _test-output-buffered-file) - 3060 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3066 # check output - 3067 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") - 3068 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") - 3069 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/2") - 3070 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/3") - 3071 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") - 3072 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/5") - 3073 # var a: t - 3074 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/6") - 3075 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/7") - 3076 # var b/eax: (addr t) - 3077 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/8") - 3078 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/9") - 3079 # foo a - 3080 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") - 3081 # - 3082 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/11") - 3083 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/12") - 3084 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") - 3085 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/14") - 3086 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") - 3087 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/16") - 3088 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/17") - 3089 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") - 3090 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") - 3091 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") - 3092 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/21") - 3093 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/22") - 3094 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") - 3095 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24") - 3096 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25") - 3097 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26") - 3098 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27") - 3099 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28") - 3100 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") - 3101 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30") - 3102 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") - 3103 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/32") - 3104 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/33") - 3105 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34") - 3106 # . epilogue - 3107 89/<- %esp 5/r32/ebp - 3108 5d/pop-to-ebp - 3109 c3/return - 3110 - 3111 test-convert-get-on-local-variable: - 3112 # . prologue - 3113 55/push-ebp - 3114 89/<- %ebp 4/r32/esp - 3115 # setup - 3116 (clear-stream _test-input-stream) - 3117 (clear-stream $_test-input-buffered-file->buffer) - 3118 (clear-stream _test-output-stream) - 3119 (clear-stream $_test-output-buffered-file->buffer) - 3120 # - 3121 (write _test-input-stream "fn foo {\n") - 3122 (write _test-input-stream " var a: t\n") - 3123 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 3124 (write _test-input-stream "}\n") - 3125 (write _test-input-stream "type t {\n") - 3126 (write _test-input-stream " x: int\n") - 3127 (write _test-input-stream " y: int\n") - 3128 (write _test-input-stream "}\n") - 3129 # convert - 3130 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3131 (flush _test-output-buffered-file) - 3132 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3138 # check output - 3139 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") - 3140 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") - 3141 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") - 3142 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") - 3143 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") - 3144 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") - 3145 # var a - 3146 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") - 3147 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") - 3148 # var c - 3149 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") - 3150 # get - 3151 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") - 3152 # reclaim c - 3153 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") - 3154 # reclaim a - 3155 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") - 3156 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") - 3157 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") - 3158 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") - 3159 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") - 3160 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") - 3161 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") - 3162 # . epilogue - 3163 89/<- %esp 5/r32/ebp - 3164 5d/pop-to-ebp - 3165 c3/return - 3166 - 3167 test-convert-get-on-function-argument: - 3168 # . prologue - 3169 55/push-ebp - 3170 89/<- %ebp 4/r32/esp - 3171 # setup - 3172 (clear-stream _test-input-stream) - 3173 (clear-stream $_test-input-buffered-file->buffer) - 3174 (clear-stream _test-output-stream) - 3175 (clear-stream $_test-output-buffered-file->buffer) - 3176 # - 3177 (write _test-input-stream "fn foo a: t {\n") - 3178 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 3179 (write _test-input-stream "}\n") - 3180 (write _test-input-stream "type t {\n") - 3181 (write _test-input-stream " x: int\n") - 3182 (write _test-input-stream " y: int\n") - 3183 (write _test-input-stream "}\n") - 3184 # convert - 3185 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3186 (flush _test-output-buffered-file) - 3187 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3193 # check output - 3194 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") - 3195 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") - 3196 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") - 3197 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") - 3198 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") - 3199 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") - 3200 # var c - 3201 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") - 3202 # get - 3203 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") - 3204 # reclaim c - 3205 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") - 3206 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") - 3207 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") - 3208 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") - 3209 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") - 3210 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") - 3211 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") - 3212 # . epilogue - 3213 89/<- %esp 5/r32/ebp - 3214 5d/pop-to-ebp - 3215 c3/return - 3216 - 3217 test-convert-get-on-function-argument-with-known-type: - 3218 # . prologue - 3219 55/push-ebp - 3220 89/<- %ebp 4/r32/esp - 3221 # setup - 3222 (clear-stream _test-input-stream) - 3223 (clear-stream $_test-input-buffered-file->buffer) - 3224 (clear-stream _test-output-stream) - 3225 (clear-stream $_test-output-buffered-file->buffer) - 3226 # - 3227 (write _test-input-stream "type t {\n") - 3228 (write _test-input-stream " x: int\n") - 3229 (write _test-input-stream " y: int\n") - 3230 (write _test-input-stream "}\n") - 3231 (write _test-input-stream "fn foo a: t {\n") - 3232 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 3233 (write _test-input-stream "}\n") - 3234 # convert - 3235 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3236 (flush _test-output-buffered-file) - 3237 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3243 # check output - 3244 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") - 3245 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") - 3246 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") - 3247 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") - 3248 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") - 3249 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") - 3250 # var c - 3251 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") - 3252 # get - 3253 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument-with-known-type/7") - 3254 # reclaim c - 3255 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") - 3256 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") - 3257 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") - 3258 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") - 3259 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") - 3260 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") - 3261 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") - 3262 # . epilogue - 3263 89/<- %esp 5/r32/ebp - 3264 5d/pop-to-ebp - 3265 c3/return - 3266 - 3267 test-convert-array-of-user-defined-types: - 3268 # . prologue - 3269 55/push-ebp - 3270 89/<- %ebp 4/r32/esp - 3271 # setup - 3272 (clear-stream _test-input-stream) - 3273 (clear-stream $_test-input-buffered-file->buffer) - 3274 (clear-stream _test-output-stream) - 3275 (clear-stream $_test-output-buffered-file->buffer) - 3276 # - 3277 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 - 3278 (write _test-input-stream " x: int\n") - 3279 (write _test-input-stream " y: int\n") - 3280 (write _test-input-stream "}\n") - 3281 (write _test-input-stream "fn foo {\n") - 3282 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 3283 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 3284 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 3285 (write _test-input-stream "}\n") - 3286 # convert - 3287 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3288 (flush _test-output-buffered-file) - 3289 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3295 # check output - 3296 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") - 3297 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") - 3298 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") - 3299 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") - 3300 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") - 3301 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") - 3302 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") - 3303 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") - 3304 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") - 3305 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") - 3306 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000003 + 4) 0x00000000/r32" "F - test-convert-array-of-user-defined-types/11") - 3307 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/13") - 3308 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/14") - 3309 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/15") - 3310 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/16") - 3311 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/17") - 3312 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/18") - 3313 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/19") - 3314 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/20") - 3315 # . epilogue - 3316 89/<- %esp 5/r32/ebp - 3317 5d/pop-to-ebp - 3318 c3/return - 3319 - 3320 test-convert-length-of-array-of-user-defined-types-to-eax: - 3321 # . prologue - 3322 55/push-ebp - 3323 89/<- %ebp 4/r32/esp - 3324 # setup - 3325 (clear-stream _test-input-stream) - 3326 (clear-stream $_test-input-buffered-file->buffer) - 3327 (clear-stream _test-output-stream) - 3328 (clear-stream $_test-output-buffered-file->buffer) - 3329 # - 3330 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 3331 (write _test-input-stream " x: int\n") - 3332 (write _test-input-stream " y: int\n") - 3333 (write _test-input-stream " z: int\n") - 3334 (write _test-input-stream "}\n") - 3335 (write _test-input-stream "fn foo {\n") - 3336 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 3337 (write _test-input-stream " var x/eax: (addr t) <- length arr\n") - 3338 (write _test-input-stream "}\n") - 3339 # convert - 3340 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3341 (flush _test-output-buffered-file) - 3342 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3348 # check output - 3349 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") - 3350 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") - 3351 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") - 3352 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/3") - 3353 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") - 3354 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") - 3355 # var arr - 3356 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/6") - 3357 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/7") - 3358 # length instruction - 3359 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") - 3360 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") - 3361 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/10") - 3362 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/11") - 3363 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/12") - 3364 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/13") - 3365 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/14") - 3366 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/15") - 3367 # reclaim arr - 3368 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/16") - 3369 # - 3370 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") - 3371 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") - 3372 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") - 3373 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/20") - 3374 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/21") - 3375 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") - 3376 # . epilogue - 3377 89/<- %esp 5/r32/ebp - 3378 5d/pop-to-ebp - 3379 c3/return - 3380 - 3381 test-convert-length-of-array-of-user-defined-types-to-ecx: - 3382 # . prologue - 3383 55/push-ebp - 3384 89/<- %ebp 4/r32/esp - 3385 # setup - 3386 (clear-stream _test-input-stream) - 3387 (clear-stream $_test-input-buffered-file->buffer) - 3388 (clear-stream _test-output-stream) - 3389 (clear-stream $_test-output-buffered-file->buffer) - 3390 # - 3391 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 3392 (write _test-input-stream " x: int\n") - 3393 (write _test-input-stream " y: int\n") - 3394 (write _test-input-stream " z: int\n") - 3395 (write _test-input-stream "}\n") - 3396 (write _test-input-stream "fn foo {\n") - 3397 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 3398 (write _test-input-stream " var x/ecx: (addr t) <- length arr\n") - 3399 (write _test-input-stream "}\n") - 3400 # convert - 3401 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3402 (flush _test-output-buffered-file) - 3403 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3409 # check output - 3410 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") - 3411 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") - 3412 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") - 3413 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/3") - 3414 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") - 3415 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") - 3416 # var a - 3417 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/6") - 3418 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/7") - 3419 # var x - 3420 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/8") - 3421 # length instruction - 3422 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") - 3423 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") - 3424 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/11") - 3425 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/12") - 3426 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/13") - 3427 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/14") - 3428 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/15") - 3429 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/16") - 3430 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/17") - 3431 # reclaim x - 3432 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/18") - 3433 # reclaim a - 3434 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/19") - 3435 # - 3436 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") - 3437 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") - 3438 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") - 3439 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/23") - 3440 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/24") - 3441 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") - 3442 # . epilogue - 3443 89/<- %esp 5/r32/ebp - 3444 5d/pop-to-ebp - 3445 c3/return - 3446 - 3447 test-convert-length-of-array-of-user-defined-types-to-edx: - 3448 # . prologue - 3449 55/push-ebp - 3450 89/<- %ebp 4/r32/esp - 3451 # setup - 3452 (clear-stream _test-input-stream) - 3453 (clear-stream $_test-input-buffered-file->buffer) - 3454 (clear-stream _test-output-stream) - 3455 (clear-stream $_test-output-buffered-file->buffer) - 3456 # - 3457 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 3458 (write _test-input-stream " x: int\n") - 3459 (write _test-input-stream " y: int\n") - 3460 (write _test-input-stream " z: int\n") - 3461 (write _test-input-stream "}\n") - 3462 (write _test-input-stream "fn foo {\n") - 3463 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 3464 (write _test-input-stream " var x/edx: (addr t) <- length arr\n") - 3465 (write _test-input-stream "}\n") - 3466 # convert - 3467 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3468 (flush _test-output-buffered-file) - 3469 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3475 # check output - 3476 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") - 3477 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") - 3478 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") - 3479 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/3") - 3480 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") - 3481 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") - 3482 # var a - 3483 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/6") - 3484 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/7") - 3485 # var x - 3486 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/8") - 3487 # length instruction - 3488 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") - 3489 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") - 3490 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/11") - 3491 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/12") - 3492 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/13") - 3493 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/14") - 3494 (check-next-stream-line-equal _test-output-stream " 89/<- %edx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/15") - 3495 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/16") - 3496 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/17") - 3497 # reclaim x - 3498 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/18") - 3499 # reclaim a - 3500 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/19") - 3501 # - 3502 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") - 3503 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") - 3504 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") - 3505 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/23") - 3506 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/24") - 3507 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") - 3508 # . epilogue - 3509 89/<- %esp 5/r32/ebp - 3510 5d/pop-to-ebp - 3511 c3/return - 3512 - 3513 test-convert-length-of-array-of-user-defined-types: - 3514 # . prologue - 3515 55/push-ebp - 3516 89/<- %ebp 4/r32/esp - 3517 # setup - 3518 (clear-stream _test-input-stream) - 3519 (clear-stream $_test-input-buffered-file->buffer) - 3520 (clear-stream _test-output-stream) - 3521 (clear-stream $_test-output-buffered-file->buffer) - 3522 # - 3523 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 - 3524 (write _test-input-stream " x: int\n") - 3525 (write _test-input-stream " y: int\n") - 3526 (write _test-input-stream " z: int\n") + 1694 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") + 1695 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") + 1696 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") + 1697 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") + 1698 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") + 1699 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") + 1700 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") + 1701 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") + 1702 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") + 1703 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") + 1704 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") + 1705 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") + 1706 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") + 1707 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") + 1708 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") + 1709 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") + 1710 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") + 1711 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") + 1712 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") + 1713 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") + 1714 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") + 1715 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") + 1716 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") + 1717 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") + 1718 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") + 1719 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") + 1720 # . epilogue + 1721 89/<- %esp 5/r32/ebp + 1722 5d/pop-to-ebp + 1723 c3/return + 1724 + 1725 test-convert-function-with-branches-in-named-block: + 1726 # . prologue + 1727 55/push-ebp + 1728 89/<- %ebp 4/r32/esp + 1729 # setup + 1730 (clear-stream _test-input-stream) + 1731 (clear-stream $_test-input-buffered-file->buffer) + 1732 (clear-stream _test-output-stream) + 1733 (clear-stream $_test-output-buffered-file->buffer) + 1734 # + 1735 (write _test-input-stream "fn foo x: int {\n") + 1736 (write _test-input-stream " $bar: {\n") + 1737 (write _test-input-stream " break-if->= $bar\n") + 1738 (write _test-input-stream " loop-if-addr< $bar\n") + 1739 (write _test-input-stream " increment x\n") + 1740 (write _test-input-stream " loop\n") + 1741 (write _test-input-stream " }\n") + 1742 (write _test-input-stream "}\n") + 1743 # convert + 1744 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1745 (flush _test-output-buffered-file) + 1746 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1752 # check output + 1753 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0") + 1754 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1") + 1755 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2") + 1756 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3") + 1757 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4") + 1758 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5") + 1759 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6") + 1760 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7") + 1761 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/8") + 1762 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-named-block/9") + 1763 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/10") + 1764 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/11") + 1765 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/12") + 1766 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-named-block/13") + 1767 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/14") + 1768 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/15") + 1769 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/16") + 1770 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/17") + 1771 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/18") + 1772 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/19") + 1773 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/20") + 1774 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/21") + 1775 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/22") + 1776 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/23") + 1777 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/24") + 1778 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/25") + 1779 # . epilogue + 1780 89/<- %esp 5/r32/ebp + 1781 5d/pop-to-ebp + 1782 c3/return + 1783 + 1784 test-convert-function-with-var-in-nested-block: + 1785 # . prologue + 1786 55/push-ebp + 1787 89/<- %ebp 4/r32/esp + 1788 # setup + 1789 (clear-stream _test-input-stream) + 1790 (clear-stream $_test-input-buffered-file->buffer) + 1791 (clear-stream _test-output-stream) + 1792 (clear-stream $_test-output-buffered-file->buffer) + 1793 # + 1794 (write _test-input-stream "fn foo x: int {\n") + 1795 (write _test-input-stream " {\n") + 1796 (write _test-input-stream " {\n") + 1797 (write _test-input-stream " var x: int\n") + 1798 (write _test-input-stream " increment x\n") + 1799 (write _test-input-stream " }\n") + 1800 (write _test-input-stream " }\n") + 1801 (write _test-input-stream "}\n") + 1802 # convert + 1803 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1804 (flush _test-output-buffered-file) + 1805 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1811 # check output + 1812 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0") + 1813 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1") + 1814 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2") + 1815 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3") + 1816 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4") + 1817 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5") + 1818 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6") + 1819 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7") + 1820 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8") + 1821 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9") + 1822 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10") + 1823 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11") + 1824 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-var-in-nested-block/12") + 1825 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13") + 1826 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14") + 1827 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15") + 1828 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16") + 1829 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17") + 1830 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18") + 1831 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19") + 1832 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20") + 1833 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21") + 1834 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22") + 1835 # . epilogue + 1836 89/<- %esp 5/r32/ebp + 1837 5d/pop-to-ebp + 1838 c3/return + 1839 + 1840 test-convert-function-with-multiple-vars-in-nested-blocks: + 1841 # . prologue + 1842 55/push-ebp + 1843 89/<- %ebp 4/r32/esp + 1844 # setup + 1845 (clear-stream _test-input-stream) + 1846 (clear-stream $_test-input-buffered-file->buffer) + 1847 (clear-stream _test-output-stream) + 1848 (clear-stream $_test-output-buffered-file->buffer) + 1849 # + 1850 (write _test-input-stream "fn foo x: int {\n") + 1851 (write _test-input-stream " {\n") + 1852 (write _test-input-stream " var x/eax: int <- copy 0\n") + 1853 (write _test-input-stream " {\n") + 1854 (write _test-input-stream " var y: int\n") + 1855 (write _test-input-stream " x <- add y\n") + 1856 (write _test-input-stream " }\n") + 1857 (write _test-input-stream " }\n") + 1858 (write _test-input-stream "}\n") + 1859 # convert + 1860 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1861 (flush _test-output-buffered-file) + 1862 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1868 # check output + 1869 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0") + 1870 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1") + 1871 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2") + 1872 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3") + 1873 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4") + 1874 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5") + 1875 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6") + 1876 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7") + 1877 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8") + 1878 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/9") + 1879 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10") + 1880 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11") + 1881 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12") + 1882 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/13") + 1883 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/14") + 1884 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15") + 1885 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16") + 1886 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17") + 1887 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18") + 1888 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19") + 1889 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20") + 1890 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21") + 1891 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22") + 1892 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23") + 1893 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24") + 1894 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25") + 1895 # . epilogue + 1896 89/<- %esp 5/r32/ebp + 1897 5d/pop-to-ebp + 1898 c3/return + 1899 + 1900 test-convert-function-with-branches-and-local-vars: + 1901 # A conditional 'break' after a 'var' in a block is converted into a + 1902 # nested block that performs all necessary cleanup before jumping. This + 1903 # results in some ugly code duplication. + 1904 # . prologue + 1905 55/push-ebp + 1906 89/<- %ebp 4/r32/esp + 1907 # setup + 1908 (clear-stream _test-input-stream) + 1909 (clear-stream $_test-input-buffered-file->buffer) + 1910 (clear-stream _test-output-stream) + 1911 (clear-stream $_test-output-buffered-file->buffer) + 1912 # + 1913 (write _test-input-stream "fn foo {\n") + 1914 (write _test-input-stream " {\n") + 1915 (write _test-input-stream " var x: int\n") + 1916 (write _test-input-stream " break-if->=\n") + 1917 (write _test-input-stream " increment x\n") + 1918 (write _test-input-stream " }\n") + 1919 (write _test-input-stream "}\n") + 1920 # convert + 1921 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1922 (flush _test-output-buffered-file) + 1923 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1929 # check output + 1930 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0") + 1931 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1") + 1932 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2") + 1933 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3") + 1934 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4") + 1935 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5") + 1936 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6") + 1937 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7") + 1938 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8") + 1939 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9") + 1940 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10") + 1941 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/11") + 1942 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12") + 1943 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13") + 1944 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14") + 1945 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/15") + 1946 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16") + 1947 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17") + 1948 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18") + 1949 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19") + 1950 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20") + 1951 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21") + 1952 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22") + 1953 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23") + 1954 # . epilogue + 1955 89/<- %esp 5/r32/ebp + 1956 5d/pop-to-ebp + 1957 c3/return + 1958 + 1959 test-convert-function-with-conditional-loops-and-local-vars: + 1960 # A conditional 'loop' after a 'var' in a block is converted into a nested + 1961 # block that performs all necessary cleanup before jumping. This results + 1962 # in some ugly code duplication. + 1963 # . prologue + 1964 55/push-ebp + 1965 89/<- %ebp 4/r32/esp + 1966 # setup + 1967 (clear-stream _test-input-stream) + 1968 (clear-stream $_test-input-buffered-file->buffer) + 1969 (clear-stream _test-output-stream) + 1970 (clear-stream $_test-output-buffered-file->buffer) + 1971 # + 1972 (write _test-input-stream "fn foo {\n") + 1973 (write _test-input-stream " {\n") + 1974 (write _test-input-stream " var x: int\n") + 1975 (write _test-input-stream " loop-if->=\n") + 1976 (write _test-input-stream " increment x\n") + 1977 (write _test-input-stream " }\n") + 1978 (write _test-input-stream "}\n") + 1979 # convert + 1980 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 1981 (flush _test-output-buffered-file) + 1982 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1988 # check output + 1989 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0") + 1990 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1") + 1991 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2") + 1992 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3") + 1993 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4") + 1994 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5") + 1995 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6") + 1996 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7") + 1997 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8") + 1998 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9") + 1999 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/10") + 2000 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/11") + 2001 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/12") + 2002 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13") + 2003 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-conditional-loops-and-local-vars/14") + 2004 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/15") + 2005 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16") + 2006 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17") + 2007 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18") + 2008 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19") + 2009 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20") + 2010 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21") + 2011 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22") + 2012 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23") + 2013 # . epilogue + 2014 89/<- %esp 5/r32/ebp + 2015 5d/pop-to-ebp + 2016 c3/return + 2017 + 2018 test-convert-function-with-unconditional-loops-and-local-vars: + 2019 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the + 2020 # regular block cleanup. Any instructions after 'loop' are dead and + 2021 # therefore skipped. + 2022 # . prologue + 2023 55/push-ebp + 2024 89/<- %ebp 4/r32/esp + 2025 # setup + 2026 (clear-stream _test-input-stream) + 2027 (clear-stream $_test-input-buffered-file->buffer) + 2028 (clear-stream _test-output-stream) + 2029 (clear-stream $_test-output-buffered-file->buffer) + 2030 # + 2031 (write _test-input-stream "fn foo {\n") + 2032 (write _test-input-stream " {\n") + 2033 (write _test-input-stream " var x: int\n") + 2034 (write _test-input-stream " loop\n") + 2035 (write _test-input-stream " increment x\n") + 2036 (write _test-input-stream " }\n") + 2037 (write _test-input-stream "}\n") + 2038 # convert + 2039 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2040 (flush _test-output-buffered-file) + 2041 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2047 # check output + 2048 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0") + 2049 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1") + 2050 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2") + 2051 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3") + 2052 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4") + 2053 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5") + 2054 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6") + 2055 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7") + 2056 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8") + 2057 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/9") + 2058 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10") + 2059 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc) + 2060 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11") + 2061 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12") + 2062 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13") + 2063 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14") + 2064 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15") + 2065 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16") + 2066 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17") + 2067 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18") + 2068 # . epilogue + 2069 89/<- %esp 5/r32/ebp + 2070 5d/pop-to-ebp + 2071 c3/return + 2072 + 2073 test-convert-function-with-branches-and-loops-and-local-vars: + 2074 # . prologue + 2075 55/push-ebp + 2076 89/<- %ebp 4/r32/esp + 2077 # setup + 2078 (clear-stream _test-input-stream) + 2079 (clear-stream $_test-input-buffered-file->buffer) + 2080 (clear-stream _test-output-stream) + 2081 (clear-stream $_test-output-buffered-file->buffer) + 2082 # + 2083 (write _test-input-stream "fn foo {\n") + 2084 (write _test-input-stream " {\n") + 2085 (write _test-input-stream " var x: int\n") + 2086 (write _test-input-stream " break-if->=\n") + 2087 (write _test-input-stream " increment x\n") + 2088 (write _test-input-stream " loop\n") + 2089 (write _test-input-stream " }\n") + 2090 (write _test-input-stream "}\n") + 2091 # convert + 2092 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2093 (flush _test-output-buffered-file) + 2094 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2100 # check output + 2101 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0") + 2102 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1") + 2103 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2") + 2104 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-loops-and-local-vars/3") + 2105 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4") + 2106 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5") + 2107 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6") + 2108 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7") + 2109 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8") + 2110 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9") + 2111 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/10") + 2112 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/11") + 2113 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/12") + 2114 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13") + 2115 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-loops-and-local-vars/14") + 2116 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/15") + 2117 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16") + 2118 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17") + 2119 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18") + 2120 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19") + 2121 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20") + 2122 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21") + 2123 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/22") + 2124 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23") + 2125 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24") + 2126 # . epilogue + 2127 89/<- %esp 5/r32/ebp + 2128 5d/pop-to-ebp + 2129 c3/return + 2130 + 2131 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars: + 2132 # . prologue + 2133 55/push-ebp + 2134 89/<- %ebp 4/r32/esp + 2135 # setup + 2136 (clear-stream _test-input-stream) + 2137 (clear-stream $_test-input-buffered-file->buffer) + 2138 (clear-stream _test-output-stream) + 2139 (clear-stream $_test-output-buffered-file->buffer) + 2140 # + 2141 (write _test-input-stream "fn foo {\n") + 2142 (write _test-input-stream " a: {\n") + 2143 (write _test-input-stream " var x: int\n") + 2144 (write _test-input-stream " {\n") + 2145 (write _test-input-stream " var y: int\n") + 2146 (write _test-input-stream " break-if->= a\n") + 2147 (write _test-input-stream " increment x\n") + 2148 (write _test-input-stream " loop\n") + 2149 (write _test-input-stream " }\n") + 2150 (write _test-input-stream " }\n") + 2151 (write _test-input-stream "}\n") + 2152 # convert + 2153 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2154 (flush _test-output-buffered-file) + 2155 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2161 # check output + 2162 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0") + 2163 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1") + 2164 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2") + 2165 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/3") + 2166 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4") + 2167 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5") + 2168 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6") + 2169 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7") + 2170 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/8") + 2171 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9") + 2172 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10") + 2173 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/11") + 2174 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12") + 2175 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/13") + 2176 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/14") + 2177 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/15") + 2178 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/16") + 2179 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17") + 2180 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/18") + 2181 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/19") + 2182 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/20") + 2183 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21") + 2184 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22") + 2185 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/23") + 2186 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24") + 2187 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25") + 2188 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26") + 2189 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27") + 2190 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28") + 2191 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/29") + 2192 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/30") + 2193 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31") + 2194 # . epilogue + 2195 89/<- %esp 5/r32/ebp + 2196 5d/pop-to-ebp + 2197 c3/return + 2198 + 2199 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2: + 2200 # . prologue + 2201 55/push-ebp + 2202 89/<- %ebp 4/r32/esp + 2203 # setup + 2204 (clear-stream _test-input-stream) + 2205 (clear-stream $_test-input-buffered-file->buffer) + 2206 (clear-stream _test-output-stream) + 2207 (clear-stream $_test-output-buffered-file->buffer) + 2208 # non-local conditional branch from a block without a local variable, + 2209 # unwinding a local on the stack + 2210 (write _test-input-stream "fn foo {\n") + 2211 (write _test-input-stream " a: {\n") + 2212 (write _test-input-stream " var x: int\n") + 2213 (write _test-input-stream " {\n") + 2214 (write _test-input-stream " break-if->= a\n") + 2215 (write _test-input-stream " }\n") + 2216 (write _test-input-stream " }\n") + 2217 (write _test-input-stream "}\n") + 2218 # convert + 2219 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2220 (flush _test-output-buffered-file) + 2221 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2227 # check output + 2228 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0") + 2229 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1") + 2230 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/2") + 2231 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/3") + 2232 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4") + 2233 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/5") + 2234 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6") + 2235 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7") + 2236 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/8") + 2237 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9") + 2238 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/10") + 2239 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11") + 2240 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/12") + 2241 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/13") + 2242 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/14") + 2243 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15") + 2244 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16") + 2245 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/17") + 2246 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/18") + 2247 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19") + 2248 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20") + 2249 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21") + 2250 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/22") + 2251 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23") + 2252 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/24") + 2253 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/25") + 2254 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26") + 2255 # . epilogue + 2256 89/<- %esp 5/r32/ebp + 2257 5d/pop-to-ebp + 2258 c3/return + 2259 + 2260 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3: + 2261 # . prologue + 2262 55/push-ebp + 2263 89/<- %ebp 4/r32/esp + 2264 # setup + 2265 (clear-stream _test-input-stream) + 2266 (clear-stream $_test-input-buffered-file->buffer) + 2267 (clear-stream _test-output-stream) + 2268 (clear-stream $_test-output-buffered-file->buffer) + 2269 # non-local unconditional branch from a block without a local variable, + 2270 # unwinding a local on the stack + 2271 (write _test-input-stream "fn foo {\n") + 2272 (write _test-input-stream " a: {\n") + 2273 (write _test-input-stream " var x: int\n") + 2274 (write _test-input-stream " {\n") + 2275 (write _test-input-stream " break a\n") + 2276 (write _test-input-stream " }\n") + 2277 (write _test-input-stream " }\n") + 2278 (write _test-input-stream "}\n") + 2279 # convert + 2280 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2281 (flush _test-output-buffered-file) + 2282 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2288 # check output + 2289 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0") + 2290 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1") + 2291 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/2") + 2292 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/3") + 2293 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4") + 2294 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/5") + 2295 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6") + 2296 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7") + 2297 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/8") + 2298 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9") + 2299 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/10") + 2300 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/11") + 2301 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/12") + 2302 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14") + 2303 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/15") + 2304 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/16") + 2305 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17") + 2306 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18") + 2307 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19") + 2308 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/20") + 2309 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21") + 2310 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/22") + 2311 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/23") + 2312 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24") + 2313 # . epilogue + 2314 89/<- %esp 5/r32/ebp + 2315 5d/pop-to-ebp + 2316 c3/return + 2317 + 2318 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4: + 2319 # . prologue + 2320 55/push-ebp + 2321 89/<- %ebp 4/r32/esp + 2322 # setup + 2323 (clear-stream _test-input-stream) + 2324 (clear-stream $_test-input-buffered-file->buffer) + 2325 (clear-stream _test-output-stream) + 2326 (clear-stream $_test-output-buffered-file->buffer) + 2327 # + 2328 (write _test-input-stream "fn foo {\n") + 2329 (write _test-input-stream " a: {\n") + 2330 (write _test-input-stream " var x/esi: int <- copy 0\n") + 2331 (write _test-input-stream " {\n") + 2332 (write _test-input-stream " break a\n") + 2333 (write _test-input-stream " }\n") + 2334 (write _test-input-stream " }\n") + 2335 (write _test-input-stream "}\n") + 2336 # convert + 2337 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2338 (flush _test-output-buffered-file) + 2339 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2345 # check output + 2346 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0") + 2347 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1") + 2348 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/2") + 2349 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/3") + 2350 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4") + 2351 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/5") + 2352 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6") + 2353 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7") + 2354 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/8") + 2355 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/9") + 2356 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10") + 2357 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/11") + 2358 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/12") + 2359 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/13") + 2360 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/14") + 2361 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/15") + 2362 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/16") + 2363 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17") + 2364 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18") + 2365 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/19") + 2366 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/20") + 2367 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/21") + 2368 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/22") + 2369 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/23") + 2370 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24") + 2371 # . epilogue + 2372 89/<- %esp 5/r32/ebp + 2373 5d/pop-to-ebp + 2374 c3/return + 2375 + 2376 test-convert-function-with-nonlocal-unconditional-break-and-local-vars: + 2377 # . prologue + 2378 55/push-ebp + 2379 89/<- %ebp 4/r32/esp + 2380 # setup + 2381 (clear-stream _test-input-stream) + 2382 (clear-stream $_test-input-buffered-file->buffer) + 2383 (clear-stream _test-output-stream) + 2384 (clear-stream $_test-output-buffered-file->buffer) + 2385 # + 2386 (write _test-input-stream "fn foo {\n") + 2387 (write _test-input-stream " a: {\n") + 2388 (write _test-input-stream " var x: int\n") + 2389 (write _test-input-stream " {\n") + 2390 (write _test-input-stream " var y: int\n") + 2391 (write _test-input-stream " break a\n") + 2392 (write _test-input-stream " increment x\n") + 2393 (write _test-input-stream " }\n") + 2394 (write _test-input-stream " }\n") + 2395 (write _test-input-stream "}\n") + 2396 # convert + 2397 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2398 (flush _test-output-buffered-file) + 2399 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2405 # check output + 2406 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0") + 2407 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1") + 2408 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2") + 2409 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/3") + 2410 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4") + 2411 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5") + 2412 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6") + 2413 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7") + 2414 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8") + 2415 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9") + 2416 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10") + 2417 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11") + 2418 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/12") + 2419 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/13") + 2420 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/14") + 2421 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15") + 2422 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16") + 2423 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/17") + 2424 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18") + 2425 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19") + 2426 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20") + 2427 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21") + 2428 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22") + 2429 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/23") + 2430 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24") + 2431 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25") + 2432 # . epilogue + 2433 89/<- %esp 5/r32/ebp + 2434 5d/pop-to-ebp + 2435 c3/return + 2436 + 2437 test-convert-function-with-unconditional-break-and-local-vars: + 2438 # . prologue + 2439 55/push-ebp + 2440 89/<- %ebp 4/r32/esp + 2441 # setup + 2442 (clear-stream _test-input-stream) + 2443 (clear-stream $_test-input-buffered-file->buffer) + 2444 (clear-stream _test-output-stream) + 2445 (clear-stream $_test-output-buffered-file->buffer) + 2446 # + 2447 (write _test-input-stream "fn foo {\n") + 2448 (write _test-input-stream " {\n") + 2449 (write _test-input-stream " var x: int\n") + 2450 (write _test-input-stream " {\n") + 2451 (write _test-input-stream " var y: int\n") + 2452 (write _test-input-stream " break\n") + 2453 (write _test-input-stream " increment x\n") + 2454 (write _test-input-stream " }\n") + 2455 (write _test-input-stream " }\n") + 2456 (write _test-input-stream "}\n") + 2457 # convert + 2458 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2459 (flush _test-output-buffered-file) + 2460 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2466 # check output + 2467 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0") + 2468 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1") + 2469 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2") + 2470 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3") + 2471 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4") + 2472 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5") + 2473 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6") + 2474 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7") + 2475 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8") + 2476 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9") + 2477 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10") + 2478 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11") + 2479 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/12") + 2480 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13") + 2481 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14") + 2482 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/15") + 2483 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16") + 2484 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17") + 2485 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18") + 2486 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19") + 2487 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20") + 2488 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21") + 2489 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22") + 2490 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23") + 2491 # . epilogue + 2492 89/<- %esp 5/r32/ebp + 2493 5d/pop-to-ebp + 2494 c3/return + 2495 + 2496 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars: + 2497 # . prologue + 2498 55/push-ebp + 2499 89/<- %ebp 4/r32/esp + 2500 # setup + 2501 (clear-stream _test-input-stream) + 2502 (clear-stream $_test-input-buffered-file->buffer) + 2503 (clear-stream _test-output-stream) + 2504 (clear-stream $_test-output-buffered-file->buffer) + 2505 # + 2506 (write _test-input-stream "fn foo {\n") + 2507 (write _test-input-stream " a: {\n") + 2508 (write _test-input-stream " var x: int\n") + 2509 (write _test-input-stream " {\n") + 2510 (write _test-input-stream " var y: int\n") + 2511 (write _test-input-stream " loop a\n") + 2512 (write _test-input-stream " increment x\n") + 2513 (write _test-input-stream " }\n") + 2514 (write _test-input-stream " }\n") + 2515 (write _test-input-stream "}\n") + 2516 # convert + 2517 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2518 (flush _test-output-buffered-file) + 2519 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2525 # check output + 2526 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0") + 2527 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1") + 2528 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2") + 2529 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/3") + 2530 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4") + 2531 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5") + 2532 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6") + 2533 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7") + 2534 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8") + 2535 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9") + 2536 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10") + 2537 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11") + 2538 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/12") + 2539 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/13") + 2540 (check-next-stream-line-equal _test-output-stream " e9/jump a:loop/disp32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/14") + 2541 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15") + 2542 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16") + 2543 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/17") + 2544 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18") + 2545 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19") + 2546 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20") + 2547 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21") + 2548 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22") + 2549 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/23") + 2550 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24") + 2551 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25") + 2552 # . epilogue + 2553 89/<- %esp 5/r32/ebp + 2554 5d/pop-to-ebp + 2555 c3/return + 2556 + 2557 test-convert-function-with-local-array-var-in-mem: + 2558 # . prologue + 2559 55/push-ebp + 2560 89/<- %ebp 4/r32/esp + 2561 # setup + 2562 (clear-stream _test-input-stream) + 2563 (clear-stream $_test-input-buffered-file->buffer) + 2564 (clear-stream _test-output-stream) + 2565 (clear-stream $_test-output-buffered-file->buffer) + 2566 # + 2567 (write _test-input-stream "fn foo {\n") + 2568 (write _test-input-stream " var x: (array int 3)\n") + 2569 (write _test-input-stream "}\n") + 2570 # convert + 2571 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2572 (flush _test-output-buffered-file) + 2573 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2579 # check output + 2580 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0") + 2581 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1") + 2582 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2") + 2583 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3") + 2584 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4") + 2585 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5") + 2586 # define x + 2587 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7") + 2588 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8") + 2589 # reclaim x + 2590 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-function-with-local-array-var-in-mem/9") + 2591 # + 2592 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10") + 2593 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11") + 2594 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12") + 2595 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13") + 2596 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14") + 2597 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15") + 2598 # . epilogue + 2599 89/<- %esp 5/r32/ebp + 2600 5d/pop-to-ebp + 2601 c3/return + 2602 + 2603 test-convert-address: + 2604 # . prologue + 2605 55/push-ebp + 2606 89/<- %ebp 4/r32/esp + 2607 # setup + 2608 (clear-stream _test-input-stream) + 2609 (clear-stream $_test-input-buffered-file->buffer) + 2610 (clear-stream _test-output-stream) + 2611 (clear-stream $_test-output-buffered-file->buffer) + 2612 # + 2613 (write _test-input-stream "fn foo {\n") + 2614 (write _test-input-stream " var a: int\n") + 2615 (write _test-input-stream " var b/eax: (addr int) <- address a\n") + 2616 (write _test-input-stream "}\n") + 2617 # convert + 2618 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2619 (flush _test-output-buffered-file) + 2620 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2626 # check output + 2627 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0") + 2628 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1") + 2629 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2") + 2630 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3") + 2631 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4") + 2632 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5") + 2633 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6") + 2634 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7") + 2635 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8") + 2636 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9") + 2637 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10") + 2638 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11") + 2639 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12") + 2640 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13") + 2641 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14") + 2642 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15") + 2643 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16") + 2644 # . epilogue + 2645 89/<- %esp 5/r32/ebp + 2646 5d/pop-to-ebp + 2647 c3/return + 2648 + 2649 test-convert-length-of-array: + 2650 # . prologue + 2651 55/push-ebp + 2652 89/<- %ebp 4/r32/esp + 2653 # setup + 2654 (clear-stream _test-input-stream) + 2655 (clear-stream $_test-input-buffered-file->buffer) + 2656 (clear-stream _test-output-stream) + 2657 (clear-stream $_test-output-buffered-file->buffer) + 2658 # + 2659 (write _test-input-stream "fn foo a: (addr array int) {\n") + 2660 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n") + 2661 (write _test-input-stream " var c/eax: int <- length b\n") + 2662 (write _test-input-stream "}\n") + 2663 # convert + 2664 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2665 (flush _test-output-buffered-file) + 2666 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2672 # check output + 2673 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0") + 2674 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1") + 2675 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2") + 2676 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3") + 2677 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4") + 2678 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") + 2679 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") + 2680 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") + 2681 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") + 2682 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9") + 2683 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") + 2684 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") + 2685 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") + 2686 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") + 2687 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") + 2688 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") + 2689 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") + 2690 # . epilogue + 2691 89/<- %esp 5/r32/ebp + 2692 5d/pop-to-ebp + 2693 c3/return + 2694 + 2695 test-convert-length-of-array-on-stack: + 2696 # . prologue + 2697 55/push-ebp + 2698 89/<- %ebp 4/r32/esp + 2699 # setup + 2700 (clear-stream _test-input-stream) + 2701 (clear-stream $_test-input-buffered-file->buffer) + 2702 (clear-stream _test-output-stream) + 2703 (clear-stream $_test-output-buffered-file->buffer) + 2704 # + 2705 (write _test-input-stream "fn foo {\n") + 2706 (write _test-input-stream " var a: (array int 3)\n") + 2707 (write _test-input-stream " var b/eax: int <- length a\n") + 2708 (write _test-input-stream "}\n") + 2709 # convert + 2710 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2711 (flush _test-output-buffered-file) + 2712 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2718 # check output + 2719 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0") + 2720 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1") + 2721 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2") + 2722 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3") + 2723 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4") + 2724 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5") + 2725 # define x + 2726 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6") + 2727 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") + 2728 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") + 2729 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") + 2730 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10") + 2731 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") + 2732 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") + 2733 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") + 2734 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") + 2735 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") + 2736 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") + 2737 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") + 2738 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") + 2739 # . epilogue + 2740 89/<- %esp 5/r32/ebp + 2741 5d/pop-to-ebp + 2742 c3/return + 2743 + 2744 test-convert-index-into-array: + 2745 # . prologue + 2746 55/push-ebp + 2747 89/<- %ebp 4/r32/esp + 2748 # setup + 2749 (clear-stream _test-input-stream) + 2750 (clear-stream $_test-input-buffered-file->buffer) + 2751 (clear-stream _test-output-stream) + 2752 (clear-stream $_test-output-buffered-file->buffer) + 2753 # + 2754 (write _test-input-stream "fn foo {\n") + 2755 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 2756 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 2757 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 2758 (write _test-input-stream "}\n") + 2759 # convert + 2760 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2761 (flush _test-output-buffered-file) + 2762 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2768 # check output + 2769 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") + 2770 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") + 2771 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") + 2772 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") + 2773 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") + 2774 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") + 2775 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") + 2776 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") + 2777 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") + 2778 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") + 2779 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/11") + 2780 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/13") + 2781 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/14") + 2782 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/15") + 2783 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/16") + 2784 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/17") + 2785 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/18") + 2786 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/19") + 2787 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/20") + 2788 # . epilogue + 2789 89/<- %esp 5/r32/ebp + 2790 5d/pop-to-ebp + 2791 c3/return + 2792 + 2793 test-convert-index-into-array-with-literal: + 2794 # . prologue + 2795 55/push-ebp + 2796 89/<- %ebp 4/r32/esp + 2797 # setup + 2798 (clear-stream _test-input-stream) + 2799 (clear-stream $_test-input-buffered-file->buffer) + 2800 (clear-stream _test-output-stream) + 2801 (clear-stream $_test-output-buffered-file->buffer) + 2802 # + 2803 (write _test-input-stream "fn foo {\n") + 2804 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 2805 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 2806 (write _test-input-stream "}\n") + 2807 # convert + 2808 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2809 (flush _test-output-buffered-file) + 2810 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2816 # check output + 2817 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") + 2818 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") + 2819 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") + 2820 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") + 2821 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") + 2822 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") + 2823 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") + 2824 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") + 2825 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 + 2826 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") + 2827 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") + 2828 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") + 2829 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/11") + 2830 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/12") + 2831 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/13") + 2832 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/14") + 2833 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/15") + 2834 # . epilogue + 2835 89/<- %esp 5/r32/ebp + 2836 5d/pop-to-ebp + 2837 c3/return + 2838 + 2839 test-convert-index-into-array-on-stack: + 2840 # . prologue + 2841 55/push-ebp + 2842 89/<- %ebp 4/r32/esp + 2843 # setup + 2844 (clear-stream _test-input-stream) + 2845 (clear-stream $_test-input-buffered-file->buffer) + 2846 (clear-stream _test-output-stream) + 2847 (clear-stream $_test-output-buffered-file->buffer) + 2848 # + 2849 (write _test-input-stream "fn foo {\n") + 2850 (write _test-input-stream " var arr: (array int 3)\n") + 2851 (write _test-input-stream " var idx/eax: int <- copy 2\n") + 2852 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 2853 (write _test-input-stream "}\n") + 2854 # convert + 2855 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2856 (flush _test-output-buffered-file) + 2857 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2863 # check output + 2864 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") + 2865 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") + 2866 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") + 2867 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") + 2868 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") + 2869 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") + 2870 # var arr + 2871 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") + 2872 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") + 2873 # var idx + 2874 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") + 2875 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") + 2876 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc + 2877 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + eax<<0x00000002 + 0xfffffff4) 0x00000000/r32" "F - test-convert-index-into-array-on-stack/10") + 2878 # reclaim idx + 2879 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/11") + 2880 # reclaim arr + 2881 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/12") + 2882 # + 2883 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/13") + 2884 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/14") + 2885 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/15") + 2886 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/16") + 2887 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/17") + 2888 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/18") + 2889 # . epilogue + 2890 89/<- %esp 5/r32/ebp + 2891 5d/pop-to-ebp + 2892 c3/return + 2893 + 2894 test-convert-index-into-array-on-stack-with-literal: + 2895 # . prologue + 2896 55/push-ebp + 2897 89/<- %ebp 4/r32/esp + 2898 # setup + 2899 (clear-stream _test-input-stream) + 2900 (clear-stream $_test-input-buffered-file->buffer) + 2901 (clear-stream _test-output-stream) + 2902 (clear-stream $_test-output-buffered-file->buffer) + 2903 # + 2904 (write _test-input-stream "fn foo {\n") + 2905 (write _test-input-stream " var arr: (array int 3)\n") + 2906 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 2907 (write _test-input-stream "}\n") + 2908 # convert + 2909 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2910 (flush _test-output-buffered-file) + 2911 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2917 # check output + 2918 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") + 2919 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") + 2920 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") + 2921 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") + 2922 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") + 2923 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") + 2924 # var arr + 2925 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") + 2926 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") + 2927 # var x + 2928 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") + 2929 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 + 2930 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xfffffffc) 0x00000000/r32" "F - test-convert-index-into-array-on-stack-with-literal/9") + 2931 # reclaim x + 2932 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/10") + 2933 # reclaim arr + 2934 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack-with-literal/11") + 2935 # + 2936 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/12") + 2937 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/13") + 2938 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/14") + 2939 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/15") + 2940 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") + 2941 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/17") + 2942 # . epilogue + 2943 89/<- %esp 5/r32/ebp + 2944 5d/pop-to-ebp + 2945 c3/return + 2946 + 2947 test-convert-index-into-array-using-offset: + 2948 # . prologue + 2949 55/push-ebp + 2950 89/<- %ebp 4/r32/esp + 2951 # setup + 2952 (clear-stream _test-input-stream) + 2953 (clear-stream $_test-input-buffered-file->buffer) + 2954 (clear-stream _test-output-stream) + 2955 (clear-stream $_test-output-buffered-file->buffer) + 2956 # + 2957 (write _test-input-stream "fn foo {\n") + 2958 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 2959 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 2960 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 2961 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 2962 (write _test-input-stream "}\n") + 2963 # convert + 2964 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 2965 (flush _test-output-buffered-file) + 2966 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 2972 # check output + 2973 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") + 2974 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") + 2975 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") + 2976 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") + 2977 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") + 2978 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") + 2979 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") + 2980 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") + 2981 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") + 2982 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") + 2983 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") + 2984 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/11") + 2985 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12") + 2986 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13") + 2987 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/14") + 2988 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/15") + 2989 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/16") + 2990 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/17") + 2991 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/18") + 2992 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/19") + 2993 # . epilogue + 2994 89/<- %esp 5/r32/ebp + 2995 5d/pop-to-ebp + 2996 c3/return + 2997 + 2998 test-convert-index-into-array-using-offset-on-stack: + 2999 # . prologue + 3000 55/push-ebp + 3001 89/<- %ebp 4/r32/esp + 3002 # setup + 3003 (clear-stream _test-input-stream) + 3004 (clear-stream $_test-input-buffered-file->buffer) + 3005 (clear-stream _test-output-stream) + 3006 (clear-stream $_test-output-buffered-file->buffer) + 3007 # + 3008 (write _test-input-stream "fn foo {\n") + 3009 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 3010 (write _test-input-stream " var idx: int\n") + 3011 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 3012 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 3013 (write _test-input-stream "}\n") + 3014 # convert + 3015 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3016 (flush _test-output-buffered-file) + 3017 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3023 # check output + 3024 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") + 3025 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") + 3026 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") + 3027 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") + 3028 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") + 3029 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") + 3030 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") + 3031 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/7") + 3032 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") + 3033 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") + 3034 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10") + 3035 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset-on-stack/11") + 3036 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12") + 3037 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-using-offset-on-stack/13") + 3038 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/14") + 3039 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/15") + 3040 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/16") + 3041 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/17") + 3042 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/18") + 3043 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/19") + 3044 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/20") + 3045 # . epilogue + 3046 89/<- %esp 5/r32/ebp + 3047 5d/pop-to-ebp + 3048 c3/return + 3049 + 3050 test-convert-function-and-type-definition: + 3051 # . prologue + 3052 55/push-ebp + 3053 89/<- %ebp 4/r32/esp + 3054 # setup + 3055 (clear-stream _test-input-stream) + 3056 (clear-stream $_test-input-buffered-file->buffer) + 3057 (clear-stream _test-output-stream) + 3058 (clear-stream $_test-output-buffered-file->buffer) + 3059 # + 3060 (write _test-input-stream "fn foo a: (addr t) {\n") + 3061 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") + 3062 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") + 3063 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") + 3064 (write _test-input-stream "}\n") + 3065 (write _test-input-stream "type t {\n") + 3066 (write _test-input-stream " x: int\n") + 3067 (write _test-input-stream " y: int\n") + 3068 (write _test-input-stream "}\n") + 3069 # convert + 3070 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3071 (flush _test-output-buffered-file) + 3072 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3078 # check output + 3079 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") + 3080 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") + 3081 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") + 3082 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") + 3083 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") + 3084 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") + 3085 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") + 3086 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") + 3087 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") + 3088 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9") + 3089 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") + 3090 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13") + 3091 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14") + 3092 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/15") + 3093 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/16") + 3094 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/17") + 3095 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/18") + 3096 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/19") + 3097 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/20") + 3098 # . epilogue + 3099 89/<- %esp 5/r32/ebp + 3100 5d/pop-to-ebp + 3101 c3/return + 3102 + 3103 test-convert-function-with-local-var-with-user-defined-type: + 3104 # . prologue + 3105 55/push-ebp + 3106 89/<- %ebp 4/r32/esp + 3107 # setup + 3108 (clear-stream _test-input-stream) + 3109 (clear-stream $_test-input-buffered-file->buffer) + 3110 (clear-stream _test-output-stream) + 3111 (clear-stream $_test-output-buffered-file->buffer) + 3112 # + 3113 (write _test-input-stream "fn foo {\n") + 3114 (write _test-input-stream " var a: t\n") + 3115 (write _test-input-stream "}\n") + 3116 (write _test-input-stream "type t {\n") + 3117 (write _test-input-stream " x: int\n") + 3118 (write _test-input-stream " y: int\n") + 3119 (write _test-input-stream "}\n") + 3120 # convert + 3121 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3122 (flush _test-output-buffered-file) + 3123 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3129 # check output + 3130 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") + 3131 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") + 3132 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") + 3133 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type/3") + 3134 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") + 3135 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") + 3136 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") + 3137 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") + 3138 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/8") + 3139 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") + 3140 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") + 3141 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") + 3142 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type/12") + 3143 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") + 3144 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") + 3145 # . epilogue + 3146 89/<- %esp 5/r32/ebp + 3147 5d/pop-to-ebp + 3148 c3/return + 3149 + 3150 test-convert-function-call-with-arg-of-user-defined-type: + 3151 # . prologue + 3152 55/push-ebp + 3153 89/<- %ebp 4/r32/esp + 3154 # setup + 3155 (clear-stream _test-input-stream) + 3156 (clear-stream $_test-input-buffered-file->buffer) + 3157 (clear-stream _test-output-stream) + 3158 (clear-stream $_test-output-buffered-file->buffer) + 3159 # + 3160 (write _test-input-stream "fn f {\n") + 3161 (write _test-input-stream " var a: t\n") + 3162 (write _test-input-stream " foo a\n") + 3163 (write _test-input-stream "}\n") + 3164 (write _test-input-stream "fn foo x: t {\n") + 3165 (write _test-input-stream "}\n") + 3166 (write _test-input-stream "type t {\n") + 3167 (write _test-input-stream " x: int\n") + 3168 (write _test-input-stream " y: int\n") + 3169 (write _test-input-stream "}\n") + 3170 # convert + 3171 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3172 (flush _test-output-buffered-file) + 3173 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3179 # check output + 3180 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 3181 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 3182 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 3183 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") + 3184 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 3185 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 3186 # var a: t + 3187 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + 3188 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + 3189 # foo a + 3190 (check-next-stream-line-equal _test-output-stream " (foo *(ebp+0xfffffff8) *(ebp+0xfffffffc))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") + 3191 # + 3192 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/9") + 3193 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 3194 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 3195 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 3196 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") + 3197 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 3198 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 3199 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 3200 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 3201 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 3202 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") + 3203 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 3204 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") + 3205 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 3206 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 3207 # . epilogue + 3208 89/<- %esp 5/r32/ebp + 3209 5d/pop-to-ebp + 3210 c3/return + 3211 + 3212 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: + 3213 # . prologue + 3214 55/push-ebp + 3215 89/<- %ebp 4/r32/esp + 3216 # setup + 3217 (clear-stream _test-input-stream) + 3218 (clear-stream $_test-input-buffered-file->buffer) + 3219 (clear-stream _test-output-stream) + 3220 (clear-stream $_test-output-buffered-file->buffer) + 3221 # + 3222 (write _test-input-stream "fn f {\n") + 3223 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") + 3224 (write _test-input-stream " foo *a\n") + 3225 (write _test-input-stream "}\n") + 3226 (write _test-input-stream "fn foo x: t {\n") + 3227 (write _test-input-stream "}\n") + 3228 (write _test-input-stream "type t {\n") + 3229 (write _test-input-stream " x: int\n") + 3230 (write _test-input-stream " y: int\n") + 3231 (write _test-input-stream "}\n") + 3232 # convert + 3233 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3234 (flush _test-output-buffered-file) + 3235 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3241 # check output + 3242 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 3243 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 3244 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 3245 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") + 3246 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 3247 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 3248 # var a + 3249 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + 3250 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + 3251 # foo a + 3252 (check-next-stream-line-equal _test-output-stream " (foo *(eax+0x00000000) *(eax+0x00000004))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") + 3253 # + 3254 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9") + 3255 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 3256 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 3257 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 3258 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") + 3259 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 3260 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 3261 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 3262 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 3263 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 3264 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") + 3265 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 3266 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") + 3267 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 3268 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 3269 # . epilogue + 3270 89/<- %esp 5/r32/ebp + 3271 5d/pop-to-ebp + 3272 c3/return + 3273 + 3274 # we don't have special support for call-by-reference; just explicitly create + 3275 # a new variable with the address of the arg + 3276 test-convert-function-call-with-arg-of-user-defined-type-by-reference: + 3277 # . prologue + 3278 55/push-ebp + 3279 89/<- %ebp 4/r32/esp + 3280 # setup + 3281 (clear-stream _test-input-stream) + 3282 (clear-stream $_test-input-buffered-file->buffer) + 3283 (clear-stream _test-output-stream) + 3284 (clear-stream $_test-output-buffered-file->buffer) + 3285 # + 3286 (write _test-input-stream "fn f {\n") + 3287 (write _test-input-stream " var a: t\n") + 3288 (write _test-input-stream " var b/eax: (addr t) <- address a\n") + 3289 (write _test-input-stream " foo b\n") + 3290 (write _test-input-stream "}\n") + 3291 (write _test-input-stream "fn foo x: (addr t) {\n") + 3292 (write _test-input-stream " var x/ecx: (addr int) <- copy x\n") + 3293 (write _test-input-stream " increment *x\n") + 3294 (write _test-input-stream "}\n") + 3295 (write _test-input-stream "type t {\n") + 3296 (write _test-input-stream " x: int\n") + 3297 (write _test-input-stream " y: int\n") + 3298 (write _test-input-stream "}\n") + 3299 # convert + 3300 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3301 (flush _test-output-buffered-file) + 3302 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3308 # check output + 3309 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") + 3310 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") + 3311 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/2") + 3312 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/3") + 3313 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") + 3314 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/5") + 3315 # var a: t + 3316 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/6") + 3317 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/7") + 3318 # var b/eax: (addr t) + 3319 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/8") + 3320 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/9") + 3321 # foo a + 3322 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") + 3323 # + 3324 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/11") + 3325 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/12") + 3326 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") + 3327 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/14") + 3328 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") + 3329 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/16") + 3330 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/17") + 3331 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") + 3332 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") + 3333 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") + 3334 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/21") + 3335 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/22") + 3336 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") + 3337 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24") + 3338 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25") + 3339 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26") + 3340 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27") + 3341 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28") + 3342 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") + 3343 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30") + 3344 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") + 3345 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/32") + 3346 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/33") + 3347 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34") + 3348 # . epilogue + 3349 89/<- %esp 5/r32/ebp + 3350 5d/pop-to-ebp + 3351 c3/return + 3352 + 3353 test-convert-get-on-local-variable: + 3354 # . prologue + 3355 55/push-ebp + 3356 89/<- %ebp 4/r32/esp + 3357 # setup + 3358 (clear-stream _test-input-stream) + 3359 (clear-stream $_test-input-buffered-file->buffer) + 3360 (clear-stream _test-output-stream) + 3361 (clear-stream $_test-output-buffered-file->buffer) + 3362 # + 3363 (write _test-input-stream "fn foo {\n") + 3364 (write _test-input-stream " var a: t\n") + 3365 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 3366 (write _test-input-stream "}\n") + 3367 (write _test-input-stream "type t {\n") + 3368 (write _test-input-stream " x: int\n") + 3369 (write _test-input-stream " y: int\n") + 3370 (write _test-input-stream "}\n") + 3371 # convert + 3372 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3373 (flush _test-output-buffered-file) + 3374 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3380 # check output + 3381 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") + 3382 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") + 3383 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") + 3384 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") + 3385 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") + 3386 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") + 3387 # var a + 3388 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") + 3389 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") + 3390 # var c + 3391 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") + 3392 # get + 3393 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") + 3394 # reclaim c + 3395 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") + 3396 # reclaim a + 3397 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") + 3398 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") + 3399 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") + 3400 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") + 3401 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") + 3402 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") + 3403 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") + 3404 # . epilogue + 3405 89/<- %esp 5/r32/ebp + 3406 5d/pop-to-ebp + 3407 c3/return + 3408 + 3409 test-convert-get-on-function-argument: + 3410 # . prologue + 3411 55/push-ebp + 3412 89/<- %ebp 4/r32/esp + 3413 # setup + 3414 (clear-stream _test-input-stream) + 3415 (clear-stream $_test-input-buffered-file->buffer) + 3416 (clear-stream _test-output-stream) + 3417 (clear-stream $_test-output-buffered-file->buffer) + 3418 # + 3419 (write _test-input-stream "fn foo a: t {\n") + 3420 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 3421 (write _test-input-stream "}\n") + 3422 (write _test-input-stream "type t {\n") + 3423 (write _test-input-stream " x: int\n") + 3424 (write _test-input-stream " y: int\n") + 3425 (write _test-input-stream "}\n") + 3426 # convert + 3427 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3428 (flush _test-output-buffered-file) + 3429 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3435 # check output + 3436 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") + 3437 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") + 3438 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") + 3439 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") + 3440 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") + 3441 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") + 3442 # var c + 3443 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") + 3444 # get + 3445 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") + 3446 # reclaim c + 3447 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") + 3448 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") + 3449 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") + 3450 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") + 3451 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") + 3452 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") + 3453 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") + 3454 # . epilogue + 3455 89/<- %esp 5/r32/ebp + 3456 5d/pop-to-ebp + 3457 c3/return + 3458 + 3459 test-convert-get-on-function-argument-with-known-type: + 3460 # . prologue + 3461 55/push-ebp + 3462 89/<- %ebp 4/r32/esp + 3463 # setup + 3464 (clear-stream _test-input-stream) + 3465 (clear-stream $_test-input-buffered-file->buffer) + 3466 (clear-stream _test-output-stream) + 3467 (clear-stream $_test-output-buffered-file->buffer) + 3468 # + 3469 (write _test-input-stream "type t {\n") + 3470 (write _test-input-stream " x: int\n") + 3471 (write _test-input-stream " y: int\n") + 3472 (write _test-input-stream "}\n") + 3473 (write _test-input-stream "fn foo a: t {\n") + 3474 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 3475 (write _test-input-stream "}\n") + 3476 # convert + 3477 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3478 (flush _test-output-buffered-file) + 3479 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3485 # check output + 3486 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") + 3487 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") + 3488 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") + 3489 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") + 3490 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") + 3491 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") + 3492 # var c + 3493 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") + 3494 # get + 3495 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument-with-known-type/7") + 3496 # reclaim c + 3497 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") + 3498 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") + 3499 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") + 3500 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") + 3501 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") + 3502 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") + 3503 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") + 3504 # . epilogue + 3505 89/<- %esp 5/r32/ebp + 3506 5d/pop-to-ebp + 3507 c3/return + 3508 + 3509 test-convert-array-of-user-defined-types: + 3510 # . prologue + 3511 55/push-ebp + 3512 89/<- %ebp 4/r32/esp + 3513 # setup + 3514 (clear-stream _test-input-stream) + 3515 (clear-stream $_test-input-buffered-file->buffer) + 3516 (clear-stream _test-output-stream) + 3517 (clear-stream $_test-output-buffered-file->buffer) + 3518 # + 3519 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 + 3520 (write _test-input-stream " x: int\n") + 3521 (write _test-input-stream " y: int\n") + 3522 (write _test-input-stream "}\n") + 3523 (write _test-input-stream "fn foo {\n") + 3524 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 3525 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 3526 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") 3527 (write _test-input-stream "}\n") - 3528 (write _test-input-stream "fn foo {\n") - 3529 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 3530 (write _test-input-stream " var x/ebx: (addr t) <- length arr\n") - 3531 (write _test-input-stream "}\n") - 3532 # convert - 3533 (convert-mu _test-input-buffered-file _test-output-buffered-file) - 3534 (flush _test-output-buffered-file) - 3535 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3541 # check output - 3542 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") - 3543 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") - 3544 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") - 3545 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") - 3546 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") - 3547 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") - 3548 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") - 3549 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types/7") - 3550 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") - 3551 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") - 3552 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") - 3553 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") - 3554 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") - 3555 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types/13") - 3556 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types/14") - 3557 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types/15") - 3558 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") - 3559 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") - 3560 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") - 3561 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") - 3562 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") - 3563 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") - 3564 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") - 3565 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") - 3566 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") - 3567 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") - 3568 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") - 3569 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") - 3570 # . epilogue - 3571 89/<- %esp 5/r32/ebp - 3572 5d/pop-to-ebp - 3573 c3/return - 3574 - 3575 ####################################################### - 3576 # Parsing - 3577 ####################################################### - 3578 - 3579 parse-mu: # in: (addr buffered-file) - 3580 # pseudocode - 3581 # var curr-function: (addr handle function) = Program->functions - 3582 # var curr-type: (addr handle typeinfo) = Program->types - 3583 # var line: (stream byte 512) - 3584 # var word-slice: slice - 3585 # while true # line loop - 3586 # clear-stream(line) - 3587 # read-line-buffered(in, line) - 3588 # if (line->write == 0) break # end of file - 3589 # word-slice = next-mu-token(line) - 3590 # if slice-empty?(word-slice) # end of line - 3591 # continue - 3592 # else if slice-starts-with?(word-slice, "#") # comment - 3593 # continue # end of line - 3594 # else if slice-equal?(word-slice, "fn") - 3595 # var new-function: (handle function) = allocate(function) - 3596 # var vars: (stack (handle var) 256) - 3597 # populate-mu-function-header(line, new-function, vars) - 3598 # populate-mu-function-body(in, new-function, vars) - 3599 # assert(vars->top == 0) - 3600 # *curr-function = new-function - 3601 # curr-function = &new-function->next - 3602 # else if slice-equal?(word-slice, "type") - 3603 # word-slice = next-mu-token(line) - 3604 # type-id = pos-or-insert-slice(Type-id, word-slice) - 3605 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) - 3606 # assert(next-word(line) == "{") - 3607 # populate-mu-type(in, new-type) - 3608 # else - 3609 # abort() - 3610 # - 3611 # . prologue - 3612 55/push-ebp - 3613 89/<- %ebp 4/r32/esp - 3614 # . save registers - 3615 50/push-eax - 3616 51/push-ecx - 3617 52/push-edx - 3618 53/push-ebx - 3619 56/push-esi - 3620 57/push-edi - 3621 # var line/ecx: (stream byte 512) - 3622 81 5/subop/subtract %esp 0x200/imm32 - 3623 68/push 0x200/imm32/size - 3624 68/push 0/imm32/read - 3625 68/push 0/imm32/write - 3626 89/<- %ecx 4/r32/esp - 3627 # var word-slice/edx: slice - 3628 68/push 0/imm32/end - 3629 68/push 0/imm32/start - 3630 89/<- %edx 4/r32/esp - 3631 # var curr-function/edi: (addr handle function) - 3632 bf/copy-to-edi _Program-functions/imm32 - 3633 # var vars/ebx: (stack (handle var) 256) - 3634 81 5/subop/subtract %esp 0x800/imm32 - 3635 68/push 0x800/imm32/size - 3636 68/push 0/imm32/top - 3637 89/<- %ebx 4/r32/esp - 3638 { - 3639 $parse-mu:line-loop: - 3640 (clear-stream %ecx) - 3641 (read-line-buffered *(ebp+8) %ecx) - 3642 # if (line->write == 0) break - 3643 81 7/subop/compare *ecx 0/imm32 - 3644 0f 84/jump-if-= break/disp32 - 3645 +-- 6 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 3651 (next-mu-token %ecx %edx) - 3652 # if slice-empty?(word-slice) continue - 3653 (slice-empty? %edx) # => eax - 3654 3d/compare-eax-and 0/imm32/false - 3655 0f 85/jump-if-!= loop/disp32 - 3656 # if (*word-slice->start == "#") continue - 3657 # . eax = *word-slice->start - 3658 8b/-> *edx 0/r32/eax - 3659 8a/copy-byte *eax 0/r32/AL - 3660 81 4/subop/and %eax 0xff/imm32 - 3661 # . if (eax == '#') continue - 3662 3d/compare-eax-and 0x23/imm32/hash - 3663 0f 84/jump-if-= loop/disp32 - 3664 # if (slice-equal?(word-slice, "fn")) parse a function - 3665 { - 3666 $parse-mu:fn: - 3667 (slice-equal? %edx "fn") # => eax - 3668 3d/compare-eax-and 0/imm32/false - 3669 0f 84/jump-if-= break/disp32 - 3670 # var new-function/esi: (handle function) - 3671 68/push 0/imm32 - 3672 68/push 0/imm32 - 3673 89/<- %esi 4/r32/esp - 3674 # populate-mu-function(line, in, vars, new-function) - 3675 (allocate Heap *Function-size %esi) - 3676 # var new-function-addr/eax: (addr function) - 3677 (lookup *esi *(esi+4)) # => eax - 3678 (clear-stack %ebx) - 3679 (populate-mu-function-header %ecx %eax %ebx) - 3680 (populate-mu-function-body *(ebp+8) %eax %ebx) - 3681 # *curr-function = new-function - 3682 8b/-> *esi 0/r32/eax - 3683 89/<- *edi 0/r32/eax - 3684 8b/-> *(esi+4) 0/r32/eax - 3685 89/<- *(edi+4) 0/r32/eax - 3686 # curr-function = &new-function->next - 3687 # . var tmp/eax: (addr function) = lookup(new-function) - 3688 (lookup *esi *(esi+4)) # => eax - 3689 # . curr-function = &tmp->next - 3690 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next - 3691 # reclaim new-function - 3692 81 0/subop/add %esp 8/imm32 - 3693 # - 3694 e9/jump $parse-mu:line-loop/disp32 - 3695 } - 3696 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition - 3697 { - 3698 $parse-mu:type: - 3699 (slice-equal? %edx "type") # => eax - 3700 3d/compare-eax-and 0/imm32 - 3701 0f 84/jump-if-= break/disp32 - 3702 (next-mu-token %ecx %edx) - 3703 # var type-id/eax: int - 3704 (pos-or-insert-slice Type-id %edx) # => eax - 3705 # spill - 3706 51/push-ecx - 3707 # var new-type/ecx: (handle typeinfo) - 3708 68/push 0/imm32 - 3709 68/push 0/imm32 - 3710 89/<- %ecx 4/r32/esp - 3711 (find-or-create-typeinfo %eax %ecx) - 3712 # - 3713 (lookup *ecx *(ecx+4)) # => eax - 3714 # TODO: ensure that 'line' has nothing else but '{' - 3715 #? (dump-typeinfos "=== aaa\n") - 3716 (populate-mu-type *(ebp+8) %eax) # => eax - 3717 #? (dump-typeinfos "=== zzz\n") - 3718 # reclaim new-type - 3719 81 0/subop/add %esp 8/imm32 - 3720 # restore - 3721 59/pop-to-ecx - 3722 e9/jump $parse-mu:line-loop/disp32 - 3723 } - 3724 # otherwise abort - 3725 e9/jump $parse-mu:error1/disp32 - 3726 } # end line loop - 3727 $parse-mu:end: - 3728 # . reclaim locals - 3729 81 0/subop/add %esp 0x630/imm32 - 3730 # . restore registers - 3731 5f/pop-to-edi - 3732 5e/pop-to-esi - 3733 5b/pop-to-ebx - 3734 5a/pop-to-edx - 3735 59/pop-to-ecx - 3736 58/pop-to-eax - 3737 # . epilogue - 3738 89/<- %esp 5/r32/ebp - 3739 5d/pop-to-ebp - 3740 c3/return - 3741 - 3742 $parse-mu:error1: - 3743 # error("unexpected top-level command: " word-slice "\n") - 3744 (write-buffered Stderr "unexpected top-level command: ") - 3745 (write-slice-buffered Stderr %edx) - 3746 (write-buffered Stderr "\n") - 3747 (flush Stderr) - 3748 # . syscall(exit, 1) - 3749 bb/copy-to-ebx 1/imm32 - 3750 b8/copy-to-eax 1/imm32/exit - 3751 cd/syscall 0x80/imm8 - 3752 # never gets here - 3753 - 3754 $parse-mu:error2: - 3755 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") - 3756 (print-int32-buffered Stderr *ebx) - 3757 (write-buffered Stderr " vars not reclaimed after fn '") - 3758 (write-slice-buffered Stderr *eax) # Function-name - 3759 (write-buffered Stderr "'\n") - 3760 (flush Stderr) - 3761 # . syscall(exit, 1) - 3762 bb/copy-to-ebx 1/imm32 - 3763 b8/copy-to-eax 1/imm32/exit - 3764 cd/syscall 0x80/imm8 - 3765 # never gets here - 3766 - 3767 # scenarios considered: - 3768 # ✗ fn foo # no block - 3769 # ✓ fn foo { - 3770 # ✗ fn foo { { - 3771 # ✗ fn foo { } - 3772 # ✗ fn foo { } { - 3773 # ✗ fn foo x { - 3774 # ✗ fn foo x: { - 3775 # ✓ fn foo x: int { - 3776 # ✓ fn foo x: int { - 3777 # ✓ fn foo x: int -> y/eax: int { - 3778 populate-mu-function-header: # first-line: (addr stream byte), out: (addr function), vars: (addr stack (handle var)) - 3779 # pseudocode: - 3780 # var name: slice - 3781 # next-mu-token(first-line, name) - 3782 # assert(name not in '{' '}' '->') - 3783 # out->name = slice-to-string(name) - 3784 # ## inouts - 3785 # while true - 3786 # ## name - 3787 # name = next-mu-token(first-line) - 3788 # if (name == '{') goto done - 3789 # if (name == '->') break - 3790 # assert(name != '}') - 3791 # var v: (handle var) = parse-var-with-type(name, first-line) - 3792 # assert(v->register == null) - 3793 # # v->block-depth is implicitly 0 - 3794 # out->inouts = append(v, out->inouts) - 3795 # push(vars, v) - 3796 # ## outputs - 3797 # while true - 3798 # ## name - 3799 # name = next-mu-token(first-line) - 3800 # assert(name not in '{' '}' '->') - 3801 # var v: (handle var) = parse-var-with-type(name, first-line) - 3802 # assert(v->register != null) - 3803 # out->outputs = append(v, out->outputs) - 3804 # done: - 3805 # - 3806 # . prologue - 3807 55/push-ebp - 3808 89/<- %ebp 4/r32/esp - 3809 # . save registers - 3810 50/push-eax - 3811 51/push-ecx - 3812 52/push-edx - 3813 53/push-ebx - 3814 57/push-edi - 3815 # edi = out - 3816 8b/-> *(ebp+0xc) 7/r32/edi - 3817 # var word-slice/ecx: slice - 3818 68/push 0/imm32/end - 3819 68/push 0/imm32/start - 3820 89/<- %ecx 4/r32/esp - 3821 # var v/ebx: (handle var) - 3822 68/push 0/imm32 - 3823 68/push 0/imm32 - 3824 89/<- %ebx 4/r32/esp - 3825 # read function name - 3826 (next-mu-token *(ebp+8) %ecx) - 3827 # error checking - 3828 # TODO: error if name starts with 'break' or 'loop' - 3829 # if (word-slice == '{') abort - 3830 (slice-equal? %ecx "{") # => eax - 3831 3d/compare-eax-and 0/imm32/false - 3832 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 3833 # if (word-slice == '->') abort - 3834 (slice-equal? %ecx "->") # => eax - 3835 3d/compare-eax-and 0/imm32/false - 3836 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 3837 # if (word-slice == '}') abort - 3838 (slice-equal? %ecx "}") # => eax - 3839 3d/compare-eax-and 0/imm32/false - 3840 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 3841 # save function name - 3842 (slice-to-string Heap %ecx %edi) # Function-name - 3843 # save function inouts - 3844 { - 3845 $populate-mu-function-header:check-for-inout: - 3846 (next-mu-token *(ebp+8) %ecx) - 3847 # if (word-slice == '{') goto done - 3848 (slice-equal? %ecx "{") # => eax - 3849 3d/compare-eax-and 0/imm32/false - 3850 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 - 3851 # if (word-slice == '->') break - 3852 (slice-equal? %ecx "->") # => eax - 3853 3d/compare-eax-and 0/imm32/false - 3854 0f 85/jump-if-!= break/disp32 - 3855 # if (word-slice == '}') abort - 3856 (slice-equal? %ecx "}") # => eax - 3857 3d/compare-eax-and 0/imm32/false - 3858 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 3859 # v = parse-var-with-type(word-slice, first-line) - 3860 (parse-var-with-type %ecx *(ebp+8) %ebx) - 3861 # assert(v->register == null) - 3862 # . eax: (addr var) = lookup(v) - 3863 (lookup *ebx *(ebx+4)) # => eax - 3864 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 3865 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 - 3866 # v->block-depth is implicitly 0 - 3867 # - 3868 # out->inouts = append(v, out->inouts) - 3869 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts - 3870 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts - 3871 # push(vars, v) - 3872 (push *(ebp+0x10) *ebx) - 3873 (push *(ebp+0x10) *(ebx+4)) - 3874 # - 3875 e9/jump loop/disp32 - 3876 } - 3877 # save function outputs - 3878 { - 3879 $populate-mu-function-header:check-for-out: - 3880 (next-mu-token *(ebp+8) %ecx) - 3881 # if (word-slice == '{') break - 3882 (slice-equal? %ecx "{") # => eax - 3883 3d/compare-eax-and 0/imm32/false - 3884 0f 85/jump-if-!= break/disp32 - 3885 # if (word-slice == '->') abort - 3886 (slice-equal? %ecx "->") # => eax - 3887 3d/compare-eax-and 0/imm32/false - 3888 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 3889 # if (word-slice == '}') abort - 3890 (slice-equal? %ecx "}") # => eax - 3891 3d/compare-eax-and 0/imm32/false - 3892 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 3893 # v = parse-var-with-type(word-slice, first-line) - 3894 (parse-var-with-type %ecx *(ebp+8) %ebx) - 3895 # assert(var->register != null) - 3896 # . eax: (addr var) = lookup(v) - 3897 (lookup *ebx *(ebx+4)) # => eax - 3898 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 3899 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 - 3900 # out->outputs = append(v, out->outputs) - 3901 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs - 3902 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs - 3903 # - 3904 e9/jump loop/disp32 - 3905 } - 3906 $populate-mu-function-header:done: - 3907 (check-no-tokens-left *(ebp+8)) - 3908 $populate-mu-function-header:end: - 3909 # . reclaim locals - 3910 81 0/subop/add %esp 0x10/imm32 - 3911 # . restore registers - 3912 5f/pop-to-edi - 3913 5b/pop-to-ebx - 3914 5a/pop-to-edx - 3915 59/pop-to-ecx - 3916 58/pop-to-eax - 3917 # . epilogue - 3918 89/<- %esp 5/r32/ebp - 3919 5d/pop-to-ebp - 3920 c3/return - 3921 - 3922 $populate-mu-function-header:error1: - 3923 # error("function header not in form 'fn <name> {'") - 3924 (write-buffered Stderr "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") - 3925 (flush Stderr) - 3926 (rewind-stream *(ebp+8)) - 3927 (write-stream 2 *(ebp+8)) - 3928 (write-buffered Stderr "'\n") - 3929 (flush Stderr) - 3930 # . syscall(exit, 1) - 3931 bb/copy-to-ebx 1/imm32 - 3932 b8/copy-to-eax 1/imm32/exit - 3933 cd/syscall 0x80/imm8 - 3934 # never gets here - 3935 - 3936 $populate-mu-function-header:error2: - 3937 # error("function input '" var "' cannot be in a register") - 3938 (write-buffered Stderr "function input '") - 3939 (write-buffered Stderr *ebx) # Var-name - 3940 (write-buffered Stderr "' cannot be in a register") - 3941 (flush Stderr) - 3942 # . syscall(exit, 1) - 3943 bb/copy-to-ebx 1/imm32 - 3944 b8/copy-to-eax 1/imm32/exit - 3945 cd/syscall 0x80/imm8 - 3946 # never gets here - 3947 - 3948 $populate-mu-function-header:error3: - 3949 # error("function input '" var "' must be in a register") - 3950 (write-buffered Stderr "function input '") - 3951 (lookup *ebx *(ebx+4)) # => eax - 3952 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 3953 (write-buffered Stderr %eax) - 3954 (write-buffered Stderr "' must be in a register, in instruction '") - 3955 (flush Stderr) - 3956 (rewind-stream *(ebp+8)) - 3957 (write-stream 2 *(ebp+8)) - 3958 (write-buffered Stderr "'\n") - 3959 (flush Stderr) - 3960 # . syscall(exit, 1) - 3961 bb/copy-to-ebx 1/imm32 - 3962 b8/copy-to-eax 1/imm32/exit - 3963 cd/syscall 0x80/imm8 - 3964 # never gets here - 3965 - 3966 test-function-header-with-arg: - 3967 # . prologue - 3968 55/push-ebp - 3969 89/<- %ebp 4/r32/esp - 3970 # setup - 3971 (clear-stream _test-input-stream) - 3972 (write _test-input-stream "foo n: int {\n") - 3973 # var result/ecx: function - 3974 2b/subtract *Function-size 4/r32/esp - 3975 89/<- %ecx 4/r32/esp - 3976 (zero-out %ecx *Function-size) - 3977 # var vars/ebx: (stack (handle var) 16) - 3978 81 5/subop/subtract %esp 0x80/imm32 - 3979 68/push 0x80/imm32/size - 3980 68/push 0/imm32/top - 3981 89/<- %ebx 4/r32/esp - 3982 # convert - 3983 (populate-mu-function-header _test-input-stream %ecx %ebx) - 3984 # check result->name - 3985 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 3986 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") - 3987 # var v/edx: (addr var) = result->inouts->value - 3988 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 3989 (lookup *eax *(eax+4)) # List-value List-value => eax - 3990 89/<- %edx 0/r32/eax - 3991 # check v->name - 3992 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 3993 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") - 3994 # check v->type - 3995 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 3996 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Tree-is-atom - 3997 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Tree-value - 3998 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Tree-right - 3999 # . epilogue - 4000 89/<- %esp 5/r32/ebp - 4001 5d/pop-to-ebp - 4002 c3/return - 4003 - 4004 test-function-header-with-multiple-args: - 4005 # . prologue - 4006 55/push-ebp - 4007 89/<- %ebp 4/r32/esp - 4008 # setup - 4009 (clear-stream _test-input-stream) - 4010 (write _test-input-stream "foo a: int, b: int c: int {\n") - 4011 # result/ecx: function - 4012 2b/subtract *Function-size 4/r32/esp - 4013 89/<- %ecx 4/r32/esp - 4014 (zero-out %ecx *Function-size) - 4015 # var vars/ebx: (stack (handle var) 16) - 4016 81 5/subop/subtract %esp 0x80/imm32 - 4017 68/push 0x80/imm32/size - 4018 68/push 0/imm32/top - 4019 89/<- %ebx 4/r32/esp - 4020 # convert - 4021 (populate-mu-function-header _test-input-stream %ecx %ebx) - 4022 # check result->name - 4023 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 4024 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") - 4025 # var inouts/edx: (addr list var) = lookup(result->inouts) - 4026 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 4027 89/<- %edx 0/r32/eax - 4028 $test-function-header-with-multiple-args:inout0: - 4029 # var v/ebx: (addr var) = lookup(inouts->value) - 4030 (lookup *edx *(edx+4)) # List-value List-value => eax - 4031 89/<- %ebx 0/r32/eax - 4032 # check v->name - 4033 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 4034 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name - 4035 # check v->type - 4036 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 4037 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Tree-is-atom - 4038 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Tree-value - 4039 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Tree-right - 4040 $test-function-header-with-multiple-args:inout1: - 4041 # inouts = lookup(inouts->next) - 4042 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 4043 89/<- %edx 0/r32/eax - 4044 # v = lookup(inouts->value) - 4045 (lookup *edx *(edx+4)) # List-value List-value => eax - 4046 89/<- %ebx 0/r32/eax - 4047 # check v->name - 4048 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 4049 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name - 4050 # check v->type - 4051 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 4052 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Tree-is-atom - 4053 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Tree-value - 4054 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Tree-right - 4055 $test-function-header-with-multiple-args:inout2: - 4056 # inouts = lookup(inouts->next) - 4057 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 4058 89/<- %edx 0/r32/eax - 4059 # v = lookup(inouts->value) - 4060 (lookup *edx *(edx+4)) # List-value List-value => eax - 4061 89/<- %ebx 0/r32/eax - 4062 # check v->name - 4063 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 4064 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name - 4065 # check v->type - 4066 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 4067 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Tree-is-atom - 4068 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Tree-value - 4069 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Tree-right - 4070 # . epilogue - 4071 89/<- %esp 5/r32/ebp - 4072 5d/pop-to-ebp - 4073 c3/return - 4074 - 4075 test-function-header-with-multiple-args-and-outputs: - 4076 # . prologue - 4077 55/push-ebp - 4078 89/<- %ebp 4/r32/esp - 4079 # setup - 4080 (clear-stream _test-input-stream) - 4081 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") - 4082 # result/ecx: function - 4083 2b/subtract *Function-size 4/r32/esp - 4084 89/<- %ecx 4/r32/esp - 4085 (zero-out %ecx *Function-size) - 4086 # var vars/ebx: (stack (handle var) 16) - 4087 81 5/subop/subtract %esp 0x80/imm32 - 4088 68/push 0x80/imm32/size - 4089 68/push 0/imm32/top - 4090 89/<- %ebx 4/r32/esp - 4091 # convert - 4092 (populate-mu-function-header _test-input-stream %ecx %ebx) - 4093 # check result->name - 4094 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 4095 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") - 4096 # var inouts/edx: (addr list var) = lookup(result->inouts) - 4097 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 4098 89/<- %edx 0/r32/eax - 4099 $test-function-header-with-multiple-args-and-outputs:inout0: - 4100 # var v/ebx: (addr var) = lookup(inouts->value) - 4101 (lookup *edx *(edx+4)) # List-value List-value => eax - 4102 89/<- %ebx 0/r32/eax - 4103 # check v->name - 4104 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 4105 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") - 4106 # check v->type - 4107 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 4108 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Tree-is-atom - 4109 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Tree-value - 4110 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Tree-right - 4111 $test-function-header-with-multiple-args-and-outputs:inout1: - 4112 # inouts = lookup(inouts->next) - 4113 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 4114 89/<- %edx 0/r32/eax - 4115 # v = lookup(inouts->value) - 4116 (lookup *edx *(edx+4)) # List-value List-value => eax - 4117 89/<- %ebx 0/r32/eax - 4118 # check v->name - 4119 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 4120 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") - 4121 # check v->type - 4122 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 4123 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Tree-is-atom - 4124 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Tree-value - 4125 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Tree-right - 4126 $test-function-header-with-multiple-args-and-outputs:inout2: - 4127 # inouts = lookup(inouts->next) - 4128 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 4129 89/<- %edx 0/r32/eax - 4130 # v = lookup(inouts->value) - 4131 (lookup *edx *(edx+4)) # List-value List-value => eax - 4132 89/<- %ebx 0/r32/eax - 4133 # check v->name - 4134 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 4135 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") - 4136 # check v->type - 4137 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 4138 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Tree-is-atom - 4139 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Tree-value - 4140 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Tree-right - 4141 $test-function-header-with-multiple-args-and-outputs:out0: - 4142 # var outputs/edx: (addr list var) = lookup(result->outputs) - 4143 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax - 4144 89/<- %edx 0/r32/eax - 4145 # v = lookup(outputs->value) - 4146 (lookup *edx *(edx+4)) # List-value List-value => eax - 4147 89/<- %ebx 0/r32/eax - 4148 # check v->name - 4149 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 4150 (check-strings-equal %eax "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") - 4151 # check v->register - 4152 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 4153 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") - 4154 # check v->type - 4155 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 4156 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Tree-is-atom - 4157 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Tree-value - 4158 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Tree-right - 4159 $test-function-header-with-multiple-args-and-outputs:out1: - 4160 # outputs = lookup(outputs->next) - 4161 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 4162 89/<- %edx 0/r32/eax - 4163 # v = lookup(inouts->value) - 4164 (lookup *edx *(edx+4)) # List-value List-value => eax - 4165 89/<- %ebx 0/r32/eax - 4166 # check v->name - 4167 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 4168 (check-strings-equal %eax "y" "F - test-function-header-with-multiple-args-and-outputs/output:1") - 4169 # check v->register - 4170 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 4171 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") - 4172 # check v->type - 4173 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 4174 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Tree-is-atom - 4175 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Tree-value - 4176 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Tree-right - 4177 # . epilogue - 4178 89/<- %esp 5/r32/ebp - 4179 5d/pop-to-ebp - 4180 c3/return - 4181 - 4182 # format for variables with types - 4183 # x: int - 4184 # x: int, - 4185 # x/eax: int - 4186 # x/eax: int, - 4187 # ignores at most one trailing comma - 4188 # WARNING: modifies name - 4189 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var) - 4190 # pseudocode: - 4191 # var s: slice - 4192 # if (!slice-ends-with(name, ":")) - 4193 # abort - 4194 # --name->end to skip ':' - 4195 # next-token-from-slice(name->start, name->end, '/', s) - 4196 # new-var-from-slice(s, out) - 4197 # ## register - 4198 # next-token-from-slice(s->end, name->end, '/', s) - 4199 # if (!slice-empty?(s)) - 4200 # out->register = slice-to-string(s) - 4201 # ## type - 4202 # var type: (handle tree type-id) = parse-type(first-line) - 4203 # out->type = type - 4204 # - 4205 # . prologue - 4206 55/push-ebp - 4207 89/<- %ebp 4/r32/esp - 4208 # . save registers - 4209 50/push-eax - 4210 51/push-ecx - 4211 52/push-edx - 4212 53/push-ebx - 4213 56/push-esi - 4214 57/push-edi - 4215 # esi = name - 4216 8b/-> *(ebp+8) 6/r32/esi - 4217 # if (!slice-ends-with?(name, ":")) abort - 4218 8b/-> *(esi+4) 1/r32/ecx # Slice-end - 4219 49/decrement-ecx - 4220 8a/copy-byte *ecx 1/r32/CL - 4221 81 4/subop/and %ecx 0xff/imm32 - 4222 81 7/subop/compare %ecx 0x3a/imm32/colon - 4223 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 - 4224 # --name->end to skip ':' - 4225 ff 1/subop/decrement *(esi+4) - 4226 # var s/ecx: slice - 4227 68/push 0/imm32/end - 4228 68/push 0/imm32/start - 4229 89/<- %ecx 4/r32/esp - 4230 $parse-var-with-type:parse-name: - 4231 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' - 4232 $parse-var-with-type:create-var: - 4233 # new-var-from-slice(s, out) - 4234 (new-var-from-slice Heap %ecx *(ebp+0x10)) - 4235 # save out->register - 4236 $parse-var-with-type:save-register: - 4237 # . var out-addr/edi: (addr var) = lookup(*out) - 4238 8b/-> *(ebp+0x10) 7/r32/edi - 4239 (lookup *edi *(edi+4)) # => eax - 4240 89/<- %edi 0/r32/eax - 4241 # . s = next-token(...) - 4242 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' - 4243 # . if (!slice-empty?(s)) out->register = slice-to-string(s) - 4244 { - 4245 $parse-var-with-type:write-register: - 4246 (slice-empty? %ecx) # => eax - 4247 3d/compare-eax-and 0/imm32/false - 4248 75/jump-if-!= break/disp8 - 4249 # out->register = slice-to-string(s) - 4250 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register - 4251 (slice-to-string Heap %ecx %eax) - 4252 } - 4253 $parse-var-with-type:save-type: - 4254 8d/copy-address *(edi+8) 0/r32/eax # Var-type - 4255 (parse-type Heap *(ebp+0xc) %eax) - 4256 $parse-var-with-type:end: - 4257 # . reclaim locals - 4258 81 0/subop/add %esp 8/imm32 - 4259 # . restore registers - 4260 5f/pop-to-edi - 4261 5e/pop-to-esi - 4262 5b/pop-to-ebx - 4263 5a/pop-to-edx - 4264 59/pop-to-ecx - 4265 58/pop-to-eax - 4266 # . epilogue - 4267 89/<- %esp 5/r32/ebp - 4268 5d/pop-to-ebp - 4269 c3/return - 4270 - 4271 $parse-var-with-type:abort: - 4272 # error("var should have form 'name: type' in '" line "'\n") - 4273 (write-buffered Stderr "var should have form 'name: type' in '") - 4274 (flush Stderr) - 4275 (rewind-stream *(ebp+0xc)) - 4276 (write-stream 2 *(ebp+0xc)) - 4277 (write-buffered Stderr "'\n") - 4278 (flush Stderr) - 4279 # . syscall(exit, 1) - 4280 bb/copy-to-ebx 1/imm32 - 4281 b8/copy-to-eax 1/imm32/exit - 4282 cd/syscall 0x80/imm8 - 4283 # never gets here - 4284 - 4285 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle tree type-id) - 4286 # pseudocode: - 4287 # var s: slice = next-mu-token(in) - 4288 # assert s != "" - 4289 # assert s != "->" - 4290 # assert s != "{" - 4291 # assert s != "}" - 4292 # if s == ")" - 4293 # return - 4294 # out = allocate(Tree) - 4295 # if s != "(" - 4296 # HACK: if s is an int, parse and return it - 4297 # out->left-is-atom? = true - 4298 # out->value = pos-or-insert-slice(Type-id, s) - 4299 # return - 4300 # out->left = parse-type(ad, in) - 4301 # out->right = parse-type-tree(ad, in) - 4302 # - 4303 # . prologue - 4304 55/push-ebp - 4305 89/<- %ebp 4/r32/esp - 4306 # . save registers - 4307 50/push-eax - 4308 51/push-ecx - 4309 52/push-edx - 4310 # clear out - 4311 (zero-out *(ebp+0x10) *Handle-size) - 4312 # var s/ecx: slice - 4313 68/push 0/imm32 - 4314 68/push 0/imm32 - 4315 89/<- %ecx 4/r32/esp - 4316 # s = next-mu-token(in) - 4317 (next-mu-token *(ebp+0xc) %ecx) - 4318 #? (write-buffered Stderr "tok: ") - 4319 #? (write-slice-buffered Stderr %ecx) - 4320 #? (write-buffered Stderr "$\n") - 4321 #? (flush Stderr) - 4322 # assert s != "" - 4323 (slice-equal? %ecx "") # => eax - 4324 3d/compare-eax-and 0/imm32/false - 4325 0f 85/jump-if-!= $parse-type:abort/disp32 - 4326 # assert s != "{" - 4327 (slice-equal? %ecx "{") # => eax - 4328 3d/compare-eax-and 0/imm32/false - 4329 0f 85/jump-if-!= $parse-type:abort/disp32 - 4330 # assert s != "}" - 4331 (slice-equal? %ecx "}") # => eax - 4332 3d/compare-eax-and 0/imm32/false - 4333 0f 85/jump-if-!= $parse-type:abort/disp32 - 4334 # assert s != "->" - 4335 (slice-equal? %ecx "->") # => eax - 4336 3d/compare-eax-and 0/imm32/false - 4337 0f 85/jump-if-!= $parse-type:abort/disp32 - 4338 # if (s == ")") return - 4339 (slice-equal? %ecx ")") # => eax - 4340 3d/compare-eax-and 0/imm32/false - 4341 0f 85/jump-if-!= $parse-type:end/disp32 - 4342 # out = new tree - 4343 (allocate *(ebp+8) *Tree-size *(ebp+0x10)) - 4344 # var out-addr/edx: (addr tree type-id) = lookup(*out) - 4345 8b/-> *(ebp+0x10) 2/r32/edx - 4346 (lookup *edx *(edx+4)) # => eax - 4347 89/<- %edx 0/r32/eax - 4348 { - 4349 # if (s != "(") break - 4350 (slice-equal? %ecx "(") # => eax - 4351 3d/compare-eax-and 0/imm32/false - 4352 75/jump-if-!= break/disp8 - 4353 # EGREGIOUS HACK for static array sizes: if s is a number, parse it - 4354 { - 4355 $parse-type:check-for-int: - 4356 (is-hex-int? %ecx) # => eax - 4357 3d/compare-eax-and 0/imm32/false - 4358 74/jump-if-= break/disp8 - 4359 $parse-type:int: - 4360 (parse-hex-int-from-slice %ecx) # => eax - 4361 89/<- *(edx+4) 0/r32/eax # Tree-value - 4362 e9/jump $parse-type:end/disp32 - 4363 } - 4364 $parse-type:atom: - 4365 # out->left-is-atom? = true - 4366 c7 0/subop/copy *edx 1/imm32/true # Tree-is-atom - 4367 # out->value = pos-or-insert-slice(Type-id, s) - 4368 (pos-or-insert-slice Type-id %ecx) # => eax - 4369 89/<- *(edx+4) 0/r32/eax # Tree-value - 4370 e9/jump $parse-type:end/disp32 - 4371 } - 4372 $parse-type:non-atom: - 4373 # otherwise s == "(" - 4374 # out->left = parse-type(ad, in) - 4375 8d/copy-address *(edx+4) 0/r32/eax # Tree-left - 4376 (parse-type *(ebp+8) *(ebp+0xc) %eax) - 4377 # out->right = parse-type-tree(ad, in) - 4378 8d/copy-address *(edx+0xc) 0/r32/eax # Tree-right - 4379 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax) - 4380 $parse-type:end: - 4381 # . reclaim locals - 4382 81 0/subop/add %esp 8/imm32 - 4383 # . restore registers - 4384 5a/pop-to-edx - 4385 59/pop-to-ecx - 4386 58/pop-to-eax - 4387 # . epilogue - 4388 89/<- %esp 5/r32/ebp - 4389 5d/pop-to-ebp - 4390 c3/return - 4391 - 4392 $parse-type:abort: - 4393 # error("unexpected token when parsing type: '" s "'\n") - 4394 (write-buffered Stderr "unexpected token when parsing type: '") - 4395 (write-slice-buffered Stderr %ecx) - 4396 (write-buffered Stderr "'\n") - 4397 (flush Stderr) - 4398 # . syscall(exit, 1) - 4399 bb/copy-to-ebx 1/imm32 - 4400 b8/copy-to-eax 1/imm32/exit - 4401 cd/syscall 0x80/imm8 - 4402 # never gets here - 4403 - 4404 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle tree type-id) - 4405 # pseudocode: - 4406 # var tmp: (handle tree type-id) = parse-type(ad, in) - 4407 # if tmp == 0 - 4408 # return 0 - 4409 # out = allocate(Tree) - 4410 # out->left = tmp - 4411 # out->right = parse-type-tree(ad, in) - 4412 # - 4413 # . prologue - 4414 55/push-ebp - 4415 89/<- %ebp 4/r32/esp - 4416 # . save registers - 4417 50/push-eax - 4418 51/push-ecx - 4419 52/push-edx - 4420 # - 4421 (zero-out *(ebp+0x10) *Handle-size) - 4422 # var tmp/ecx: (handle tree type-id) - 4423 68/push 0/imm32 - 4424 68/push 0/imm32 - 4425 89/<- %ecx 4/r32/esp - 4426 # tmp = parse-type(ad, in) - 4427 (parse-type *(ebp+8) *(ebp+0xc) %ecx) - 4428 # if (tmp == 0) return - 4429 81 7/subop/compare *ecx 0/imm32 - 4430 74/jump-if-= $parse-type-tree:end/disp8 - 4431 # out = new tree - 4432 (allocate *(ebp+8) *Tree-size *(ebp+0x10)) - 4433 # var out-addr/edx: (addr tree) = lookup(*out) - 4434 8b/-> *(ebp+0x10) 2/r32/edx - 4435 (lookup *edx *(edx+4)) # => eax - 4436 89/<- %edx 0/r32/eax - 4437 # out->left = tmp - 4438 8b/-> *ecx 0/r32/eax - 4439 89/<- *(edx+4) 0/r32/eax # Tree-left - 4440 8b/-> *(ecx+4) 0/r32/eax - 4441 89/<- *(edx+8) 0/r32/eax # Tree-left - 4442 # out->right = parse-type-tree(ad, in) - 4443 8d/copy-address *(edx+0xc) 0/r32/eax # Tree-right - 4444 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax) - 4445 $parse-type-tree:end: - 4446 # . reclaim locals - 4447 81 0/subop/add %esp 8/imm32 - 4448 # . restore registers - 4449 5a/pop-to-edx - 4450 59/pop-to-ecx - 4451 58/pop-to-eax - 4452 # . epilogue - 4453 89/<- %esp 5/r32/ebp - 4454 5d/pop-to-ebp - 4455 c3/return - 4456 - 4457 next-mu-token: # in: (addr stream byte), out: (addr slice) - 4458 # pseudocode: - 4459 # start: - 4460 # skip-chars-matching-whitespace(in) - 4461 # if in->read >= in->write # end of in - 4462 # out = {0, 0} - 4463 # return - 4464 # out->start = &in->data[in->read] - 4465 # var curr-byte/eax: byte = in->data[in->read] - 4466 # if curr->byte == ',' # comment token - 4467 # ++in->read - 4468 # goto start - 4469 # if curr-byte == '#' # comment - 4470 # goto done # treat as eof - 4471 # if curr-byte == '"' # string literal - 4472 # skip-string(in) - 4473 # goto done # no metadata - 4474 # if curr-byte == '(' - 4475 # ++in->read - 4476 # goto done - 4477 # if curr-byte == ')' - 4478 # ++in->read - 4479 # goto done - 4480 # # read a word - 4481 # while true - 4482 # if in->read >= in->write - 4483 # break - 4484 # curr-byte = in->data[in->read] - 4485 # if curr-byte == ' ' - 4486 # break - 4487 # if curr-byte == '\r' - 4488 # break - 4489 # if curr-byte == '\n' - 4490 # break - 4491 # if curr-byte == '(' - 4492 # break - 4493 # if curr-byte == ')' - 4494 # break - 4495 # if curr-byte == ',' - 4496 # break - 4497 # ++in->read - 4498 # done: - 4499 # out->end = &in->data[in->read] - 4500 # - 4501 # . prologue - 4502 55/push-ebp - 4503 89/<- %ebp 4/r32/esp - 4504 # . save registers - 4505 50/push-eax - 4506 51/push-ecx - 4507 56/push-esi - 4508 57/push-edi - 4509 # esi = in - 4510 8b/-> *(ebp+8) 6/r32/esi - 4511 # edi = out - 4512 8b/-> *(ebp+0xc) 7/r32/edi - 4513 $next-mu-token:start: - 4514 (skip-chars-matching-whitespace %esi) - 4515 $next-mu-token:check0: - 4516 # if (in->read >= in->write) return out = {0, 0} - 4517 # . ecx = in->read - 4518 8b/-> *(esi+4) 1/r32/ecx - 4519 # . if (ecx >= in->write) return out = {0, 0} - 4520 3b/compare<- *esi 1/r32/ecx - 4521 c7 0/subop/copy *edi 0/imm32 - 4522 c7 0/subop/copy *(edi+4) 0/imm32 - 4523 0f 8d/jump-if->= $next-mu-token:end/disp32 - 4524 # out->start = &in->data[in->read] - 4525 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 4526 89/<- *edi 0/r32/eax - 4527 # var curr-byte/eax: byte = in->data[in->read] - 4528 31/xor-with %eax 0/r32/eax - 4529 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 4530 { - 4531 $next-mu-token:check-for-comma: - 4532 # if (curr-byte != ',') break - 4533 3d/compare-eax-and 0x2c/imm32/comma - 4534 75/jump-if-!= break/disp8 - 4535 # ++in->read - 4536 ff 0/subop/increment *(esi+4) - 4537 # restart - 4538 e9/jump $next-mu-token:start/disp32 - 4539 } - 4540 { - 4541 $next-mu-token:check-for-comment: - 4542 # if (curr-byte != '#') break - 4543 3d/compare-eax-and 0x23/imm32/pound - 4544 75/jump-if-!= break/disp8 - 4545 # return eof - 4546 e9/jump $next-mu-token:done/disp32 - 4547 } - 4548 { - 4549 $next-mu-token:check-for-string-literal: - 4550 # if (curr-byte != '"') break - 4551 3d/compare-eax-and 0x22/imm32/dquote - 4552 75/jump-if-!= break/disp8 - 4553 (skip-string %esi) - 4554 # return - 4555 e9/jump $next-mu-token:done/disp32 - 4556 } - 4557 { - 4558 $next-mu-token:check-for-open-paren: - 4559 # if (curr-byte != '(') break - 4560 3d/compare-eax-and 0x28/imm32/open-paren - 4561 75/jump-if-!= break/disp8 - 4562 # ++in->read - 4563 ff 0/subop/increment *(esi+4) - 4564 # return - 4565 e9/jump $next-mu-token:done/disp32 - 4566 } - 4567 { - 4568 $next-mu-token:check-for-close-paren: - 4569 # if (curr-byte != ')') break - 4570 3d/compare-eax-and 0x29/imm32/close-paren - 4571 75/jump-if-!= break/disp8 - 4572 # ++in->read - 4573 ff 0/subop/increment *(esi+4) - 4574 # return - 4575 e9/jump $next-mu-token:done/disp32 - 4576 } - 4577 { - 4578 $next-mu-token:regular-word-without-metadata: - 4579 # if (in->read >= in->write) break - 4580 # . ecx = in->read - 4581 8b/-> *(esi+4) 1/r32/ecx - 4582 # . if (ecx >= in->write) break - 4583 3b/compare<- *esi 1/r32/ecx - 4584 7d/jump-if->= break/disp8 - 4585 # var c/eax: byte = in->data[in->read] - 4586 31/xor-with %eax 0/r32/eax - 4587 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 4588 # if (c == ' ') break - 4589 3d/compare-eax-and 0x20/imm32/space - 4590 74/jump-if-= break/disp8 - 4591 # if (c == '\r') break - 4592 3d/compare-eax-and 0xd/imm32/carriage-return - 4593 74/jump-if-= break/disp8 - 4594 # if (c == '\n') break - 4595 3d/compare-eax-and 0xa/imm32/newline - 4596 74/jump-if-= break/disp8 - 4597 # if (c == '(') break - 4598 3d/compare-eax-and 0x28/imm32/open-paren - 4599 0f 84/jump-if-= break/disp32 - 4600 # if (c == ')') break - 4601 3d/compare-eax-and 0x29/imm32/close-paren - 4602 0f 84/jump-if-= break/disp32 - 4603 # if (c == ',') break - 4604 3d/compare-eax-and 0x2c/imm32/comma - 4605 0f 84/jump-if-= break/disp32 - 4606 # ++in->read - 4607 ff 0/subop/increment *(esi+4) - 4608 # - 4609 e9/jump loop/disp32 - 4610 } - 4611 $next-mu-token:done: - 4612 # out->end = &in->data[in->read] - 4613 8b/-> *(esi+4) 1/r32/ecx - 4614 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 4615 89/<- *(edi+4) 0/r32/eax - 4616 $next-mu-token:end: - 4617 # . restore registers - 4618 5f/pop-to-edi - 4619 5e/pop-to-esi - 4620 59/pop-to-ecx - 4621 58/pop-to-eax - 4622 # . epilogue - 4623 89/<- %esp 5/r32/ebp - 4624 5d/pop-to-ebp - 4625 c3/return - 4626 - 4627 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int - 4628 # . prologue - 4629 55/push-ebp - 4630 89/<- %ebp 4/r32/esp - 4631 # if (pos-slice(arr, s) != -1) return it - 4632 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax - 4633 3d/compare-eax-and -1/imm32 - 4634 75/jump-if-!= $pos-or-insert-slice:end/disp8 - 4635 $pos-or-insert-slice:insert: - 4636 # var s2/eax: (handle array byte) - 4637 68/push 0/imm32 - 4638 68/push 0/imm32 - 4639 89/<- %eax 4/r32/esp - 4640 (slice-to-string Heap *(ebp+0xc) %eax) - 4641 # throw away alloc-id - 4642 (lookup *eax *(eax+4)) # => eax - 4643 (write-int *(ebp+8) %eax) - 4644 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax - 4645 $pos-or-insert-slice:end: - 4646 # . reclaim locals - 4647 81 0/subop/add %esp 8/imm32 - 4648 # . epilogue - 4649 89/<- %esp 5/r32/ebp - 4650 5d/pop-to-ebp - 4651 c3/return - 4652 - 4653 # return the index in an array of strings matching 's', -1 if not found - 4654 # index is denominated in elements, not bytes - 4655 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 3528 # convert + 3529 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3530 (flush _test-output-buffered-file) + 3531 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3537 # check output + 3538 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") + 3539 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") + 3540 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") + 3541 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") + 3542 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") + 3543 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") + 3544 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") + 3545 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") + 3546 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") + 3547 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") + 3548 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000003 + 4) 0x00000000/r32" "F - test-convert-array-of-user-defined-types/11") + 3549 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/13") + 3550 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/14") + 3551 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/15") + 3552 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/16") + 3553 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/17") + 3554 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/18") + 3555 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/19") + 3556 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/20") + 3557 # . epilogue + 3558 89/<- %esp 5/r32/ebp + 3559 5d/pop-to-ebp + 3560 c3/return + 3561 + 3562 test-convert-length-of-array-of-user-defined-types-to-eax: + 3563 # . prologue + 3564 55/push-ebp + 3565 89/<- %ebp 4/r32/esp + 3566 # setup + 3567 (clear-stream _test-input-stream) + 3568 (clear-stream $_test-input-buffered-file->buffer) + 3569 (clear-stream _test-output-stream) + 3570 (clear-stream $_test-output-buffered-file->buffer) + 3571 # + 3572 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 3573 (write _test-input-stream " x: int\n") + 3574 (write _test-input-stream " y: int\n") + 3575 (write _test-input-stream " z: int\n") + 3576 (write _test-input-stream "}\n") + 3577 (write _test-input-stream "fn foo {\n") + 3578 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 3579 (write _test-input-stream " var x/eax: (addr t) <- length arr\n") + 3580 (write _test-input-stream "}\n") + 3581 # convert + 3582 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3583 (flush _test-output-buffered-file) + 3584 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3590 # check output + 3591 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") + 3592 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") + 3593 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") + 3594 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/3") + 3595 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") + 3596 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") + 3597 # var arr + 3598 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/6") + 3599 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/7") + 3600 # length instruction + 3601 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") + 3602 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") + 3603 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/10") + 3604 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/11") + 3605 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/12") + 3606 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/13") + 3607 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/14") + 3608 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/15") + 3609 # reclaim arr + 3610 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/16") + 3611 # + 3612 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") + 3613 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") + 3614 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") + 3615 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/20") + 3616 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/21") + 3617 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") + 3618 # . epilogue + 3619 89/<- %esp 5/r32/ebp + 3620 5d/pop-to-ebp + 3621 c3/return + 3622 + 3623 test-convert-length-of-array-of-user-defined-types-to-ecx: + 3624 # . prologue + 3625 55/push-ebp + 3626 89/<- %ebp 4/r32/esp + 3627 # setup + 3628 (clear-stream _test-input-stream) + 3629 (clear-stream $_test-input-buffered-file->buffer) + 3630 (clear-stream _test-output-stream) + 3631 (clear-stream $_test-output-buffered-file->buffer) + 3632 # + 3633 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 3634 (write _test-input-stream " x: int\n") + 3635 (write _test-input-stream " y: int\n") + 3636 (write _test-input-stream " z: int\n") + 3637 (write _test-input-stream "}\n") + 3638 (write _test-input-stream "fn foo {\n") + 3639 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 3640 (write _test-input-stream " var x/ecx: (addr t) <- length arr\n") + 3641 (write _test-input-stream "}\n") + 3642 # convert + 3643 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3644 (flush _test-output-buffered-file) + 3645 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3651 # check output + 3652 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") + 3653 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") + 3654 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") + 3655 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/3") + 3656 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") + 3657 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") + 3658 # var a + 3659 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/6") + 3660 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/7") + 3661 # var x + 3662 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/8") + 3663 # length instruction + 3664 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") + 3665 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") + 3666 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/11") + 3667 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/12") + 3668 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/13") + 3669 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/14") + 3670 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/15") + 3671 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/16") + 3672 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/17") + 3673 # reclaim x + 3674 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/18") + 3675 # reclaim a + 3676 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/19") + 3677 # + 3678 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") + 3679 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") + 3680 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") + 3681 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/23") + 3682 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/24") + 3683 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") + 3684 # . epilogue + 3685 89/<- %esp 5/r32/ebp + 3686 5d/pop-to-ebp + 3687 c3/return + 3688 + 3689 test-convert-length-of-array-of-user-defined-types-to-edx: + 3690 # . prologue + 3691 55/push-ebp + 3692 89/<- %ebp 4/r32/esp + 3693 # setup + 3694 (clear-stream _test-input-stream) + 3695 (clear-stream $_test-input-buffered-file->buffer) + 3696 (clear-stream _test-output-stream) + 3697 (clear-stream $_test-output-buffered-file->buffer) + 3698 # + 3699 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 3700 (write _test-input-stream " x: int\n") + 3701 (write _test-input-stream " y: int\n") + 3702 (write _test-input-stream " z: int\n") + 3703 (write _test-input-stream "}\n") + 3704 (write _test-input-stream "fn foo {\n") + 3705 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 3706 (write _test-input-stream " var x/edx: (addr t) <- length arr\n") + 3707 (write _test-input-stream "}\n") + 3708 # convert + 3709 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3710 (flush _test-output-buffered-file) + 3711 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3717 # check output + 3718 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") + 3719 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") + 3720 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") + 3721 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/3") + 3722 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") + 3723 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") + 3724 # var a + 3725 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/6") + 3726 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/7") + 3727 # var x + 3728 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/8") + 3729 # length instruction + 3730 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") + 3731 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") + 3732 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/11") + 3733 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/12") + 3734 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/13") + 3735 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/14") + 3736 (check-next-stream-line-equal _test-output-stream " 89/<- %edx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/15") + 3737 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/16") + 3738 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/17") + 3739 # reclaim x + 3740 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/18") + 3741 # reclaim a + 3742 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/19") + 3743 # + 3744 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") + 3745 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") + 3746 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") + 3747 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/23") + 3748 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/24") + 3749 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") + 3750 # . epilogue + 3751 89/<- %esp 5/r32/ebp + 3752 5d/pop-to-ebp + 3753 c3/return + 3754 + 3755 test-convert-length-of-array-of-user-defined-types: + 3756 # . prologue + 3757 55/push-ebp + 3758 89/<- %ebp 4/r32/esp + 3759 # setup + 3760 (clear-stream _test-input-stream) + 3761 (clear-stream $_test-input-buffered-file->buffer) + 3762 (clear-stream _test-output-stream) + 3763 (clear-stream $_test-output-buffered-file->buffer) + 3764 # + 3765 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 + 3766 (write _test-input-stream " x: int\n") + 3767 (write _test-input-stream " y: int\n") + 3768 (write _test-input-stream " z: int\n") + 3769 (write _test-input-stream "}\n") + 3770 (write _test-input-stream "fn foo {\n") + 3771 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 3772 (write _test-input-stream " var x/ebx: (addr t) <- length arr\n") + 3773 (write _test-input-stream "}\n") + 3774 # convert + 3775 (convert-mu _test-input-buffered-file _test-output-buffered-file) + 3776 (flush _test-output-buffered-file) + 3777 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3783 # check output + 3784 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") + 3785 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") + 3786 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") + 3787 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") + 3788 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") + 3789 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") + 3790 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") + 3791 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types/7") + 3792 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") + 3793 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") + 3794 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") + 3795 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") + 3796 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") + 3797 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types/13") + 3798 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types/14") + 3799 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types/15") + 3800 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") + 3801 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") + 3802 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") + 3803 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") + 3804 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") + 3805 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") + 3806 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") + 3807 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") + 3808 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") + 3809 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") + 3810 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") + 3811 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") + 3812 # . epilogue + 3813 89/<- %esp 5/r32/ebp + 3814 5d/pop-to-ebp + 3815 c3/return + 3816 + 3817 ####################################################### + 3818 # Parsing + 3819 ####################################################### + 3820 + 3821 parse-mu: # in: (addr buffered-file) + 3822 # pseudocode + 3823 # var curr-function: (addr handle function) = Program->functions + 3824 # var curr-type: (addr handle typeinfo) = Program->types + 3825 # var line: (stream byte 512) + 3826 # var word-slice: slice + 3827 # while true # line loop + 3828 # clear-stream(line) + 3829 # read-line-buffered(in, line) + 3830 # if (line->write == 0) break # end of file + 3831 # word-slice = next-mu-token(line) + 3832 # if slice-empty?(word-slice) # end of line + 3833 # continue + 3834 # else if slice-starts-with?(word-slice, "#") # comment + 3835 # continue # end of line + 3836 # else if slice-equal?(word-slice, "fn") + 3837 # var new-function: (handle function) = allocate(function) + 3838 # var vars: (stack live-var 256) + 3839 # populate-mu-function-header(line, new-function, vars) + 3840 # populate-mu-function-body(in, new-function, vars) + 3841 # assert(vars->top == 0) + 3842 # *curr-function = new-function + 3843 # curr-function = &new-function->next + 3844 # else if slice-equal?(word-slice, "type") + 3845 # word-slice = next-mu-token(line) + 3846 # type-id = pos-or-insert-slice(Type-id, word-slice) + 3847 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) + 3848 # assert(next-word(line) == "{") + 3849 # populate-mu-type(in, new-type) + 3850 # else + 3851 # abort() + 3852 # + 3853 # . prologue + 3854 55/push-ebp + 3855 89/<- %ebp 4/r32/esp + 3856 # . save registers + 3857 50/push-eax + 3858 51/push-ecx + 3859 52/push-edx + 3860 53/push-ebx + 3861 56/push-esi + 3862 57/push-edi + 3863 # var line/ecx: (stream byte 512) + 3864 81 5/subop/subtract %esp 0x200/imm32 + 3865 68/push 0x200/imm32/size + 3866 68/push 0/imm32/read + 3867 68/push 0/imm32/write + 3868 89/<- %ecx 4/r32/esp + 3869 # var word-slice/edx: slice + 3870 68/push 0/imm32/end + 3871 68/push 0/imm32/start + 3872 89/<- %edx 4/r32/esp + 3873 # var curr-function/edi: (addr handle function) + 3874 bf/copy-to-edi _Program-functions/imm32 + 3875 # var vars/ebx: (stack live-var 256) + 3876 81 5/subop/subtract %esp 0xc00/imm32 + 3877 68/push 0xc00/imm32/size + 3878 68/push 0/imm32/top + 3879 89/<- %ebx 4/r32/esp + 3880 { + 3881 $parse-mu:line-loop: + 3882 (clear-stream %ecx) + 3883 (read-line-buffered *(ebp+8) %ecx) + 3884 # if (line->write == 0) break + 3885 81 7/subop/compare *ecx 0/imm32 + 3886 0f 84/jump-if-= break/disp32 + 3887 +-- 6 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + 3893 (next-mu-token %ecx %edx) + 3894 # if slice-empty?(word-slice) continue + 3895 (slice-empty? %edx) # => eax + 3896 3d/compare-eax-and 0/imm32/false + 3897 0f 85/jump-if-!= loop/disp32 + 3898 # if (*word-slice->start == "#") continue + 3899 # . eax = *word-slice->start + 3900 8b/-> *edx 0/r32/eax + 3901 8a/copy-byte *eax 0/r32/AL + 3902 81 4/subop/and %eax 0xff/imm32 + 3903 # . if (eax == '#') continue + 3904 3d/compare-eax-and 0x23/imm32/hash + 3905 0f 84/jump-if-= loop/disp32 + 3906 # if (slice-equal?(word-slice, "fn")) parse a function + 3907 { + 3908 $parse-mu:fn: + 3909 (slice-equal? %edx "fn") # => eax + 3910 3d/compare-eax-and 0/imm32/false + 3911 0f 84/jump-if-= break/disp32 + 3912 # var new-function/esi: (handle function) + 3913 68/push 0/imm32 + 3914 68/push 0/imm32 + 3915 89/<- %esi 4/r32/esp + 3916 # populate-mu-function(line, in, vars, new-function) + 3917 (allocate Heap *Function-size %esi) + 3918 # var new-function-addr/eax: (addr function) + 3919 (lookup *esi *(esi+4)) # => eax + 3920 (clear-stack %ebx) + 3921 (populate-mu-function-header %ecx %eax %ebx) + 3922 (populate-mu-function-body *(ebp+8) %eax %ebx) + 3923 # *curr-function = new-function + 3924 8b/-> *esi 0/r32/eax + 3925 89/<- *edi 0/r32/eax + 3926 8b/-> *(esi+4) 0/r32/eax + 3927 89/<- *(edi+4) 0/r32/eax + 3928 # curr-function = &new-function->next + 3929 # . var tmp/eax: (addr function) = lookup(new-function) + 3930 (lookup *esi *(esi+4)) # => eax + 3931 # . curr-function = &tmp->next + 3932 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next + 3933 # reclaim new-function + 3934 81 0/subop/add %esp 8/imm32 + 3935 # + 3936 e9/jump $parse-mu:line-loop/disp32 + 3937 } + 3938 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition + 3939 { + 3940 $parse-mu:type: + 3941 (slice-equal? %edx "type") # => eax + 3942 3d/compare-eax-and 0/imm32 + 3943 0f 84/jump-if-= break/disp32 + 3944 (next-mu-token %ecx %edx) + 3945 # var type-id/eax: int + 3946 (pos-or-insert-slice Type-id %edx) # => eax + 3947 # spill + 3948 51/push-ecx + 3949 # var new-type/ecx: (handle typeinfo) + 3950 68/push 0/imm32 + 3951 68/push 0/imm32 + 3952 89/<- %ecx 4/r32/esp + 3953 (find-or-create-typeinfo %eax %ecx) + 3954 # + 3955 (lookup *ecx *(ecx+4)) # => eax + 3956 # TODO: ensure that 'line' has nothing else but '{' + 3957 #? (dump-typeinfos "=== aaa\n") + 3958 (populate-mu-type *(ebp+8) %eax) # => eax + 3959 #? (dump-typeinfos "=== zzz\n") + 3960 # reclaim new-type + 3961 81 0/subop/add %esp 8/imm32 + 3962 # restore + 3963 59/pop-to-ecx + 3964 e9/jump $parse-mu:line-loop/disp32 + 3965 } + 3966 # otherwise abort + 3967 e9/jump $parse-mu:error1/disp32 + 3968 } # end line loop + 3969 $parse-mu:end: + 3970 # . reclaim locals + 3971 81 0/subop/add %esp 0xe1c/imm32 + 3972 # . restore registers + 3973 5f/pop-to-edi + 3974 5e/pop-to-esi + 3975 5b/pop-to-ebx + 3976 5a/pop-to-edx + 3977 59/pop-to-ecx + 3978 58/pop-to-eax + 3979 # . epilogue + 3980 89/<- %esp 5/r32/ebp + 3981 5d/pop-to-ebp + 3982 c3/return + 3983 + 3984 $parse-mu:error1: + 3985 # error("unexpected top-level command: " word-slice "\n") + 3986 (write-buffered Stderr "unexpected top-level command: ") + 3987 (write-slice-buffered Stderr %edx) + 3988 (write-buffered Stderr "\n") + 3989 (flush Stderr) + 3990 # . syscall(exit, 1) + 3991 bb/copy-to-ebx 1/imm32 + 3992 b8/copy-to-eax 1/imm32/exit + 3993 cd/syscall 0x80/imm8 + 3994 # never gets here + 3995 + 3996 $parse-mu:error2: + 3997 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") + 3998 (print-int32-buffered Stderr *ebx) + 3999 (write-buffered Stderr " vars not reclaimed after fn '") + 4000 (write-slice-buffered Stderr *eax) # Function-name + 4001 (write-buffered Stderr "'\n") + 4002 (flush Stderr) + 4003 # . syscall(exit, 1) + 4004 bb/copy-to-ebx 1/imm32 + 4005 b8/copy-to-eax 1/imm32/exit + 4006 cd/syscall 0x80/imm8 + 4007 # never gets here + 4008 + 4009 # scenarios considered: + 4010 # ✗ fn foo # no block + 4011 # ✓ fn foo { + 4012 # ✗ fn foo { { + 4013 # ✗ fn foo { } + 4014 # ✗ fn foo { } { + 4015 # ✗ fn foo x { + 4016 # ✗ fn foo x: { + 4017 # ✓ fn foo x: int { + 4018 # ✓ fn foo x: int { + 4019 # ✓ fn foo x: int -> y/eax: int { + 4020 populate-mu-function-header: # first-line: (addr stream byte), out: (addr function), vars: (addr stack live-var) + 4021 # pseudocode: + 4022 # var name: slice + 4023 # next-mu-token(first-line, name) + 4024 # assert(name not in '{' '}' '->') + 4025 # out->name = slice-to-string(name) + 4026 # ## inouts + 4027 # while true + 4028 # ## name + 4029 # name = next-mu-token(first-line) + 4030 # if (name == '{') goto done + 4031 # if (name == '->') break + 4032 # assert(name != '}') + 4033 # var v: (handle var) = parse-var-with-type(name, first-line) + 4034 # assert(v->register == null) + 4035 # # v->block-depth is implicitly 0 + 4036 # out->inouts = append(v, out->inouts) + 4037 # push(vars, {v, false}) + 4038 # ## outputs + 4039 # while true + 4040 # ## name + 4041 # name = next-mu-token(first-line) + 4042 # assert(name not in '{' '}' '->') + 4043 # var v: (handle var) = parse-var-with-type(name, first-line) + 4044 # assert(v->register != null) + 4045 # out->outputs = append(v, out->outputs) + 4046 # done: + 4047 # + 4048 # . prologue + 4049 55/push-ebp + 4050 89/<- %ebp 4/r32/esp + 4051 # . save registers + 4052 50/push-eax + 4053 51/push-ecx + 4054 52/push-edx + 4055 53/push-ebx + 4056 57/push-edi + 4057 # edi = out + 4058 8b/-> *(ebp+0xc) 7/r32/edi + 4059 # var word-slice/ecx: slice + 4060 68/push 0/imm32/end + 4061 68/push 0/imm32/start + 4062 89/<- %ecx 4/r32/esp + 4063 # var v/ebx: (handle var) + 4064 68/push 0/imm32 + 4065 68/push 0/imm32 + 4066 89/<- %ebx 4/r32/esp + 4067 # read function name + 4068 (next-mu-token *(ebp+8) %ecx) + 4069 # error checking + 4070 # TODO: error if name starts with 'break' or 'loop' + 4071 # if (word-slice == '{') abort + 4072 (slice-equal? %ecx "{") # => eax + 4073 3d/compare-eax-and 0/imm32/false + 4074 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 4075 # if (word-slice == '->') abort + 4076 (slice-equal? %ecx "->") # => eax + 4077 3d/compare-eax-and 0/imm32/false + 4078 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 4079 # if (word-slice == '}') abort + 4080 (slice-equal? %ecx "}") # => eax + 4081 3d/compare-eax-and 0/imm32/false + 4082 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 4083 # save function name + 4084 (slice-to-string Heap %ecx %edi) # Function-name + 4085 # save function inouts + 4086 { + 4087 $populate-mu-function-header:check-for-inout: + 4088 (next-mu-token *(ebp+8) %ecx) + 4089 # if (word-slice == '{') goto done + 4090 (slice-equal? %ecx "{") # => eax + 4091 3d/compare-eax-and 0/imm32/false + 4092 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 + 4093 # if (word-slice == '->') break + 4094 (slice-equal? %ecx "->") # => eax + 4095 3d/compare-eax-and 0/imm32/false + 4096 0f 85/jump-if-!= break/disp32 + 4097 # if (word-slice == '}') abort + 4098 (slice-equal? %ecx "}") # => eax + 4099 3d/compare-eax-and 0/imm32/false + 4100 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 4101 # v = parse-var-with-type(word-slice, first-line) + 4102 (parse-var-with-type %ecx *(ebp+8) %ebx) + 4103 # assert(v->register == null) + 4104 # . eax: (addr var) = lookup(v) + 4105 (lookup *ebx *(ebx+4)) # => eax + 4106 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 4107 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 + 4108 # v->block-depth is implicitly 0 + 4109 # + 4110 # out->inouts = append(v, out->inouts) + 4111 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts + 4112 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts + 4113 # push(vars, {v, false}) + 4114 (push *(ebp+0x10) *ebx) + 4115 (push *(ebp+0x10) *(ebx+4)) + 4116 (push *(ebp+0x10) 0) # false + 4117 # + 4118 e9/jump loop/disp32 + 4119 } + 4120 # save function outputs + 4121 { + 4122 $populate-mu-function-header:check-for-out: + 4123 (next-mu-token *(ebp+8) %ecx) + 4124 # if (word-slice == '{') break + 4125 (slice-equal? %ecx "{") # => eax + 4126 3d/compare-eax-and 0/imm32/false + 4127 0f 85/jump-if-!= break/disp32 + 4128 # if (word-slice == '->') abort + 4129 (slice-equal? %ecx "->") # => eax + 4130 3d/compare-eax-and 0/imm32/false + 4131 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 4132 # if (word-slice == '}') abort + 4133 (slice-equal? %ecx "}") # => eax + 4134 3d/compare-eax-and 0/imm32/false + 4135 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 4136 # v = parse-var-with-type(word-slice, first-line) + 4137 (parse-var-with-type %ecx *(ebp+8) %ebx) + 4138 # assert(var->register != null) + 4139 # . eax: (addr var) = lookup(v) + 4140 (lookup *ebx *(ebx+4)) # => eax + 4141 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 4142 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 + 4143 # out->outputs = append(v, out->outputs) + 4144 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs + 4145 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs + 4146 # + 4147 e9/jump loop/disp32 + 4148 } + 4149 $populate-mu-function-header:done: + 4150 (check-no-tokens-left *(ebp+8)) + 4151 $populate-mu-function-header:end: + 4152 # . reclaim locals + 4153 81 0/subop/add %esp 0x10/imm32 + 4154 # . restore registers + 4155 5f/pop-to-edi + 4156 5b/pop-to-ebx + 4157 5a/pop-to-edx + 4158 59/pop-to-ecx + 4159 58/pop-to-eax + 4160 # . epilogue + 4161 89/<- %esp 5/r32/ebp + 4162 5d/pop-to-ebp + 4163 c3/return + 4164 + 4165 $populate-mu-function-header:error1: + 4166 # error("function header not in form 'fn <name> {'") + 4167 (write-buffered Stderr "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") + 4168 (flush Stderr) + 4169 (rewind-stream *(ebp+8)) + 4170 (write-stream 2 *(ebp+8)) + 4171 (write-buffered Stderr "'\n") + 4172 (flush Stderr) + 4173 # . syscall(exit, 1) + 4174 bb/copy-to-ebx 1/imm32 + 4175 b8/copy-to-eax 1/imm32/exit + 4176 cd/syscall 0x80/imm8 + 4177 # never gets here + 4178 + 4179 $populate-mu-function-header:error2: + 4180 # error("function input '" var "' cannot be in a register") + 4181 (write-buffered Stderr "function input '") + 4182 (write-buffered Stderr *ebx) # Var-name + 4183 (write-buffered Stderr "' cannot be in a register") + 4184 (flush Stderr) + 4185 # . syscall(exit, 1) + 4186 bb/copy-to-ebx 1/imm32 + 4187 b8/copy-to-eax 1/imm32/exit + 4188 cd/syscall 0x80/imm8 + 4189 # never gets here + 4190 + 4191 $populate-mu-function-header:error3: + 4192 # error("function input '" var "' must be in a register") + 4193 (write-buffered Stderr "function input '") + 4194 (lookup *ebx *(ebx+4)) # => eax + 4195 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 4196 (write-buffered Stderr %eax) + 4197 (write-buffered Stderr "' must be in a register, in instruction '") + 4198 (flush Stderr) + 4199 (rewind-stream *(ebp+8)) + 4200 (write-stream 2 *(ebp+8)) + 4201 (write-buffered Stderr "'\n") + 4202 (flush Stderr) + 4203 # . syscall(exit, 1) + 4204 bb/copy-to-ebx 1/imm32 + 4205 b8/copy-to-eax 1/imm32/exit + 4206 cd/syscall 0x80/imm8 + 4207 # never gets here + 4208 + 4209 test-function-header-with-arg: + 4210 # . prologue + 4211 55/push-ebp + 4212 89/<- %ebp 4/r32/esp + 4213 # setup + 4214 (clear-stream _test-input-stream) + 4215 (write _test-input-stream "foo n: int {\n") + 4216 # var result/ecx: function + 4217 2b/subtract *Function-size 4/r32/esp + 4218 89/<- %ecx 4/r32/esp + 4219 (zero-out %ecx *Function-size) + 4220 # var vars/ebx: (stack live-var 16) + 4221 81 5/subop/subtract %esp 0xc0/imm32 + 4222 68/push 0xc0/imm32/size + 4223 68/push 0/imm32/top + 4224 89/<- %ebx 4/r32/esp + 4225 # convert + 4226 (populate-mu-function-header _test-input-stream %ecx %ebx) + 4227 # check result->name + 4228 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 4229 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") + 4230 # var v/edx: (addr var) = result->inouts->value + 4231 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 4232 (lookup *eax *(eax+4)) # List-value List-value => eax + 4233 89/<- %edx 0/r32/eax + 4234 # check v->name + 4235 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 4236 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") + 4237 # check v->type + 4238 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 4239 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Tree-is-atom + 4240 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Tree-value + 4241 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Tree-right + 4242 # . epilogue + 4243 89/<- %esp 5/r32/ebp + 4244 5d/pop-to-ebp + 4245 c3/return + 4246 + 4247 test-function-header-with-multiple-args: + 4248 # . prologue + 4249 55/push-ebp + 4250 89/<- %ebp 4/r32/esp + 4251 # setup + 4252 (clear-stream _test-input-stream) + 4253 (write _test-input-stream "foo a: int, b: int c: int {\n") + 4254 # result/ecx: function + 4255 2b/subtract *Function-size 4/r32/esp + 4256 89/<- %ecx 4/r32/esp + 4257 (zero-out %ecx *Function-size) + 4258 # var vars/ebx: (stack live-var 16) + 4259 81 5/subop/subtract %esp 0xc0/imm32 + 4260 68/push 0xc0/imm32/size + 4261 68/push 0/imm32/top + 4262 89/<- %ebx 4/r32/esp + 4263 # convert + 4264 (populate-mu-function-header _test-input-stream %ecx %ebx) + 4265 # check result->name + 4266 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 4267 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") + 4268 # var inouts/edx: (addr list var) = lookup(result->inouts) + 4269 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 4270 89/<- %edx 0/r32/eax + 4271 $test-function-header-with-multiple-args:inout0: + 4272 # var v/ebx: (addr var) = lookup(inouts->value) + 4273 (lookup *edx *(edx+4)) # List-value List-value => eax + 4274 89/<- %ebx 0/r32/eax + 4275 # check v->name + 4276 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 4277 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name + 4278 # check v->type + 4279 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 4280 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Tree-is-atom + 4281 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Tree-value + 4282 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Tree-right + 4283 $test-function-header-with-multiple-args:inout1: + 4284 # inouts = lookup(inouts->next) + 4285 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 4286 89/<- %edx 0/r32/eax + 4287 # v = lookup(inouts->value) + 4288 (lookup *edx *(edx+4)) # List-value List-value => eax + 4289 89/<- %ebx 0/r32/eax + 4290 # check v->name + 4291 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 4292 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name + 4293 # check v->type + 4294 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 4295 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Tree-is-atom + 4296 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Tree-value + 4297 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Tree-right + 4298 $test-function-header-with-multiple-args:inout2: + 4299 # inouts = lookup(inouts->next) + 4300 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 4301 89/<- %edx 0/r32/eax + 4302 # v = lookup(inouts->value) + 4303 (lookup *edx *(edx+4)) # List-value List-value => eax + 4304 89/<- %ebx 0/r32/eax + 4305 # check v->name + 4306 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 4307 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name + 4308 # check v->type + 4309 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 4310 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Tree-is-atom + 4311 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Tree-value + 4312 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Tree-right + 4313 # . epilogue + 4314 89/<- %esp 5/r32/ebp + 4315 5d/pop-to-ebp + 4316 c3/return + 4317 + 4318 test-function-header-with-multiple-args-and-outputs: + 4319 # . prologue + 4320 55/push-ebp + 4321 89/<- %ebp 4/r32/esp + 4322 # setup + 4323 (clear-stream _test-input-stream) + 4324 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") + 4325 # result/ecx: function + 4326 2b/subtract *Function-size 4/r32/esp + 4327 89/<- %ecx 4/r32/esp + 4328 (zero-out %ecx *Function-size) + 4329 # var vars/ebx: (stack live-var 16) + 4330 81 5/subop/subtract %esp 0xc0/imm32 + 4331 68/push 0xc0/imm32/size + 4332 68/push 0/imm32/top + 4333 89/<- %ebx 4/r32/esp + 4334 # convert + 4335 (populate-mu-function-header _test-input-stream %ecx %ebx) + 4336 # check result->name + 4337 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 4338 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") + 4339 # var inouts/edx: (addr list var) = lookup(result->inouts) + 4340 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 4341 89/<- %edx 0/r32/eax + 4342 $test-function-header-with-multiple-args-and-outputs:inout0: + 4343 # var v/ebx: (addr var) = lookup(inouts->value) + 4344 (lookup *edx *(edx+4)) # List-value List-value => eax + 4345 89/<- %ebx 0/r32/eax + 4346 # check v->name + 4347 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 4348 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") + 4349 # check v->type + 4350 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 4351 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Tree-is-atom + 4352 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Tree-value + 4353 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Tree-right + 4354 $test-function-header-with-multiple-args-and-outputs:inout1: + 4355 # inouts = lookup(inouts->next) + 4356 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 4357 89/<- %edx 0/r32/eax + 4358 # v = lookup(inouts->value) + 4359 (lookup *edx *(edx+4)) # List-value List-value => eax + 4360 89/<- %ebx 0/r32/eax + 4361 # check v->name + 4362 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 4363 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") + 4364 # check v->type + 4365 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 4366 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Tree-is-atom + 4367 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Tree-value + 4368 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Tree-right + 4369 $test-function-header-with-multiple-args-and-outputs:inout2: + 4370 # inouts = lookup(inouts->next) + 4371 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 4372 89/<- %edx 0/r32/eax + 4373 # v = lookup(inouts->value) + 4374 (lookup *edx *(edx+4)) # List-value List-value => eax + 4375 89/<- %ebx 0/r32/eax + 4376 # check v->name + 4377 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 4378 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") + 4379 # check v->type + 4380 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 4381 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Tree-is-atom + 4382 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Tree-value + 4383 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Tree-right + 4384 $test-function-header-with-multiple-args-and-outputs:out0: + 4385 # var outputs/edx: (addr list var) = lookup(result->outputs) + 4386 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax + 4387 89/<- %edx 0/r32/eax + 4388 # v = lookup(outputs->value) + 4389 (lookup *edx *(edx+4)) # List-value List-value => eax + 4390 89/<- %ebx 0/r32/eax + 4391 # check v->name + 4392 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 4393 (check-strings-equal %eax "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") + 4394 # check v->register + 4395 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 4396 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") + 4397 # check v->type + 4398 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 4399 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Tree-is-atom + 4400 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Tree-value + 4401 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Tree-right + 4402 $test-function-header-with-multiple-args-and-outputs:out1: + 4403 # outputs = lookup(outputs->next) + 4404 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 4405 89/<- %edx 0/r32/eax + 4406 # v = lookup(inouts->value) + 4407 (lookup *edx *(edx+4)) # List-value List-value => eax + 4408 89/<- %ebx 0/r32/eax + 4409 # check v->name + 4410 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 4411 (check-strings-equal %eax "y" "F - test-function-header-with-multiple-args-and-outputs/output:1") + 4412 # check v->register + 4413 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 4414 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") + 4415 # check v->type + 4416 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 4417 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Tree-is-atom + 4418 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Tree-value + 4419 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Tree-right + 4420 # . epilogue + 4421 89/<- %esp 5/r32/ebp + 4422 5d/pop-to-ebp + 4423 c3/return + 4424 + 4425 # format for variables with types + 4426 # x: int + 4427 # x: int, + 4428 # x/eax: int + 4429 # x/eax: int, + 4430 # ignores at most one trailing comma + 4431 # WARNING: modifies name + 4432 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var) + 4433 # pseudocode: + 4434 # var s: slice + 4435 # if (!slice-ends-with(name, ":")) + 4436 # abort + 4437 # --name->end to skip ':' + 4438 # next-token-from-slice(name->start, name->end, '/', s) + 4439 # new-var-from-slice(s, out) + 4440 # ## register + 4441 # next-token-from-slice(s->end, name->end, '/', s) + 4442 # if (!slice-empty?(s)) + 4443 # out->register = slice-to-string(s) + 4444 # ## type + 4445 # var type: (handle tree type-id) = parse-type(first-line) + 4446 # out->type = type + 4447 # + 4448 # . prologue + 4449 55/push-ebp + 4450 89/<- %ebp 4/r32/esp + 4451 # . save registers + 4452 50/push-eax + 4453 51/push-ecx + 4454 52/push-edx + 4455 53/push-ebx + 4456 56/push-esi + 4457 57/push-edi + 4458 # esi = name + 4459 8b/-> *(ebp+8) 6/r32/esi + 4460 # if (!slice-ends-with?(name, ":")) abort + 4461 8b/-> *(esi+4) 1/r32/ecx # Slice-end + 4462 49/decrement-ecx + 4463 8a/copy-byte *ecx 1/r32/CL + 4464 81 4/subop/and %ecx 0xff/imm32 + 4465 81 7/subop/compare %ecx 0x3a/imm32/colon + 4466 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 + 4467 # --name->end to skip ':' + 4468 ff 1/subop/decrement *(esi+4) + 4469 # var s/ecx: slice + 4470 68/push 0/imm32/end + 4471 68/push 0/imm32/start + 4472 89/<- %ecx 4/r32/esp + 4473 $parse-var-with-type:parse-name: + 4474 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' + 4475 $parse-var-with-type:create-var: + 4476 # new-var-from-slice(s, out) + 4477 (new-var-from-slice Heap %ecx *(ebp+0x10)) + 4478 # save out->register + 4479 $parse-var-with-type:save-register: + 4480 # . var out-addr/edi: (addr var) = lookup(*out) + 4481 8b/-> *(ebp+0x10) 7/r32/edi + 4482 (lookup *edi *(edi+4)) # => eax + 4483 89/<- %edi 0/r32/eax + 4484 # . s = next-token(...) + 4485 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' + 4486 # . if (!slice-empty?(s)) out->register = slice-to-string(s) + 4487 { + 4488 $parse-var-with-type:write-register: + 4489 (slice-empty? %ecx) # => eax + 4490 3d/compare-eax-and 0/imm32/false + 4491 75/jump-if-!= break/disp8 + 4492 # out->register = slice-to-string(s) + 4493 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register + 4494 (slice-to-string Heap %ecx %eax) + 4495 } + 4496 $parse-var-with-type:save-type: + 4497 8d/copy-address *(edi+8) 0/r32/eax # Var-type + 4498 (parse-type Heap *(ebp+0xc) %eax) + 4499 $parse-var-with-type:end: + 4500 # . reclaim locals + 4501 81 0/subop/add %esp 8/imm32 + 4502 # . restore registers + 4503 5f/pop-to-edi + 4504 5e/pop-to-esi + 4505 5b/pop-to-ebx + 4506 5a/pop-to-edx + 4507 59/pop-to-ecx + 4508 58/pop-to-eax + 4509 # . epilogue + 4510 89/<- %esp 5/r32/ebp + 4511 5d/pop-to-ebp + 4512 c3/return + 4513 + 4514 $parse-var-with-type:abort: + 4515 # error("var should have form 'name: type' in '" line "'\n") + 4516 (write-buffered Stderr "var should have form 'name: type' in '") + 4517 (flush Stderr) + 4518 (rewind-stream *(ebp+0xc)) + 4519 (write-stream 2 *(ebp+0xc)) + 4520 (write-buffered Stderr "'\n") + 4521 (flush Stderr) + 4522 # . syscall(exit, 1) + 4523 bb/copy-to-ebx 1/imm32 + 4524 b8/copy-to-eax 1/imm32/exit + 4525 cd/syscall 0x80/imm8 + 4526 # never gets here + 4527 + 4528 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle tree type-id) + 4529 # pseudocode: + 4530 # var s: slice = next-mu-token(in) + 4531 # assert s != "" + 4532 # assert s != "->" + 4533 # assert s != "{" + 4534 # assert s != "}" + 4535 # if s == ")" + 4536 # return + 4537 # out = allocate(Tree) + 4538 # if s != "(" + 4539 # HACK: if s is an int, parse and return it + 4540 # out->left-is-atom? = true + 4541 # out->value = pos-or-insert-slice(Type-id, s) + 4542 # return + 4543 # out->left = parse-type(ad, in) + 4544 # out->right = parse-type-tree(ad, in) + 4545 # + 4546 # . prologue + 4547 55/push-ebp + 4548 89/<- %ebp 4/r32/esp + 4549 # . save registers + 4550 50/push-eax + 4551 51/push-ecx + 4552 52/push-edx + 4553 # clear out + 4554 (zero-out *(ebp+0x10) *Handle-size) + 4555 # var s/ecx: slice + 4556 68/push 0/imm32 + 4557 68/push 0/imm32 + 4558 89/<- %ecx 4/r32/esp + 4559 # s = next-mu-token(in) + 4560 (next-mu-token *(ebp+0xc) %ecx) + 4561 #? (write-buffered Stderr "tok: ") + 4562 #? (write-slice-buffered Stderr %ecx) + 4563 #? (write-buffered Stderr "$\n") + 4564 #? (flush Stderr) + 4565 # assert s != "" + 4566 (slice-equal? %ecx "") # => eax + 4567 3d/compare-eax-and 0/imm32/false + 4568 0f 85/jump-if-!= $parse-type:abort/disp32 + 4569 # assert s != "{" + 4570 (slice-equal? %ecx "{") # => eax + 4571 3d/compare-eax-and 0/imm32/false + 4572 0f 85/jump-if-!= $parse-type:abort/disp32 + 4573 # assert s != "}" + 4574 (slice-equal? %ecx "}") # => eax + 4575 3d/compare-eax-and 0/imm32/false + 4576 0f 85/jump-if-!= $parse-type:abort/disp32 + 4577 # assert s != "->" + 4578 (slice-equal? %ecx "->") # => eax + 4579 3d/compare-eax-and 0/imm32/false + 4580 0f 85/jump-if-!= $parse-type:abort/disp32 + 4581 # if (s == ")") return + 4582 (slice-equal? %ecx ")") # => eax + 4583 3d/compare-eax-and 0/imm32/false + 4584 0f 85/jump-if-!= $parse-type:end/disp32 + 4585 # out = new tree + 4586 (allocate *(ebp+8) *Tree-size *(ebp+0x10)) + 4587 # var out-addr/edx: (addr tree type-id) = lookup(*out) + 4588 8b/-> *(ebp+0x10) 2/r32/edx + 4589 (lookup *edx *(edx+4)) # => eax + 4590 89/<- %edx 0/r32/eax + 4591 { + 4592 # if (s != "(") break + 4593 (slice-equal? %ecx "(") # => eax + 4594 3d/compare-eax-and 0/imm32/false + 4595 75/jump-if-!= break/disp8 + 4596 # EGREGIOUS HACK for static array sizes: if s is a number, parse it + 4597 { + 4598 $parse-type:check-for-int: + 4599 (is-hex-int? %ecx) # => eax + 4600 3d/compare-eax-and 0/imm32/false + 4601 74/jump-if-= break/disp8 + 4602 $parse-type:int: + 4603 (parse-hex-int-from-slice %ecx) # => eax + 4604 89/<- *(edx+4) 0/r32/eax # Tree-value + 4605 e9/jump $parse-type:end/disp32 + 4606 } + 4607 $parse-type:atom: + 4608 # out->left-is-atom? = true + 4609 c7 0/subop/copy *edx 1/imm32/true # Tree-is-atom + 4610 # out->value = pos-or-insert-slice(Type-id, s) + 4611 (pos-or-insert-slice Type-id %ecx) # => eax + 4612 89/<- *(edx+4) 0/r32/eax # Tree-value + 4613 e9/jump $parse-type:end/disp32 + 4614 } + 4615 $parse-type:non-atom: + 4616 # otherwise s == "(" + 4617 # out->left = parse-type(ad, in) + 4618 8d/copy-address *(edx+4) 0/r32/eax # Tree-left + 4619 (parse-type *(ebp+8) *(ebp+0xc) %eax) + 4620 # out->right = parse-type-tree(ad, in) + 4621 8d/copy-address *(edx+0xc) 0/r32/eax # Tree-right + 4622 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax) + 4623 $parse-type:end: + 4624 # . reclaim locals + 4625 81 0/subop/add %esp 8/imm32 + 4626 # . restore registers + 4627 5a/pop-to-edx + 4628 59/pop-to-ecx + 4629 58/pop-to-eax + 4630 # . epilogue + 4631 89/<- %esp 5/r32/ebp + 4632 5d/pop-to-ebp + 4633 c3/return + 4634 + 4635 $parse-type:abort: + 4636 # error("unexpected token when parsing type: '" s "'\n") + 4637 (write-buffered Stderr "unexpected token when parsing type: '") + 4638 (write-slice-buffered Stderr %ecx) + 4639 (write-buffered Stderr "'\n") + 4640 (flush Stderr) + 4641 # . syscall(exit, 1) + 4642 bb/copy-to-ebx 1/imm32 + 4643 b8/copy-to-eax 1/imm32/exit + 4644 cd/syscall 0x80/imm8 + 4645 # never gets here + 4646 + 4647 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle tree type-id) + 4648 # pseudocode: + 4649 # var tmp: (handle tree type-id) = parse-type(ad, in) + 4650 # if tmp == 0 + 4651 # return 0 + 4652 # out = allocate(Tree) + 4653 # out->left = tmp + 4654 # out->right = parse-type-tree(ad, in) + 4655 # 4656 # . prologue 4657 55/push-ebp 4658 89/<- %ebp 4/r32/esp 4659 # . save registers - 4660 51/push-ecx - 4661 52/push-edx - 4662 53/push-ebx - 4663 56/push-esi - 4664 #? (write-buffered Stderr "pos-slice: ") - 4665 #? (write-slice-buffered Stderr *(ebp+0xc)) - 4666 #? (write-buffered Stderr "\n") - 4667 #? (flush Stderr) - 4668 # esi = arr - 4669 8b/-> *(ebp+8) 6/r32/esi - 4670 # var index/ecx: int = 0 - 4671 b9/copy-to-ecx 0/imm32 - 4672 # var curr/edx: (addr (addr array byte)) = arr->data - 4673 8d/copy-address *(esi+0xc) 2/r32/edx - 4674 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] - 4675 8b/-> *esi 3/r32/ebx - 4676 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx - 4677 { - 4678 #? (write-buffered Stderr " ") - 4679 #? (print-int32-buffered Stderr %ecx) - 4680 #? (write-buffered Stderr "\n") - 4681 #? (flush Stderr) - 4682 # if (curr >= max) return -1 - 4683 39/compare %edx 3/r32/ebx - 4684 b8/copy-to-eax -1/imm32 - 4685 73/jump-if-addr>= $pos-slice:end/disp8 - 4686 # if (slice-equal?(s, *curr)) break - 4687 (slice-equal? *(ebp+0xc) *edx) # => eax - 4688 3d/compare-eax-and 0/imm32/false - 4689 75/jump-if-!= break/disp8 - 4690 # ++index - 4691 41/increment-ecx - 4692 # curr += 4 - 4693 81 0/subop/add %edx 4/imm32 - 4694 # - 4695 eb/jump loop/disp8 - 4696 } - 4697 # return index - 4698 89/<- %eax 1/r32/ecx - 4699 $pos-slice:end: - 4700 #? (write-buffered Stderr "=> ") - 4701 #? (print-int32-buffered Stderr %eax) - 4702 #? (write-buffered Stderr "\n") - 4703 # . restore registers - 4704 5e/pop-to-esi - 4705 5b/pop-to-ebx - 4706 5a/pop-to-edx - 4707 59/pop-to-ecx - 4708 # . epilogue - 4709 89/<- %esp 5/r32/ebp - 4710 5d/pop-to-ebp - 4711 c3/return - 4712 - 4713 test-parse-var-with-type: - 4714 # . prologue - 4715 55/push-ebp - 4716 89/<- %ebp 4/r32/esp - 4717 # (eax..ecx) = "x:" - 4718 b8/copy-to-eax "x:"/imm32 - 4719 8b/-> *eax 1/r32/ecx - 4720 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 4721 05/add-to-eax 4/imm32 - 4722 # var slice/ecx: slice = {eax, ecx} - 4723 51/push-ecx - 4724 50/push-eax - 4725 89/<- %ecx 4/r32/esp - 4726 # _test-input-stream contains "int" - 4727 (clear-stream _test-input-stream) - 4728 (write _test-input-stream "int") - 4729 # var v/edx: (handle var) - 4730 68/push 0/imm32 - 4731 68/push 0/imm32 - 4732 89/<- %edx 4/r32/esp - 4733 # - 4734 (parse-var-with-type %ecx _test-input-stream %edx) - 4735 # var v-addr/edx: (addr var) = lookup(v) - 4736 (lookup *edx *(edx+4)) # => eax - 4737 89/<- %edx 0/r32/eax - 4738 # check v-addr->name - 4739 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 4740 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") - 4741 # check v-addr->type - 4742 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 4743 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Tree-is-atom - 4744 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Tree-value - 4745 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Tree-right - 4746 # . epilogue - 4747 89/<- %esp 5/r32/ebp - 4748 5d/pop-to-ebp - 4749 c3/return - 4750 - 4751 test-parse-var-with-type-and-register: - 4752 # . prologue - 4753 55/push-ebp - 4754 89/<- %ebp 4/r32/esp - 4755 # (eax..ecx) = "x/eax:" - 4756 b8/copy-to-eax "x/eax:"/imm32 - 4757 8b/-> *eax 1/r32/ecx - 4758 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 4759 05/add-to-eax 4/imm32 - 4760 # var slice/ecx: slice = {eax, ecx} - 4761 51/push-ecx - 4762 50/push-eax - 4763 89/<- %ecx 4/r32/esp - 4764 # _test-input-stream contains "int" - 4765 (clear-stream _test-input-stream) - 4766 (write _test-input-stream "int") - 4767 # var v/edx: (handle var) - 4768 68/push 0/imm32 - 4769 68/push 0/imm32 - 4770 89/<- %edx 4/r32/esp - 4771 # - 4772 (parse-var-with-type %ecx _test-input-stream %edx) - 4773 # var v-addr/edx: (addr var) = lookup(v) - 4774 (lookup *edx *(edx+4)) # => eax - 4775 89/<- %edx 0/r32/eax - 4776 # check v-addr->name - 4777 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 4778 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") - 4779 # check v-addr->register - 4780 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 4781 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") - 4782 # check v-addr->type - 4783 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 4784 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Tree-is-atom - 4785 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Tree-left - 4786 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Tree-right - 4787 # . epilogue - 4788 89/<- %esp 5/r32/ebp - 4789 5d/pop-to-ebp - 4790 c3/return - 4791 - 4792 test-parse-var-with-trailing-characters: - 4793 # . prologue - 4794 55/push-ebp - 4795 89/<- %ebp 4/r32/esp - 4796 # (eax..ecx) = "x:" - 4797 b8/copy-to-eax "x:"/imm32 - 4798 8b/-> *eax 1/r32/ecx - 4799 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 4800 05/add-to-eax 4/imm32 - 4801 # var slice/ecx: slice = {eax, ecx} - 4802 51/push-ecx - 4803 50/push-eax - 4804 89/<- %ecx 4/r32/esp - 4805 # _test-input-stream contains "int," - 4806 (clear-stream _test-input-stream) - 4807 (write _test-input-stream "int,") - 4808 # var v/edx: (handle var) - 4809 68/push 0/imm32 - 4810 68/push 0/imm32 - 4811 89/<- %edx 4/r32/esp - 4812 # - 4813 (parse-var-with-type %ecx _test-input-stream %edx) - 4814 # var v-addr/edx: (addr var) = lookup(v) - 4815 (lookup *edx *(edx+4)) # => eax - 4816 89/<- %edx 0/r32/eax - 4817 # check v-addr->name - 4818 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 4819 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") - 4820 # check v-addr->register - 4821 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register - 4822 # check v-addr->type - 4823 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 4824 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Tree-is-atom - 4825 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Tree-left - 4826 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Tree-right - 4827 # . epilogue - 4828 89/<- %esp 5/r32/ebp - 4829 5d/pop-to-ebp - 4830 c3/return - 4831 - 4832 test-parse-var-with-register-and-trailing-characters: - 4833 # . prologue - 4834 55/push-ebp - 4835 89/<- %ebp 4/r32/esp - 4836 # (eax..ecx) = "x/eax:" - 4837 b8/copy-to-eax "x/eax:"/imm32 - 4838 8b/-> *eax 1/r32/ecx - 4839 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 4840 05/add-to-eax 4/imm32 - 4841 # var slice/ecx: slice = {eax, ecx} - 4842 51/push-ecx - 4843 50/push-eax - 4844 89/<- %ecx 4/r32/esp - 4845 # _test-input-stream contains "int," - 4846 (clear-stream _test-input-stream) - 4847 (write _test-input-stream "int,") - 4848 # var v/edx: (handle var) - 4849 68/push 0/imm32 - 4850 68/push 0/imm32 - 4851 89/<- %edx 4/r32/esp - 4852 # - 4853 (parse-var-with-type %ecx _test-input-stream %edx) - 4854 # var v-addr/edx: (addr var) = lookup(v) - 4855 (lookup *edx *(edx+4)) # => eax - 4856 89/<- %edx 0/r32/eax - 4857 # check v-addr->name - 4858 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 4859 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") - 4860 # check v-addr->register - 4861 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 4862 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") - 4863 # check v-addr->type - 4864 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 4865 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Tree-is-atom - 4866 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Tree-left - 4867 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Tree-right - 4868 # . epilogue - 4869 89/<- %esp 5/r32/ebp - 4870 5d/pop-to-ebp - 4871 c3/return - 4872 - 4873 test-parse-var-with-compound-type: - 4874 # . prologue - 4875 55/push-ebp - 4876 89/<- %ebp 4/r32/esp - 4877 # (eax..ecx) = "x:" - 4878 b8/copy-to-eax "x:"/imm32 - 4879 8b/-> *eax 1/r32/ecx - 4880 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 4881 05/add-to-eax 4/imm32 - 4882 # var slice/ecx: slice = {eax, ecx} - 4883 51/push-ecx - 4884 50/push-eax - 4885 89/<- %ecx 4/r32/esp - 4886 # _test-input-stream contains "(addr int)" - 4887 (clear-stream _test-input-stream) - 4888 (write _test-input-stream "(addr int)") - 4889 # var v/edx: (handle var) - 4890 68/push 0/imm32 - 4891 68/push 0/imm32 - 4892 89/<- %edx 4/r32/esp - 4893 # - 4894 (parse-var-with-type %ecx _test-input-stream %edx) - 4895 # var v-addr/edx: (addr var) = lookup(v) - 4896 (lookup *edx *(edx+4)) # => eax - 4897 89/<- %edx 0/r32/eax - 4898 # check v-addr->name - 4899 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 4900 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") - 4901 # check v-addr->register - 4902 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register - 4903 # - check v-addr->type - 4904 # var type/edx: (addr tree type-id) = var->type - 4905 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 4906 89/<- %edx 0/r32/eax - 4907 # type is a non-atom - 4908 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Tree-is-atom - 4909 # type->left == atom(addr) - 4910 (lookup *(edx+4) *(edx+8)) # Tree-left Tree-left => eax - 4911 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Tree-is-atom - 4912 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Tree-value - 4913 # type->right->left == atom(int) - 4914 (lookup *(edx+0xc) *(edx+0x10)) # Tree-right Tree-right => eax - 4915 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax - 4916 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Tree-is-atom - 4917 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Tree-value - 4918 # type->right->right == null - 4919 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Tree-right - 4920 # . epilogue - 4921 89/<- %esp 5/r32/ebp - 4922 5d/pop-to-ebp - 4923 c3/return - 4924 - 4925 # identifier starts with a letter or '$' or '_' - 4926 # no constraints at the moment on later letters - 4927 # all we really want to do so far is exclude '{', '}' and '->' - 4928 is-identifier?: # in: (addr slice) -> result/eax: boolean - 4929 # . prologue - 4930 55/push-ebp - 4931 89/<- %ebp 4/r32/esp - 4932 # if (slice-empty?(in)) return false - 4933 (slice-empty? *(ebp+8)) # => eax - 4934 3d/compare-eax-and 0/imm32/false - 4935 75/jump-if-!= $is-identifier?:false/disp8 - 4936 # var c/eax: byte = *in->start - 4937 8b/-> *(ebp+8) 0/r32/eax - 4938 8b/-> *eax 0/r32/eax - 4939 8a/copy-byte *eax 0/r32/AL - 4940 81 4/subop/and %eax 0xff/imm32 - 4941 # if (c == '$') return true - 4942 3d/compare-eax-and 0x24/imm32/$ - 4943 74/jump-if-= $is-identifier?:true/disp8 - 4944 # if (c == '_') return true - 4945 3d/compare-eax-and 0x5f/imm32/_ - 4946 74/jump-if-= $is-identifier?:true/disp8 - 4947 # drop case - 4948 25/and-eax-with 0x5f/imm32 - 4949 # if (c < 'A') return false - 4950 3d/compare-eax-and 0x41/imm32/A - 4951 7c/jump-if-< $is-identifier?:false/disp8 - 4952 # if (c > 'Z') return false - 4953 3d/compare-eax-and 0x5a/imm32/Z - 4954 7f/jump-if-> $is-identifier?:false/disp8 - 4955 # otherwise return true - 4956 $is-identifier?:true: - 4957 b8/copy-to-eax 1/imm32/true - 4958 eb/jump $is-identifier?:end/disp8 - 4959 $is-identifier?:false: - 4960 b8/copy-to-eax 0/imm32/false - 4961 $is-identifier?:end: - 4962 # . epilogue - 4963 89/<- %esp 5/r32/ebp - 4964 5d/pop-to-ebp - 4965 c3/return - 4966 - 4967 test-is-identifier-dollar: - 4968 # . prologue - 4969 55/push-ebp - 4970 89/<- %ebp 4/r32/esp - 4971 # (eax..ecx) = "$a" - 4972 b8/copy-to-eax "$a"/imm32 - 4973 8b/-> *eax 1/r32/ecx - 4974 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 4975 05/add-to-eax 4/imm32 - 4976 # var slice/ecx: slice = {eax, ecx} - 4977 51/push-ecx - 4978 50/push-eax - 4979 89/<- %ecx 4/r32/esp - 4980 # - 4981 (is-identifier? %ecx) - 4982 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") - 4983 # . epilogue - 4984 89/<- %esp 5/r32/ebp - 4985 5d/pop-to-ebp - 4986 c3/return - 4987 - 4988 test-is-identifier-underscore: - 4989 # . prologue - 4990 55/push-ebp - 4991 89/<- %ebp 4/r32/esp - 4992 # (eax..ecx) = "_a" - 4993 b8/copy-to-eax "_a"/imm32 - 4994 8b/-> *eax 1/r32/ecx - 4995 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 4996 05/add-to-eax 4/imm32 - 4997 # var slice/ecx: slice = {eax, ecx} - 4998 51/push-ecx - 4999 50/push-eax - 5000 89/<- %ecx 4/r32/esp - 5001 # - 5002 (is-identifier? %ecx) - 5003 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") - 5004 # . epilogue - 5005 89/<- %esp 5/r32/ebp - 5006 5d/pop-to-ebp - 5007 c3/return - 5008 - 5009 test-is-identifier-a: - 5010 # . prologue - 5011 55/push-ebp - 5012 89/<- %ebp 4/r32/esp - 5013 # (eax..ecx) = "a$" - 5014 b8/copy-to-eax "a$"/imm32 - 5015 8b/-> *eax 1/r32/ecx - 5016 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5017 05/add-to-eax 4/imm32 - 5018 # var slice/ecx: slice = {eax, ecx} - 5019 51/push-ecx - 5020 50/push-eax - 5021 89/<- %ecx 4/r32/esp - 5022 # - 5023 (is-identifier? %ecx) - 5024 (check-ints-equal %eax 1 "F - test-is-identifier-a") - 5025 # . epilogue - 5026 89/<- %esp 5/r32/ebp - 5027 5d/pop-to-ebp - 5028 c3/return - 5029 - 5030 test-is-identifier-z: - 5031 # . prologue - 5032 55/push-ebp - 5033 89/<- %ebp 4/r32/esp - 5034 # (eax..ecx) = "z$" - 5035 b8/copy-to-eax "z$"/imm32 - 5036 8b/-> *eax 1/r32/ecx - 5037 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5038 05/add-to-eax 4/imm32 - 5039 # var slice/ecx: slice = {eax, ecx} - 5040 51/push-ecx - 5041 50/push-eax - 5042 89/<- %ecx 4/r32/esp - 5043 # - 5044 (is-identifier? %ecx) - 5045 (check-ints-equal %eax 1 "F - test-is-identifier-z") - 5046 # . epilogue - 5047 89/<- %esp 5/r32/ebp - 5048 5d/pop-to-ebp - 5049 c3/return - 5050 - 5051 test-is-identifier-A: - 5052 # . prologue - 5053 55/push-ebp - 5054 89/<- %ebp 4/r32/esp - 5055 # (eax..ecx) = "A$" - 5056 b8/copy-to-eax "A$"/imm32 - 5057 8b/-> *eax 1/r32/ecx - 5058 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5059 05/add-to-eax 4/imm32 - 5060 # var slice/ecx: slice = {eax, ecx} - 5061 51/push-ecx - 5062 50/push-eax - 5063 89/<- %ecx 4/r32/esp - 5064 # - 5065 (is-identifier? %ecx) - 5066 (check-ints-equal %eax 1 "F - test-is-identifier-A") - 5067 # . epilogue - 5068 89/<- %esp 5/r32/ebp - 5069 5d/pop-to-ebp - 5070 c3/return - 5071 - 5072 test-is-identifier-Z: - 5073 # . prologue - 5074 55/push-ebp - 5075 89/<- %ebp 4/r32/esp - 5076 # (eax..ecx) = "Z$" - 5077 b8/copy-to-eax "Z$"/imm32 - 5078 8b/-> *eax 1/r32/ecx - 5079 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5080 05/add-to-eax 4/imm32 - 5081 # var slice/ecx: slice = {eax, ecx} - 5082 51/push-ecx - 5083 50/push-eax - 5084 89/<- %ecx 4/r32/esp - 5085 # - 5086 (is-identifier? %ecx) - 5087 (check-ints-equal %eax 1 "F - test-is-identifier-Z") - 5088 # . epilogue - 5089 89/<- %esp 5/r32/ebp - 5090 5d/pop-to-ebp - 5091 c3/return - 5092 - 5093 test-is-identifier-at: - 5094 # character before 'A' is invalid - 5095 # . prologue - 5096 55/push-ebp - 5097 89/<- %ebp 4/r32/esp - 5098 # (eax..ecx) = "@a" - 5099 b8/copy-to-eax "@a"/imm32 - 5100 8b/-> *eax 1/r32/ecx - 5101 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5102 05/add-to-eax 4/imm32 - 5103 # var slice/ecx: slice = {eax, ecx} - 5104 51/push-ecx - 5105 50/push-eax - 5106 89/<- %ecx 4/r32/esp - 5107 # - 5108 (is-identifier? %ecx) - 5109 (check-ints-equal %eax 0 "F - test-is-identifier-@") - 5110 # . epilogue - 5111 89/<- %esp 5/r32/ebp - 5112 5d/pop-to-ebp - 5113 c3/return - 5114 - 5115 test-is-identifier-square-bracket: - 5116 # character after 'Z' is invalid + 4660 50/push-eax + 4661 51/push-ecx + 4662 52/push-edx + 4663 # + 4664 (zero-out *(ebp+0x10) *Handle-size) + 4665 # var tmp/ecx: (handle tree type-id) + 4666 68/push 0/imm32 + 4667 68/push 0/imm32 + 4668 89/<- %ecx 4/r32/esp + 4669 # tmp = parse-type(ad, in) + 4670 (parse-type *(ebp+8) *(ebp+0xc) %ecx) + 4671 # if (tmp == 0) return + 4672 81 7/subop/compare *ecx 0/imm32 + 4673 74/jump-if-= $parse-type-tree:end/disp8 + 4674 # out = new tree + 4675 (allocate *(ebp+8) *Tree-size *(ebp+0x10)) + 4676 # var out-addr/edx: (addr tree) = lookup(*out) + 4677 8b/-> *(ebp+0x10) 2/r32/edx + 4678 (lookup *edx *(edx+4)) # => eax + 4679 89/<- %edx 0/r32/eax + 4680 # out->left = tmp + 4681 8b/-> *ecx 0/r32/eax + 4682 89/<- *(edx+4) 0/r32/eax # Tree-left + 4683 8b/-> *(ecx+4) 0/r32/eax + 4684 89/<- *(edx+8) 0/r32/eax # Tree-left + 4685 # out->right = parse-type-tree(ad, in) + 4686 8d/copy-address *(edx+0xc) 0/r32/eax # Tree-right + 4687 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax) + 4688 $parse-type-tree:end: + 4689 # . reclaim locals + 4690 81 0/subop/add %esp 8/imm32 + 4691 # . restore registers + 4692 5a/pop-to-edx + 4693 59/pop-to-ecx + 4694 58/pop-to-eax + 4695 # . epilogue + 4696 89/<- %esp 5/r32/ebp + 4697 5d/pop-to-ebp + 4698 c3/return + 4699 + 4700 next-mu-token: # in: (addr stream byte), out: (addr slice) + 4701 # pseudocode: + 4702 # start: + 4703 # skip-chars-matching-whitespace(in) + 4704 # if in->read >= in->write # end of in + 4705 # out = {0, 0} + 4706 # return + 4707 # out->start = &in->data[in->read] + 4708 # var curr-byte/eax: byte = in->data[in->read] + 4709 # if curr->byte == ',' # comment token + 4710 # ++in->read + 4711 # goto start + 4712 # if curr-byte == '#' # comment + 4713 # goto done # treat as eof + 4714 # if curr-byte == '"' # string literal + 4715 # skip-string(in) + 4716 # goto done # no metadata + 4717 # if curr-byte == '(' + 4718 # ++in->read + 4719 # goto done + 4720 # if curr-byte == ')' + 4721 # ++in->read + 4722 # goto done + 4723 # # read a word + 4724 # while true + 4725 # if in->read >= in->write + 4726 # break + 4727 # curr-byte = in->data[in->read] + 4728 # if curr-byte == ' ' + 4729 # break + 4730 # if curr-byte == '\r' + 4731 # break + 4732 # if curr-byte == '\n' + 4733 # break + 4734 # if curr-byte == '(' + 4735 # break + 4736 # if curr-byte == ')' + 4737 # break + 4738 # if curr-byte == ',' + 4739 # break + 4740 # ++in->read + 4741 # done: + 4742 # out->end = &in->data[in->read] + 4743 # + 4744 # . prologue + 4745 55/push-ebp + 4746 89/<- %ebp 4/r32/esp + 4747 # . save registers + 4748 50/push-eax + 4749 51/push-ecx + 4750 56/push-esi + 4751 57/push-edi + 4752 # esi = in + 4753 8b/-> *(ebp+8) 6/r32/esi + 4754 # edi = out + 4755 8b/-> *(ebp+0xc) 7/r32/edi + 4756 $next-mu-token:start: + 4757 (skip-chars-matching-whitespace %esi) + 4758 $next-mu-token:check0: + 4759 # if (in->read >= in->write) return out = {0, 0} + 4760 # . ecx = in->read + 4761 8b/-> *(esi+4) 1/r32/ecx + 4762 # . if (ecx >= in->write) return out = {0, 0} + 4763 3b/compare<- *esi 1/r32/ecx + 4764 c7 0/subop/copy *edi 0/imm32 + 4765 c7 0/subop/copy *(edi+4) 0/imm32 + 4766 0f 8d/jump-if->= $next-mu-token:end/disp32 + 4767 # out->start = &in->data[in->read] + 4768 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 4769 89/<- *edi 0/r32/eax + 4770 # var curr-byte/eax: byte = in->data[in->read] + 4771 31/xor-with %eax 0/r32/eax + 4772 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 4773 { + 4774 $next-mu-token:check-for-comma: + 4775 # if (curr-byte != ',') break + 4776 3d/compare-eax-and 0x2c/imm32/comma + 4777 75/jump-if-!= break/disp8 + 4778 # ++in->read + 4779 ff 0/subop/increment *(esi+4) + 4780 # restart + 4781 e9/jump $next-mu-token:start/disp32 + 4782 } + 4783 { + 4784 $next-mu-token:check-for-comment: + 4785 # if (curr-byte != '#') break + 4786 3d/compare-eax-and 0x23/imm32/pound + 4787 75/jump-if-!= break/disp8 + 4788 # return eof + 4789 e9/jump $next-mu-token:done/disp32 + 4790 } + 4791 { + 4792 $next-mu-token:check-for-string-literal: + 4793 # if (curr-byte != '"') break + 4794 3d/compare-eax-and 0x22/imm32/dquote + 4795 75/jump-if-!= break/disp8 + 4796 (skip-string %esi) + 4797 # return + 4798 e9/jump $next-mu-token:done/disp32 + 4799 } + 4800 { + 4801 $next-mu-token:check-for-open-paren: + 4802 # if (curr-byte != '(') break + 4803 3d/compare-eax-and 0x28/imm32/open-paren + 4804 75/jump-if-!= break/disp8 + 4805 # ++in->read + 4806 ff 0/subop/increment *(esi+4) + 4807 # return + 4808 e9/jump $next-mu-token:done/disp32 + 4809 } + 4810 { + 4811 $next-mu-token:check-for-close-paren: + 4812 # if (curr-byte != ')') break + 4813 3d/compare-eax-and 0x29/imm32/close-paren + 4814 75/jump-if-!= break/disp8 + 4815 # ++in->read + 4816 ff 0/subop/increment *(esi+4) + 4817 # return + 4818 e9/jump $next-mu-token:done/disp32 + 4819 } + 4820 { + 4821 $next-mu-token:regular-word-without-metadata: + 4822 # if (in->read >= in->write) break + 4823 # . ecx = in->read + 4824 8b/-> *(esi+4) 1/r32/ecx + 4825 # . if (ecx >= in->write) break + 4826 3b/compare<- *esi 1/r32/ecx + 4827 7d/jump-if->= break/disp8 + 4828 # var c/eax: byte = in->data[in->read] + 4829 31/xor-with %eax 0/r32/eax + 4830 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 4831 # if (c == ' ') break + 4832 3d/compare-eax-and 0x20/imm32/space + 4833 74/jump-if-= break/disp8 + 4834 # if (c == '\r') break + 4835 3d/compare-eax-and 0xd/imm32/carriage-return + 4836 74/jump-if-= break/disp8 + 4837 # if (c == '\n') break + 4838 3d/compare-eax-and 0xa/imm32/newline + 4839 74/jump-if-= break/disp8 + 4840 # if (c == '(') break + 4841 3d/compare-eax-and 0x28/imm32/open-paren + 4842 0f 84/jump-if-= break/disp32 + 4843 # if (c == ')') break + 4844 3d/compare-eax-and 0x29/imm32/close-paren + 4845 0f 84/jump-if-= break/disp32 + 4846 # if (c == ',') break + 4847 3d/compare-eax-and 0x2c/imm32/comma + 4848 0f 84/jump-if-= break/disp32 + 4849 # ++in->read + 4850 ff 0/subop/increment *(esi+4) + 4851 # + 4852 e9/jump loop/disp32 + 4853 } + 4854 $next-mu-token:done: + 4855 # out->end = &in->data[in->read] + 4856 8b/-> *(esi+4) 1/r32/ecx + 4857 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 4858 89/<- *(edi+4) 0/r32/eax + 4859 $next-mu-token:end: + 4860 # . restore registers + 4861 5f/pop-to-edi + 4862 5e/pop-to-esi + 4863 59/pop-to-ecx + 4864 58/pop-to-eax + 4865 # . epilogue + 4866 89/<- %esp 5/r32/ebp + 4867 5d/pop-to-ebp + 4868 c3/return + 4869 + 4870 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 4871 # . prologue + 4872 55/push-ebp + 4873 89/<- %ebp 4/r32/esp + 4874 # if (pos-slice(arr, s) != -1) return it + 4875 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax + 4876 3d/compare-eax-and -1/imm32 + 4877 75/jump-if-!= $pos-or-insert-slice:end/disp8 + 4878 $pos-or-insert-slice:insert: + 4879 # var s2/eax: (handle array byte) + 4880 68/push 0/imm32 + 4881 68/push 0/imm32 + 4882 89/<- %eax 4/r32/esp + 4883 (slice-to-string Heap *(ebp+0xc) %eax) + 4884 # throw away alloc-id + 4885 (lookup *eax *(eax+4)) # => eax + 4886 (write-int *(ebp+8) %eax) + 4887 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax + 4888 $pos-or-insert-slice:end: + 4889 # . reclaim locals + 4890 81 0/subop/add %esp 8/imm32 + 4891 # . epilogue + 4892 89/<- %esp 5/r32/ebp + 4893 5d/pop-to-ebp + 4894 c3/return + 4895 + 4896 # return the index in an array of strings matching 's', -1 if not found + 4897 # index is denominated in elements, not bytes + 4898 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 4899 # . prologue + 4900 55/push-ebp + 4901 89/<- %ebp 4/r32/esp + 4902 # . save registers + 4903 51/push-ecx + 4904 52/push-edx + 4905 53/push-ebx + 4906 56/push-esi + 4907 #? (write-buffered Stderr "pos-slice: ") + 4908 #? (write-slice-buffered Stderr *(ebp+0xc)) + 4909 #? (write-buffered Stderr "\n") + 4910 #? (flush Stderr) + 4911 # esi = arr + 4912 8b/-> *(ebp+8) 6/r32/esi + 4913 # var index/ecx: int = 0 + 4914 b9/copy-to-ecx 0/imm32 + 4915 # var curr/edx: (addr (addr array byte)) = arr->data + 4916 8d/copy-address *(esi+0xc) 2/r32/edx + 4917 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] + 4918 8b/-> *esi 3/r32/ebx + 4919 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx + 4920 { + 4921 #? (write-buffered Stderr " ") + 4922 #? (print-int32-buffered Stderr %ecx) + 4923 #? (write-buffered Stderr "\n") + 4924 #? (flush Stderr) + 4925 # if (curr >= max) return -1 + 4926 39/compare %edx 3/r32/ebx + 4927 b8/copy-to-eax -1/imm32 + 4928 73/jump-if-addr>= $pos-slice:end/disp8 + 4929 # if (slice-equal?(s, *curr)) break + 4930 (slice-equal? *(ebp+0xc) *edx) # => eax + 4931 3d/compare-eax-and 0/imm32/false + 4932 75/jump-if-!= break/disp8 + 4933 # ++index + 4934 41/increment-ecx + 4935 # curr += 4 + 4936 81 0/subop/add %edx 4/imm32 + 4937 # + 4938 eb/jump loop/disp8 + 4939 } + 4940 # return index + 4941 89/<- %eax 1/r32/ecx + 4942 $pos-slice:end: + 4943 #? (write-buffered Stderr "=> ") + 4944 #? (print-int32-buffered Stderr %eax) + 4945 #? (write-buffered Stderr "\n") + 4946 # . restore registers + 4947 5e/pop-to-esi + 4948 5b/pop-to-ebx + 4949 5a/pop-to-edx + 4950 59/pop-to-ecx + 4951 # . epilogue + 4952 89/<- %esp 5/r32/ebp + 4953 5d/pop-to-ebp + 4954 c3/return + 4955 + 4956 test-parse-var-with-type: + 4957 # . prologue + 4958 55/push-ebp + 4959 89/<- %ebp 4/r32/esp + 4960 # (eax..ecx) = "x:" + 4961 b8/copy-to-eax "x:"/imm32 + 4962 8b/-> *eax 1/r32/ecx + 4963 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 4964 05/add-to-eax 4/imm32 + 4965 # var slice/ecx: slice = {eax, ecx} + 4966 51/push-ecx + 4967 50/push-eax + 4968 89/<- %ecx 4/r32/esp + 4969 # _test-input-stream contains "int" + 4970 (clear-stream _test-input-stream) + 4971 (write _test-input-stream "int") + 4972 # var v/edx: (handle var) + 4973 68/push 0/imm32 + 4974 68/push 0/imm32 + 4975 89/<- %edx 4/r32/esp + 4976 # + 4977 (parse-var-with-type %ecx _test-input-stream %edx) + 4978 # var v-addr/edx: (addr var) = lookup(v) + 4979 (lookup *edx *(edx+4)) # => eax + 4980 89/<- %edx 0/r32/eax + 4981 # check v-addr->name + 4982 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 4983 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") + 4984 # check v-addr->type + 4985 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 4986 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Tree-is-atom + 4987 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Tree-value + 4988 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Tree-right + 4989 # . epilogue + 4990 89/<- %esp 5/r32/ebp + 4991 5d/pop-to-ebp + 4992 c3/return + 4993 + 4994 test-parse-var-with-type-and-register: + 4995 # . prologue + 4996 55/push-ebp + 4997 89/<- %ebp 4/r32/esp + 4998 # (eax..ecx) = "x/eax:" + 4999 b8/copy-to-eax "x/eax:"/imm32 + 5000 8b/-> *eax 1/r32/ecx + 5001 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5002 05/add-to-eax 4/imm32 + 5003 # var slice/ecx: slice = {eax, ecx} + 5004 51/push-ecx + 5005 50/push-eax + 5006 89/<- %ecx 4/r32/esp + 5007 # _test-input-stream contains "int" + 5008 (clear-stream _test-input-stream) + 5009 (write _test-input-stream "int") + 5010 # var v/edx: (handle var) + 5011 68/push 0/imm32 + 5012 68/push 0/imm32 + 5013 89/<- %edx 4/r32/esp + 5014 # + 5015 (parse-var-with-type %ecx _test-input-stream %edx) + 5016 # var v-addr/edx: (addr var) = lookup(v) + 5017 (lookup *edx *(edx+4)) # => eax + 5018 89/<- %edx 0/r32/eax + 5019 # check v-addr->name + 5020 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 5021 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") + 5022 # check v-addr->register + 5023 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 5024 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") + 5025 # check v-addr->type + 5026 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 5027 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Tree-is-atom + 5028 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Tree-left + 5029 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Tree-right + 5030 # . epilogue + 5031 89/<- %esp 5/r32/ebp + 5032 5d/pop-to-ebp + 5033 c3/return + 5034 + 5035 test-parse-var-with-trailing-characters: + 5036 # . prologue + 5037 55/push-ebp + 5038 89/<- %ebp 4/r32/esp + 5039 # (eax..ecx) = "x:" + 5040 b8/copy-to-eax "x:"/imm32 + 5041 8b/-> *eax 1/r32/ecx + 5042 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5043 05/add-to-eax 4/imm32 + 5044 # var slice/ecx: slice = {eax, ecx} + 5045 51/push-ecx + 5046 50/push-eax + 5047 89/<- %ecx 4/r32/esp + 5048 # _test-input-stream contains "int," + 5049 (clear-stream _test-input-stream) + 5050 (write _test-input-stream "int,") + 5051 # var v/edx: (handle var) + 5052 68/push 0/imm32 + 5053 68/push 0/imm32 + 5054 89/<- %edx 4/r32/esp + 5055 # + 5056 (parse-var-with-type %ecx _test-input-stream %edx) + 5057 # var v-addr/edx: (addr var) = lookup(v) + 5058 (lookup *edx *(edx+4)) # => eax + 5059 89/<- %edx 0/r32/eax + 5060 # check v-addr->name + 5061 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 5062 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") + 5063 # check v-addr->register + 5064 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register + 5065 # check v-addr->type + 5066 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 5067 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Tree-is-atom + 5068 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Tree-left + 5069 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Tree-right + 5070 # . epilogue + 5071 89/<- %esp 5/r32/ebp + 5072 5d/pop-to-ebp + 5073 c3/return + 5074 + 5075 test-parse-var-with-register-and-trailing-characters: + 5076 # . prologue + 5077 55/push-ebp + 5078 89/<- %ebp 4/r32/esp + 5079 # (eax..ecx) = "x/eax:" + 5080 b8/copy-to-eax "x/eax:"/imm32 + 5081 8b/-> *eax 1/r32/ecx + 5082 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5083 05/add-to-eax 4/imm32 + 5084 # var slice/ecx: slice = {eax, ecx} + 5085 51/push-ecx + 5086 50/push-eax + 5087 89/<- %ecx 4/r32/esp + 5088 # _test-input-stream contains "int," + 5089 (clear-stream _test-input-stream) + 5090 (write _test-input-stream "int,") + 5091 # var v/edx: (handle var) + 5092 68/push 0/imm32 + 5093 68/push 0/imm32 + 5094 89/<- %edx 4/r32/esp + 5095 # + 5096 (parse-var-with-type %ecx _test-input-stream %edx) + 5097 # var v-addr/edx: (addr var) = lookup(v) + 5098 (lookup *edx *(edx+4)) # => eax + 5099 89/<- %edx 0/r32/eax + 5100 # check v-addr->name + 5101 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 5102 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") + 5103 # check v-addr->register + 5104 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 5105 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") + 5106 # check v-addr->type + 5107 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 5108 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Tree-is-atom + 5109 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Tree-left + 5110 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Tree-right + 5111 # . epilogue + 5112 89/<- %esp 5/r32/ebp + 5113 5d/pop-to-ebp + 5114 c3/return + 5115 + 5116 test-parse-var-with-compound-type: 5117 # . prologue 5118 55/push-ebp 5119 89/<- %ebp 4/r32/esp - 5120 # (eax..ecx) = "[a" - 5121 b8/copy-to-eax "[a"/imm32 + 5120 # (eax..ecx) = "x:" + 5121 b8/copy-to-eax "x:"/imm32 5122 8b/-> *eax 1/r32/ecx 5123 8d/copy-address *(eax+ecx+4) 1/r32/ecx 5124 05/add-to-eax 4/imm32 @@ -4888,10281 +4868,10725 @@ if ('onhashchange' in window) { 5126 51/push-ecx 5127 50/push-eax 5128 89/<- %ecx 4/r32/esp - 5129 # - 5130 (is-identifier? %ecx) - 5131 (check-ints-equal %eax 0 "F - test-is-identifier-@") - 5132 # . epilogue - 5133 89/<- %esp 5/r32/ebp - 5134 5d/pop-to-ebp - 5135 c3/return - 5136 - 5137 test-is-identifier-backtick: - 5138 # character before 'a' is invalid - 5139 # . prologue - 5140 55/push-ebp - 5141 89/<- %ebp 4/r32/esp - 5142 # (eax..ecx) = "`a" - 5143 b8/copy-to-eax "`a"/imm32 - 5144 8b/-> *eax 1/r32/ecx - 5145 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5146 05/add-to-eax 4/imm32 - 5147 # var slice/ecx: slice = {eax, ecx} - 5148 51/push-ecx - 5149 50/push-eax - 5150 89/<- %ecx 4/r32/esp - 5151 # - 5152 (is-identifier? %ecx) - 5153 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") - 5154 # . epilogue - 5155 89/<- %esp 5/r32/ebp - 5156 5d/pop-to-ebp - 5157 c3/return - 5158 - 5159 test-is-identifier-curly-brace-open: - 5160 # character after 'z' is invalid; also used for blocks - 5161 # . prologue - 5162 55/push-ebp - 5163 89/<- %ebp 4/r32/esp - 5164 # (eax..ecx) = "{a" - 5165 b8/copy-to-eax "{a"/imm32 - 5166 8b/-> *eax 1/r32/ecx - 5167 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5168 05/add-to-eax 4/imm32 - 5169 # var slice/ecx: slice = {eax, ecx} - 5170 51/push-ecx - 5171 50/push-eax - 5172 89/<- %ecx 4/r32/esp - 5173 # - 5174 (is-identifier? %ecx) - 5175 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") - 5176 # . epilogue - 5177 89/<- %esp 5/r32/ebp - 5178 5d/pop-to-ebp - 5179 c3/return - 5180 - 5181 test-is-identifier-curly-brace-close: - 5182 # . prologue - 5183 55/push-ebp - 5184 89/<- %ebp 4/r32/esp - 5185 # (eax..ecx) = "}a" - 5186 b8/copy-to-eax "}a"/imm32 - 5187 8b/-> *eax 1/r32/ecx - 5188 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5189 05/add-to-eax 4/imm32 - 5190 # var slice/ecx: slice = {eax, ecx} - 5191 51/push-ecx - 5192 50/push-eax - 5193 89/<- %ecx 4/r32/esp - 5194 # - 5195 (is-identifier? %ecx) - 5196 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") - 5197 # . epilogue - 5198 89/<- %esp 5/r32/ebp - 5199 5d/pop-to-ebp - 5200 c3/return - 5201 - 5202 test-is-identifier-hyphen: - 5203 # disallow leading '-' since '->' has special meaning - 5204 # . prologue - 5205 55/push-ebp - 5206 89/<- %ebp 4/r32/esp - 5207 # (eax..ecx) = "-a" - 5208 b8/copy-to-eax "-a"/imm32 - 5209 8b/-> *eax 1/r32/ecx - 5210 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 5211 05/add-to-eax 4/imm32 - 5212 # var slice/ecx: slice = {eax, ecx} - 5213 51/push-ecx - 5214 50/push-eax - 5215 89/<- %ecx 4/r32/esp - 5216 # - 5217 (is-identifier? %ecx) - 5218 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") - 5219 # . epilogue - 5220 89/<- %esp 5/r32/ebp - 5221 5d/pop-to-ebp - 5222 c3/return - 5223 - 5224 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack (handle var)) - 5225 # . prologue - 5226 55/push-ebp - 5227 89/<- %ebp 4/r32/esp - 5228 # . save registers - 5229 50/push-eax - 5230 56/push-esi - 5231 57/push-edi - 5232 # esi = in - 5233 8b/-> *(ebp+8) 6/r32/esi - 5234 # edi = out - 5235 8b/-> *(ebp+0xc) 7/r32/edi - 5236 # parse-mu-block(in, vars, out, out->body) - 5237 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body - 5238 (parse-mu-block %esi *(ebp+0x10) %edi %eax) - 5239 $populate-mu-function-body:end: - 5240 # . restore registers - 5241 5f/pop-to-edi - 5242 5e/pop-to-esi - 5243 58/pop-to-eax - 5244 # . epilogue - 5245 89/<- %esp 5/r32/ebp - 5246 5d/pop-to-ebp - 5247 c3/return - 5248 - 5249 # parses a block, assuming that the leading '{' has already been read by the caller - 5250 parse-mu-block: # in: (addr buffered-file), vars: (addr stack (handle var)), fn: (addr function), out: (addr handle block) - 5251 # pseudocode: - 5252 # var line: (stream byte 512) - 5253 # var word-slice: slice - 5254 # allocate(Heap, Stmt-size, out) - 5255 # var out-addr: (addr block) = lookup(*out) - 5256 # out-addr->tag = 0/block - 5257 # out-addr->var = some unique name - 5258 # push(vars, out-addr->var) - 5259 # while true # line loop - 5260 # clear-stream(line) - 5261 # read-line-buffered(in, line) - 5262 # if (line->write == 0) break # end of file - 5263 # word-slice = next-mu-token(line) - 5264 # if slice-empty?(word-slice) # end of line - 5265 # continue - 5266 # else if slice-starts-with?(word-slice, "#") - 5267 # continue - 5268 # else if slice-equal?(word-slice, "{") - 5269 # assert(no-tokens-in(line)) - 5270 # block = parse-mu-block(in, vars, fn) - 5271 # append-to-block(out-addr, block) - 5272 # else if slice-equal?(word-slice, "}") - 5273 # break - 5274 # else if slice-ends-with?(word-slice, ":") - 5275 # # TODO: error-check the rest of 'line' - 5276 # --word-slice->end to skip ':' - 5277 # named-block = parse-mu-named-block(word-slice, in, vars, fn) - 5278 # append-to-block(out-addr, named-block) - 5279 # else if slice-equal?(word-slice, "var") - 5280 # var-def = parse-mu-var-def(line, vars) - 5281 # append-to-block(out-addr, var-def) - 5282 # else - 5283 # stmt = parse-mu-stmt(line, vars, fn) - 5284 # append-to-block(out-addr, stmt) - 5285 # pop(vars) + 5129 # _test-input-stream contains "(addr int)" + 5130 (clear-stream _test-input-stream) + 5131 (write _test-input-stream "(addr int)") + 5132 # var v/edx: (handle var) + 5133 68/push 0/imm32 + 5134 68/push 0/imm32 + 5135 89/<- %edx 4/r32/esp + 5136 # + 5137 (parse-var-with-type %ecx _test-input-stream %edx) + 5138 # var v-addr/edx: (addr var) = lookup(v) + 5139 (lookup *edx *(edx+4)) # => eax + 5140 89/<- %edx 0/r32/eax + 5141 # check v-addr->name + 5142 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 5143 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") + 5144 # check v-addr->register + 5145 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register + 5146 # - check v-addr->type + 5147 # var type/edx: (addr tree type-id) = var->type + 5148 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 5149 89/<- %edx 0/r32/eax + 5150 # type is a non-atom + 5151 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Tree-is-atom + 5152 # type->left == atom(addr) + 5153 (lookup *(edx+4) *(edx+8)) # Tree-left Tree-left => eax + 5154 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Tree-is-atom + 5155 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Tree-value + 5156 # type->right->left == atom(int) + 5157 (lookup *(edx+0xc) *(edx+0x10)) # Tree-right Tree-right => eax + 5158 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax + 5159 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Tree-is-atom + 5160 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Tree-value + 5161 # type->right->right == null + 5162 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Tree-right + 5163 # . epilogue + 5164 89/<- %esp 5/r32/ebp + 5165 5d/pop-to-ebp + 5166 c3/return + 5167 + 5168 # identifier starts with a letter or '$' or '_' + 5169 # no constraints at the moment on later letters + 5170 # all we really want to do so far is exclude '{', '}' and '->' + 5171 is-identifier?: # in: (addr slice) -> result/eax: boolean + 5172 # . prologue + 5173 55/push-ebp + 5174 89/<- %ebp 4/r32/esp + 5175 # if (slice-empty?(in)) return false + 5176 (slice-empty? *(ebp+8)) # => eax + 5177 3d/compare-eax-and 0/imm32/false + 5178 75/jump-if-!= $is-identifier?:false/disp8 + 5179 # var c/eax: byte = *in->start + 5180 8b/-> *(ebp+8) 0/r32/eax + 5181 8b/-> *eax 0/r32/eax + 5182 8a/copy-byte *eax 0/r32/AL + 5183 81 4/subop/and %eax 0xff/imm32 + 5184 # if (c == '$') return true + 5185 3d/compare-eax-and 0x24/imm32/$ + 5186 74/jump-if-= $is-identifier?:true/disp8 + 5187 # if (c == '_') return true + 5188 3d/compare-eax-and 0x5f/imm32/_ + 5189 74/jump-if-= $is-identifier?:true/disp8 + 5190 # drop case + 5191 25/and-eax-with 0x5f/imm32 + 5192 # if (c < 'A') return false + 5193 3d/compare-eax-and 0x41/imm32/A + 5194 7c/jump-if-< $is-identifier?:false/disp8 + 5195 # if (c > 'Z') return false + 5196 3d/compare-eax-and 0x5a/imm32/Z + 5197 7f/jump-if-> $is-identifier?:false/disp8 + 5198 # otherwise return true + 5199 $is-identifier?:true: + 5200 b8/copy-to-eax 1/imm32/true + 5201 eb/jump $is-identifier?:end/disp8 + 5202 $is-identifier?:false: + 5203 b8/copy-to-eax 0/imm32/false + 5204 $is-identifier?:end: + 5205 # . epilogue + 5206 89/<- %esp 5/r32/ebp + 5207 5d/pop-to-ebp + 5208 c3/return + 5209 + 5210 test-is-identifier-dollar: + 5211 # . prologue + 5212 55/push-ebp + 5213 89/<- %ebp 4/r32/esp + 5214 # (eax..ecx) = "$a" + 5215 b8/copy-to-eax "$a"/imm32 + 5216 8b/-> *eax 1/r32/ecx + 5217 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5218 05/add-to-eax 4/imm32 + 5219 # var slice/ecx: slice = {eax, ecx} + 5220 51/push-ecx + 5221 50/push-eax + 5222 89/<- %ecx 4/r32/esp + 5223 # + 5224 (is-identifier? %ecx) + 5225 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") + 5226 # . epilogue + 5227 89/<- %esp 5/r32/ebp + 5228 5d/pop-to-ebp + 5229 c3/return + 5230 + 5231 test-is-identifier-underscore: + 5232 # . prologue + 5233 55/push-ebp + 5234 89/<- %ebp 4/r32/esp + 5235 # (eax..ecx) = "_a" + 5236 b8/copy-to-eax "_a"/imm32 + 5237 8b/-> *eax 1/r32/ecx + 5238 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5239 05/add-to-eax 4/imm32 + 5240 # var slice/ecx: slice = {eax, ecx} + 5241 51/push-ecx + 5242 50/push-eax + 5243 89/<- %ecx 4/r32/esp + 5244 # + 5245 (is-identifier? %ecx) + 5246 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") + 5247 # . epilogue + 5248 89/<- %esp 5/r32/ebp + 5249 5d/pop-to-ebp + 5250 c3/return + 5251 + 5252 test-is-identifier-a: + 5253 # . prologue + 5254 55/push-ebp + 5255 89/<- %ebp 4/r32/esp + 5256 # (eax..ecx) = "a$" + 5257 b8/copy-to-eax "a$"/imm32 + 5258 8b/-> *eax 1/r32/ecx + 5259 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5260 05/add-to-eax 4/imm32 + 5261 # var slice/ecx: slice = {eax, ecx} + 5262 51/push-ecx + 5263 50/push-eax + 5264 89/<- %ecx 4/r32/esp + 5265 # + 5266 (is-identifier? %ecx) + 5267 (check-ints-equal %eax 1 "F - test-is-identifier-a") + 5268 # . epilogue + 5269 89/<- %esp 5/r32/ebp + 5270 5d/pop-to-ebp + 5271 c3/return + 5272 + 5273 test-is-identifier-z: + 5274 # . prologue + 5275 55/push-ebp + 5276 89/<- %ebp 4/r32/esp + 5277 # (eax..ecx) = "z$" + 5278 b8/copy-to-eax "z$"/imm32 + 5279 8b/-> *eax 1/r32/ecx + 5280 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5281 05/add-to-eax 4/imm32 + 5282 # var slice/ecx: slice = {eax, ecx} + 5283 51/push-ecx + 5284 50/push-eax + 5285 89/<- %ecx 4/r32/esp 5286 # - 5287 # . prologue - 5288 55/push-ebp - 5289 89/<- %ebp 4/r32/esp - 5290 # . save registers - 5291 50/push-eax - 5292 51/push-ecx - 5293 52/push-edx - 5294 53/push-ebx - 5295 57/push-edi - 5296 # var line/ecx: (stream byte 512) - 5297 81 5/subop/subtract %esp 0x200/imm32 - 5298 68/push 0x200/imm32/size - 5299 68/push 0/imm32/read - 5300 68/push 0/imm32/write - 5301 89/<- %ecx 4/r32/esp - 5302 # var word-slice/edx: slice - 5303 68/push 0/imm32/end - 5304 68/push 0/imm32/start - 5305 89/<- %edx 4/r32/esp - 5306 # allocate into out - 5307 (allocate Heap *Stmt-size *(ebp+0x14)) - 5308 # var out-addr/edi: (addr block) = lookup(*out) - 5309 8b/-> *(ebp+0x14) 7/r32/edi - 5310 (lookup *edi *(edi+4)) # => eax - 5311 89/<- %edi 0/r32/eax - 5312 # out-addr->tag is 0 (block) by default - 5313 # set out-addr->var - 5314 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var - 5315 (new-block-name *(ebp+0x10) %eax) - 5316 # push(vars, out-addr->var) - 5317 (push *(ebp+0xc) *(edi+0xc)) # Block-var - 5318 (push *(ebp+0xc) *(edi+0x10)) # Block-var - 5319 { - 5320 $parse-mu-block:line-loop: - 5321 # line = read-line-buffered(in) - 5322 (clear-stream %ecx) - 5323 (read-line-buffered *(ebp+8) %ecx) - 5324 #? (write-buffered Stderr "line: ") - 5325 #? (write-stream-data Stderr %ecx) - 5326 #? (write-buffered Stderr Newline) - 5327 #? (flush Stderr) - 5328 # if (line->write == 0) break - 5329 81 7/subop/compare *ecx 0/imm32 - 5330 0f 84/jump-if-= break/disp32 - 5331 # word-slice = next-mu-token(line) - 5332 (next-mu-token %ecx %edx) - 5333 #? (write-buffered Stderr "word: ") - 5334 #? (write-slice-buffered Stderr %edx) - 5335 #? (write-buffered Stderr Newline) - 5336 #? (flush Stderr) - 5337 # if slice-empty?(word-slice) continue - 5338 (slice-empty? %edx) - 5339 3d/compare-eax-and 0/imm32/false - 5340 0f 85/jump-if-!= loop/disp32 - 5341 # if (slice-starts-with?(word-slice, '#') continue - 5342 # . eax = *word-slice->start - 5343 8b/-> *edx 0/r32/eax - 5344 8a/copy-byte *eax 0/r32/AL - 5345 81 4/subop/and %eax 0xff/imm32 - 5346 # . if (eax == '#') continue - 5347 3d/compare-eax-and 0x23/imm32/hash - 5348 0f 84/jump-if-= loop/disp32 - 5349 # if slice-equal?(word-slice, "{") - 5350 { - 5351 $parse-mu-block:check-for-block: - 5352 (slice-equal? %edx "{") - 5353 3d/compare-eax-and 0/imm32/false - 5354 74/jump-if-= break/disp8 - 5355 (check-no-tokens-left %ecx) - 5356 # parse new block and append - 5357 # . var tmp/eax: (handle block) - 5358 68/push 0/imm32 - 5359 68/push 0/imm32 - 5360 89/<- %eax 4/r32/esp - 5361 # . - 5362 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax) - 5363 (append-to-block Heap %edi *eax *(eax+4)) - 5364 # . reclaim tmp - 5365 81 0/subop/add %esp 8/imm32 - 5366 # . - 5367 e9/jump $parse-mu-block:line-loop/disp32 - 5368 } - 5369 # if slice-equal?(word-slice, "}") break - 5370 $parse-mu-block:check-for-end: - 5371 (slice-equal? %edx "}") - 5372 3d/compare-eax-and 0/imm32/false - 5373 0f 85/jump-if-!= break/disp32 - 5374 # if slice-ends-with?(word-slice, ":") parse named block and append - 5375 { - 5376 $parse-mu-block:check-for-named-block: - 5377 # . eax = *(word-slice->end-1) - 5378 8b/-> *(edx+4) 0/r32/eax - 5379 48/decrement-eax - 5380 8a/copy-byte *eax 0/r32/AL - 5381 81 4/subop/and %eax 0xff/imm32 - 5382 # . if (eax != ':') break - 5383 3d/compare-eax-and 0x3a/imm32/colon - 5384 0f 85/jump-if-!= break/disp32 - 5385 # TODO: error-check the rest of 'line' - 5386 # - 5387 # skip ':' - 5388 ff 1/subop/decrement *(edx+4) # Slice-end - 5389 # var tmp/eax: (handle block) - 5390 68/push 0/imm32 - 5391 68/push 0/imm32 - 5392 89/<- %eax 4/r32/esp - 5393 # - 5394 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax) - 5395 (append-to-block Heap %edi *eax *(eax+4)) - 5396 # reclaim tmp - 5397 81 0/subop/add %esp 8/imm32 - 5398 # - 5399 e9/jump $parse-mu-block:line-loop/disp32 - 5400 } - 5401 # if slice-equal?(word-slice, "var") - 5402 { - 5403 $parse-mu-block:check-for-var: - 5404 (slice-equal? %edx "var") - 5405 3d/compare-eax-and 0/imm32/false - 5406 74/jump-if-= break/disp8 - 5407 # var tmp/eax: (handle block) - 5408 68/push 0/imm32 - 5409 68/push 0/imm32 - 5410 89/<- %eax 4/r32/esp - 5411 # - 5412 (parse-mu-var-def %ecx *(ebp+0xc) %eax) - 5413 (append-to-block Heap %edi *eax *(eax+4)) - 5414 # reclaim tmp - 5415 81 0/subop/add %esp 8/imm32 - 5416 # - 5417 e9/jump $parse-mu-block:line-loop/disp32 - 5418 } - 5419 $parse-mu-block:regular-stmt: - 5420 # otherwise - 5421 # var tmp/eax: (handle block) - 5422 68/push 0/imm32 - 5423 68/push 0/imm32 - 5424 89/<- %eax 4/r32/esp - 5425 # - 5426 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax) - 5427 (append-to-block Heap %edi *eax *(eax+4)) - 5428 # reclaim tmp - 5429 81 0/subop/add %esp 8/imm32 - 5430 # - 5431 e9/jump loop/disp32 - 5432 } # end line loop - 5433 # pop(vars) - 5434 (pop *(ebp+0xc)) # => eax - 5435 (pop *(ebp+0xc)) # => eax - 5436 $parse-mu-block:end: - 5437 # . reclaim locals - 5438 81 0/subop/add %esp 0x214/imm32 - 5439 # . restore registers - 5440 5f/pop-to-edi - 5441 5b/pop-to-ebx - 5442 5a/pop-to-edx - 5443 59/pop-to-ecx - 5444 58/pop-to-eax - 5445 # . epilogue - 5446 89/<- %esp 5/r32/ebp - 5447 5d/pop-to-ebp - 5448 c3/return - 5449 - 5450 $parse-mu-block:abort: - 5451 # error("'{' or '}' should be on its own line, but got '") - 5452 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") - 5453 (rewind-stream %ecx) - 5454 (write-stream 2 %ecx) - 5455 (write-buffered Stderr "'\n") - 5456 (flush Stderr) - 5457 # . syscall(exit, 1) - 5458 bb/copy-to-ebx 1/imm32 - 5459 b8/copy-to-eax 1/imm32/exit - 5460 cd/syscall 0x80/imm8 - 5461 # never gets here - 5462 - 5463 new-block-name: # fn: (addr function), out: (addr handle var) - 5464 # . prologue - 5465 55/push-ebp - 5466 89/<- %ebp 4/r32/esp - 5467 # . save registers - 5468 50/push-eax - 5469 51/push-ecx - 5470 52/push-edx - 5471 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' - 5472 8b/-> *(ebp+8) 0/r32/eax - 5473 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 5474 8b/-> *eax 0/r32/eax # String-size - 5475 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' - 5476 89/<- %ecx 0/r32/eax - 5477 # var name/edx: (stream byte n) - 5478 29/subtract-from %esp 1/r32/ecx - 5479 ff 6/subop/push %ecx - 5480 68/push 0/imm32/read - 5481 68/push 0/imm32/write - 5482 89/<- %edx 4/r32/esp - 5483 (clear-stream %edx) - 5484 # eax = fn->name - 5485 8b/-> *(ebp+8) 0/r32/eax - 5486 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 5487 # construct result using Next-block-index (and increment it) - 5488 (write %edx "$") - 5489 (write %edx %eax) - 5490 (write %edx ":") - 5491 (print-int32 %edx *Next-block-index) - 5492 ff 0/subop/increment *Next-block-index - 5493 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) - 5494 # . eax = name->write - 5495 8b/-> *edx 0/r32/eax - 5496 # . edx = name->data - 5497 8d/copy-address *(edx+0xc) 2/r32/edx - 5498 # . eax = name->write + name->data - 5499 01/add-to %eax 2/r32/edx - 5500 # . push {edx, eax} - 5501 ff 6/subop/push %eax - 5502 ff 6/subop/push %edx - 5503 89/<- %eax 4/r32/esp - 5504 # out = new literal(s) - 5505 (new-literal Heap %eax *(ebp+0xc)) - 5506 #? 8b/-> *(ebp+0xc) 0/r32/eax - 5507 #? (write-buffered Stderr "type allocid in caller after new-literal: ") - 5508 #? (print-int32-buffered Stderr *(eax+8)) - 5509 #? (write-buffered Stderr " for var ") - 5510 #? (print-int32-buffered Stderr %eax) - 5511 #? (write-buffered Stderr Newline) - 5512 #? (flush Stderr) - 5513 $new-block-name:end: - 5514 # . reclaim locals - 5515 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} - 5516 81 0/subop/add %ecx 8/imm32 # slice - 5517 01/add-to %esp 1/r32/ecx - 5518 # . restore registers - 5519 5a/pop-to-edx - 5520 59/pop-to-ecx - 5521 58/pop-to-eax - 5522 # . epilogue - 5523 89/<- %esp 5/r32/ebp - 5524 5d/pop-to-ebp - 5525 c3/return - 5526 - 5527 == data - 5528 - 5529 # Global state added to each var record when parsing a function - 5530 Next-block-index: # (addr int) - 5531 1/imm32 - 5532 - 5533 == code - 5534 - 5535 check-no-tokens-left: # line: (addr stream byte) - 5536 # . prologue - 5537 55/push-ebp - 5538 89/<- %ebp 4/r32/esp - 5539 # . save registers - 5540 50/push-eax - 5541 51/push-ecx - 5542 # var s/ecx: slice - 5543 68/push 0/imm32/end - 5544 68/push 0/imm32/start - 5545 89/<- %ecx 4/r32/esp - 5546 # - 5547 (next-mu-token *(ebp+8) %ecx) - 5548 # if slice-empty?(s) return - 5549 (slice-empty? %ecx) - 5550 3d/compare-eax-and 0/imm32/false - 5551 75/jump-if-!= $check-no-tokens-left:end/disp8 - 5552 # if (slice-starts-with?(s, '#') return - 5553 # . eax = *s->start - 5554 8b/-> *edx 0/r32/eax - 5555 8a/copy-byte *eax 0/r32/AL - 5556 81 4/subop/and %eax 0xff/imm32 - 5557 # . if (eax == '#') continue - 5558 3d/compare-eax-and 0x23/imm32/hash - 5559 74/jump-if-= $check-no-tokens-left:end/disp8 - 5560 # abort - 5561 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") - 5562 (rewind-stream %ecx) - 5563 (write-stream 2 %ecx) - 5564 (write-buffered Stderr "'\n") - 5565 (flush Stderr) - 5566 # . syscall(exit, 1) - 5567 bb/copy-to-ebx 1/imm32 - 5568 b8/copy-to-eax 1/imm32/exit - 5569 cd/syscall 0x80/imm8 - 5570 # never gets here - 5571 $check-no-tokens-left:end: - 5572 # . reclaim locals - 5573 81 0/subop/add %esp 8/imm32 - 5574 # . restore registers - 5575 59/pop-to-ecx - 5576 58/pop-to-eax - 5577 # . epilogue - 5578 89/<- %esp 5/r32/ebp - 5579 5d/pop-to-ebp - 5580 c3/return - 5581 - 5582 parse-mu-named-block: # name: (addr slice), in: (addr buffered-file), vars: (addr stack (handle var)), fn: (addr function), out: (addr handle stmt) - 5583 # pseudocode: - 5584 # var v: (handle var) - 5585 # new-literal(name, v) - 5586 # push(vars, v) - 5587 # parse-mu-block(in, vars, fn, out) - 5588 # pop(vars) - 5589 # out->tag = block - 5590 # out->var = v - 5591 # - 5592 # . prologue - 5593 55/push-ebp - 5594 89/<- %ebp 4/r32/esp - 5595 # . save registers - 5596 50/push-eax - 5597 51/push-ecx - 5598 57/push-edi - 5599 # var v/ecx: (handle var) - 5600 68/push 0/imm32 - 5601 68/push 0/imm32 - 5602 89/<- %ecx 4/r32/esp - 5603 # - 5604 (new-literal Heap *(ebp+8) %ecx) - 5605 # push(vars, v) - 5606 (push *(ebp+0x10) *ecx) - 5607 (push *(ebp+0x10) *(ecx+4)) - 5608 # - 5609 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) - 5610 # pop v off vars - 5611 (pop *(ebp+0x10)) # => eax - 5612 (pop *(ebp+0x10)) # => eax - 5613 # var out-addr/edi: (addr stmt) = lookup(*out) - 5614 8b/-> *(ebp+0x18) 7/r32/edi - 5615 (lookup *edi *(edi+4)) # => eax - 5616 89/<- %edi 0/r32/eax - 5617 # out-addr->tag = named-block - 5618 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag - 5619 # out-addr->var = v - 5620 8b/-> *ecx 0/r32/eax - 5621 89/<- *(edi+0xc) 0/r32/eax # Block-var - 5622 8b/-> *(ecx+4) 0/r32/eax - 5623 89/<- *(edi+0x10) 0/r32/eax # Block-var - 5624 $parse-mu-named-block:end: - 5625 # . reclaim locals - 5626 81 0/subop/add %esp 8/imm32 - 5627 # . restore registers - 5628 5f/pop-to-edi - 5629 59/pop-to-ecx - 5630 58/pop-to-eax - 5631 # . epilogue - 5632 89/<- %esp 5/r32/ebp - 5633 5d/pop-to-ebp - 5634 c3/return - 5635 - 5636 parse-mu-var-def: # line: (addr stream byte), vars: (addr stack (handle var)), out: (addr handle stmt) - 5637 # . prologue - 5638 55/push-ebp - 5639 89/<- %ebp 4/r32/esp - 5640 # . save registers - 5641 50/push-eax - 5642 51/push-ecx - 5643 52/push-edx - 5644 57/push-edi - 5645 # edi = out - 5646 8b/-> *(ebp+0x10) 7/r32/edi - 5647 # var word-slice/ecx: slice - 5648 68/push 0/imm32/end - 5649 68/push 0/imm32/start - 5650 89/<- %ecx 4/r32/esp - 5651 # var v/edx: (handle var) - 5652 68/push 0/imm32 - 5653 68/push 0/imm32 - 5654 89/<- %edx 4/r32/esp - 5655 # v = parse-var-with-type(next-mu-token(line)) - 5656 (next-mu-token *(ebp+8) %ecx) - 5657 (parse-var-with-type %ecx *(ebp+8) %edx) - 5658 # - 5659 (push *(ebp+0xc) *edx) - 5660 (push *(ebp+0xc) *(edx+4)) - 5661 # either v has no register and there's no more to this line - 5662 (lookup *edx *(edx+4)) # => eax - 5663 8b/-> *(eax+0x18) 0/r32/eax # Var-register - 5664 3d/compare-eax-and 0/imm32 - 5665 { - 5666 75/jump-if-!= break/disp8 - 5667 # TODO: ensure that there's nothing else on this line - 5668 (new-var-def Heap *edx *(edx+4) %edi) - 5669 eb/jump $parse-mu-var-def:end/disp8 - 5670 } - 5671 # or v has a register and there's more to this line - 5672 { - 5673 74/jump-if-= break/disp8 - 5674 # ensure that the next word is '<-' - 5675 (next-mu-token *(ebp+8) %ecx) - 5676 (slice-equal? %ecx "<-") # => eax - 5677 3d/compare-eax-and 0/imm32/false - 5678 74/jump-if-= $parse-mu-var-def:abort/disp8 - 5679 # - 5680 (new-reg-var-def Heap *edx *(edx+4) %edi) - 5681 (lookup *edi *(edi+4)) # => eax - 5682 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc)) - 5683 } - 5684 $parse-mu-var-def:end: - 5685 # . reclaim locals - 5686 81 0/subop/add %esp 0x10/imm32 - 5687 # . restore registers - 5688 5f/pop-to-edi - 5689 5a/pop-to-edx - 5690 59/pop-to-ecx - 5691 58/pop-to-eax - 5692 # . epilogue - 5693 89/<- %esp 5/r32/ebp - 5694 5d/pop-to-ebp - 5695 c3/return - 5696 - 5697 $parse-mu-var-def:abort: - 5698 (rewind-stream *(ebp+8)) - 5699 # error("register variable requires a valid instruction to initialize but got '" line "'\n") - 5700 (write-buffered Stderr "register variable requires a valid instruction to initialize but got '") + 5287 (is-identifier? %ecx) + 5288 (check-ints-equal %eax 1 "F - test-is-identifier-z") + 5289 # . epilogue + 5290 89/<- %esp 5/r32/ebp + 5291 5d/pop-to-ebp + 5292 c3/return + 5293 + 5294 test-is-identifier-A: + 5295 # . prologue + 5296 55/push-ebp + 5297 89/<- %ebp 4/r32/esp + 5298 # (eax..ecx) = "A$" + 5299 b8/copy-to-eax "A$"/imm32 + 5300 8b/-> *eax 1/r32/ecx + 5301 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5302 05/add-to-eax 4/imm32 + 5303 # var slice/ecx: slice = {eax, ecx} + 5304 51/push-ecx + 5305 50/push-eax + 5306 89/<- %ecx 4/r32/esp + 5307 # + 5308 (is-identifier? %ecx) + 5309 (check-ints-equal %eax 1 "F - test-is-identifier-A") + 5310 # . epilogue + 5311 89/<- %esp 5/r32/ebp + 5312 5d/pop-to-ebp + 5313 c3/return + 5314 + 5315 test-is-identifier-Z: + 5316 # . prologue + 5317 55/push-ebp + 5318 89/<- %ebp 4/r32/esp + 5319 # (eax..ecx) = "Z$" + 5320 b8/copy-to-eax "Z$"/imm32 + 5321 8b/-> *eax 1/r32/ecx + 5322 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5323 05/add-to-eax 4/imm32 + 5324 # var slice/ecx: slice = {eax, ecx} + 5325 51/push-ecx + 5326 50/push-eax + 5327 89/<- %ecx 4/r32/esp + 5328 # + 5329 (is-identifier? %ecx) + 5330 (check-ints-equal %eax 1 "F - test-is-identifier-Z") + 5331 # . epilogue + 5332 89/<- %esp 5/r32/ebp + 5333 5d/pop-to-ebp + 5334 c3/return + 5335 + 5336 test-is-identifier-at: + 5337 # character before 'A' is invalid + 5338 # . prologue + 5339 55/push-ebp + 5340 89/<- %ebp 4/r32/esp + 5341 # (eax..ecx) = "@a" + 5342 b8/copy-to-eax "@a"/imm32 + 5343 8b/-> *eax 1/r32/ecx + 5344 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5345 05/add-to-eax 4/imm32 + 5346 # var slice/ecx: slice = {eax, ecx} + 5347 51/push-ecx + 5348 50/push-eax + 5349 89/<- %ecx 4/r32/esp + 5350 # + 5351 (is-identifier? %ecx) + 5352 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 5353 # . epilogue + 5354 89/<- %esp 5/r32/ebp + 5355 5d/pop-to-ebp + 5356 c3/return + 5357 + 5358 test-is-identifier-square-bracket: + 5359 # character after 'Z' is invalid + 5360 # . prologue + 5361 55/push-ebp + 5362 89/<- %ebp 4/r32/esp + 5363 # (eax..ecx) = "[a" + 5364 b8/copy-to-eax "[a"/imm32 + 5365 8b/-> *eax 1/r32/ecx + 5366 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5367 05/add-to-eax 4/imm32 + 5368 # var slice/ecx: slice = {eax, ecx} + 5369 51/push-ecx + 5370 50/push-eax + 5371 89/<- %ecx 4/r32/esp + 5372 # + 5373 (is-identifier? %ecx) + 5374 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 5375 # . epilogue + 5376 89/<- %esp 5/r32/ebp + 5377 5d/pop-to-ebp + 5378 c3/return + 5379 + 5380 test-is-identifier-backtick: + 5381 # character before 'a' is invalid + 5382 # . prologue + 5383 55/push-ebp + 5384 89/<- %ebp 4/r32/esp + 5385 # (eax..ecx) = "`a" + 5386 b8/copy-to-eax "`a"/imm32 + 5387 8b/-> *eax 1/r32/ecx + 5388 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5389 05/add-to-eax 4/imm32 + 5390 # var slice/ecx: slice = {eax, ecx} + 5391 51/push-ecx + 5392 50/push-eax + 5393 89/<- %ecx 4/r32/esp + 5394 # + 5395 (is-identifier? %ecx) + 5396 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") + 5397 # . epilogue + 5398 89/<- %esp 5/r32/ebp + 5399 5d/pop-to-ebp + 5400 c3/return + 5401 + 5402 test-is-identifier-curly-brace-open: + 5403 # character after 'z' is invalid; also used for blocks + 5404 # . prologue + 5405 55/push-ebp + 5406 89/<- %ebp 4/r32/esp + 5407 # (eax..ecx) = "{a" + 5408 b8/copy-to-eax "{a"/imm32 + 5409 8b/-> *eax 1/r32/ecx + 5410 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5411 05/add-to-eax 4/imm32 + 5412 # var slice/ecx: slice = {eax, ecx} + 5413 51/push-ecx + 5414 50/push-eax + 5415 89/<- %ecx 4/r32/esp + 5416 # + 5417 (is-identifier? %ecx) + 5418 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") + 5419 # . epilogue + 5420 89/<- %esp 5/r32/ebp + 5421 5d/pop-to-ebp + 5422 c3/return + 5423 + 5424 test-is-identifier-curly-brace-close: + 5425 # . prologue + 5426 55/push-ebp + 5427 89/<- %ebp 4/r32/esp + 5428 # (eax..ecx) = "}a" + 5429 b8/copy-to-eax "}a"/imm32 + 5430 8b/-> *eax 1/r32/ecx + 5431 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5432 05/add-to-eax 4/imm32 + 5433 # var slice/ecx: slice = {eax, ecx} + 5434 51/push-ecx + 5435 50/push-eax + 5436 89/<- %ecx 4/r32/esp + 5437 # + 5438 (is-identifier? %ecx) + 5439 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") + 5440 # . epilogue + 5441 89/<- %esp 5/r32/ebp + 5442 5d/pop-to-ebp + 5443 c3/return + 5444 + 5445 test-is-identifier-hyphen: + 5446 # disallow leading '-' since '->' has special meaning + 5447 # . prologue + 5448 55/push-ebp + 5449 89/<- %ebp 4/r32/esp + 5450 # (eax..ecx) = "-a" + 5451 b8/copy-to-eax "-a"/imm32 + 5452 8b/-> *eax 1/r32/ecx + 5453 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 5454 05/add-to-eax 4/imm32 + 5455 # var slice/ecx: slice = {eax, ecx} + 5456 51/push-ecx + 5457 50/push-eax + 5458 89/<- %ecx 4/r32/esp + 5459 # + 5460 (is-identifier? %ecx) + 5461 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") + 5462 # . epilogue + 5463 89/<- %esp 5/r32/ebp + 5464 5d/pop-to-ebp + 5465 c3/return + 5466 + 5467 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var) + 5468 # . prologue + 5469 55/push-ebp + 5470 89/<- %ebp 4/r32/esp + 5471 # . save registers + 5472 50/push-eax + 5473 56/push-esi + 5474 57/push-edi + 5475 # esi = in + 5476 8b/-> *(ebp+8) 6/r32/esi + 5477 # edi = out + 5478 8b/-> *(ebp+0xc) 7/r32/edi + 5479 # parse-mu-block(in, vars, out, out->body) + 5480 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body + 5481 (parse-mu-block %esi *(ebp+0x10) %edi %eax) + 5482 $populate-mu-function-body:end: + 5483 # . restore registers + 5484 5f/pop-to-edi + 5485 5e/pop-to-esi + 5486 58/pop-to-eax + 5487 # . epilogue + 5488 89/<- %esp 5/r32/ebp + 5489 5d/pop-to-ebp + 5490 c3/return + 5491 + 5492 # parses a block, assuming that the leading '{' has already been read by the caller + 5493 parse-mu-block: # in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle block) + 5494 # pseudocode: + 5495 # var line: (stream byte 512) + 5496 # var word-slice: slice + 5497 # allocate(Heap, Stmt-size, out) + 5498 # var out-addr: (addr block) = lookup(*out) + 5499 # out-addr->tag = 0/block + 5500 # out-addr->var = some unique name + 5501 # push(vars, {out-addr->var, false}) + 5502 # while true # line loop + 5503 # clear-stream(line) + 5504 # read-line-buffered(in, line) + 5505 # if (line->write == 0) break # end of file + 5506 # word-slice = next-mu-token(line) + 5507 # if slice-empty?(word-slice) # end of line + 5508 # continue + 5509 # else if slice-starts-with?(word-slice, "#") + 5510 # continue + 5511 # else if slice-equal?(word-slice, "{") + 5512 # assert(no-tokens-in(line)) + 5513 # block = parse-mu-block(in, vars, fn) + 5514 # append-to-block(out-addr, block) + 5515 # else if slice-equal?(word-slice, "}") + 5516 # break + 5517 # else if slice-ends-with?(word-slice, ":") + 5518 # # TODO: error-check the rest of 'line' + 5519 # --word-slice->end to skip ':' + 5520 # named-block = parse-mu-named-block(word-slice, in, vars, fn) + 5521 # append-to-block(out-addr, named-block) + 5522 # else if slice-equal?(word-slice, "var") + 5523 # var-def = parse-mu-var-def(line, vars) + 5524 # append-to-block(out-addr, var-def) + 5525 # else + 5526 # stmt = parse-mu-stmt(line, vars, fn) + 5527 # append-to-block(out-addr, stmt) + 5528 # pop(vars) + 5529 # + 5530 # . prologue + 5531 55/push-ebp + 5532 89/<- %ebp 4/r32/esp + 5533 # . save registers + 5534 50/push-eax + 5535 51/push-ecx + 5536 52/push-edx + 5537 53/push-ebx + 5538 57/push-edi + 5539 # var line/ecx: (stream byte 512) + 5540 81 5/subop/subtract %esp 0x200/imm32 + 5541 68/push 0x200/imm32/size + 5542 68/push 0/imm32/read + 5543 68/push 0/imm32/write + 5544 89/<- %ecx 4/r32/esp + 5545 # var word-slice/edx: slice + 5546 68/push 0/imm32/end + 5547 68/push 0/imm32/start + 5548 89/<- %edx 4/r32/esp + 5549 # allocate into out + 5550 (allocate Heap *Stmt-size *(ebp+0x14)) + 5551 # var out-addr/edi: (addr block) = lookup(*out) + 5552 8b/-> *(ebp+0x14) 7/r32/edi + 5553 (lookup *edi *(edi+4)) # => eax + 5554 89/<- %edi 0/r32/eax + 5555 # out-addr->tag is 0 (block) by default + 5556 # set out-addr->var + 5557 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var + 5558 (new-block-name *(ebp+0x10) %eax) + 5559 # push(vars, out-addr->var) + 5560 (push *(ebp+0xc) *(edi+0xc)) # Block-var + 5561 (push *(ebp+0xc) *(edi+0x10)) # Block-var + 5562 (push *(ebp+0xc) 0) # false + 5563 { + 5564 $parse-mu-block:line-loop: + 5565 # line = read-line-buffered(in) + 5566 (clear-stream %ecx) + 5567 (read-line-buffered *(ebp+8) %ecx) + 5568 #? (write-buffered Stderr "line: ") + 5569 #? (write-stream-data Stderr %ecx) + 5570 #? (write-buffered Stderr Newline) + 5571 #? (flush Stderr) + 5572 # if (line->write == 0) break + 5573 81 7/subop/compare *ecx 0/imm32 + 5574 0f 84/jump-if-= break/disp32 + 5575 # word-slice = next-mu-token(line) + 5576 (next-mu-token %ecx %edx) + 5577 #? (write-buffered Stderr "word: ") + 5578 #? (write-slice-buffered Stderr %edx) + 5579 #? (write-buffered Stderr Newline) + 5580 #? (flush Stderr) + 5581 # if slice-empty?(word-slice) continue + 5582 (slice-empty? %edx) + 5583 3d/compare-eax-and 0/imm32/false + 5584 0f 85/jump-if-!= loop/disp32 + 5585 # if (slice-starts-with?(word-slice, '#') continue + 5586 # . eax = *word-slice->start + 5587 8b/-> *edx 0/r32/eax + 5588 8a/copy-byte *eax 0/r32/AL + 5589 81 4/subop/and %eax 0xff/imm32 + 5590 # . if (eax == '#') continue + 5591 3d/compare-eax-and 0x23/imm32/hash + 5592 0f 84/jump-if-= loop/disp32 + 5593 # if slice-equal?(word-slice, "{") + 5594 { + 5595 $parse-mu-block:check-for-block: + 5596 (slice-equal? %edx "{") + 5597 3d/compare-eax-and 0/imm32/false + 5598 74/jump-if-= break/disp8 + 5599 (check-no-tokens-left %ecx) + 5600 # parse new block and append + 5601 # . var tmp/eax: (handle block) + 5602 68/push 0/imm32 + 5603 68/push 0/imm32 + 5604 89/<- %eax 4/r32/esp + 5605 # . + 5606 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax) + 5607 (append-to-block Heap %edi *eax *(eax+4)) + 5608 # . reclaim tmp + 5609 81 0/subop/add %esp 8/imm32 + 5610 # . + 5611 e9/jump $parse-mu-block:line-loop/disp32 + 5612 } + 5613 # if slice-equal?(word-slice, "}") break + 5614 $parse-mu-block:check-for-end: + 5615 (slice-equal? %edx "}") + 5616 3d/compare-eax-and 0/imm32/false + 5617 0f 85/jump-if-!= break/disp32 + 5618 # if slice-ends-with?(word-slice, ":") parse named block and append + 5619 { + 5620 $parse-mu-block:check-for-named-block: + 5621 # . eax = *(word-slice->end-1) + 5622 8b/-> *(edx+4) 0/r32/eax + 5623 48/decrement-eax + 5624 8a/copy-byte *eax 0/r32/AL + 5625 81 4/subop/and %eax 0xff/imm32 + 5626 # . if (eax != ':') break + 5627 3d/compare-eax-and 0x3a/imm32/colon + 5628 0f 85/jump-if-!= break/disp32 + 5629 # TODO: error-check the rest of 'line' + 5630 # + 5631 # skip ':' + 5632 ff 1/subop/decrement *(edx+4) # Slice-end + 5633 # var tmp/eax: (handle block) + 5634 68/push 0/imm32 + 5635 68/push 0/imm32 + 5636 89/<- %eax 4/r32/esp + 5637 # + 5638 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax) + 5639 (append-to-block Heap %edi *eax *(eax+4)) + 5640 # reclaim tmp + 5641 81 0/subop/add %esp 8/imm32 + 5642 # + 5643 e9/jump $parse-mu-block:line-loop/disp32 + 5644 } + 5645 # if slice-equal?(word-slice, "var") + 5646 { + 5647 $parse-mu-block:check-for-var: + 5648 (slice-equal? %edx "var") + 5649 3d/compare-eax-and 0/imm32/false + 5650 74/jump-if-= break/disp8 + 5651 # var tmp/eax: (handle block) + 5652 68/push 0/imm32 + 5653 68/push 0/imm32 + 5654 89/<- %eax 4/r32/esp + 5655 # + 5656 (parse-mu-var-def %ecx *(ebp+0xc) %eax) + 5657 (append-to-block Heap %edi *eax *(eax+4)) + 5658 # reclaim tmp + 5659 81 0/subop/add %esp 8/imm32 + 5660 # + 5661 e9/jump $parse-mu-block:line-loop/disp32 + 5662 } + 5663 $parse-mu-block:regular-stmt: + 5664 # otherwise + 5665 # var tmp/eax: (handle block) + 5666 68/push 0/imm32 + 5667 68/push 0/imm32 + 5668 89/<- %eax 4/r32/esp + 5669 # + 5670 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax) + 5671 (append-to-block Heap %edi *eax *(eax+4)) + 5672 # reclaim tmp + 5673 81 0/subop/add %esp 8/imm32 + 5674 # + 5675 e9/jump loop/disp32 + 5676 } # end line loop + 5677 # pop(vars) + 5678 (pop *(ebp+0xc)) # => eax + 5679 (pop *(ebp+0xc)) # => eax + 5680 (pop *(ebp+0xc)) # => eax + 5681 $parse-mu-block:end: + 5682 # . reclaim locals + 5683 81 0/subop/add %esp 0x214/imm32 + 5684 # . restore registers + 5685 5f/pop-to-edi + 5686 5b/pop-to-ebx + 5687 5a/pop-to-edx + 5688 59/pop-to-ecx + 5689 58/pop-to-eax + 5690 # . epilogue + 5691 89/<- %esp 5/r32/ebp + 5692 5d/pop-to-ebp + 5693 c3/return + 5694 + 5695 $parse-mu-block:abort: + 5696 # error("'{' or '}' should be on its own line, but got '") + 5697 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") + 5698 (rewind-stream %ecx) + 5699 (write-stream 2 %ecx) + 5700 (write-buffered Stderr "'\n") 5701 (flush Stderr) - 5702 (write-stream 2 *(ebp+8)) - 5703 (write-buffered Stderr "'\n") - 5704 (flush Stderr) - 5705 # . syscall(exit, 1) - 5706 bb/copy-to-ebx 1/imm32 - 5707 b8/copy-to-eax 1/imm32/exit - 5708 cd/syscall 0x80/imm8 - 5709 # never gets here - 5710 - 5711 test-parse-mu-var-def: - 5712 # 'var n: int' - 5713 # . prologue - 5714 55/push-ebp - 5715 89/<- %ebp 4/r32/esp - 5716 # setup - 5717 (clear-stream _test-input-stream) - 5718 (write _test-input-stream "n: int\n") # caller has consumed the 'var' - 5719 # var out/esi: (handle stmt) - 5720 68/push 0/imm32 - 5721 68/push 0/imm32 - 5722 89/<- %esi 4/r32/esp - 5723 # var vars/ecx: (stack (addr var) 16) - 5724 81 5/subop/subtract %esp 0x80/imm32 - 5725 68/push 0x80/imm32/size - 5726 68/push 0/imm32/top - 5727 89/<- %ecx 4/r32/esp - 5728 (clear-stack %ecx) - 5729 # convert - 5730 (parse-mu-var-def _test-input-stream %ecx %esi) - 5731 # var out-addr/esi: (addr stmt) - 5732 (lookup *esi *(esi+4)) # => eax - 5733 89/<- %esi 0/r32/eax - 5734 # - 5735 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def - 5736 # var v/ecx: (addr var) = lookup(out->var) - 5737 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax - 5738 89/<- %ecx 0/r32/eax - 5739 # v->name - 5740 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 5741 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") - 5742 # v->register - 5743 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register - 5744 # v->type == int - 5745 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 5746 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Tree-is-atom - 5747 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Tree-value - 5748 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Tree-right - 5749 # . epilogue - 5750 89/<- %esp 5/r32/ebp - 5751 5d/pop-to-ebp - 5752 c3/return - 5753 - 5754 test-parse-mu-reg-var-def: - 5755 # 'var n/eax: int <- copy 0' - 5756 # . prologue - 5757 55/push-ebp - 5758 89/<- %ebp 4/r32/esp - 5759 # setup - 5760 (clear-stream _test-input-stream) - 5761 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' - 5762 # var out/esi: (handle stmt) - 5763 68/push 0/imm32 - 5764 68/push 0/imm32 - 5765 89/<- %esi 4/r32/esp - 5766 # var vars/ecx: (stack (addr var) 16) - 5767 81 5/subop/subtract %esp 0x80/imm32 - 5768 68/push 0x80/imm32/size - 5769 68/push 0/imm32/top - 5770 89/<- %ecx 4/r32/esp - 5771 (clear-stack %ecx) - 5772 # convert - 5773 (parse-mu-var-def _test-input-stream %ecx %esi) - 5774 # var out-addr/esi: (addr stmt) - 5775 (lookup *esi *(esi+4)) # => eax - 5776 89/<- %esi 0/r32/eax - 5777 # - 5778 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def - 5779 # var v/ecx: (addr var) = lookup(out->outputs->value) - 5780 # . eax: (addr stmt-var) = lookup(out->outputs) - 5781 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax - 5782 # . - 5783 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next - 5784 # . eax: (addr var) = lookup(eax->value) - 5785 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 5786 # . ecx = eax - 5787 89/<- %ecx 0/r32/eax - 5788 # v->name - 5789 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 5790 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name - 5791 # v->register - 5792 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 5793 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") - 5794 # v->type == int - 5795 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 5796 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Tree-is-atom - 5797 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Tree-value - 5798 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Tree-right - 5799 # . epilogue - 5800 89/<- %esp 5/r32/ebp - 5801 5d/pop-to-ebp - 5802 c3/return - 5803 - 5804 parse-mu-stmt: # line: (addr stream byte), vars: (addr stack (handle var)), fn: (addr function), out: (addr handle stmt) - 5805 # pseudocode: - 5806 # var name: slice - 5807 # allocate(Heap, Stmt-size, out) - 5808 # var out-addr: (addr stmt) = lookup(*out) - 5809 # out-addr->tag = stmt - 5810 # if stmt-has-outputs?(line) - 5811 # while true - 5812 # name = next-mu-token(line) - 5813 # if (name == '<-') break - 5814 # assert(is-identifier?(name)) - 5815 # var v: (handle var) = lookup-or-define-var(name, vars, fn) # regular stmts may define vars in fn outputs - 5816 # out-addr->outputs = append(v, out-addr->outputs) - 5817 # add-operation-and-inputs-to-stmt(out-addr, line, vars) - 5818 # - 5819 # . prologue - 5820 55/push-ebp - 5821 89/<- %ebp 4/r32/esp - 5822 # . save registers - 5823 50/push-eax - 5824 51/push-ecx - 5825 52/push-edx - 5826 53/push-ebx - 5827 57/push-edi - 5828 # var name/ecx: slice - 5829 68/push 0/imm32/end - 5830 68/push 0/imm32/start - 5831 89/<- %ecx 4/r32/esp - 5832 # var is-deref?/edx: boolean = false - 5833 ba/copy-to-edx 0/imm32/false - 5834 # var v: (handle var) - 5835 68/push 0/imm32 - 5836 68/push 0/imm32 - 5837 89/<- %ebx 4/r32/esp - 5838 # - 5839 (allocate Heap *Stmt-size *(ebp+0x14)) - 5840 # var out-addr/edi: (addr stmt) = lookup(*out) - 5841 8b/-> *(ebp+0x14) 7/r32/edi - 5842 (lookup *edi *(edi+4)) # => eax - 5843 89/<- %edi 0/r32/eax - 5844 # out-addr->tag = 1/stmt - 5845 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag - 5846 { - 5847 (stmt-has-outputs? *(ebp+8)) - 5848 3d/compare-eax-and 0/imm32/false - 5849 0f 84/jump-if-= break/disp32 - 5850 { - 5851 $parse-mu-stmt:read-outputs: - 5852 # name = next-mu-token(line) - 5853 (next-mu-token *(ebp+8) %ecx) - 5854 # if slice-empty?(word-slice) break - 5855 (slice-empty? %ecx) # => eax - 5856 3d/compare-eax-and 0/imm32/false - 5857 0f 85/jump-if-!= break/disp32 - 5858 # if (name == "<-") break - 5859 (slice-equal? %ecx "<-") # => eax - 5860 3d/compare-eax-and 0/imm32/false - 5861 0f 85/jump-if-!= break/disp32 - 5862 # is-deref? = false - 5863 ba/copy-to-edx 0/imm32/false - 5864 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? - 5865 8b/-> *ecx 0/r32/eax # Slice-start - 5866 8a/copy-byte *eax 0/r32/AL - 5867 81 4/subop/and %eax 0xff/imm32 - 5868 3d/compare-eax-and 0x2a/imm32/asterisk - 5869 { - 5870 75/jump-if-!= break/disp8 - 5871 ff 0/subop/increment *ecx - 5872 ba/copy-to-edx 1/imm32/true - 5873 } - 5874 # assert(is-identifier?(name)) - 5875 (is-identifier? %ecx) # => eax - 5876 3d/compare-eax-and 0/imm32/false - 5877 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 - 5878 # - 5879 (lookup-or-define-var %ecx *(ebp+0xc) *(ebp+0x10) %ebx) - 5880 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs - 5881 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) %edx %eax) # Stmt1-outputs - 5882 # - 5883 e9/jump loop/disp32 - 5884 } - 5885 } - 5886 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc)) - 5887 $parse-mu-stmt:end: - 5888 # . reclaim locals - 5889 81 0/subop/add %esp 0x10/imm32 - 5890 # . restore registers - 5891 5f/pop-to-edi - 5892 5b/pop-to-ebx - 5893 5a/pop-to-edx - 5894 59/pop-to-ecx - 5895 58/pop-to-eax - 5896 # . epilogue - 5897 89/<- %esp 5/r32/ebp - 5898 5d/pop-to-ebp - 5899 c3/return - 5900 - 5901 $parse-mu-stmt:abort: - 5902 # error("invalid identifier '" name "'\n") - 5903 (write-buffered Stderr "invalid identifier '") - 5904 (write-slice-buffered Stderr %ecx) - 5905 (write-buffered Stderr "'\n") - 5906 (flush Stderr) - 5907 # . syscall(exit, 1) - 5908 bb/copy-to-ebx 1/imm32 - 5909 b8/copy-to-eax 1/imm32/exit - 5910 cd/syscall 0x80/imm8 - 5911 # never gets here - 5912 - 5913 add-operation-and-inputs-to-stmt: # stmt: (addr stmt), line: (addr stream byte), vars: (addr stack (handle var)) - 5914 # pseudocode: - 5915 # stmt->name = slice-to-string(next-mu-token(line)) - 5916 # while true - 5917 # name = next-mu-token(line) - 5918 # v = lookup-var-or-literal(name) - 5919 # stmt->inouts = append(v, stmt->inouts) - 5920 # - 5921 # . prologue - 5922 55/push-ebp - 5923 89/<- %ebp 4/r32/esp - 5924 # . save registers - 5925 50/push-eax - 5926 51/push-ecx - 5927 52/push-edx - 5928 53/push-ebx - 5929 56/push-esi - 5930 57/push-edi - 5931 # edi = stmt - 5932 8b/-> *(ebp+8) 7/r32/edi - 5933 # var name/ecx: slice - 5934 68/push 0/imm32/end - 5935 68/push 0/imm32/start - 5936 89/<- %ecx 4/r32/esp - 5937 # var is-deref?/edx: boolean = false - 5938 ba/copy-to-edx 0/imm32/false - 5939 # var v/esi: (handle var) - 5940 68/push 0/imm32 - 5941 68/push 0/imm32 - 5942 89/<- %esi 4/r32/esp - 5943 $add-operation-and-inputs-to-stmt:read-operation: - 5944 (next-mu-token *(ebp+0xc) %ecx) - 5945 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation - 5946 (slice-to-string Heap %ecx %eax) - 5947 # var is-get?/ebx: boolean = (name == "get") - 5948 (slice-equal? %ecx "get") # => eax - 5949 89/<- %ebx 0/r32/eax - 5950 { - 5951 $add-operation-and-inputs-to-stmt:read-inouts: - 5952 # name = next-mu-token(line) - 5953 (next-mu-token *(ebp+0xc) %ecx) - 5954 # if slice-empty?(word-slice) break - 5955 (slice-empty? %ecx) # => eax - 5956 3d/compare-eax-and 0/imm32/false - 5957 0f 85/jump-if-!= break/disp32 - 5958 # if (name == "<-") abort - 5959 (slice-equal? %ecx "<-") - 5960 3d/compare-eax-and 0/imm32/false - 5961 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 - 5962 # if (is-get? && second operand) lookup or create offset - 5963 { - 5964 81 7/subop/compare %ebx 0/imm32/false - 5965 74/jump-if-= break/disp8 - 5966 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 5967 3d/compare-eax-and 0/imm32 - 5968 74/jump-if-= break/disp8 - 5969 (lookup-or-create-constant %eax %ecx %esi) - 5970 #? (lookup *esi *(esi+4)) - 5971 #? (write-buffered Stderr "creating new output var ") - 5972 #? (print-int32-buffered Stderr %eax) - 5973 #? (write-buffered Stderr " for field called ") - 5974 #? (write-slice-buffered Stderr %ecx) - 5975 #? (write-buffered Stderr "; var name ") - 5976 #? (lookup *eax *(eax+4)) # Var-name - 5977 #? (write-buffered Stderr %eax) - 5978 #? (write-buffered Stderr Newline) - 5979 #? (flush Stderr) - 5980 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 - 5981 } - 5982 # is-deref? = false - 5983 ba/copy-to-edx 0/imm32/false - 5984 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? - 5985 8b/-> *ecx 0/r32/eax # Slice-start - 5986 8a/copy-byte *eax 0/r32/AL - 5987 81 4/subop/and %eax 0xff/imm32 - 5988 3d/compare-eax-and 0x2a/imm32/asterisk - 5989 { - 5990 75/jump-if-!= break/disp8 - 5991 $add-operation-and-inputs-to-stmt:inout-is-deref: - 5992 ff 0/subop/increment *ecx - 5993 ba/copy-to-edx 1/imm32/true - 5994 } - 5995 (lookup-var-or-literal %ecx *(ebp+0x10) %esi) - 5996 $add-operation-and-inputs-to-stmt:save-var: - 5997 8d/copy-address *(edi+0xc) 0/r32/eax - 5998 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts - 5999 # - 6000 e9/jump loop/disp32 - 6001 } - 6002 $add-operation-and-inputs-to-stmt:end: - 6003 # . reclaim locals - 6004 81 0/subop/add %esp 0x10/imm32 - 6005 # . restore registers - 6006 5f/pop-to-edi - 6007 5e/pop-to-esi - 6008 5b/pop-to-ebx - 6009 5a/pop-to-edx - 6010 59/pop-to-ecx - 6011 58/pop-to-eax - 6012 # . epilogue - 6013 89/<- %esp 5/r32/ebp - 6014 5d/pop-to-ebp - 6015 c3/return - 6016 - 6017 $add-operation-and-inputs-to-stmt:abort: - 6018 # error("invalid statement '" line "'\n") - 6019 (rewind-stream *(ebp+8)) - 6020 (write-buffered Stderr "invalid identifier '") - 6021 (flush Stderr) - 6022 (write-stream 2 *(ebp+8)) - 6023 (write-buffered Stderr "'\n") - 6024 (flush Stderr) - 6025 # . syscall(exit, 1) - 6026 bb/copy-to-ebx 1/imm32 - 6027 b8/copy-to-eax 1/imm32/exit - 6028 cd/syscall 0x80/imm8 - 6029 # never gets here - 6030 - 6031 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean - 6032 # . prologue - 6033 55/push-ebp - 6034 89/<- %ebp 4/r32/esp - 6035 # . save registers - 6036 51/push-ecx - 6037 # var word-slice/ecx: slice - 6038 68/push 0/imm32/end - 6039 68/push 0/imm32/start - 6040 89/<- %ecx 4/r32/esp - 6041 # result = false - 6042 b8/copy-to-eax 0/imm32/false - 6043 (rewind-stream *(ebp+8)) - 6044 { - 6045 (next-mu-token *(ebp+8) %ecx) - 6046 # if slice-empty?(word-slice) break - 6047 (slice-empty? %ecx) - 6048 3d/compare-eax-and 0/imm32/false - 6049 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) - 6050 0f 85/jump-if-!= break/disp32 - 6051 # if slice-starts-with?(word-slice, '#') break - 6052 # . eax = *word-slice->start - 6053 8b/-> *ecx 0/r32/eax - 6054 8a/copy-byte *eax 0/r32/AL - 6055 81 4/subop/and %eax 0xff/imm32 - 6056 # . if (eax == '#') break - 6057 3d/compare-eax-and 0x23/imm32/hash - 6058 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) - 6059 0f 84/jump-if-= break/disp32 - 6060 # if slice-equal?(word-slice, '<-') return true - 6061 (slice-equal? %ecx "<-") - 6062 3d/compare-eax-and 0/imm32/false - 6063 74/jump-if-= loop/disp8 - 6064 b8/copy-to-eax 1/imm32/true - 6065 } - 6066 $stmt-has-outputs:end: - 6067 (rewind-stream *(ebp+8)) - 6068 # . reclaim locals - 6069 81 0/subop/add %esp 8/imm32 - 6070 # . restore registers - 6071 59/pop-to-ecx - 6072 # . epilogue - 6073 89/<- %esp 5/r32/ebp - 6074 5d/pop-to-ebp - 6075 c3/return - 6076 - 6077 # if 'name' starts with a digit, create a new literal var for it - 6078 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found - 6079 lookup-var-or-literal: # name: (addr slice), vars: (addr stack (handle var)), out: (addr handle var) - 6080 # . prologue - 6081 55/push-ebp - 6082 89/<- %ebp 4/r32/esp - 6083 # . save registers - 6084 50/push-eax - 6085 51/push-ecx - 6086 56/push-esi - 6087 # esi = name - 6088 8b/-> *(ebp+8) 6/r32/esi - 6089 # if slice-empty?(name) abort - 6090 (slice-empty? %esi) # => eax - 6091 3d/compare-eax-and 0/imm32/false - 6092 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 - 6093 # var c/ecx: byte = *name->start - 6094 8b/-> *esi 1/r32/ecx - 6095 8a/copy-byte *ecx 1/r32/CL - 6096 81 4/subop/and %ecx 0xff/imm32 - 6097 # if is-decimal-digit?(c) return new var(name) - 6098 { - 6099 (is-decimal-digit? %ecx) # => eax - 6100 3d/compare-eax-and 0/imm32/false - 6101 74/jump-if-= break/disp8 - 6102 (new-literal-integer Heap %esi *(ebp+0x10)) - 6103 eb/jump $lookup-var-or-literal:end/disp8 - 6104 } - 6105 # else if (c == '"') return new var(name) - 6106 { - 6107 81 7/subop/compare %ecx 0x22/imm32/dquote - 6108 75/jump-if-!= break/disp8 - 6109 (new-literal Heap %esi *(ebp+0x10)) - 6110 eb/jump $lookup-var-or-literal:end/disp8 - 6111 } - 6112 # otherwise return lookup-var(name, vars) - 6113 { - 6114 (lookup-var %esi *(ebp+0xc)) # => eax - 6115 } - 6116 $lookup-var-or-literal:end: - 6117 # . restore registers - 6118 5e/pop-to-esi - 6119 59/pop-to-ecx - 6120 58/pop-to-eax - 6121 # . epilogue - 6122 89/<- %esp 5/r32/ebp - 6123 5d/pop-to-ebp - 6124 c3/return - 6125 - 6126 $lookup-var-or-literal:abort: - 6127 (write-buffered Stderr "empty variable!") - 6128 (flush Stderr) - 6129 # . syscall(exit, 1) - 6130 bb/copy-to-ebx 1/imm32 - 6131 b8/copy-to-eax 1/imm32/exit - 6132 cd/syscall 0x80/imm8 - 6133 # never gets here - 6134 - 6135 # return first 'name' from the top (back) of 'vars' and abort if not found - 6136 lookup-var: # name: (addr slice), vars: (addr stack (handle var)), out: (addr handle var) - 6137 # . prologue - 6138 55/push-ebp - 6139 89/<- %ebp 4/r32/esp - 6140 # . save registers - 6141 50/push-eax - 6142 # - 6143 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10)) - 6144 # if (*out == 0) abort - 6145 8b/-> *(ebp+0x10) 0/r32/eax - 6146 81 7/subop/compare *eax 0/imm32 - 6147 74/jump-if-= $lookup-var:abort/disp8 - 6148 $lookup-var:end: - 6149 # . restore registers - 6150 58/pop-to-eax - 6151 # . epilogue - 6152 89/<- %esp 5/r32/ebp - 6153 5d/pop-to-ebp - 6154 c3/return - 6155 - 6156 $lookup-var:abort: - 6157 (write-buffered Stderr "unknown variable '") - 6158 (write-slice-buffered Stderr *(ebp+8)) - 6159 (write-buffered Stderr "'\n") - 6160 (flush Stderr) - 6161 # . syscall(exit, 1) - 6162 bb/copy-to-ebx 1/imm32 - 6163 b8/copy-to-eax 1/imm32/exit - 6164 cd/syscall 0x80/imm8 - 6165 # never gets here - 6166 - 6167 # return first 'name' from the top (back) of 'vars', and 0/null if not found - 6168 lookup-var-helper: # name: (addr slice), vars: (addr stack (handle var)), out: (addr handle var) - 6169 # pseudocode: - 6170 # var curr: (addr handle var) = &vars->data[vars->top - 8] - 6171 # var min = vars->data - 6172 # while curr >= min - 6173 # var v: (handle var) = *curr - 6174 # if v->name == name - 6175 # return - 6176 # curr -= 8 - 6177 # - 6178 # . prologue - 6179 55/push-ebp - 6180 89/<- %ebp 4/r32/esp - 6181 # . save registers - 6182 50/push-eax - 6183 51/push-ecx - 6184 52/push-edx - 6185 53/push-ebx - 6186 56/push-esi - 6187 # clear out - 6188 (zero-out *(ebp+0x10) *Handle-size) - 6189 # esi = vars - 6190 8b/-> *(ebp+0xc) 6/r32/esi - 6191 # ebx = vars->top - 6192 8b/-> *esi 3/r32/ebx - 6193 # if (vars->top > vars->size) abort - 6194 3b/compare<- *(esi+4) 0/r32/eax - 6195 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 - 6196 # var min/edx: (addr handle var) = vars->data - 6197 8d/copy-address *(esi+8) 2/r32/edx - 6198 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 8] - 6199 8d/copy-address *(esi+ebx) 3/r32/ebx - 6200 { - 6201 # if (curr < min) return - 6202 39/compare %ebx 2/r32/edx - 6203 0f 82/jump-if-addr< break/disp32 - 6204 # var v/ecx: (addr var) = lookup(*curr) - 6205 (lookup *ebx *(ebx+4)) # => eax - 6206 89/<- %ecx 0/r32/eax - 6207 # var vn/eax: (addr array byte) = lookup(v->name) - 6208 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 6209 # if (vn == name) return curr - 6210 (slice-equal? *(ebp+8) %eax) # => eax - 6211 3d/compare-eax-and 0/imm32/false - 6212 { + 5702 # . syscall(exit, 1) + 5703 bb/copy-to-ebx 1/imm32 + 5704 b8/copy-to-eax 1/imm32/exit + 5705 cd/syscall 0x80/imm8 + 5706 # never gets here + 5707 + 5708 new-block-name: # fn: (addr function), out: (addr handle var) + 5709 # . prologue + 5710 55/push-ebp + 5711 89/<- %ebp 4/r32/esp + 5712 # . save registers + 5713 50/push-eax + 5714 51/push-ecx + 5715 52/push-edx + 5716 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' + 5717 8b/-> *(ebp+8) 0/r32/eax + 5718 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 5719 8b/-> *eax 0/r32/eax # String-size + 5720 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' + 5721 89/<- %ecx 0/r32/eax + 5722 # var name/edx: (stream byte n) + 5723 29/subtract-from %esp 1/r32/ecx + 5724 ff 6/subop/push %ecx + 5725 68/push 0/imm32/read + 5726 68/push 0/imm32/write + 5727 89/<- %edx 4/r32/esp + 5728 (clear-stream %edx) + 5729 # eax = fn->name + 5730 8b/-> *(ebp+8) 0/r32/eax + 5731 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 5732 # construct result using Next-block-index (and increment it) + 5733 (write %edx "$") + 5734 (write %edx %eax) + 5735 (write %edx ":") + 5736 (print-int32 %edx *Next-block-index) + 5737 ff 0/subop/increment *Next-block-index + 5738 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) + 5739 # . eax = name->write + 5740 8b/-> *edx 0/r32/eax + 5741 # . edx = name->data + 5742 8d/copy-address *(edx+0xc) 2/r32/edx + 5743 # . eax = name->write + name->data + 5744 01/add-to %eax 2/r32/edx + 5745 # . push {edx, eax} + 5746 ff 6/subop/push %eax + 5747 ff 6/subop/push %edx + 5748 89/<- %eax 4/r32/esp + 5749 # out = new literal(s) + 5750 (new-literal Heap %eax *(ebp+0xc)) + 5751 #? 8b/-> *(ebp+0xc) 0/r32/eax + 5752 #? (write-buffered Stderr "type allocid in caller after new-literal: ") + 5753 #? (print-int32-buffered Stderr *(eax+8)) + 5754 #? (write-buffered Stderr " for var ") + 5755 #? (print-int32-buffered Stderr %eax) + 5756 #? (write-buffered Stderr Newline) + 5757 #? (flush Stderr) + 5758 $new-block-name:end: + 5759 # . reclaim locals + 5760 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} + 5761 81 0/subop/add %ecx 8/imm32 # slice + 5762 01/add-to %esp 1/r32/ecx + 5763 # . restore registers + 5764 5a/pop-to-edx + 5765 59/pop-to-ecx + 5766 58/pop-to-eax + 5767 # . epilogue + 5768 89/<- %esp 5/r32/ebp + 5769 5d/pop-to-ebp + 5770 c3/return + 5771 + 5772 == data + 5773 + 5774 # Global state added to each var record when parsing a function + 5775 Next-block-index: # (addr int) + 5776 1/imm32 + 5777 + 5778 == code + 5779 + 5780 check-no-tokens-left: # line: (addr stream byte) + 5781 # . prologue + 5782 55/push-ebp + 5783 89/<- %ebp 4/r32/esp + 5784 # . save registers + 5785 50/push-eax + 5786 51/push-ecx + 5787 # var s/ecx: slice + 5788 68/push 0/imm32/end + 5789 68/push 0/imm32/start + 5790 89/<- %ecx 4/r32/esp + 5791 # + 5792 (next-mu-token *(ebp+8) %ecx) + 5793 # if slice-empty?(s) return + 5794 (slice-empty? %ecx) + 5795 3d/compare-eax-and 0/imm32/false + 5796 75/jump-if-!= $check-no-tokens-left:end/disp8 + 5797 # if (slice-starts-with?(s, '#') return + 5798 # . eax = *s->start + 5799 8b/-> *edx 0/r32/eax + 5800 8a/copy-byte *eax 0/r32/AL + 5801 81 4/subop/and %eax 0xff/imm32 + 5802 # . if (eax == '#') continue + 5803 3d/compare-eax-and 0x23/imm32/hash + 5804 74/jump-if-= $check-no-tokens-left:end/disp8 + 5805 # abort + 5806 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") + 5807 (rewind-stream %ecx) + 5808 (write-stream 2 %ecx) + 5809 (write-buffered Stderr "'\n") + 5810 (flush Stderr) + 5811 # . syscall(exit, 1) + 5812 bb/copy-to-ebx 1/imm32 + 5813 b8/copy-to-eax 1/imm32/exit + 5814 cd/syscall 0x80/imm8 + 5815 # never gets here + 5816 $check-no-tokens-left:end: + 5817 # . reclaim locals + 5818 81 0/subop/add %esp 8/imm32 + 5819 # . restore registers + 5820 59/pop-to-ecx + 5821 58/pop-to-eax + 5822 # . epilogue + 5823 89/<- %esp 5/r32/ebp + 5824 5d/pop-to-ebp + 5825 c3/return + 5826 + 5827 parse-mu-named-block: # name: (addr slice), in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt) + 5828 # pseudocode: + 5829 # var v: (handle var) + 5830 # new-literal(name, v) + 5831 # push(vars, {v, false}) + 5832 # parse-mu-block(in, vars, fn, out) + 5833 # pop(vars) + 5834 # out->tag = block + 5835 # out->var = v + 5836 # + 5837 # . prologue + 5838 55/push-ebp + 5839 89/<- %ebp 4/r32/esp + 5840 # . save registers + 5841 50/push-eax + 5842 51/push-ecx + 5843 57/push-edi + 5844 # var v/ecx: (handle var) + 5845 68/push 0/imm32 + 5846 68/push 0/imm32 + 5847 89/<- %ecx 4/r32/esp + 5848 # + 5849 (new-literal Heap *(ebp+8) %ecx) + 5850 # push(vars, v) + 5851 (push *(ebp+0x10) *ecx) + 5852 (push *(ebp+0x10) *(ecx+4)) + 5853 (push *(ebp+0x10) 0) # false + 5854 # + 5855 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) + 5856 # pop v off vars + 5857 (pop *(ebp+0x10)) # => eax + 5858 (pop *(ebp+0x10)) # => eax + 5859 (pop *(ebp+0x10)) # => eax + 5860 # var out-addr/edi: (addr stmt) = lookup(*out) + 5861 8b/-> *(ebp+0x18) 7/r32/edi + 5862 (lookup *edi *(edi+4)) # => eax + 5863 89/<- %edi 0/r32/eax + 5864 # out-addr->tag = named-block + 5865 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag + 5866 # out-addr->var = v + 5867 8b/-> *ecx 0/r32/eax + 5868 89/<- *(edi+0xc) 0/r32/eax # Block-var + 5869 8b/-> *(ecx+4) 0/r32/eax + 5870 89/<- *(edi+0x10) 0/r32/eax # Block-var + 5871 $parse-mu-named-block:end: + 5872 # . reclaim locals + 5873 81 0/subop/add %esp 8/imm32 + 5874 # . restore registers + 5875 5f/pop-to-edi + 5876 59/pop-to-ecx + 5877 58/pop-to-eax + 5878 # . epilogue + 5879 89/<- %esp 5/r32/ebp + 5880 5d/pop-to-ebp + 5881 c3/return + 5882 + 5883 parse-mu-var-def: # line: (addr stream byte), vars: (addr stack live-var), out: (addr handle stmt) + 5884 # . prologue + 5885 55/push-ebp + 5886 89/<- %ebp 4/r32/esp + 5887 # . save registers + 5888 50/push-eax + 5889 51/push-ecx + 5890 52/push-edx + 5891 57/push-edi + 5892 # edi = out + 5893 8b/-> *(ebp+0x10) 7/r32/edi + 5894 # var word-slice/ecx: slice + 5895 68/push 0/imm32/end + 5896 68/push 0/imm32/start + 5897 89/<- %ecx 4/r32/esp + 5898 # var v/edx: (handle var) + 5899 68/push 0/imm32 + 5900 68/push 0/imm32 + 5901 89/<- %edx 4/r32/esp + 5902 # v = parse-var-with-type(next-mu-token(line)) + 5903 (next-mu-token *(ebp+8) %ecx) + 5904 (parse-var-with-type %ecx *(ebp+8) %edx) + 5905 # + 5906 (push *(ebp+0xc) *edx) + 5907 (push *(ebp+0xc) *(edx+4)) + 5908 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing + 5909 # either v has no register and there's no more to this line + 5910 (lookup *edx *(edx+4)) # => eax + 5911 8b/-> *(eax+0x18) 0/r32/eax # Var-register + 5912 3d/compare-eax-and 0/imm32 + 5913 { + 5914 75/jump-if-!= break/disp8 + 5915 # TODO: ensure that there's nothing else on this line + 5916 (new-var-def Heap *edx *(edx+4) %edi) + 5917 eb/jump $parse-mu-var-def:end/disp8 + 5918 } + 5919 # or v has a register and there's more to this line + 5920 { + 5921 74/jump-if-= break/disp8 + 5922 # ensure that the next word is '<-' + 5923 (next-mu-token *(ebp+8) %ecx) + 5924 (slice-equal? %ecx "<-") # => eax + 5925 3d/compare-eax-and 0/imm32/false + 5926 74/jump-if-= $parse-mu-var-def:abort/disp8 + 5927 # + 5928 (new-reg-var-def Heap *edx *(edx+4) %edi) + 5929 (lookup *edi *(edi+4)) # => eax + 5930 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc)) + 5931 } + 5932 $parse-mu-var-def:end: + 5933 # . reclaim locals + 5934 81 0/subop/add %esp 0x10/imm32 + 5935 # . restore registers + 5936 5f/pop-to-edi + 5937 5a/pop-to-edx + 5938 59/pop-to-ecx + 5939 58/pop-to-eax + 5940 # . epilogue + 5941 89/<- %esp 5/r32/ebp + 5942 5d/pop-to-ebp + 5943 c3/return + 5944 + 5945 $parse-mu-var-def:abort: + 5946 (rewind-stream *(ebp+8)) + 5947 # error("register variable requires a valid instruction to initialize but got '" line "'\n") + 5948 (write-buffered Stderr "register variable requires a valid instruction to initialize but got '") + 5949 (flush Stderr) + 5950 (write-stream 2 *(ebp+8)) + 5951 (write-buffered Stderr "'\n") + 5952 (flush Stderr) + 5953 # . syscall(exit, 1) + 5954 bb/copy-to-ebx 1/imm32 + 5955 b8/copy-to-eax 1/imm32/exit + 5956 cd/syscall 0x80/imm8 + 5957 # never gets here + 5958 + 5959 test-parse-mu-var-def: + 5960 # 'var n: int' + 5961 # . prologue + 5962 55/push-ebp + 5963 89/<- %ebp 4/r32/esp + 5964 # setup + 5965 (clear-stream _test-input-stream) + 5966 (write _test-input-stream "n: int\n") # caller has consumed the 'var' + 5967 # var out/esi: (handle stmt) + 5968 68/push 0/imm32 + 5969 68/push 0/imm32 + 5970 89/<- %esi 4/r32/esp + 5971 # var vars/ecx: (stack (addr var) 16) + 5972 81 5/subop/subtract %esp 0xc0/imm32 + 5973 68/push 0xc0/imm32/size + 5974 68/push 0/imm32/top + 5975 89/<- %ecx 4/r32/esp + 5976 (clear-stack %ecx) + 5977 # convert + 5978 (parse-mu-var-def _test-input-stream %ecx %esi) + 5979 # var out-addr/esi: (addr stmt) + 5980 (lookup *esi *(esi+4)) # => eax + 5981 89/<- %esi 0/r32/eax + 5982 # + 5983 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def + 5984 # var v/ecx: (addr var) = lookup(out->var) + 5985 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax + 5986 89/<- %ecx 0/r32/eax + 5987 # v->name + 5988 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 5989 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") + 5990 # v->register + 5991 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register + 5992 # v->type == int + 5993 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 5994 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Tree-is-atom + 5995 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Tree-value + 5996 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Tree-right + 5997 # . epilogue + 5998 89/<- %esp 5/r32/ebp + 5999 5d/pop-to-ebp + 6000 c3/return + 6001 + 6002 test-parse-mu-reg-var-def: + 6003 # 'var n/eax: int <- copy 0' + 6004 # . prologue + 6005 55/push-ebp + 6006 89/<- %ebp 4/r32/esp + 6007 # setup + 6008 (clear-stream _test-input-stream) + 6009 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' + 6010 # var out/esi: (handle stmt) + 6011 68/push 0/imm32 + 6012 68/push 0/imm32 + 6013 89/<- %esi 4/r32/esp + 6014 # var vars/ecx: (stack (addr var) 16) + 6015 81 5/subop/subtract %esp 0xc0/imm32 + 6016 68/push 0xc0/imm32/size + 6017 68/push 0/imm32/top + 6018 89/<- %ecx 4/r32/esp + 6019 (clear-stack %ecx) + 6020 # convert + 6021 (parse-mu-var-def _test-input-stream %ecx %esi) + 6022 # var out-addr/esi: (addr stmt) + 6023 (lookup *esi *(esi+4)) # => eax + 6024 89/<- %esi 0/r32/eax + 6025 # + 6026 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def + 6027 # var v/ecx: (addr var) = lookup(out->outputs->value) + 6028 # . eax: (addr stmt-var) = lookup(out->outputs) + 6029 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax + 6030 # . + 6031 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next + 6032 # . eax: (addr var) = lookup(eax->value) + 6033 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 6034 # . ecx = eax + 6035 89/<- %ecx 0/r32/eax + 6036 # v->name + 6037 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 6038 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name + 6039 # v->register + 6040 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 6041 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") + 6042 # v->type == int + 6043 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 6044 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Tree-is-atom + 6045 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Tree-value + 6046 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Tree-right + 6047 # . epilogue + 6048 89/<- %esp 5/r32/ebp + 6049 5d/pop-to-ebp + 6050 c3/return + 6051 + 6052 parse-mu-stmt: # line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt) + 6053 # pseudocode: + 6054 # var name: slice + 6055 # allocate(Heap, Stmt-size, out) + 6056 # var out-addr: (addr stmt) = lookup(*out) + 6057 # out-addr->tag = stmt + 6058 # if stmt-has-outputs?(line) + 6059 # while true + 6060 # name = next-mu-token(line) + 6061 # if (name == '<-') break + 6062 # assert(is-identifier?(name)) + 6063 # var v: (handle var) = lookup-or-define-var(name, vars, fn) # regular stmts may define vars in fn outputs + 6064 # out-addr->outputs = append(v, out-addr->outputs) + 6065 # add-operation-and-inputs-to-stmt(out-addr, line, vars) + 6066 # + 6067 # . prologue + 6068 55/push-ebp + 6069 89/<- %ebp 4/r32/esp + 6070 # . save registers + 6071 50/push-eax + 6072 51/push-ecx + 6073 52/push-edx + 6074 53/push-ebx + 6075 57/push-edi + 6076 # var name/ecx: slice + 6077 68/push 0/imm32/end + 6078 68/push 0/imm32/start + 6079 89/<- %ecx 4/r32/esp + 6080 # var is-deref?/edx: boolean = false + 6081 ba/copy-to-edx 0/imm32/false + 6082 # var v: (handle var) + 6083 68/push 0/imm32 + 6084 68/push 0/imm32 + 6085 89/<- %ebx 4/r32/esp + 6086 # + 6087 (allocate Heap *Stmt-size *(ebp+0x14)) + 6088 # var out-addr/edi: (addr stmt) = lookup(*out) + 6089 8b/-> *(ebp+0x14) 7/r32/edi + 6090 (lookup *edi *(edi+4)) # => eax + 6091 89/<- %edi 0/r32/eax + 6092 # out-addr->tag = 1/stmt + 6093 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag + 6094 { + 6095 (stmt-has-outputs? *(ebp+8)) + 6096 3d/compare-eax-and 0/imm32/false + 6097 0f 84/jump-if-= break/disp32 + 6098 { + 6099 $parse-mu-stmt:read-outputs: + 6100 # name = next-mu-token(line) + 6101 (next-mu-token *(ebp+8) %ecx) + 6102 # if slice-empty?(word-slice) break + 6103 (slice-empty? %ecx) # => eax + 6104 3d/compare-eax-and 0/imm32/false + 6105 0f 85/jump-if-!= break/disp32 + 6106 # if (name == "<-") break + 6107 (slice-equal? %ecx "<-") # => eax + 6108 3d/compare-eax-and 0/imm32/false + 6109 0f 85/jump-if-!= break/disp32 + 6110 # is-deref? = false + 6111 ba/copy-to-edx 0/imm32/false + 6112 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? + 6113 8b/-> *ecx 0/r32/eax # Slice-start + 6114 8a/copy-byte *eax 0/r32/AL + 6115 81 4/subop/and %eax 0xff/imm32 + 6116 3d/compare-eax-and 0x2a/imm32/asterisk + 6117 { + 6118 75/jump-if-!= break/disp8 + 6119 ff 0/subop/increment *ecx + 6120 ba/copy-to-edx 1/imm32/true + 6121 } + 6122 # assert(is-identifier?(name)) + 6123 (is-identifier? %ecx) # => eax + 6124 3d/compare-eax-and 0/imm32/false + 6125 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 + 6126 # + 6127 (lookup-or-define-var %ecx *(ebp+0xc) *(ebp+0x10) %ebx) + 6128 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs + 6129 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) %edx %eax) # Stmt1-outputs + 6130 # + 6131 e9/jump loop/disp32 + 6132 } + 6133 } + 6134 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc)) + 6135 $parse-mu-stmt:end: + 6136 # . reclaim locals + 6137 81 0/subop/add %esp 0x10/imm32 + 6138 # . restore registers + 6139 5f/pop-to-edi + 6140 5b/pop-to-ebx + 6141 5a/pop-to-edx + 6142 59/pop-to-ecx + 6143 58/pop-to-eax + 6144 # . epilogue + 6145 89/<- %esp 5/r32/ebp + 6146 5d/pop-to-ebp + 6147 c3/return + 6148 + 6149 $parse-mu-stmt:abort: + 6150 # error("invalid identifier '" name "'\n") + 6151 (write-buffered Stderr "invalid identifier '") + 6152 (write-slice-buffered Stderr %ecx) + 6153 (write-buffered Stderr "'\n") + 6154 (flush Stderr) + 6155 # . syscall(exit, 1) + 6156 bb/copy-to-ebx 1/imm32 + 6157 b8/copy-to-eax 1/imm32/exit + 6158 cd/syscall 0x80/imm8 + 6159 # never gets here + 6160 + 6161 add-operation-and-inputs-to-stmt: # stmt: (addr stmt), line: (addr stream byte), vars: (addr stack live-var) + 6162 # pseudocode: + 6163 # stmt->name = slice-to-string(next-mu-token(line)) + 6164 # while true + 6165 # name = next-mu-token(line) + 6166 # v = lookup-var-or-literal(name) + 6167 # stmt->inouts = append(v, stmt->inouts) + 6168 # + 6169 # . prologue + 6170 55/push-ebp + 6171 89/<- %ebp 4/r32/esp + 6172 # . save registers + 6173 50/push-eax + 6174 51/push-ecx + 6175 52/push-edx + 6176 53/push-ebx + 6177 56/push-esi + 6178 57/push-edi + 6179 # edi = stmt + 6180 8b/-> *(ebp+8) 7/r32/edi + 6181 # var name/ecx: slice + 6182 68/push 0/imm32/end + 6183 68/push 0/imm32/start + 6184 89/<- %ecx 4/r32/esp + 6185 # var is-deref?/edx: boolean = false + 6186 ba/copy-to-edx 0/imm32/false + 6187 # var v/esi: (handle var) + 6188 68/push 0/imm32 + 6189 68/push 0/imm32 + 6190 89/<- %esi 4/r32/esp + 6191 $add-operation-and-inputs-to-stmt:read-operation: + 6192 (next-mu-token *(ebp+0xc) %ecx) + 6193 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation + 6194 (slice-to-string Heap %ecx %eax) + 6195 # var is-get?/ebx: boolean = (name == "get") + 6196 (slice-equal? %ecx "get") # => eax + 6197 89/<- %ebx 0/r32/eax + 6198 { + 6199 $add-operation-and-inputs-to-stmt:read-inouts: + 6200 # name = next-mu-token(line) + 6201 (next-mu-token *(ebp+0xc) %ecx) + 6202 # if slice-empty?(word-slice) break + 6203 (slice-empty? %ecx) # => eax + 6204 3d/compare-eax-and 0/imm32/false + 6205 0f 85/jump-if-!= break/disp32 + 6206 # if (name == "<-") abort + 6207 (slice-equal? %ecx "<-") + 6208 3d/compare-eax-and 0/imm32/false + 6209 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 + 6210 # if (is-get? && second operand) lookup or create offset + 6211 { + 6212 81 7/subop/compare %ebx 0/imm32/false 6213 74/jump-if-= break/disp8 - 6214 # esi = out - 6215 8b/-> *(ebp+0x10) 6/r32/esi - 6216 # *out = *curr - 6217 8b/-> *ebx 0/r32/eax - 6218 89/<- *esi 0/r32/eax - 6219 8b/-> *(ebx+4) 0/r32/eax - 6220 89/<- *(esi+4) 0/r32/eax - 6221 # return - 6222 eb/jump $lookup-var-helper:end/disp8 - 6223 } - 6224 # curr -= 8 - 6225 81 5/subop/subtract %ebx 8/imm32 - 6226 e9/jump loop/disp32 - 6227 } - 6228 $lookup-var-helper:end: - 6229 # . restore registers - 6230 5e/pop-to-esi - 6231 5b/pop-to-ebx - 6232 5a/pop-to-edx - 6233 59/pop-to-ecx - 6234 58/pop-to-eax - 6235 # . epilogue - 6236 89/<- %esp 5/r32/ebp - 6237 5d/pop-to-ebp - 6238 c3/return - 6239 - 6240 $lookup-var-helper:error1: - 6241 (write-buffered Stderr "malformed stack when looking up '") - 6242 (write-slice-buffered Stderr *(ebp+8)) - 6243 (write-buffered Stderr "'\n") - 6244 (flush Stderr) - 6245 # . syscall(exit, 1) - 6246 bb/copy-to-ebx 1/imm32 - 6247 b8/copy-to-eax 1/imm32/exit - 6248 cd/syscall 0x80/imm8 - 6249 # never gets here - 6250 - 6251 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found - 6252 lookup-or-define-var: # name: (addr slice), vars: (addr stack (handle var)), fn: (addr function), out: (addr handle var) - 6253 # . prologue - 6254 55/push-ebp - 6255 89/<- %ebp 4/r32/esp - 6256 # . save registers - 6257 50/push-eax - 6258 # - 6259 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x14)) - 6260 { - 6261 # if (out != 0) return - 6262 8b/-> *(ebp+0x14) 0/r32/eax - 6263 81 7/subop/compare *eax 0/imm32 - 6264 75/jump-if-!= break/disp8 - 6265 # if name is one of fn's outputs, return it - 6266 { - 6267 (find-in-function-outputs *(ebp+0x10) *(ebp+8) *(ebp+0x14)) - 6268 8b/-> *(ebp+0x14) 0/r32/eax - 6269 81 7/subop/compare *eax 0/imm32 - 6270 # otherwise abort - 6271 0f 84/jump-if-= $lookup-var:abort/disp32 - 6272 } - 6273 } - 6274 $lookup-or-define-var:end: - 6275 # . restore registers - 6276 58/pop-to-eax - 6277 # . epilogue - 6278 89/<- %esp 5/r32/ebp - 6279 5d/pop-to-ebp - 6280 c3/return - 6281 - 6282 find-in-function-outputs: # fn: (addr function), name: (addr slice), out: (addr handle var) - 6283 # . prologue - 6284 55/push-ebp - 6285 89/<- %ebp 4/r32/esp - 6286 # . save registers - 6287 50/push-eax - 6288 51/push-ecx - 6289 # var curr/ecx: (addr list var) = lookup(fn->outputs) - 6290 8b/-> *(ebp+8) 1/r32/ecx - 6291 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax - 6292 89/<- %ecx 0/r32/eax - 6293 # while curr != null - 6294 { - 6295 81 7/subop/compare %ecx 0/imm32 - 6296 74/jump-if-= break/disp8 - 6297 # var v/eax: (addr var) = lookup(curr->value) - 6298 (lookup *ecx *(ecx+4)) # List-value List-value => eax - 6299 # var s/eax: (addr array byte) = lookup(v->name) - 6300 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 6301 # if (s == name) return curr->value - 6302 (slice-equal? *(ebp+0xc) %eax) # => eax - 6303 3d/compare-eax-and 0/imm32/false - 6304 { - 6305 74/jump-if-= break/disp8 - 6306 # var edi = out - 6307 57/push-edi - 6308 8b/-> *(ebp+0x10) 7/r32/edi - 6309 # *out = curr->value - 6310 8b/-> *ecx 0/r32/eax - 6311 89/<- *edi 0/r32/eax - 6312 8b/-> *(ecx+4) 0/r32/eax - 6313 89/<- *(edi+4) 0/r32/eax - 6314 # - 6315 5f/pop-to-edi - 6316 eb/jump $find-in-function-outputs:end/disp8 - 6317 } - 6318 # curr = curr->next - 6319 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax - 6320 89/<- %ecx 0/r32/eax - 6321 # - 6322 eb/jump loop/disp8 - 6323 } - 6324 b8/copy-to-eax 0/imm32 - 6325 $find-in-function-outputs:end: - 6326 # . restore registers - 6327 59/pop-to-ecx - 6328 58/pop-to-eax - 6329 # . epilogue - 6330 89/<- %esp 5/r32/ebp - 6331 5d/pop-to-ebp - 6332 c3/return - 6333 - 6334 test-parse-mu-stmt: - 6335 # . prologue - 6336 55/push-ebp - 6337 89/<- %ebp 4/r32/esp - 6338 # setup - 6339 (clear-stream _test-input-stream) - 6340 (write _test-input-stream "increment n\n") - 6341 # var vars/ecx: (stack (addr var) 16) - 6342 81 5/subop/subtract %esp 0x80/imm32 - 6343 68/push 0x80/imm32/size - 6344 68/push 0/imm32/top - 6345 89/<- %ecx 4/r32/esp - 6346 (clear-stack %ecx) - 6347 # var v/edx: (handle var) - 6348 68/push 0/imm32 - 6349 68/push 0/imm32 - 6350 89/<- %edx 4/r32/esp - 6351 # var s/eax: (handle array byte) - 6352 68/push 0/imm32 - 6353 68/push 0/imm32 - 6354 89/<- %eax 4/r32/esp - 6355 # v = new var("n") - 6356 (copy-array Heap "n" %eax) - 6357 (new-var Heap *eax *(eax+4) %edx) - 6358 # - 6359 (push %ecx *edx) - 6360 (push %ecx *(edx+4)) - 6361 # var out/eax: (handle stmt) - 6362 68/push 0/imm32 - 6363 68/push 0/imm32 - 6364 89/<- %eax 4/r32/esp - 6365 # convert - 6366 (parse-mu-stmt _test-input-stream %ecx 0 %eax) - 6367 # var out-addr/edx: (addr stmt) = lookup(*out) - 6368 (lookup *eax *(eax+4)) # => eax - 6369 89/<- %edx 0/r32/eax - 6370 # out->tag - 6371 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 - 6372 # out->operation - 6373 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax - 6374 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation - 6375 # out->inouts->value->name - 6376 # . eax = out->inouts - 6377 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 6378 # . eax = out->inouts->value - 6379 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 6380 # . eax = out->inouts->value->name - 6381 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 6382 # . - 6383 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") - 6384 # . epilogue - 6385 89/<- %esp 5/r32/ebp - 6386 5d/pop-to-ebp - 6387 c3/return - 6388 - 6389 test-parse-mu-stmt-with-comma: - 6390 # . prologue - 6391 55/push-ebp - 6392 89/<- %ebp 4/r32/esp - 6393 # setup - 6394 (clear-stream _test-input-stream) - 6395 (write _test-input-stream "copy-to n, 3\n") - 6396 # var vars/ecx: (stack (addr var) 16) - 6397 81 5/subop/subtract %esp 0x80/imm32 - 6398 68/push 0x80/imm32/size - 6399 68/push 0/imm32/top - 6400 89/<- %ecx 4/r32/esp - 6401 (clear-stack %ecx) - 6402 # var v/edx: (handle var) - 6403 68/push 0/imm32 - 6404 68/push 0/imm32 - 6405 89/<- %edx 4/r32/esp - 6406 # var s/eax: (handle array byte) - 6407 68/push 0/imm32 - 6408 68/push 0/imm32 - 6409 89/<- %eax 4/r32/esp - 6410 # v = new var("n") - 6411 (copy-array Heap "n" %eax) - 6412 (new-var Heap *eax *(eax+4) %edx) - 6413 # - 6414 (push %ecx *edx) - 6415 (push %ecx *(edx+4)) - 6416 # var out/eax: (handle stmt) - 6417 68/push 0/imm32 - 6418 68/push 0/imm32 - 6419 89/<- %eax 4/r32/esp - 6420 # convert - 6421 (parse-mu-stmt _test-input-stream %ecx 0 %eax) - 6422 # var out-addr/edx: (addr stmt) = lookup(*out) - 6423 (lookup *eax *(eax+4)) # => eax - 6424 89/<- %edx 0/r32/eax - 6425 # out->tag - 6426 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 - 6427 # out->operation - 6428 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax - 6429 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation - 6430 # out->inouts->value->name - 6431 # . eax = out->inouts - 6432 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 6433 # . eax = out->inouts->value - 6434 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 6435 # . eax = out->inouts->value->name - 6436 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 6437 # . - 6438 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") - 6439 # . epilogue - 6440 89/<- %esp 5/r32/ebp - 6441 5d/pop-to-ebp - 6442 c3/return - 6443 - 6444 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) - 6445 # . prologue - 6446 55/push-ebp - 6447 89/<- %ebp 4/r32/esp - 6448 # . save registers - 6449 50/push-eax - 6450 51/push-ecx - 6451 # ecx = out - 6452 8b/-> *(ebp+0x14) 1/r32/ecx - 6453 # - 6454 (allocate *(ebp+8) *Var-size %ecx) - 6455 # var out-addr/eax: (addr var) - 6456 (lookup *ecx *(ecx+4)) # => eax - 6457 # out-addr->name = name - 6458 8b/-> *(ebp+0xc) 1/r32/ecx - 6459 89/<- *eax 1/r32/ecx # Var-name - 6460 8b/-> *(ebp+0x10) 1/r32/ecx - 6461 89/<- *(eax+4) 1/r32/ecx # Var-name - 6462 #? (write-buffered Stderr "var ") - 6463 #? (lookup *(ebp+0xc) *(ebp+0x10)) - 6464 #? (write-buffered Stderr %eax) - 6465 #? (write-buffered Stderr " at ") - 6466 #? 8b/-> *(ebp+0x14) 1/r32/ecx - 6467 #? (lookup *ecx *(ecx+4)) # => eax - 6468 #? (print-int32-buffered Stderr %eax) - 6469 #? (write-buffered Stderr Newline) - 6470 #? (flush Stderr) - 6471 $new-var:end: - 6472 # . restore registers - 6473 59/pop-to-ecx - 6474 58/pop-to-eax - 6475 # . epilogue - 6476 89/<- %esp 5/r32/ebp - 6477 5d/pop-to-ebp - 6478 c3/return - 6479 - 6480 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) - 6481 # . prologue - 6482 55/push-ebp - 6483 89/<- %ebp 4/r32/esp - 6484 # . save registers - 6485 50/push-eax - 6486 51/push-ecx - 6487 # if (!is-hex-int?(name)) abort - 6488 (is-hex-int? *(ebp+0xc)) # => eax - 6489 3d/compare-eax-and 0/imm32/false - 6490 0f 84/jump-if-= $new-literal-integer:abort/disp32 - 6491 # out = new var(s) - 6492 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) - 6493 # var out-addr/ecx: (addr var) = lookup(*out) - 6494 8b/-> *(ebp+0x10) 0/r32/eax - 6495 (lookup *eax *(eax+4)) # => eax - 6496 89/<- %ecx 0/r32/eax - 6497 # out-addr->type = new tree() - 6498 8d/copy-address *(ecx+8) 0/r32/eax # Var-type - 6499 (allocate *(ebp+8) *Tree-size %eax) - 6500 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 6501 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom - 6502 # nothing else to do; default type is 'literal' - 6503 $new-literal-integer:end: - 6504 # . reclaim locals - 6505 81 0/subop/add %esp 8/imm32 - 6506 # . restore registers - 6507 59/pop-to-ecx - 6508 58/pop-to-eax - 6509 # . epilogue - 6510 89/<- %esp 5/r32/ebp - 6511 5d/pop-to-ebp - 6512 c3/return - 6513 - 6514 $new-literal-integer:abort: - 6515 (write-buffered Stderr "variable cannot begin with a digit '") - 6516 (write-slice-buffered Stderr *(ebp+0xc)) - 6517 (write-buffered Stderr "'\n") - 6518 (flush Stderr) - 6519 # . syscall(exit, 1) - 6520 bb/copy-to-ebx 1/imm32 - 6521 b8/copy-to-eax 1/imm32/exit - 6522 cd/syscall 0x80/imm8 - 6523 # never gets here - 6524 - 6525 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) - 6526 # . prologue - 6527 55/push-ebp - 6528 89/<- %ebp 4/r32/esp - 6529 # . save registers - 6530 50/push-eax - 6531 51/push-ecx - 6532 # var s/ecx: (handle array byte) - 6533 68/push 0/imm32 - 6534 68/push 0/imm32 - 6535 89/<- %ecx 4/r32/esp - 6536 # s = slice-to-string(name) - 6537 (slice-to-string Heap *(ebp+0xc) %ecx) - 6538 # allocate to out - 6539 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) - 6540 # var out-addr/ecx: (addr var) = lookup(*out) - 6541 8b/-> *(ebp+0x10) 1/r32/ecx - 6542 (lookup *ecx *(ecx+4)) # => eax - 6543 89/<- %ecx 0/r32/eax - 6544 # out-addr->type/eax = new type - 6545 8d/copy-address *(ecx+8) 0/r32/eax # Var-type - 6546 (allocate *(ebp+8) *Tree-size %eax) - 6547 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 6548 # nothing else to do; default type is 'literal' - 6549 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom - 6550 $new-literal:end: - 6551 # . reclaim locals - 6552 81 0/subop/add %esp 8/imm32 - 6553 # . restore registers - 6554 59/pop-to-ecx - 6555 58/pop-to-eax - 6556 # . epilogue - 6557 89/<- %esp 5/r32/ebp - 6558 5d/pop-to-ebp - 6559 c3/return - 6560 - 6561 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) - 6562 # . prologue - 6563 55/push-ebp - 6564 89/<- %ebp 4/r32/esp - 6565 # . save registers - 6566 51/push-ecx - 6567 # var tmp/ecx: (handle array byte) - 6568 68/push 0/imm32 - 6569 68/push 0/imm32 - 6570 89/<- %ecx 4/r32/esp - 6571 # tmp = slice-to-string(name) - 6572 (slice-to-string Heap *(ebp+0xc) %ecx) - 6573 # out = new-var(tmp) - 6574 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) - 6575 $new-var-from-slice:end: - 6576 # . reclaim locals - 6577 81 0/subop/add %esp 8/imm32 + 6214 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 6215 3d/compare-eax-and 0/imm32 + 6216 74/jump-if-= break/disp8 + 6217 (lookup-or-create-constant %eax %ecx %esi) + 6218 #? (lookup *esi *(esi+4)) + 6219 #? (write-buffered Stderr "creating new output var ") + 6220 #? (print-int32-buffered Stderr %eax) + 6221 #? (write-buffered Stderr " for field called ") + 6222 #? (write-slice-buffered Stderr %ecx) + 6223 #? (write-buffered Stderr "; var name ") + 6224 #? (lookup *eax *(eax+4)) # Var-name + 6225 #? (write-buffered Stderr %eax) + 6226 #? (write-buffered Stderr Newline) + 6227 #? (flush Stderr) + 6228 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 + 6229 } + 6230 # is-deref? = false + 6231 ba/copy-to-edx 0/imm32/false + 6232 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? + 6233 8b/-> *ecx 0/r32/eax # Slice-start + 6234 8a/copy-byte *eax 0/r32/AL + 6235 81 4/subop/and %eax 0xff/imm32 + 6236 3d/compare-eax-and 0x2a/imm32/asterisk + 6237 { + 6238 75/jump-if-!= break/disp8 + 6239 $add-operation-and-inputs-to-stmt:inout-is-deref: + 6240 ff 0/subop/increment *ecx + 6241 ba/copy-to-edx 1/imm32/true + 6242 } + 6243 (lookup-var-or-literal %ecx *(ebp+0x10) %esi) + 6244 $add-operation-and-inputs-to-stmt:save-var: + 6245 8d/copy-address *(edi+0xc) 0/r32/eax + 6246 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts + 6247 # + 6248 e9/jump loop/disp32 + 6249 } + 6250 $add-operation-and-inputs-to-stmt:end: + 6251 # . reclaim locals + 6252 81 0/subop/add %esp 0x10/imm32 + 6253 # . restore registers + 6254 5f/pop-to-edi + 6255 5e/pop-to-esi + 6256 5b/pop-to-ebx + 6257 5a/pop-to-edx + 6258 59/pop-to-ecx + 6259 58/pop-to-eax + 6260 # . epilogue + 6261 89/<- %esp 5/r32/ebp + 6262 5d/pop-to-ebp + 6263 c3/return + 6264 + 6265 $add-operation-and-inputs-to-stmt:abort: + 6266 # error("invalid statement '" line "'\n") + 6267 (rewind-stream *(ebp+8)) + 6268 (write-buffered Stderr "invalid identifier '") + 6269 (flush Stderr) + 6270 (write-stream 2 *(ebp+8)) + 6271 (write-buffered Stderr "'\n") + 6272 (flush Stderr) + 6273 # . syscall(exit, 1) + 6274 bb/copy-to-ebx 1/imm32 + 6275 b8/copy-to-eax 1/imm32/exit + 6276 cd/syscall 0x80/imm8 + 6277 # never gets here + 6278 + 6279 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean + 6280 # . prologue + 6281 55/push-ebp + 6282 89/<- %ebp 4/r32/esp + 6283 # . save registers + 6284 51/push-ecx + 6285 # var word-slice/ecx: slice + 6286 68/push 0/imm32/end + 6287 68/push 0/imm32/start + 6288 89/<- %ecx 4/r32/esp + 6289 # result = false + 6290 b8/copy-to-eax 0/imm32/false + 6291 (rewind-stream *(ebp+8)) + 6292 { + 6293 (next-mu-token *(ebp+8) %ecx) + 6294 # if slice-empty?(word-slice) break + 6295 (slice-empty? %ecx) + 6296 3d/compare-eax-and 0/imm32/false + 6297 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) + 6298 0f 85/jump-if-!= break/disp32 + 6299 # if slice-starts-with?(word-slice, '#') break + 6300 # . eax = *word-slice->start + 6301 8b/-> *ecx 0/r32/eax + 6302 8a/copy-byte *eax 0/r32/AL + 6303 81 4/subop/and %eax 0xff/imm32 + 6304 # . if (eax == '#') break + 6305 3d/compare-eax-and 0x23/imm32/hash + 6306 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) + 6307 0f 84/jump-if-= break/disp32 + 6308 # if slice-equal?(word-slice, '<-') return true + 6309 (slice-equal? %ecx "<-") + 6310 3d/compare-eax-and 0/imm32/false + 6311 74/jump-if-= loop/disp8 + 6312 b8/copy-to-eax 1/imm32/true + 6313 } + 6314 $stmt-has-outputs:end: + 6315 (rewind-stream *(ebp+8)) + 6316 # . reclaim locals + 6317 81 0/subop/add %esp 8/imm32 + 6318 # . restore registers + 6319 59/pop-to-ecx + 6320 # . epilogue + 6321 89/<- %esp 5/r32/ebp + 6322 5d/pop-to-ebp + 6323 c3/return + 6324 + 6325 # if 'name' starts with a digit, create a new literal var for it + 6326 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found + 6327 lookup-var-or-literal: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var) + 6328 # . prologue + 6329 55/push-ebp + 6330 89/<- %ebp 4/r32/esp + 6331 # . save registers + 6332 50/push-eax + 6333 51/push-ecx + 6334 56/push-esi + 6335 # esi = name + 6336 8b/-> *(ebp+8) 6/r32/esi + 6337 # if slice-empty?(name) abort + 6338 (slice-empty? %esi) # => eax + 6339 3d/compare-eax-and 0/imm32/false + 6340 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 + 6341 # var c/ecx: byte = *name->start + 6342 8b/-> *esi 1/r32/ecx + 6343 8a/copy-byte *ecx 1/r32/CL + 6344 81 4/subop/and %ecx 0xff/imm32 + 6345 # if is-decimal-digit?(c) return new var(name) + 6346 { + 6347 (is-decimal-digit? %ecx) # => eax + 6348 3d/compare-eax-and 0/imm32/false + 6349 74/jump-if-= break/disp8 + 6350 (new-literal-integer Heap %esi *(ebp+0x10)) + 6351 eb/jump $lookup-var-or-literal:end/disp8 + 6352 } + 6353 # else if (c == '"') return new var(name) + 6354 { + 6355 81 7/subop/compare %ecx 0x22/imm32/dquote + 6356 75/jump-if-!= break/disp8 + 6357 (new-literal Heap %esi *(ebp+0x10)) + 6358 eb/jump $lookup-var-or-literal:end/disp8 + 6359 } + 6360 # otherwise return lookup-var(name, vars) + 6361 { + 6362 (lookup-var %esi *(ebp+0xc)) # => eax + 6363 } + 6364 $lookup-var-or-literal:end: + 6365 # . restore registers + 6366 5e/pop-to-esi + 6367 59/pop-to-ecx + 6368 58/pop-to-eax + 6369 # . epilogue + 6370 89/<- %esp 5/r32/ebp + 6371 5d/pop-to-ebp + 6372 c3/return + 6373 + 6374 $lookup-var-or-literal:abort: + 6375 (write-buffered Stderr "empty variable!") + 6376 (flush Stderr) + 6377 # . syscall(exit, 1) + 6378 bb/copy-to-ebx 1/imm32 + 6379 b8/copy-to-eax 1/imm32/exit + 6380 cd/syscall 0x80/imm8 + 6381 # never gets here + 6382 + 6383 # return first 'name' from the top (back) of 'vars' and abort if not found + 6384 lookup-var: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var) + 6385 # . prologue + 6386 55/push-ebp + 6387 89/<- %ebp 4/r32/esp + 6388 # . save registers + 6389 50/push-eax + 6390 # + 6391 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10)) + 6392 # if (*out == 0) abort + 6393 8b/-> *(ebp+0x10) 0/r32/eax + 6394 81 7/subop/compare *eax 0/imm32 + 6395 74/jump-if-= $lookup-var:abort/disp8 + 6396 $lookup-var:end: + 6397 # . restore registers + 6398 58/pop-to-eax + 6399 # . epilogue + 6400 89/<- %esp 5/r32/ebp + 6401 5d/pop-to-ebp + 6402 c3/return + 6403 + 6404 $lookup-var:abort: + 6405 (write-buffered Stderr "unknown variable '") + 6406 (write-slice-buffered Stderr *(ebp+8)) + 6407 (write-buffered Stderr "'\n") + 6408 (flush Stderr) + 6409 # . syscall(exit, 1) + 6410 bb/copy-to-ebx 1/imm32 + 6411 b8/copy-to-eax 1/imm32/exit + 6412 cd/syscall 0x80/imm8 + 6413 # never gets here + 6414 + 6415 # return first 'name' from the top (back) of 'vars', and 0/null if not found + 6416 lookup-var-helper: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var) + 6417 # pseudocode: + 6418 # var curr: (addr handle var) = &vars->data[vars->top - 12] + 6419 # var min = vars->data + 6420 # while curr >= min + 6421 # var v: (handle var) = *curr + 6422 # if v->name == name + 6423 # return + 6424 # curr -= 12 + 6425 # + 6426 # . prologue + 6427 55/push-ebp + 6428 89/<- %ebp 4/r32/esp + 6429 # . save registers + 6430 50/push-eax + 6431 51/push-ecx + 6432 52/push-edx + 6433 53/push-ebx + 6434 56/push-esi + 6435 # clear out + 6436 (zero-out *(ebp+0x10) *Handle-size) + 6437 # esi = vars + 6438 8b/-> *(ebp+0xc) 6/r32/esi + 6439 # ebx = vars->top + 6440 8b/-> *esi 3/r32/ebx + 6441 # if (vars->top > vars->size) abort + 6442 3b/compare<- *(esi+4) 0/r32/eax + 6443 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 + 6444 # var min/edx: (addr handle var) = vars->data + 6445 8d/copy-address *(esi+8) 2/r32/edx + 6446 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] + 6447 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 + 6448 { + 6449 # if (curr < min) return + 6450 39/compare %ebx 2/r32/edx + 6451 0f 82/jump-if-addr< break/disp32 + 6452 # var v/ecx: (addr var) = lookup(*curr) + 6453 (lookup *ebx *(ebx+4)) # => eax + 6454 89/<- %ecx 0/r32/eax + 6455 # var vn/eax: (addr array byte) = lookup(v->name) + 6456 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 6457 # if (vn == name) return curr + 6458 (slice-equal? *(ebp+8) %eax) # => eax + 6459 3d/compare-eax-and 0/imm32/false + 6460 { + 6461 74/jump-if-= break/disp8 + 6462 # esi = out + 6463 8b/-> *(ebp+0x10) 6/r32/esi + 6464 # *out = *curr + 6465 8b/-> *ebx 0/r32/eax + 6466 89/<- *esi 0/r32/eax + 6467 8b/-> *(ebx+4) 0/r32/eax + 6468 89/<- *(esi+4) 0/r32/eax + 6469 # return + 6470 eb/jump $lookup-var-helper:end/disp8 + 6471 } + 6472 # curr -= 12 + 6473 81 5/subop/subtract %ebx 0xc/imm32 + 6474 e9/jump loop/disp32 + 6475 } + 6476 $lookup-var-helper:end: + 6477 # . restore registers + 6478 5e/pop-to-esi + 6479 5b/pop-to-ebx + 6480 5a/pop-to-edx + 6481 59/pop-to-ecx + 6482 58/pop-to-eax + 6483 # . epilogue + 6484 89/<- %esp 5/r32/ebp + 6485 5d/pop-to-ebp + 6486 c3/return + 6487 + 6488 $lookup-var-helper:error1: + 6489 (write-buffered Stderr "malformed stack when looking up '") + 6490 (write-slice-buffered Stderr *(ebp+8)) + 6491 (write-buffered Stderr "'\n") + 6492 (flush Stderr) + 6493 # . syscall(exit, 1) + 6494 bb/copy-to-ebx 1/imm32 + 6495 b8/copy-to-eax 1/imm32/exit + 6496 cd/syscall 0x80/imm8 + 6497 # never gets here + 6498 + 6499 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found + 6500 lookup-or-define-var: # name: (addr slice), vars: (addr stack live-var), fn: (addr function), out: (addr handle var) + 6501 # . prologue + 6502 55/push-ebp + 6503 89/<- %ebp 4/r32/esp + 6504 # . save registers + 6505 50/push-eax + 6506 # + 6507 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x14)) + 6508 { + 6509 # if (out != 0) return + 6510 8b/-> *(ebp+0x14) 0/r32/eax + 6511 81 7/subop/compare *eax 0/imm32 + 6512 75/jump-if-!= break/disp8 + 6513 # if name is one of fn's outputs, return it + 6514 { + 6515 (find-in-function-outputs *(ebp+0x10) *(ebp+8) *(ebp+0x14)) + 6516 8b/-> *(ebp+0x14) 0/r32/eax + 6517 81 7/subop/compare *eax 0/imm32 + 6518 # otherwise abort + 6519 0f 84/jump-if-= $lookup-var:abort/disp32 + 6520 # update vars + 6521 (push *(ebp+0xc) *eax) + 6522 (push *(ebp+0xc) *(eax+4)) + 6523 (push *(ebp+0xc) 0) # never spill fn-outputs + 6524 } + 6525 } + 6526 $lookup-or-define-var:end: + 6527 # . restore registers + 6528 58/pop-to-eax + 6529 # . epilogue + 6530 89/<- %esp 5/r32/ebp + 6531 5d/pop-to-ebp + 6532 c3/return + 6533 + 6534 find-in-function-outputs: # fn: (addr function), name: (addr slice), out: (addr handle var) + 6535 # . prologue + 6536 55/push-ebp + 6537 89/<- %ebp 4/r32/esp + 6538 # . save registers + 6539 50/push-eax + 6540 51/push-ecx + 6541 # var curr/ecx: (addr list var) = lookup(fn->outputs) + 6542 8b/-> *(ebp+8) 1/r32/ecx + 6543 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax + 6544 89/<- %ecx 0/r32/eax + 6545 # while curr != null + 6546 { + 6547 81 7/subop/compare %ecx 0/imm32 + 6548 74/jump-if-= break/disp8 + 6549 # var v/eax: (addr var) = lookup(curr->value) + 6550 (lookup *ecx *(ecx+4)) # List-value List-value => eax + 6551 # var s/eax: (addr array byte) = lookup(v->name) + 6552 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 6553 # if (s == name) return curr->value + 6554 (slice-equal? *(ebp+0xc) %eax) # => eax + 6555 3d/compare-eax-and 0/imm32/false + 6556 { + 6557 74/jump-if-= break/disp8 + 6558 # var edi = out + 6559 57/push-edi + 6560 8b/-> *(ebp+0x10) 7/r32/edi + 6561 # *out = curr->value + 6562 8b/-> *ecx 0/r32/eax + 6563 89/<- *edi 0/r32/eax + 6564 8b/-> *(ecx+4) 0/r32/eax + 6565 89/<- *(edi+4) 0/r32/eax + 6566 # + 6567 5f/pop-to-edi + 6568 eb/jump $find-in-function-outputs:end/disp8 + 6569 } + 6570 # curr = curr->next + 6571 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax + 6572 89/<- %ecx 0/r32/eax + 6573 # + 6574 eb/jump loop/disp8 + 6575 } + 6576 b8/copy-to-eax 0/imm32 + 6577 $find-in-function-outputs:end: 6578 # . restore registers 6579 59/pop-to-ecx - 6580 # . epilogue - 6581 89/<- %esp 5/r32/ebp - 6582 5d/pop-to-ebp - 6583 c3/return - 6584 - 6585 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) - 6586 # . prologue - 6587 55/push-ebp - 6588 89/<- %ebp 4/r32/esp - 6589 # . save registers - 6590 50/push-eax - 6591 51/push-ecx - 6592 # - 6593 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) - 6594 # var out-addr/eax: (addr stmt) = lookup(*out) - 6595 8b/-> *(ebp+0x14) 0/r32/eax - 6596 (lookup *eax *(eax+4)) # => eax - 6597 # out-addr->tag = stmt - 6598 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag - 6599 # result->var = var - 6600 8b/-> *(ebp+0xc) 1/r32/ecx - 6601 89/<- *(eax+4) 1/r32/ecx # Vardef-var - 6602 8b/-> *(ebp+0x10) 1/r32/ecx - 6603 89/<- *(eax+8) 1/r32/ecx # Vardef-var - 6604 $new-var-def:end: - 6605 # . restore registers - 6606 59/pop-to-ecx - 6607 58/pop-to-eax - 6608 # . epilogue - 6609 89/<- %esp 5/r32/ebp - 6610 5d/pop-to-ebp - 6611 c3/return - 6612 - 6613 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) - 6614 # . prologue - 6615 55/push-ebp - 6616 89/<- %ebp 4/r32/esp - 6617 # . save registers - 6618 50/push-eax - 6619 # eax = out - 6620 8b/-> *(ebp+0x14) 0/r32/eax - 6621 # - 6622 (allocate *(ebp+8) *Stmt-size %eax) - 6623 # var out-addr/eax: (addr stmt) = lookup(*out) - 6624 (lookup *eax *(eax+4)) # => eax - 6625 # set tag - 6626 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag - 6627 # set output - 6628 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs - 6629 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) - 6630 $new-reg-var-def:end: - 6631 # . restore registers - 6632 58/pop-to-eax - 6633 # . epilogue - 6634 89/<- %esp 5/r32/ebp - 6635 5d/pop-to-ebp - 6636 c3/return - 6637 - 6638 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) - 6639 # . prologue - 6640 55/push-ebp - 6641 89/<- %ebp 4/r32/esp - 6642 # . save registers - 6643 50/push-eax - 6644 51/push-ecx - 6645 57/push-edi - 6646 # edi = out - 6647 8b/-> *(ebp+0x1c) 7/r32/edi - 6648 # *out = new list - 6649 (allocate *(ebp+8) *List-size %edi) - 6650 # var out-addr/edi: (addr list _type) = lookup(*out) - 6651 (lookup *edi *(edi+4)) # => eax - 6652 89/<- %edi 0/r32/eax - 6653 # out-addr->value = value - 6654 8b/-> *(ebp+0xc) 0/r32/eax - 6655 89/<- *edi 0/r32/eax # List-value - 6656 8b/-> *(ebp+0x10) 0/r32/eax - 6657 89/<- *(edi+4) 0/r32/eax # List-value - 6658 # if (list == null) return - 6659 81 7/subop/compare *(ebp+0x14) 0/imm32 - 6660 74/jump-if-= $append-list:end/disp8 - 6661 # otherwise append - 6662 $append-list:non-empty-list: - 6663 # var curr/eax: (addr list _type) = lookup(list) - 6664 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax - 6665 # while (curr->next != null) curr = curr->next - 6666 { - 6667 81 7/subop/compare *(eax+8) 0/imm32 # List-next - 6668 74/jump-if-= break/disp8 - 6669 # curr = lookup(curr->next) - 6670 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax - 6671 # - 6672 eb/jump loop/disp8 - 6673 } - 6674 # edi = out - 6675 8b/-> *(ebp+0x1c) 7/r32/edi - 6676 # curr->next = out - 6677 8b/-> *edi 1/r32/ecx - 6678 89/<- *(eax+8) 1/r32/ecx # List-next - 6679 8b/-> *(edi+4) 1/r32/ecx - 6680 89/<- *(eax+0xc) 1/r32/ecx # List-next - 6681 # out = list - 6682 8b/-> *(ebp+0x14) 1/r32/ecx - 6683 89/<- *edi 1/r32/ecx - 6684 8b/-> *(ebp+0x18) 1/r32/ecx - 6685 89/<- *(edi+4) 1/r32/ecx - 6686 $append-list:end: - 6687 # . restore registers - 6688 5f/pop-to-edi - 6689 59/pop-to-ecx - 6690 58/pop-to-eax - 6691 # . epilogue - 6692 89/<- %esp 5/r32/ebp - 6693 5d/pop-to-ebp - 6694 c3/return - 6695 - 6696 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) - 6697 # . prologue - 6698 55/push-ebp - 6699 89/<- %ebp 4/r32/esp - 6700 # . save registers - 6701 50/push-eax - 6702 51/push-ecx - 6703 57/push-edi - 6704 # edi = out - 6705 8b/-> *(ebp+0x20) 7/r32/edi - 6706 # out = new stmt-var - 6707 (allocate *(ebp+8) *Stmt-var-size %edi) - 6708 # var out-addr/ecx: (addr stmt-var) = lookup(*out) - 6709 (lookup *edi *(edi+4)) # => eax - 6710 89/<- %ecx 0/r32/eax - 6711 # out-addr->value = v - 6712 8b/-> *(ebp+0xc) 0/r32/eax - 6713 89/<- *ecx 0/r32/eax # Stmt-var-value - 6714 8b/-> *(ebp+0x10) 0/r32/eax - 6715 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value - 6716 # out-addr->is-deref? = is-deref? - 6717 8b/-> *(ebp+0x1c) 0/r32/eax - 6718 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref - 6719 # if (vars == null) return result - 6720 81 7/subop/compare *(ebp+0x14) 0/imm32/null - 6721 74/jump-if-= $append-stmt-var:end/disp8 - 6722 # otherwise append - 6723 # var curr/eax: (addr stmt-var) = lookup(vars) - 6724 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax - 6725 # while (curr->next != null) curr = curr->next - 6726 { - 6727 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next - 6728 74/jump-if-= break/disp8 - 6729 # curr = lookup(curr->next) - 6730 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax - 6731 # - 6732 eb/jump loop/disp8 - 6733 } - 6734 # curr->next = out - 6735 8b/-> *edi 1/r32/ecx - 6736 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next - 6737 8b/-> *(edi+4) 1/r32/ecx - 6738 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next - 6739 # out = vars - 6740 8b/-> *(ebp+0x14) 1/r32/ecx - 6741 89/<- *edi 1/r32/ecx - 6742 8b/-> *(ebp+0x18) 1/r32/ecx - 6743 89/<- *(edi+4) 1/r32/ecx - 6744 $append-stmt-var:end: - 6745 # . restore registers - 6746 5f/pop-to-edi - 6747 59/pop-to-ecx - 6748 58/pop-to-eax - 6749 # . epilogue - 6750 89/<- %esp 5/r32/ebp - 6751 5d/pop-to-ebp - 6752 c3/return - 6753 - 6754 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) - 6755 # . prologue - 6756 55/push-ebp - 6757 89/<- %ebp 4/r32/esp - 6758 # . save registers - 6759 50/push-eax - 6760 56/push-esi - 6761 # esi = block - 6762 8b/-> *(ebp+0xc) 6/r32/esi - 6763 # block->stmts = append(x, block->stmts) - 6764 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts - 6765 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts - 6766 $append-to-block:end: - 6767 # . restore registers - 6768 5e/pop-to-esi - 6769 58/pop-to-eax - 6770 # . epilogue - 6771 89/<- %esp 5/r32/ebp - 6772 5d/pop-to-ebp - 6773 c3/return - 6774 - 6775 ## Parsing types - 6776 # We need to create metadata on user-defined types, and we need to use this - 6777 # metadata as we parse instructions. - 6778 # However, we also want to allow types to be used before their definitions. - 6779 # This means we can't ever assume any type data structures exist. - 6780 - 6781 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) - 6782 # . prologue - 6783 55/push-ebp - 6784 89/<- %ebp 4/r32/esp - 6785 # . save registers - 6786 50/push-eax - 6787 56/push-esi - 6788 # var container-type/esi: type-id - 6789 (container-type *(ebp+8)) # => eax - 6790 89/<- %esi 0/r32/eax - 6791 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) - 6792 68/push 0/imm32 - 6793 68/push 0/imm32 - 6794 89/<- %eax 4/r32/esp - 6795 (find-or-create-typeinfo %esi %eax) - 6796 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) - 6797 (lookup *eax *(eax+4)) # => eax - 6798 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) - 6799 #? (write-buffered Stderr "constant: ") - 6800 #? (write-slice-buffered Stderr *(ebp+0xc)) - 6801 #? (write-buffered Stderr Newline) - 6802 #? (flush Stderr) - 6803 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) - 6804 #? 8b/-> *(ebp+0x10) 0/r32/eax - 6805 #? (write-buffered Stderr "@") - 6806 #? (lookup *eax *(eax+4)) - 6807 #? (print-int32-buffered Stderr %eax) - 6808 #? (lookup *eax *(eax+4)) - 6809 #? (write-buffered Stderr %eax) - 6810 #? (write-buffered Stderr Newline) - 6811 #? (flush Stderr) - 6812 #? (write-buffered Stderr "offset: ") - 6813 #? 8b/-> *(eax+0x14) 0/r32/eax - 6814 #? (print-int32-buffered Stderr %eax) - 6815 #? (write-buffered Stderr Newline) - 6816 #? (flush Stderr) - 6817 $lookup-or-create-constant:end: - 6818 # . reclaim locals - 6819 81 0/subop/add %esp 8/imm32 - 6820 # . restore registers - 6821 5e/pop-to-esi - 6822 58/pop-to-eax - 6823 # . epilogue - 6824 89/<- %esp 5/r32/ebp - 6825 5d/pop-to-ebp - 6826 c3/return - 6827 - 6828 # if addr var: - 6829 # container->var->type->right->left->value - 6830 # otherwise - 6831 # container->var->type->value - 6832 container-type: # container: (addr stmt-var) -> result/eax: type-id - 6833 # . prologue - 6834 55/push-ebp - 6835 89/<- %ebp 4/r32/esp - 6836 # - 6837 8b/-> *(ebp+8) 0/r32/eax - 6838 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 6839 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax - 6840 { - 6841 81 7/subop/compare *(eax+8) 0/imm32 # Tree-right - 6842 74/jump-if-= break/disp8 - 6843 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax - 6844 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax - 6845 } - 6846 8b/-> *(eax+4) 0/r32/eax # Tree-value - 6847 $container-type:end: - 6848 # . epilogue - 6849 89/<- %esp 5/r32/ebp - 6850 5d/pop-to-ebp - 6851 c3/return - 6852 - 6853 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) - 6854 # . prologue - 6855 55/push-ebp - 6856 89/<- %ebp 4/r32/esp - 6857 # . save registers - 6858 50/push-eax - 6859 51/push-ecx - 6860 52/push-edx - 6861 57/push-edi - 6862 # edi = out - 6863 8b/-> *(ebp+0xc) 7/r32/edi - 6864 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) - 6865 68/push 0/imm32 - 6866 68/push 0/imm32 - 6867 89/<- %ecx 4/r32/esp - 6868 # find-typeinfo(t, out) - 6869 (find-typeinfo *(ebp+8) %edi) - 6870 { - 6871 # if (*out != 0) break - 6872 81 7/subop/compare *edi 0/imm32 - 6873 0f 85/jump-if-!= break/disp32 - 6874 $find-or-create-typeinfo:create: - 6875 # *out = allocate - 6876 (allocate Heap *Typeinfo-size %edi) - 6877 # var tmp/eax: (addr typeinfo) = lookup(*out) - 6878 (lookup *edi *(edi+4)) # => eax - 6879 #? (write-buffered Stderr "created typeinfo at ") - 6880 #? (print-int32-buffered Stderr %eax) - 6881 #? (write-buffered Stderr " for type-id ") - 6882 #? (print-int32-buffered Stderr *(ebp+8)) - 6883 #? (write-buffered Stderr Newline) - 6884 #? (flush Stderr) - 6885 # tmp->id = t - 6886 8b/-> *(ebp+8) 2/r32/edx - 6887 89/<- *eax 2/r32/edx # Typeinfo-id - 6888 # tmp->fields = new table - 6889 # . fields = new table - 6890 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) - 6891 # . tmp->fields = fields - 6892 8b/-> *ecx 2/r32/edx - 6893 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields - 6894 8b/-> *(ecx+4) 2/r32/edx - 6895 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields - 6896 # tmp->next = Program->types - 6897 8b/-> *_Program-types 1/r32/ecx - 6898 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next - 6899 8b/-> *_Program-types->payload 1/r32/ecx - 6900 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next - 6901 # Program->types = out - 6902 8b/-> *edi 1/r32/ecx - 6903 89/<- *_Program-types 1/r32/ecx - 6904 8b/-> *(edi+4) 1/r32/ecx - 6905 89/<- *_Program-types->payload 1/r32/ecx - 6906 } - 6907 $find-or-create-typeinfo:end: - 6908 # . reclaim locals - 6909 81 0/subop/add %esp 8/imm32 - 6910 # . restore registers - 6911 5f/pop-to-edi - 6912 5a/pop-to-edx - 6913 59/pop-to-ecx - 6914 58/pop-to-eax - 6915 # . epilogue - 6916 89/<- %esp 5/r32/ebp - 6917 5d/pop-to-ebp - 6918 c3/return - 6919 - 6920 find-typeinfo: # t: type-id, out: (addr handle typeinfo) - 6921 # . prologue - 6922 55/push-ebp - 6923 89/<- %ebp 4/r32/esp - 6924 # . save registers - 6925 50/push-eax - 6926 51/push-ecx - 6927 52/push-edx - 6928 57/push-edi - 6929 # ecx = t - 6930 8b/-> *(ebp+8) 1/r32/ecx - 6931 # edi = out - 6932 8b/-> *(ebp+0xc) 7/r32/edi - 6933 # *out = Program->types - 6934 8b/-> *_Program-types 0/r32/eax - 6935 89/<- *edi 0/r32/eax - 6936 8b/-> *_Program-types->payload 0/r32/eax - 6937 89/<- *(edi+4) 0/r32/eax - 6938 { - 6939 # if (*out == 0) break - 6940 81 7/subop/compare *edi 0/imm32 - 6941 74/jump-if-= break/disp8 - 6942 # var tmp/eax: (addr typeinfo) = lookup(*out) - 6943 (lookup *edi *(edi+4)) # => eax - 6944 # if (tmp->id == t) break - 6945 39/compare *eax 1/r32/ecx # Typeinfo-id - 6946 74/jump-if-= break/disp8 - 6947 # *out = tmp->next - 6948 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next - 6949 89/<- *edi 2/r32/edx - 6950 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next - 6951 89/<- *(edi+4) 2/r32/edx - 6952 # - 6953 eb/jump loop/disp8 - 6954 } - 6955 $find-typeinfo:end: - 6956 # . restore registers - 6957 5f/pop-to-edi - 6958 5a/pop-to-edx - 6959 59/pop-to-ecx - 6960 58/pop-to-eax - 6961 # . epilogue - 6962 89/<- %esp 5/r32/ebp - 6963 5d/pop-to-ebp - 6964 c3/return - 6965 - 6966 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) - 6967 # . prologue - 6968 55/push-ebp - 6969 89/<- %ebp 4/r32/esp - 6970 # . save registers - 6971 50/push-eax - 6972 52/push-edx - 6973 57/push-edi - 6974 # var dest/edi: (handle typeinfo-entry) - 6975 68/push 0/imm32 - 6976 68/push 0/imm32 - 6977 89/<- %edi 4/r32/esp - 6978 # find-or-create-typeinfo-fields(T, f, dest) - 6979 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) - 6980 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) - 6981 (lookup *edi *(edi+4)) # => eax - 6982 89/<- %edi 0/r32/eax - 6983 # if dest-addr->output-var doesn't exist, create it - 6984 { - 6985 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var - 6986 0f 85/jump-if-!= break/disp32 - 6987 # dest-addr->output-var = new var(dummy name, type, -1 offset) - 6988 # . var name/eax: (handle array byte) = "field" - 6989 68/push 0/imm32 - 6990 68/push 0/imm32 - 6991 89/<- %eax 4/r32/esp - 6992 (copy-array Heap "field" %eax) - 6993 # . new var - 6994 8d/copy-address *(edi+0xc) 2/r32/edx - 6995 (new-var Heap *eax *(eax+4) %edx) - 6996 # . reclaim name - 6997 81 0/subop/add %esp 8/imm32 - 6998 # var result/edx: (addr var) = lookup(dest-addr->output-var) - 6999 (lookup *(edi+0xc) *(edi+0x10)) # => eax - 7000 89/<- %edx 0/r32/eax - 7001 # result->type = new constant type - 7002 8d/copy-address *(edx+8) 0/r32/eax # Var-type - 7003 (allocate Heap *Tree-size %eax) - 7004 (lookup *(edx+8) *(edx+0xc)) # => eax - 7005 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom - 7006 c7 0/subop/copy *(eax+4) 6/imm32/constant # Tree-value - 7007 c7 0/subop/copy *(eax+8) 0/imm32 # Tree-left - 7008 c7 0/subop/copy *(eax+0xc) 0/imm32 # Tree-right - 7009 c7 0/subop/copy *(eax+0x10) 0/imm32 # Tree-right - 7010 # result->offset isn't filled out yet - 7011 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset - 7012 } - 7013 # out = dest-addr->output-var - 7014 8b/-> *(ebp+0x10) 2/r32/edx - 7015 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var - 7016 89/<- *edx 0/r32/eax - 7017 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var - 7018 89/<- *(edx+4) 0/r32/eax - 7019 $find-or-create-typeinfo-output-var:end: - 7020 # . reclaim locals - 7021 81 0/subop/add %esp 8/imm32 - 7022 # . restore registers - 7023 5f/pop-to-edi - 7024 5a/pop-to-edx - 7025 58/pop-to-eax - 7026 # . epilogue - 7027 89/<- %esp 5/r32/ebp - 7028 5d/pop-to-ebp - 7029 c3/return - 7030 - 7031 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) - 7032 # . prologue - 7033 55/push-ebp - 7034 89/<- %ebp 4/r32/esp - 7035 # . save registers - 7036 50/push-eax - 7037 56/push-esi - 7038 57/push-edi - 7039 # eax = lookup(T->fields) - 7040 8b/-> *(ebp+8) 0/r32/eax - 7041 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax - 7042 # edi = out - 7043 8b/-> *(ebp+0x10) 7/r32/edi - 7044 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) - 7045 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax - 7046 89/<- %esi 0/r32/eax - 7047 # if src doesn't exist, allocate it - 7048 { - 7049 81 7/subop/compare *esi 0/imm32 - 7050 75/jump-if-!= break/disp8 - 7051 (allocate Heap *Typeinfo-entry-size %esi) - 7052 #? (write-buffered Stderr "handle at ") - 7053 #? (print-int32-buffered Stderr %esi) - 7054 #? (write-buffered Stderr ": ") - 7055 #? (print-int32-buffered Stderr *esi) - 7056 #? (write-buffered Stderr " ") - 7057 #? (print-int32-buffered Stderr *(esi+4)) - 7058 #? (write-buffered Stderr Newline) - 7059 #? (flush Stderr) - 7060 #? (lookup *esi *(esi+4)) - 7061 #? (write-buffered Stderr "created typeinfo fields at ") - 7062 #? (print-int32-buffered Stderr %esi) - 7063 #? (write-buffered Stderr " for ") - 7064 #? (print-int32-buffered Stderr *(ebp+8)) - 7065 #? (write-buffered Stderr Newline) - 7066 #? (flush Stderr) - 7067 } - 7068 # *out = src - 7069 # . *edi = *src - 7070 8b/-> *esi 0/r32/eax - 7071 89/<- *edi 0/r32/eax - 7072 8b/-> *(esi+4) 0/r32/eax - 7073 89/<- *(edi+4) 0/r32/eax - 7074 $find-or-create-typeinfo-fields:end: - 7075 # . restore registers - 7076 5f/pop-to-edi - 7077 5e/pop-to-esi - 7078 58/pop-to-eax - 7079 # . epilogue - 7080 89/<- %esp 5/r32/ebp - 7081 5d/pop-to-ebp - 7082 c3/return - 7083 - 7084 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo) - 7085 # pseudocode: - 7086 # var line: (stream byte 512) - 7087 # curr-index = 0 - 7088 # while true - 7089 # clear-stream(line) - 7090 # read-line-buffered(in, line) - 7091 # if line->write == 0 - 7092 # abort - 7093 # word-slice = next-mu-token(line) - 7094 # if slice-empty?(word-slice) # end of line - 7095 # continue - 7096 # if slice-equal?(word-slice, "}") - 7097 # break - 7098 # var v: (handle var) = parse-var-with-type(word-slice, line) - 7099 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) - 7100 # TODO: ensure that r->first is null - 7101 # r->index = curr-index - 7102 # curr-index++ - 7103 # r->input-var = v - 7104 # if r->output-var == 0 - 7105 # r->output-var = new literal - 7106 # TODO: ensure nothing else in line - 7107 # t->total-size-in-bytes = -2 (not yet initialized) - 7108 # - 7109 # . prologue - 7110 55/push-ebp - 7111 89/<- %ebp 4/r32/esp - 7112 # var curr-index: int at *(ebp-4) - 7113 68/push 0/imm32 - 7114 # . save registers - 7115 50/push-eax - 7116 51/push-ecx - 7117 52/push-edx - 7118 53/push-ebx - 7119 56/push-esi - 7120 57/push-edi - 7121 # edi = t - 7122 8b/-> *(ebp+0xc) 7/r32/edi - 7123 # var line/ecx: (stream byte 512) - 7124 81 5/subop/subtract %esp 0x200/imm32 - 7125 68/push 0x200/imm32/size - 7126 68/push 0/imm32/read - 7127 68/push 0/imm32/write - 7128 89/<- %ecx 4/r32/esp - 7129 # var word-slice/edx: slice - 7130 68/push 0/imm32/end - 7131 68/push 0/imm32/start - 7132 89/<- %edx 4/r32/esp - 7133 # var v/esi: (handle var) - 7134 68/push 0/imm32 - 7135 68/push 0/imm32 - 7136 89/<- %esi 4/r32/esp - 7137 # var r/ebx: (handle typeinfo-entry) - 7138 68/push 0/imm32 - 7139 68/push 0/imm32 - 7140 89/<- %ebx 4/r32/esp - 7141 { - 7142 $populate-mu-type:line-loop: - 7143 (clear-stream %ecx) - 7144 (read-line-buffered *(ebp+8) %ecx) - 7145 # if (line->write == 0) abort - 7146 81 7/subop/compare *ecx 0/imm32 - 7147 0f 84/jump-if-= $populate-mu-type:abort/disp32 - 7148 +-- 6 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 7154 (next-mu-token %ecx %edx) - 7155 # if slice-empty?(word-slice) continue - 7156 (slice-empty? %edx) # => eax - 7157 3d/compare-eax-and 0/imm32 - 7158 0f 85/jump-if-!= loop/disp32 - 7159 # if slice-equal?(word-slice, "}") break - 7160 (slice-equal? %edx "}") - 7161 3d/compare-eax-and 0/imm32 - 7162 0f 85/jump-if-!= break/disp32 - 7163 $populate-mu-type:parse-element: - 7164 # v = parse-var-with-type(word-slice, first-line) - 7165 # must do this first to strip the trailing ':' from word-slice before - 7166 # using it in find-or-create-typeinfo-fields below - 7167 # TODO: clean up that mutation in parse-var-with-type - 7168 (parse-var-with-type %edx %ecx %esi) # => eax - 7169 # var tmp/ecx - 7170 51/push-ecx - 7171 $populate-mu-type:create-typeinfo-fields: - 7172 # var r/ebx: (handle typeinfo-entry) - 7173 (find-or-create-typeinfo-fields %edi %edx %ebx) - 7174 # r->index = curr-index - 7175 (lookup *ebx *(ebx+4)) # => eax - 7176 8b/-> *(ebp-4) 1/r32/ecx - 7177 #? (write-buffered Stderr "saving index ") - 7178 #? (print-int32-buffered Stderr %ecx) - 7179 #? (write-buffered Stderr " at ") - 7180 #? (print-int32-buffered Stderr %edi) - 7181 #? (write-buffered Stderr Newline) - 7182 #? (flush Stderr) - 7183 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index - 7184 # ++curr-index - 7185 ff 0/subop/increment *(ebp-4) - 7186 $populate-mu-type:set-input-type: - 7187 # r->input-var = v - 7188 8b/-> *esi 1/r32/ecx - 7189 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var - 7190 8b/-> *(esi+4) 1/r32/ecx - 7191 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var - 7192 59/pop-to-ecx - 7193 { - 7194 $populate-mu-type:create-output-type: - 7195 # if (r->output-var == 0) create a new var with some placeholder data - 7196 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var - 7197 75/jump-if-!= break/disp8 - 7198 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var - 7199 (new-literal Heap %edx %eax) - 7200 } - 7201 e9/jump loop/disp32 - 7202 } - 7203 $populate-mu-type:invalidate-total-size-in-bytes: - 7204 # Offsets and total size may not be accurate here since we may not yet - 7205 # have encountered the element types. - 7206 # We'll recompute them separately after parsing the entire program. - 7207 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes - 7208 $populate-mu-type:end: - 7209 # . reclaim locals - 7210 81 0/subop/add %esp 0x224/imm32 - 7211 # . restore registers - 7212 5f/pop-to-edi - 7213 5e/pop-to-esi - 7214 5b/pop-to-ebx - 7215 5a/pop-to-edx - 7216 59/pop-to-ecx - 7217 58/pop-to-eax - 7218 # reclaim curr-index - 7219 81 0/subop/add %esp 4/imm32 - 7220 # . epilogue - 7221 89/<- %esp 5/r32/ebp - 7222 5d/pop-to-ebp - 7223 c3/return - 7224 - 7225 $populate-mu-type:abort: - 7226 # error("unexpected top-level command: " word-slice "\n") - 7227 (write-buffered Stderr "incomplete type definition '") - 7228 (type-name *edi) # Typeinfo-id => eax - 7229 (write-buffered Stderr %eax) - 7230 (write-buffered Stderr "\n") - 7231 (flush Stderr) - 7232 # . syscall(exit, 1) - 7233 bb/copy-to-ebx 1/imm32 - 7234 b8/copy-to-eax 1/imm32/exit - 7235 cd/syscall 0x80/imm8 - 7236 # never gets here - 7237 - 7238 type-name: # index: int -> result/eax: (addr array byte) - 7239 # . prologue - 7240 55/push-ebp - 7241 89/<- %ebp 4/r32/esp - 7242 # - 7243 (index Type-id *(ebp+8)) - 7244 $type-name:end: - 7245 # . epilogue - 7246 89/<- %esp 5/r32/ebp - 7247 5d/pop-to-ebp - 7248 c3/return - 7249 - 7250 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) - 7251 # . prologue - 7252 55/push-ebp - 7253 89/<- %ebp 4/r32/esp - 7254 # . save registers - 7255 56/push-esi - 7256 # TODO: bounds-check index - 7257 # esi = arr - 7258 8b/-> *(ebp+8) 6/r32/esi - 7259 # eax = index - 7260 8b/-> *(ebp+0xc) 0/r32/eax - 7261 # eax = *(arr + 12 + index) - 7262 8b/-> *(esi+eax+0xc) 0/r32/eax - 7263 $index:end: - 7264 # . restore registers - 7265 5e/pop-to-esi - 7266 # . epilogue - 7267 89/<- %esp 5/r32/ebp - 7268 5d/pop-to-ebp - 7269 c3/return - 7270 - 7271 ####################################################### - 7272 # Compute type sizes - 7273 ####################################################### - 7274 - 7275 # Compute the sizes of all user-defined types. - 7276 # We'll need the sizes of their elements, which may be other user-defined - 7277 # types, which we will compute as needed. - 7278 - 7279 # Initially, all user-defined types have their sizes set to -2 (invalid) - 7280 populate-mu-type-sizes: - 7281 # . prologue - 7282 55/push-ebp - 7283 89/<- %ebp 4/r32/esp - 7284 $populate-mu-type-sizes:total-sizes: - 7285 # var curr/eax: (addr typeinfo) = lookup(Program->types) - 7286 (lookup *_Program-types *_Program-types->payload) # => eax - 7287 { - 7288 # if (curr == null) break - 7289 3d/compare-eax-and 0/imm32/null - 7290 74/jump-if-= break/disp8 - 7291 (populate-mu-type-sizes-in-type %eax) - 7292 # curr = lookup(curr->next) - 7293 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax - 7294 eb/jump loop/disp8 - 7295 } - 7296 $populate-mu-type-sizes:offsets: - 7297 # curr = *Program->types - 7298 (lookup *_Program-types *_Program-types->payload) # => eax - 7299 { - 7300 # if (curr == null) break - 7301 3d/compare-eax-and 0/imm32/null - 7302 74/jump-if-= break/disp8 - 7303 (populate-mu-type-offsets %eax) - 7304 # curr = curr->next - 7305 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax - 7306 eb/jump loop/disp8 - 7307 } - 7308 $populate-mu-type-sizes:end: - 7309 # . epilogue - 7310 89/<- %esp 5/r32/ebp - 7311 5d/pop-to-ebp - 7312 c3/return - 7313 - 7314 # compute sizes of all fields, recursing as necessary - 7315 # sum up all their sizes to arrive at total size - 7316 # fields may be out of order, but that doesn't affect the answer - 7317 populate-mu-type-sizes-in-type: # T: (addr typeinfo) - 7318 # . prologue - 7319 55/push-ebp - 7320 89/<- %ebp 4/r32/esp - 7321 # . save registers - 7322 50/push-eax - 7323 51/push-ecx - 7324 52/push-edx - 7325 56/push-esi - 7326 57/push-edi - 7327 # esi = T - 7328 8b/-> *(ebp+8) 6/r32/esi - 7329 # if T is already computed, return - 7330 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes - 7331 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 - 7332 # if T is being computed, abort - 7333 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes - 7334 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 - 7335 # tag T (-2 to -1) to avoid infinite recursion - 7336 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes - 7337 # var total-size/edi: int = 0 - 7338 bf/copy-to-edi 0/imm32 - 7339 # - for every field, if it's a user-defined type, compute its size - 7340 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) - 7341 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax - 7342 89/<- %ecx 0/r32/eax - 7343 # var table-size/edx: int = table->write - 7344 8b/-> *ecx 2/r32/edx # stream-write - 7345 # var curr/ecx: (addr table_row) = table->data - 7346 8d/copy-address *(ecx+0xc) 1/r32/ecx - 7347 # var max/edx: (addr table_row) = table->data + table->write - 7348 8d/copy-address *(ecx+edx) 2/r32/edx - 7349 { - 7350 $populate-mu-type-sizes-in-type:loop: - 7351 # if (curr >= max) break - 7352 39/compare %ecx 2/r32/edx - 7353 73/jump-if-addr>= break/disp8 - 7354 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) - 7355 (lookup *(ecx+8) *(ecx+0xc)) # => eax - 7356 # compute size of t->input-var - 7357 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax - 7358 (compute-size-of-var %eax) # => eax - 7359 # result += eax - 7360 01/add-to %edi 0/r32/eax - 7361 # curr += row-size - 7362 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size - 7363 # - 7364 eb/jump loop/disp8 - 7365 } - 7366 # - save result - 7367 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes - 7368 $populate-mu-type-sizes-in-type:end: - 7369 # . restore registers - 7370 5f/pop-to-edi - 7371 5e/pop-to-esi - 7372 5a/pop-to-edx - 7373 59/pop-to-ecx - 7374 58/pop-to-eax - 7375 # . epilogue - 7376 89/<- %esp 5/r32/ebp - 7377 5d/pop-to-ebp - 7378 c3/return - 7379 - 7380 $populate-mu-type-sizes-in-type:abort: - 7381 (write-buffered Stderr "cycle in type definitions\n") - 7382 (flush Stderr) - 7383 # . syscall(exit, 1) - 7384 bb/copy-to-ebx 1/imm32 - 7385 b8/copy-to-eax 1/imm32/exit - 7386 cd/syscall 0x80/imm8 - 7387 # never gets here - 7388 - 7389 # Analogous to size-of, except we need to compute what size-of can just read - 7390 # off the right data structures. - 7391 compute-size-of-var: # in: (addr var) -> result/eax: int - 7392 # . prologue - 7393 55/push-ebp - 7394 89/<- %ebp 4/r32/esp - 7395 # . push registers - 7396 51/push-ecx - 7397 # var t/ecx: (addr tree type-id) = lookup(v->type) - 7398 8b/-> *(ebp+8) 1/r32/ecx - 7399 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 7400 89/<- %ecx 0/r32/eax - 7401 # if (t->is-atom == false) t = lookup(t->left) - 7402 { - 7403 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom - 7404 75/jump-if-!= break/disp8 - 7405 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax - 7406 89/<- %ecx 0/r32/eax - 7407 } - 7408 # TODO: ensure t is an atom - 7409 (compute-size-of-type-id *(ecx+4)) # Tree-value => eax - 7410 $compute-size-of-var:end: - 7411 # . restore registers - 7412 59/pop-to-ecx - 7413 # . epilogue - 7414 89/<- %esp 5/r32/ebp - 7415 5d/pop-to-ebp - 7416 c3/return - 7417 - 7418 compute-size-of-type-id: # t: type-id -> result/eax: int - 7419 # . prologue - 7420 55/push-ebp - 7421 89/<- %ebp 4/r32/esp - 7422 # . save registers - 7423 51/push-ecx - 7424 # var out/ecx: (handle typeinfo) - 7425 68/push 0/imm32 - 7426 68/push 0/imm32 - 7427 89/<- %ecx 4/r32/esp - 7428 # eax = t - 7429 8b/-> *(ebp+8) 0/r32/eax - 7430 # if v is a literal, return 0 - 7431 3d/compare-eax-and 0/imm32 - 7432 74/jump-if-= $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int - 7433 # if v has a user-defined type, compute its size - 7434 # TODO: support non-atom type - 7435 (find-typeinfo %eax %ecx) - 7436 { - 7437 81 7/subop/compare *ecx 0/imm32 - 7438 74/jump-if-= break/disp8 - 7439 $compute-size-of-type-id:user-defined: - 7440 (populate-mu-type-sizes %eax) - 7441 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes - 7442 eb/jump $compute-size-of-type-id:end/disp8 - 7443 } - 7444 # otherwise return the word size - 7445 b8/copy-to-eax 4/imm32 - 7446 $compute-size-of-type-id:end: - 7447 # . reclaim locals - 7448 81 0/subop/add %esp 8/imm32 - 7449 # . restore registers - 7450 59/pop-to-ecx - 7451 # . epilogue - 7452 89/<- %esp 5/r32/ebp - 7453 5d/pop-to-ebp - 7454 c3/return - 7455 - 7456 # at this point we have total sizes for all user-defined types - 7457 # compute offsets for each element - 7458 # complication: fields may be out of order - 7459 populate-mu-type-offsets: # in: (addr typeinfo) - 7460 # . prologue - 7461 55/push-ebp - 7462 89/<- %ebp 4/r32/esp - 7463 # . save registers - 7464 50/push-eax - 7465 51/push-ecx - 7466 52/push-edx - 7467 53/push-ebx - 7468 56/push-esi - 7469 57/push-edi - 7470 #? (dump-typeinfos "aaa\n") - 7471 # var curr-offset/edi: int = 0 - 7472 bf/copy-to-edi 0/imm32 - 7473 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) - 7474 8b/-> *(ebp+8) 1/r32/ecx - 7475 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax - 7476 89/<- %ecx 0/r32/eax - 7477 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size - 7478 8b/-> *ecx 2/r32/edx # stream-write - 7479 c1 5/subop/shift-right-logical %edx 4/imm8 - 7480 # var i/ebx: int = 0 - 7481 bb/copy-to-ebx 0/imm32 - 7482 { - 7483 $populate-mu-type-offsets:loop: - 7484 39/compare %ebx 2/r32/edx - 7485 7d/jump-if->= break/disp8 - 7486 #? (write-buffered Stderr "looking up index ") - 7487 #? (print-int32-buffered Stderr %ebx) - 7488 #? (write-buffered Stderr " in ") - 7489 #? (print-int32-buffered Stderr *(ebp+8)) - 7490 #? (write-buffered Stderr Newline) - 7491 #? (flush Stderr) - 7492 # var v/esi: (addr typeinfo-entry) - 7493 (locate-typeinfo-entry-with-index %ecx %ebx) # => eax - 7494 89/<- %esi 0/r32/eax - 7495 # v->output-var->offset = curr-offset - 7496 # . eax: (addr var) - 7497 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax - 7498 89/<- *(eax+0x14) 7/r32/edi # Var-offset - 7499 # curr-offset += size-of(v->input-var) - 7500 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax - 7501 (size-of %eax) # => eax - 7502 01/add-to %edi 0/r32/eax - 7503 # ++i - 7504 43/increment-ebx - 7505 eb/jump loop/disp8 - 7506 } - 7507 $populate-mu-type-offsets:end: - 7508 # . restore registers - 7509 5f/pop-to-edi - 7510 5e/pop-to-esi - 7511 5b/pop-to-ebx - 7512 5a/pop-to-edx - 7513 59/pop-to-ecx - 7514 58/pop-to-eax - 7515 # . epilogue - 7516 89/<- %esp 5/r32/ebp - 7517 5d/pop-to-ebp - 7518 c3/return - 7519 - 7520 locate-typeinfo-entry-with-index: # table: (addr table (handle array byte) (handle typeinfo-entry)), idx: int -> result/eax: (addr typeinfo-entry) - 7521 # . prologue - 7522 55/push-ebp - 7523 89/<- %ebp 4/r32/esp - 7524 # . save registers - 7525 51/push-ecx - 7526 52/push-edx - 7527 53/push-ebx - 7528 56/push-esi - 7529 57/push-edi - 7530 # esi = table - 7531 8b/-> *(ebp+8) 6/r32/esi - 7532 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data - 7533 8d/copy-address *(esi+0xc) 1/r32/ecx - 7534 # var max/edx: (addr byte) = &table->data[table->write] - 7535 8b/-> *esi 2/r32/edx - 7536 8d/copy-address *(ecx+edx) 2/r32/edx - 7537 { - 7538 $locate-typeinfo-entry-with-index:loop: - 7539 39/compare %ecx 2/r32/edx - 7540 73/jump-if-addr>= $locate-typeinfo-entry-with-index:abort/disp8 - 7541 # var v/eax: (addr typeinfo-entry) - 7542 (lookup *(ecx+8) *(ecx+0xc)) # => eax - 7543 # if (v->index == idx) return v - 7544 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index - 7545 #? (write-buffered Stderr "comparing ") - 7546 #? (print-int32-buffered Stderr %ebx) - 7547 #? (write-buffered Stderr " and ") - 7548 #? (print-int32-buffered Stderr *(ebp+0xc)) - 7549 #? (write-buffered Stderr Newline) - 7550 #? (flush Stderr) - 7551 39/compare *(ebp+0xc) 3/r32/ebx - 7552 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 - 7553 # curr += Typeinfo-entry-size - 7554 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size - 7555 # - 7556 eb/jump loop/disp8 - 7557 } - 7558 # return 0 - 7559 b8/copy-to-eax 0/imm32 - 7560 $locate-typeinfo-entry-with-index:end: - 7561 #? (write-buffered Stderr "returning ") - 7562 #? (print-int32-buffered Stderr %eax) - 7563 #? (write-buffered Stderr Newline) - 7564 #? (flush Stderr) - 7565 # . restore registers - 7566 5f/pop-to-edi - 7567 5e/pop-to-esi - 7568 5b/pop-to-ebx - 7569 5a/pop-to-edx - 7570 59/pop-to-ecx - 7571 # . epilogue - 7572 89/<- %esp 5/r32/ebp - 7573 5d/pop-to-ebp - 7574 c3/return - 7575 - 7576 $locate-typeinfo-entry-with-index:abort: - 7577 (write-buffered Stderr "overflowing typeinfo-entry->index ") - 7578 (print-int32-buffered Stderr %ecx) - 7579 (write-buffered Stderr "\n") - 7580 (flush Stderr) - 7581 # . syscall(exit, 1) - 7582 bb/copy-to-ebx 1/imm32 - 7583 b8/copy-to-eax 1/imm32/exit - 7584 cd/syscall 0x80/imm8 - 7585 # never gets here - 7586 - 7587 dump-typeinfos: # hdr: (addr array byte) - 7588 # . prologue - 7589 55/push-ebp - 7590 89/<- %ebp 4/r32/esp - 7591 # . save registers - 7592 50/push-eax - 7593 # - 7594 (write-buffered Stderr *(ebp+8)) - 7595 (flush Stderr) - 7596 # var curr/eax: (addr typeinfo) = lookup(Program->types) - 7597 (lookup *_Program-types *_Program-types->payload) # => eax - 7598 { - 7599 # if (curr == null) break - 7600 3d/compare-eax-and 0/imm32 - 7601 74/jump-if-= break/disp8 - 7602 (write-buffered Stderr "---\n") - 7603 (flush Stderr) - 7604 (dump-typeinfo %eax) - 7605 # curr = lookup(curr->next) - 7606 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax - 7607 eb/jump loop/disp8 - 7608 } - 7609 $dump-typeinfos:end: - 7610 # . restore registers - 7611 58/pop-to-eax - 7612 # . epilogue - 7613 89/<- %esp 5/r32/ebp - 7614 5d/pop-to-ebp - 7615 c3/return - 7616 - 7617 dump-typeinfo: # in: (addr typeinfo) - 7618 # . prologue - 7619 55/push-ebp - 7620 89/<- %ebp 4/r32/esp - 7621 # . save registers - 7622 50/push-eax - 7623 51/push-ecx - 7624 52/push-edx - 7625 53/push-ebx - 7626 56/push-esi - 7627 57/push-edi - 7628 # esi = in - 7629 8b/-> *(ebp+8) 6/r32/esi - 7630 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) - 7631 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax - 7632 89/<- %ecx 0/r32/eax - 7633 (write-buffered Stderr "id:") - 7634 (print-int32-buffered Stderr *esi) - 7635 (write-buffered Stderr "\n") - 7636 (write-buffered Stderr "fields @ ") - 7637 (print-int32-buffered Stderr %ecx) - 7638 (write-buffered Stderr Newline) - 7639 (flush Stderr) - 7640 (write-buffered Stderr " write: ") - 7641 (print-int32-buffered Stderr *ecx) - 7642 (write-buffered Stderr Newline) - 7643 (flush Stderr) - 7644 (write-buffered Stderr " read: ") - 7645 (print-int32-buffered Stderr *(ecx+4)) - 7646 (write-buffered Stderr Newline) - 7647 (flush Stderr) - 7648 (write-buffered Stderr " size: ") - 7649 (print-int32-buffered Stderr *(ecx+8)) - 7650 (write-buffered Stderr Newline) - 7651 (flush Stderr) - 7652 # var table-size/edx: int = table->write - 7653 8b/-> *ecx 2/r32/edx # stream-write - 7654 # var curr/ecx: (addr table_row) = table->data - 7655 8d/copy-address *(ecx+0xc) 1/r32/ecx - 7656 # var max/edx: (addr table_row) = table->data + table->write - 7657 8d/copy-address *(ecx+edx) 2/r32/edx - 7658 { - 7659 $dump-typeinfo:loop: - 7660 # if (curr >= max) break - 7661 39/compare %ecx 2/r32/edx - 7662 0f 83/jump-if-addr>= break/disp32 - 7663 (write-buffered Stderr " row:\n") - 7664 (write-buffered Stderr " key: ") - 7665 (print-int32-buffered Stderr *ecx) - 7666 (write-buffered Stderr ",") - 7667 (print-int32-buffered Stderr *(ecx+4)) - 7668 (write-buffered Stderr " = '") - 7669 (lookup *ecx *(ecx+4)) - 7670 (write-buffered Stderr %eax) - 7671 (write-buffered Stderr "' @ ") - 7672 (print-int32-buffered Stderr %eax) - 7673 (write-buffered Stderr Newline) - 7674 (flush Stderr) - 7675 (write-buffered Stderr " value: ") - 7676 (print-int32-buffered Stderr *(ecx+8)) - 7677 (write-buffered Stderr ",") - 7678 (print-int32-buffered Stderr *(ecx+0xc)) - 7679 (write-buffered Stderr " = typeinfo-entry@") - 7680 (lookup *(ecx+8) *(ecx+0xc)) - 7681 (print-int32-buffered Stderr %eax) - 7682 (write-buffered Stderr Newline) - 7683 (flush Stderr) - 7684 (write-buffered Stderr " input var@") - 7685 (print-int32-buffered Stderr *eax) - 7686 (write-buffered Stderr ",") - 7687 (print-int32-buffered Stderr *(eax+4)) - 7688 (write-buffered Stderr "->") - 7689 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var - 7690 (print-int32-buffered Stderr %eax) - 7691 { - 7692 3d/compare-eax-and 0/imm32 - 7693 74/jump-if-= break/disp8 - 7694 (write-buffered Stderr " ") - 7695 # TODO - 7696 } - 7697 (write-buffered Stderr Newline) - 7698 (flush Stderr) - 7699 (lookup *(ecx+8) *(ecx+0xc)) - 7700 (write-buffered Stderr " index: ") - 7701 (print-int32-buffered Stderr *(eax+8)) - 7702 (write-buffered Stderr Newline) - 7703 (flush Stderr) - 7704 (write-buffered Stderr " output var@") - 7705 (print-int32-buffered Stderr *(eax+0xc)) - 7706 (write-buffered Stderr ",") - 7707 (print-int32-buffered Stderr *(eax+0x10)) - 7708 (write-buffered Stderr "->") - 7709 (lookup *(eax+0xc) *(eax+0x10)) # Typeinfo-entry-output-var - 7710 (print-int32-buffered Stderr %eax) - 7711 (write-buffered Stderr Newline) - 7712 (flush Stderr) - 7713 { - 7714 3d/compare-eax-and 0/imm32 - 7715 0f 84/jump-if-= break/disp32 - 7716 (write-buffered Stderr " name: ") - 7717 89/<- %ebx 0/r32/eax - 7718 (print-int32-buffered Stderr *ebx) # Var-name - 7719 (write-buffered Stderr ",") - 7720 (print-int32-buffered Stderr *(ebx+4)) # Var-name - 7721 (write-buffered Stderr "->") - 7722 (lookup *ebx *(ebx+4)) # Var-name - 7723 (print-int32-buffered Stderr %eax) - 7724 { - 7725 3d/compare-eax-and 0/imm32 - 7726 74/jump-if-= break/disp8 - 7727 (write-buffered Stderr Space) - 7728 (write-buffered Stderr %eax) - 7729 } - 7730 (write-buffered Stderr Newline) - 7731 (flush Stderr) - 7732 (write-buffered Stderr " block depth: ") - 7733 (print-int32-buffered Stderr *(ebx+0x10)) # Var-block-depth - 7734 (write-buffered Stderr Newline) - 7735 (flush Stderr) - 7736 (write-buffered Stderr " stack offset: ") - 7737 (print-int32-buffered Stderr *(ebx+0x14)) # Var-offset - 7738 (write-buffered Stderr Newline) - 7739 (flush Stderr) - 7740 (write-buffered Stderr " reg: ") - 7741 (print-int32-buffered Stderr *(ebx+0x18)) # Var-register - 7742 (write-buffered Stderr ",") - 7743 (print-int32-buffered Stderr *(ebx+0x1c)) # Var-register - 7744 (write-buffered Stderr "->") - 7745 (flush Stderr) - 7746 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register - 7747 (print-int32-buffered Stderr %eax) - 7748 { - 7749 3d/compare-eax-and 0/imm32 - 7750 74/jump-if-= break/disp8 - 7751 (write-buffered Stderr Space) - 7752 (write-buffered Stderr %eax) - 7753 } - 7754 (write-buffered Stderr Newline) - 7755 (flush Stderr) - 7756 } - 7757 (flush Stderr) - 7758 # curr += row-size - 7759 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size - 7760 # - 7761 e9/jump loop/disp32 - 7762 } - 7763 $dump-typeinfo:end: - 7764 # . restore registers - 7765 5f/pop-to-edi - 7766 5e/pop-to-esi - 7767 5b/pop-to-ebx - 7768 5a/pop-to-edx - 7769 59/pop-to-ecx - 7770 58/pop-to-eax - 7771 # . epilogue - 7772 89/<- %esp 5/r32/ebp - 7773 5d/pop-to-ebp - 7774 c3/return - 7775 - 7776 ####################################################### - 7777 # Type-checking - 7778 ####################################################### - 7779 - 7780 check-mu-types: - 7781 # . prologue - 7782 55/push-ebp - 7783 89/<- %ebp 4/r32/esp - 7784 # - 7785 $check-mu-types:end: - 7786 # . epilogue - 7787 89/<- %esp 5/r32/ebp - 7788 5d/pop-to-ebp - 7789 c3/return - 7790 - 7791 size-of: # v: (addr var) -> result/eax: int - 7792 # . prologue - 7793 55/push-ebp - 7794 89/<- %ebp 4/r32/esp - 7795 # . save registers - 7796 51/push-ecx - 7797 # var t/ecx: (addr tree type-id) = lookup(v->type) - 7798 8b/-> *(ebp+8) 1/r32/ecx - 7799 #? (write-buffered Stderr "size-of ") - 7800 #? (print-int32-buffered Stderr %ecx) - 7801 #? (write-buffered Stderr Newline) - 7802 #? (write-buffered Stderr "type allocid: ") - 7803 #? (print-int32-buffered Stderr *(ecx+8)) - 7804 #? (write-buffered Stderr Newline) - 7805 #? (flush Stderr) - 7806 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 7807 89/<- %ecx 0/r32/eax - 7808 # if is-mu-array?(t) return size-of-array(t) - 7809 { - 7810 (is-mu-array? %ecx) # => eax - 7811 3d/compare-eax-and 0/imm32/false - 7812 74/jump-if-= break/disp8 - 7813 (size-of-array %ecx) # => eax - 7814 eb/jump $size-of:end/disp8 - 7815 } - 7816 # if (!t->is-atom?) t = lookup(t->left) - 7817 { - 7818 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom - 7819 75/jump-if-!= break/disp8 - 7820 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax - 7821 89/<- %ecx 0/r32/eax - 7822 } - 7823 # TODO: assert t->is-atom? - 7824 (size-of-type-id *(ecx+4)) # Tree-value => eax - 7825 $size-of:end: - 7826 # . restore registers - 7827 59/pop-to-ecx - 7828 # . epilogue - 7829 89/<- %esp 5/r32/ebp - 7830 5d/pop-to-ebp - 7831 c3/return - 7832 - 7833 size-of-deref: # v: (addr var) -> result/eax: int - 7834 # . prologue - 7835 55/push-ebp - 7836 89/<- %ebp 4/r32/esp - 7837 # . save registers - 7838 51/push-ecx - 7839 # var t/ecx: (addr tree type-id) = lookup(v->type) - 7840 8b/-> *(ebp+8) 1/r32/ecx - 7841 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 7842 89/<- %ecx 0/r32/eax - 7843 # TODO: assert(t is an addr) - 7844 # t = lookup(t->right) - 7845 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax - 7846 89/<- %ecx 0/r32/eax - 7847 # if is-mu-array?(t) return size-of-array(t) - 7848 { - 7849 (is-mu-array? %ecx) # => eax - 7850 3d/compare-eax-and 0/imm32/false - 7851 74/jump-if-= break/disp8 - 7852 (size-of-array %ecx) # => eax - 7853 eb/jump $size-of:end/disp8 - 7854 } - 7855 # if (!t->is-atom?) t = lookup(t->left) - 7856 { - 7857 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom - 7858 75/jump-if-!= break/disp8 - 7859 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax - 7860 89/<- %ecx 0/r32/eax - 7861 } - 7862 # TODO: assert t->is-atom? - 7863 (size-of-type-id *(ecx+4)) # Tree-value => eax - 7864 $size-of-deref:end: - 7865 # . restore registers - 7866 59/pop-to-ecx - 7867 # . epilogue - 7868 89/<- %esp 5/r32/ebp - 7869 5d/pop-to-ebp - 7870 c3/return - 7871 - 7872 is-mu-array?: # t: (addr tree type-id) -> result/eax: boolean - 7873 # . prologue - 7874 55/push-ebp - 7875 89/<- %ebp 4/r32/esp - 7876 # . save registers + 6580 58/pop-to-eax + 6581 # . epilogue + 6582 89/<- %esp 5/r32/ebp + 6583 5d/pop-to-ebp + 6584 c3/return + 6585 + 6586 test-parse-mu-stmt: + 6587 # . prologue + 6588 55/push-ebp + 6589 89/<- %ebp 4/r32/esp + 6590 # setup + 6591 (clear-stream _test-input-stream) + 6592 (write _test-input-stream "increment n\n") + 6593 # var vars/ecx: (stack (addr var) 16) + 6594 81 5/subop/subtract %esp 0xc0/imm32 + 6595 68/push 0xc0/imm32/size + 6596 68/push 0/imm32/top + 6597 89/<- %ecx 4/r32/esp + 6598 (clear-stack %ecx) + 6599 # var v/edx: (handle var) + 6600 68/push 0/imm32 + 6601 68/push 0/imm32 + 6602 89/<- %edx 4/r32/esp + 6603 # var s/eax: (handle array byte) + 6604 68/push 0/imm32 + 6605 68/push 0/imm32 + 6606 89/<- %eax 4/r32/esp + 6607 # v = new var("n") + 6608 (copy-array Heap "n" %eax) + 6609 (new-var Heap *eax *(eax+4) %edx) + 6610 # + 6611 (push %ecx *edx) + 6612 (push %ecx *(edx+4)) + 6613 (push %ecx 0) + 6614 # var out/eax: (handle stmt) + 6615 68/push 0/imm32 + 6616 68/push 0/imm32 + 6617 89/<- %eax 4/r32/esp + 6618 # convert + 6619 (parse-mu-stmt _test-input-stream %ecx 0 %eax) + 6620 # var out-addr/edx: (addr stmt) = lookup(*out) + 6621 (lookup *eax *(eax+4)) # => eax + 6622 89/<- %edx 0/r32/eax + 6623 # out->tag + 6624 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 + 6625 # out->operation + 6626 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax + 6627 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation + 6628 # out->inouts->value->name + 6629 # . eax = out->inouts + 6630 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 6631 # . eax = out->inouts->value + 6632 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 6633 # . eax = out->inouts->value->name + 6634 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 6635 # . + 6636 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") + 6637 # . epilogue + 6638 89/<- %esp 5/r32/ebp + 6639 5d/pop-to-ebp + 6640 c3/return + 6641 + 6642 test-parse-mu-stmt-with-comma: + 6643 # . prologue + 6644 55/push-ebp + 6645 89/<- %ebp 4/r32/esp + 6646 # setup + 6647 (clear-stream _test-input-stream) + 6648 (write _test-input-stream "copy-to n, 3\n") + 6649 # var vars/ecx: (stack (addr var) 16) + 6650 81 5/subop/subtract %esp 0xc0/imm32 + 6651 68/push 0xc0/imm32/size + 6652 68/push 0/imm32/top + 6653 89/<- %ecx 4/r32/esp + 6654 (clear-stack %ecx) + 6655 # var v/edx: (handle var) + 6656 68/push 0/imm32 + 6657 68/push 0/imm32 + 6658 89/<- %edx 4/r32/esp + 6659 # var s/eax: (handle array byte) + 6660 68/push 0/imm32 + 6661 68/push 0/imm32 + 6662 89/<- %eax 4/r32/esp + 6663 # v = new var("n") + 6664 (copy-array Heap "n" %eax) + 6665 (new-var Heap *eax *(eax+4) %edx) + 6666 # + 6667 (push %ecx *edx) + 6668 (push %ecx *(edx+4)) + 6669 (push %ecx 0) + 6670 # var out/eax: (handle stmt) + 6671 68/push 0/imm32 + 6672 68/push 0/imm32 + 6673 89/<- %eax 4/r32/esp + 6674 # convert + 6675 (parse-mu-stmt _test-input-stream %ecx 0 %eax) + 6676 # var out-addr/edx: (addr stmt) = lookup(*out) + 6677 (lookup *eax *(eax+4)) # => eax + 6678 89/<- %edx 0/r32/eax + 6679 # out->tag + 6680 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 + 6681 # out->operation + 6682 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax + 6683 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation + 6684 # out->inouts->value->name + 6685 # . eax = out->inouts + 6686 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 6687 # . eax = out->inouts->value + 6688 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 6689 # . eax = out->inouts->value->name + 6690 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 6691 # . + 6692 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") + 6693 # . epilogue + 6694 89/<- %esp 5/r32/ebp + 6695 5d/pop-to-ebp + 6696 c3/return + 6697 + 6698 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) + 6699 # . prologue + 6700 55/push-ebp + 6701 89/<- %ebp 4/r32/esp + 6702 # . save registers + 6703 50/push-eax + 6704 51/push-ecx + 6705 # ecx = out + 6706 8b/-> *(ebp+0x14) 1/r32/ecx + 6707 # + 6708 (allocate *(ebp+8) *Var-size %ecx) + 6709 # var out-addr/eax: (addr var) + 6710 (lookup *ecx *(ecx+4)) # => eax + 6711 # out-addr->name = name + 6712 8b/-> *(ebp+0xc) 1/r32/ecx + 6713 89/<- *eax 1/r32/ecx # Var-name + 6714 8b/-> *(ebp+0x10) 1/r32/ecx + 6715 89/<- *(eax+4) 1/r32/ecx # Var-name + 6716 #? (write-buffered Stderr "var ") + 6717 #? (lookup *(ebp+0xc) *(ebp+0x10)) + 6718 #? (write-buffered Stderr %eax) + 6719 #? (write-buffered Stderr " at ") + 6720 #? 8b/-> *(ebp+0x14) 1/r32/ecx + 6721 #? (lookup *ecx *(ecx+4)) # => eax + 6722 #? (print-int32-buffered Stderr %eax) + 6723 #? (write-buffered Stderr Newline) + 6724 #? (flush Stderr) + 6725 $new-var:end: + 6726 # . restore registers + 6727 59/pop-to-ecx + 6728 58/pop-to-eax + 6729 # . epilogue + 6730 89/<- %esp 5/r32/ebp + 6731 5d/pop-to-ebp + 6732 c3/return + 6733 + 6734 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) + 6735 # . prologue + 6736 55/push-ebp + 6737 89/<- %ebp 4/r32/esp + 6738 # . save registers + 6739 50/push-eax + 6740 51/push-ecx + 6741 # if (!is-hex-int?(name)) abort + 6742 (is-hex-int? *(ebp+0xc)) # => eax + 6743 3d/compare-eax-and 0/imm32/false + 6744 0f 84/jump-if-= $new-literal-integer:abort/disp32 + 6745 # out = new var(s) + 6746 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) + 6747 # var out-addr/ecx: (addr var) = lookup(*out) + 6748 8b/-> *(ebp+0x10) 0/r32/eax + 6749 (lookup *eax *(eax+4)) # => eax + 6750 89/<- %ecx 0/r32/eax + 6751 # out-addr->type = new tree() + 6752 8d/copy-address *(ecx+8) 0/r32/eax # Var-type + 6753 (allocate *(ebp+8) *Tree-size %eax) + 6754 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 6755 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom + 6756 # nothing else to do; default type is 'literal' + 6757 $new-literal-integer:end: + 6758 # . reclaim locals + 6759 81 0/subop/add %esp 8/imm32 + 6760 # . restore registers + 6761 59/pop-to-ecx + 6762 58/pop-to-eax + 6763 # . epilogue + 6764 89/<- %esp 5/r32/ebp + 6765 5d/pop-to-ebp + 6766 c3/return + 6767 + 6768 $new-literal-integer:abort: + 6769 (write-buffered Stderr "variable cannot begin with a digit '") + 6770 (write-slice-buffered Stderr *(ebp+0xc)) + 6771 (write-buffered Stderr "'\n") + 6772 (flush Stderr) + 6773 # . syscall(exit, 1) + 6774 bb/copy-to-ebx 1/imm32 + 6775 b8/copy-to-eax 1/imm32/exit + 6776 cd/syscall 0x80/imm8 + 6777 # never gets here + 6778 + 6779 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) + 6780 # . prologue + 6781 55/push-ebp + 6782 89/<- %ebp 4/r32/esp + 6783 # . save registers + 6784 50/push-eax + 6785 51/push-ecx + 6786 # var s/ecx: (handle array byte) + 6787 68/push 0/imm32 + 6788 68/push 0/imm32 + 6789 89/<- %ecx 4/r32/esp + 6790 # s = slice-to-string(name) + 6791 (slice-to-string Heap *(ebp+0xc) %ecx) + 6792 # allocate to out + 6793 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) + 6794 # var out-addr/ecx: (addr var) = lookup(*out) + 6795 8b/-> *(ebp+0x10) 1/r32/ecx + 6796 (lookup *ecx *(ecx+4)) # => eax + 6797 89/<- %ecx 0/r32/eax + 6798 # out-addr->type/eax = new type + 6799 8d/copy-address *(ecx+8) 0/r32/eax # Var-type + 6800 (allocate *(ebp+8) *Tree-size %eax) + 6801 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 6802 # nothing else to do; default type is 'literal' + 6803 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom + 6804 $new-literal:end: + 6805 # . reclaim locals + 6806 81 0/subop/add %esp 8/imm32 + 6807 # . restore registers + 6808 59/pop-to-ecx + 6809 58/pop-to-eax + 6810 # . epilogue + 6811 89/<- %esp 5/r32/ebp + 6812 5d/pop-to-ebp + 6813 c3/return + 6814 + 6815 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) + 6816 # . prologue + 6817 55/push-ebp + 6818 89/<- %ebp 4/r32/esp + 6819 # . save registers + 6820 51/push-ecx + 6821 # var tmp/ecx: (handle array byte) + 6822 68/push 0/imm32 + 6823 68/push 0/imm32 + 6824 89/<- %ecx 4/r32/esp + 6825 # tmp = slice-to-string(name) + 6826 (slice-to-string Heap *(ebp+0xc) %ecx) + 6827 # out = new-var(tmp) + 6828 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) + 6829 $new-var-from-slice:end: + 6830 # . reclaim locals + 6831 81 0/subop/add %esp 8/imm32 + 6832 # . restore registers + 6833 59/pop-to-ecx + 6834 # . epilogue + 6835 89/<- %esp 5/r32/ebp + 6836 5d/pop-to-ebp + 6837 c3/return + 6838 + 6839 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) + 6840 # . prologue + 6841 55/push-ebp + 6842 89/<- %ebp 4/r32/esp + 6843 # . save registers + 6844 50/push-eax + 6845 51/push-ecx + 6846 # + 6847 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) + 6848 # var out-addr/eax: (addr stmt) = lookup(*out) + 6849 8b/-> *(ebp+0x14) 0/r32/eax + 6850 (lookup *eax *(eax+4)) # => eax + 6851 # out-addr->tag = stmt + 6852 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag + 6853 # result->var = var + 6854 8b/-> *(ebp+0xc) 1/r32/ecx + 6855 89/<- *(eax+4) 1/r32/ecx # Vardef-var + 6856 8b/-> *(ebp+0x10) 1/r32/ecx + 6857 89/<- *(eax+8) 1/r32/ecx # Vardef-var + 6858 $new-var-def:end: + 6859 # . restore registers + 6860 59/pop-to-ecx + 6861 58/pop-to-eax + 6862 # . epilogue + 6863 89/<- %esp 5/r32/ebp + 6864 5d/pop-to-ebp + 6865 c3/return + 6866 + 6867 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) + 6868 # . prologue + 6869 55/push-ebp + 6870 89/<- %ebp 4/r32/esp + 6871 # . save registers + 6872 50/push-eax + 6873 # eax = out + 6874 8b/-> *(ebp+0x14) 0/r32/eax + 6875 # + 6876 (allocate *(ebp+8) *Stmt-size %eax) + 6877 # var out-addr/eax: (addr stmt) = lookup(*out) + 6878 (lookup *eax *(eax+4)) # => eax + 6879 # set tag + 6880 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag + 6881 # set output + 6882 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs + 6883 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) + 6884 $new-reg-var-def:end: + 6885 # . restore registers + 6886 58/pop-to-eax + 6887 # . epilogue + 6888 89/<- %esp 5/r32/ebp + 6889 5d/pop-to-ebp + 6890 c3/return + 6891 + 6892 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) + 6893 # . prologue + 6894 55/push-ebp + 6895 89/<- %ebp 4/r32/esp + 6896 # . save registers + 6897 50/push-eax + 6898 51/push-ecx + 6899 57/push-edi + 6900 # edi = out + 6901 8b/-> *(ebp+0x1c) 7/r32/edi + 6902 # *out = new list + 6903 (allocate *(ebp+8) *List-size %edi) + 6904 # var out-addr/edi: (addr list _type) = lookup(*out) + 6905 (lookup *edi *(edi+4)) # => eax + 6906 89/<- %edi 0/r32/eax + 6907 # out-addr->value = value + 6908 8b/-> *(ebp+0xc) 0/r32/eax + 6909 89/<- *edi 0/r32/eax # List-value + 6910 8b/-> *(ebp+0x10) 0/r32/eax + 6911 89/<- *(edi+4) 0/r32/eax # List-value + 6912 # if (list == null) return + 6913 81 7/subop/compare *(ebp+0x14) 0/imm32 + 6914 74/jump-if-= $append-list:end/disp8 + 6915 # otherwise append + 6916 $append-list:non-empty-list: + 6917 # var curr/eax: (addr list _type) = lookup(list) + 6918 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax + 6919 # while (curr->next != null) curr = curr->next + 6920 { + 6921 81 7/subop/compare *(eax+8) 0/imm32 # List-next + 6922 74/jump-if-= break/disp8 + 6923 # curr = lookup(curr->next) + 6924 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax + 6925 # + 6926 eb/jump loop/disp8 + 6927 } + 6928 # edi = out + 6929 8b/-> *(ebp+0x1c) 7/r32/edi + 6930 # curr->next = out + 6931 8b/-> *edi 1/r32/ecx + 6932 89/<- *(eax+8) 1/r32/ecx # List-next + 6933 8b/-> *(edi+4) 1/r32/ecx + 6934 89/<- *(eax+0xc) 1/r32/ecx # List-next + 6935 # out = list + 6936 8b/-> *(ebp+0x14) 1/r32/ecx + 6937 89/<- *edi 1/r32/ecx + 6938 8b/-> *(ebp+0x18) 1/r32/ecx + 6939 89/<- *(edi+4) 1/r32/ecx + 6940 $append-list:end: + 6941 # . restore registers + 6942 5f/pop-to-edi + 6943 59/pop-to-ecx + 6944 58/pop-to-eax + 6945 # . epilogue + 6946 89/<- %esp 5/r32/ebp + 6947 5d/pop-to-ebp + 6948 c3/return + 6949 + 6950 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) + 6951 # . prologue + 6952 55/push-ebp + 6953 89/<- %ebp 4/r32/esp + 6954 # . save registers + 6955 50/push-eax + 6956 51/push-ecx + 6957 57/push-edi + 6958 # edi = out + 6959 8b/-> *(ebp+0x20) 7/r32/edi + 6960 # out = new stmt-var + 6961 (allocate *(ebp+8) *Stmt-var-size %edi) + 6962 # var out-addr/ecx: (addr stmt-var) = lookup(*out) + 6963 (lookup *edi *(edi+4)) # => eax + 6964 89/<- %ecx 0/r32/eax + 6965 # out-addr->value = v + 6966 8b/-> *(ebp+0xc) 0/r32/eax + 6967 89/<- *ecx 0/r32/eax # Stmt-var-value + 6968 8b/-> *(ebp+0x10) 0/r32/eax + 6969 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value + 6970 # out-addr->is-deref? = is-deref? + 6971 8b/-> *(ebp+0x1c) 0/r32/eax + 6972 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref + 6973 # if (vars == null) return result + 6974 81 7/subop/compare *(ebp+0x14) 0/imm32/null + 6975 74/jump-if-= $append-stmt-var:end/disp8 + 6976 # otherwise append + 6977 # var curr/eax: (addr stmt-var) = lookup(vars) + 6978 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax + 6979 # while (curr->next != null) curr = curr->next + 6980 { + 6981 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next + 6982 74/jump-if-= break/disp8 + 6983 # curr = lookup(curr->next) + 6984 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax + 6985 # + 6986 eb/jump loop/disp8 + 6987 } + 6988 # curr->next = out + 6989 8b/-> *edi 1/r32/ecx + 6990 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next + 6991 8b/-> *(edi+4) 1/r32/ecx + 6992 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next + 6993 # out = vars + 6994 8b/-> *(ebp+0x14) 1/r32/ecx + 6995 89/<- *edi 1/r32/ecx + 6996 8b/-> *(ebp+0x18) 1/r32/ecx + 6997 89/<- *(edi+4) 1/r32/ecx + 6998 $append-stmt-var:end: + 6999 # . restore registers + 7000 5f/pop-to-edi + 7001 59/pop-to-ecx + 7002 58/pop-to-eax + 7003 # . epilogue + 7004 89/<- %esp 5/r32/ebp + 7005 5d/pop-to-ebp + 7006 c3/return + 7007 + 7008 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) + 7009 # . prologue + 7010 55/push-ebp + 7011 89/<- %ebp 4/r32/esp + 7012 # . save registers + 7013 50/push-eax + 7014 56/push-esi + 7015 # esi = block + 7016 8b/-> *(ebp+0xc) 6/r32/esi + 7017 # block->stmts = append(x, block->stmts) + 7018 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts + 7019 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts + 7020 $append-to-block:end: + 7021 # . restore registers + 7022 5e/pop-to-esi + 7023 58/pop-to-eax + 7024 # . epilogue + 7025 89/<- %esp 5/r32/ebp + 7026 5d/pop-to-ebp + 7027 c3/return + 7028 + 7029 ## Parsing types + 7030 # We need to create metadata on user-defined types, and we need to use this + 7031 # metadata as we parse instructions. + 7032 # However, we also want to allow types to be used before their definitions. + 7033 # This means we can't ever assume any type data structures exist. + 7034 + 7035 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) + 7036 # . prologue + 7037 55/push-ebp + 7038 89/<- %ebp 4/r32/esp + 7039 # . save registers + 7040 50/push-eax + 7041 56/push-esi + 7042 # var container-type/esi: type-id + 7043 (container-type *(ebp+8)) # => eax + 7044 89/<- %esi 0/r32/eax + 7045 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) + 7046 68/push 0/imm32 + 7047 68/push 0/imm32 + 7048 89/<- %eax 4/r32/esp + 7049 (find-or-create-typeinfo %esi %eax) + 7050 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) + 7051 (lookup *eax *(eax+4)) # => eax + 7052 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) + 7053 #? (write-buffered Stderr "constant: ") + 7054 #? (write-slice-buffered Stderr *(ebp+0xc)) + 7055 #? (write-buffered Stderr Newline) + 7056 #? (flush Stderr) + 7057 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) + 7058 #? 8b/-> *(ebp+0x10) 0/r32/eax + 7059 #? (write-buffered Stderr "@") + 7060 #? (lookup *eax *(eax+4)) + 7061 #? (print-int32-buffered Stderr %eax) + 7062 #? (lookup *eax *(eax+4)) + 7063 #? (write-buffered Stderr %eax) + 7064 #? (write-buffered Stderr Newline) + 7065 #? (flush Stderr) + 7066 #? (write-buffered Stderr "offset: ") + 7067 #? 8b/-> *(eax+0x14) 0/r32/eax + 7068 #? (print-int32-buffered Stderr %eax) + 7069 #? (write-buffered Stderr Newline) + 7070 #? (flush Stderr) + 7071 $lookup-or-create-constant:end: + 7072 # . reclaim locals + 7073 81 0/subop/add %esp 8/imm32 + 7074 # . restore registers + 7075 5e/pop-to-esi + 7076 58/pop-to-eax + 7077 # . epilogue + 7078 89/<- %esp 5/r32/ebp + 7079 5d/pop-to-ebp + 7080 c3/return + 7081 + 7082 # if addr var: + 7083 # container->var->type->right->left->value + 7084 # otherwise + 7085 # container->var->type->value + 7086 container-type: # container: (addr stmt-var) -> result/eax: type-id + 7087 # . prologue + 7088 55/push-ebp + 7089 89/<- %ebp 4/r32/esp + 7090 # + 7091 8b/-> *(ebp+8) 0/r32/eax + 7092 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 7093 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax + 7094 { + 7095 81 7/subop/compare *(eax+8) 0/imm32 # Tree-right + 7096 74/jump-if-= break/disp8 + 7097 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax + 7098 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax + 7099 } + 7100 8b/-> *(eax+4) 0/r32/eax # Tree-value + 7101 $container-type:end: + 7102 # . epilogue + 7103 89/<- %esp 5/r32/ebp + 7104 5d/pop-to-ebp + 7105 c3/return + 7106 + 7107 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) + 7108 # . prologue + 7109 55/push-ebp + 7110 89/<- %ebp 4/r32/esp + 7111 # . save registers + 7112 50/push-eax + 7113 51/push-ecx + 7114 52/push-edx + 7115 57/push-edi + 7116 # edi = out + 7117 8b/-> *(ebp+0xc) 7/r32/edi + 7118 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) + 7119 68/push 0/imm32 + 7120 68/push 0/imm32 + 7121 89/<- %ecx 4/r32/esp + 7122 # find-typeinfo(t, out) + 7123 (find-typeinfo *(ebp+8) %edi) + 7124 { + 7125 # if (*out != 0) break + 7126 81 7/subop/compare *edi 0/imm32 + 7127 0f 85/jump-if-!= break/disp32 + 7128 $find-or-create-typeinfo:create: + 7129 # *out = allocate + 7130 (allocate Heap *Typeinfo-size %edi) + 7131 # var tmp/eax: (addr typeinfo) = lookup(*out) + 7132 (lookup *edi *(edi+4)) # => eax + 7133 #? (write-buffered Stderr "created typeinfo at ") + 7134 #? (print-int32-buffered Stderr %eax) + 7135 #? (write-buffered Stderr " for type-id ") + 7136 #? (print-int32-buffered Stderr *(ebp+8)) + 7137 #? (write-buffered Stderr Newline) + 7138 #? (flush Stderr) + 7139 # tmp->id = t + 7140 8b/-> *(ebp+8) 2/r32/edx + 7141 89/<- *eax 2/r32/edx # Typeinfo-id + 7142 # tmp->fields = new table + 7143 # . fields = new table + 7144 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) + 7145 # . tmp->fields = fields + 7146 8b/-> *ecx 2/r32/edx + 7147 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields + 7148 8b/-> *(ecx+4) 2/r32/edx + 7149 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields + 7150 # tmp->next = Program->types + 7151 8b/-> *_Program-types 1/r32/ecx + 7152 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next + 7153 8b/-> *_Program-types->payload 1/r32/ecx + 7154 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next + 7155 # Program->types = out + 7156 8b/-> *edi 1/r32/ecx + 7157 89/<- *_Program-types 1/r32/ecx + 7158 8b/-> *(edi+4) 1/r32/ecx + 7159 89/<- *_Program-types->payload 1/r32/ecx + 7160 } + 7161 $find-or-create-typeinfo:end: + 7162 # . reclaim locals + 7163 81 0/subop/add %esp 8/imm32 + 7164 # . restore registers + 7165 5f/pop-to-edi + 7166 5a/pop-to-edx + 7167 59/pop-to-ecx + 7168 58/pop-to-eax + 7169 # . epilogue + 7170 89/<- %esp 5/r32/ebp + 7171 5d/pop-to-ebp + 7172 c3/return + 7173 + 7174 find-typeinfo: # t: type-id, out: (addr handle typeinfo) + 7175 # . prologue + 7176 55/push-ebp + 7177 89/<- %ebp 4/r32/esp + 7178 # . save registers + 7179 50/push-eax + 7180 51/push-ecx + 7181 52/push-edx + 7182 57/push-edi + 7183 # ecx = t + 7184 8b/-> *(ebp+8) 1/r32/ecx + 7185 # edi = out + 7186 8b/-> *(ebp+0xc) 7/r32/edi + 7187 # *out = Program->types + 7188 8b/-> *_Program-types 0/r32/eax + 7189 89/<- *edi 0/r32/eax + 7190 8b/-> *_Program-types->payload 0/r32/eax + 7191 89/<- *(edi+4) 0/r32/eax + 7192 { + 7193 # if (*out == 0) break + 7194 81 7/subop/compare *edi 0/imm32 + 7195 74/jump-if-= break/disp8 + 7196 # var tmp/eax: (addr typeinfo) = lookup(*out) + 7197 (lookup *edi *(edi+4)) # => eax + 7198 # if (tmp->id == t) break + 7199 39/compare *eax 1/r32/ecx # Typeinfo-id + 7200 74/jump-if-= break/disp8 + 7201 # *out = tmp->next + 7202 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next + 7203 89/<- *edi 2/r32/edx + 7204 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next + 7205 89/<- *(edi+4) 2/r32/edx + 7206 # + 7207 eb/jump loop/disp8 + 7208 } + 7209 $find-typeinfo:end: + 7210 # . restore registers + 7211 5f/pop-to-edi + 7212 5a/pop-to-edx + 7213 59/pop-to-ecx + 7214 58/pop-to-eax + 7215 # . epilogue + 7216 89/<- %esp 5/r32/ebp + 7217 5d/pop-to-ebp + 7218 c3/return + 7219 + 7220 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) + 7221 # . prologue + 7222 55/push-ebp + 7223 89/<- %ebp 4/r32/esp + 7224 # . save registers + 7225 50/push-eax + 7226 52/push-edx + 7227 57/push-edi + 7228 # var dest/edi: (handle typeinfo-entry) + 7229 68/push 0/imm32 + 7230 68/push 0/imm32 + 7231 89/<- %edi 4/r32/esp + 7232 # find-or-create-typeinfo-fields(T, f, dest) + 7233 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) + 7234 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) + 7235 (lookup *edi *(edi+4)) # => eax + 7236 89/<- %edi 0/r32/eax + 7237 # if dest-addr->output-var doesn't exist, create it + 7238 { + 7239 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var + 7240 0f 85/jump-if-!= break/disp32 + 7241 # dest-addr->output-var = new var(dummy name, type, -1 offset) + 7242 # . var name/eax: (handle array byte) = "field" + 7243 68/push 0/imm32 + 7244 68/push 0/imm32 + 7245 89/<- %eax 4/r32/esp + 7246 (copy-array Heap "field" %eax) + 7247 # . new var + 7248 8d/copy-address *(edi+0xc) 2/r32/edx + 7249 (new-var Heap *eax *(eax+4) %edx) + 7250 # . reclaim name + 7251 81 0/subop/add %esp 8/imm32 + 7252 # var result/edx: (addr var) = lookup(dest-addr->output-var) + 7253 (lookup *(edi+0xc) *(edi+0x10)) # => eax + 7254 89/<- %edx 0/r32/eax + 7255 # result->type = new constant type + 7256 8d/copy-address *(edx+8) 0/r32/eax # Var-type + 7257 (allocate Heap *Tree-size %eax) + 7258 (lookup *(edx+8) *(edx+0xc)) # => eax + 7259 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom + 7260 c7 0/subop/copy *(eax+4) 6/imm32/constant # Tree-value + 7261 c7 0/subop/copy *(eax+8) 0/imm32 # Tree-left + 7262 c7 0/subop/copy *(eax+0xc) 0/imm32 # Tree-right + 7263 c7 0/subop/copy *(eax+0x10) 0/imm32 # Tree-right + 7264 # result->offset isn't filled out yet + 7265 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset + 7266 } + 7267 # out = dest-addr->output-var + 7268 8b/-> *(ebp+0x10) 2/r32/edx + 7269 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var + 7270 89/<- *edx 0/r32/eax + 7271 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var + 7272 89/<- *(edx+4) 0/r32/eax + 7273 $find-or-create-typeinfo-output-var:end: + 7274 # . reclaim locals + 7275 81 0/subop/add %esp 8/imm32 + 7276 # . restore registers + 7277 5f/pop-to-edi + 7278 5a/pop-to-edx + 7279 58/pop-to-eax + 7280 # . epilogue + 7281 89/<- %esp 5/r32/ebp + 7282 5d/pop-to-ebp + 7283 c3/return + 7284 + 7285 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) + 7286 # . prologue + 7287 55/push-ebp + 7288 89/<- %ebp 4/r32/esp + 7289 # . save registers + 7290 50/push-eax + 7291 56/push-esi + 7292 57/push-edi + 7293 # eax = lookup(T->fields) + 7294 8b/-> *(ebp+8) 0/r32/eax + 7295 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax + 7296 # edi = out + 7297 8b/-> *(ebp+0x10) 7/r32/edi + 7298 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) + 7299 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax + 7300 89/<- %esi 0/r32/eax + 7301 # if src doesn't exist, allocate it + 7302 { + 7303 81 7/subop/compare *esi 0/imm32 + 7304 75/jump-if-!= break/disp8 + 7305 (allocate Heap *Typeinfo-entry-size %esi) + 7306 #? (write-buffered Stderr "handle at ") + 7307 #? (print-int32-buffered Stderr %esi) + 7308 #? (write-buffered Stderr ": ") + 7309 #? (print-int32-buffered Stderr *esi) + 7310 #? (write-buffered Stderr " ") + 7311 #? (print-int32-buffered Stderr *(esi+4)) + 7312 #? (write-buffered Stderr Newline) + 7313 #? (flush Stderr) + 7314 #? (lookup *esi *(esi+4)) + 7315 #? (write-buffered Stderr "created typeinfo fields at ") + 7316 #? (print-int32-buffered Stderr %esi) + 7317 #? (write-buffered Stderr " for ") + 7318 #? (print-int32-buffered Stderr *(ebp+8)) + 7319 #? (write-buffered Stderr Newline) + 7320 #? (flush Stderr) + 7321 } + 7322 # *out = src + 7323 # . *edi = *src + 7324 8b/-> *esi 0/r32/eax + 7325 89/<- *edi 0/r32/eax + 7326 8b/-> *(esi+4) 0/r32/eax + 7327 89/<- *(edi+4) 0/r32/eax + 7328 $find-or-create-typeinfo-fields:end: + 7329 # . restore registers + 7330 5f/pop-to-edi + 7331 5e/pop-to-esi + 7332 58/pop-to-eax + 7333 # . epilogue + 7334 89/<- %esp 5/r32/ebp + 7335 5d/pop-to-ebp + 7336 c3/return + 7337 + 7338 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo) + 7339 # pseudocode: + 7340 # var line: (stream byte 512) + 7341 # curr-index = 0 + 7342 # while true + 7343 # clear-stream(line) + 7344 # read-line-buffered(in, line) + 7345 # if line->write == 0 + 7346 # abort + 7347 # word-slice = next-mu-token(line) + 7348 # if slice-empty?(word-slice) # end of line + 7349 # continue + 7350 # if slice-equal?(word-slice, "}") + 7351 # break + 7352 # var v: (handle var) = parse-var-with-type(word-slice, line) + 7353 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) + 7354 # TODO: ensure that r->first is null + 7355 # r->index = curr-index + 7356 # curr-index++ + 7357 # r->input-var = v + 7358 # if r->output-var == 0 + 7359 # r->output-var = new literal + 7360 # TODO: ensure nothing else in line + 7361 # t->total-size-in-bytes = -2 (not yet initialized) + 7362 # + 7363 # . prologue + 7364 55/push-ebp + 7365 89/<- %ebp 4/r32/esp + 7366 # var curr-index: int at *(ebp-4) + 7367 68/push 0/imm32 + 7368 # . save registers + 7369 50/push-eax + 7370 51/push-ecx + 7371 52/push-edx + 7372 53/push-ebx + 7373 56/push-esi + 7374 57/push-edi + 7375 # edi = t + 7376 8b/-> *(ebp+0xc) 7/r32/edi + 7377 # var line/ecx: (stream byte 512) + 7378 81 5/subop/subtract %esp 0x200/imm32 + 7379 68/push 0x200/imm32/size + 7380 68/push 0/imm32/read + 7381 68/push 0/imm32/write + 7382 89/<- %ecx 4/r32/esp + 7383 # var word-slice/edx: slice + 7384 68/push 0/imm32/end + 7385 68/push 0/imm32/start + 7386 89/<- %edx 4/r32/esp + 7387 # var v/esi: (handle var) + 7388 68/push 0/imm32 + 7389 68/push 0/imm32 + 7390 89/<- %esi 4/r32/esp + 7391 # var r/ebx: (handle typeinfo-entry) + 7392 68/push 0/imm32 + 7393 68/push 0/imm32 + 7394 89/<- %ebx 4/r32/esp + 7395 { + 7396 $populate-mu-type:line-loop: + 7397 (clear-stream %ecx) + 7398 (read-line-buffered *(ebp+8) %ecx) + 7399 # if (line->write == 0) abort + 7400 81 7/subop/compare *ecx 0/imm32 + 7401 0f 84/jump-if-= $populate-mu-type:abort/disp32 + 7402 +-- 6 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + 7408 (next-mu-token %ecx %edx) + 7409 # if slice-empty?(word-slice) continue + 7410 (slice-empty? %edx) # => eax + 7411 3d/compare-eax-and 0/imm32 + 7412 0f 85/jump-if-!= loop/disp32 + 7413 # if slice-equal?(word-slice, "}") break + 7414 (slice-equal? %edx "}") + 7415 3d/compare-eax-and 0/imm32 + 7416 0f 85/jump-if-!= break/disp32 + 7417 $populate-mu-type:parse-element: + 7418 # v = parse-var-with-type(word-slice, first-line) + 7419 # must do this first to strip the trailing ':' from word-slice before + 7420 # using it in find-or-create-typeinfo-fields below + 7421 # TODO: clean up that mutation in parse-var-with-type + 7422 (parse-var-with-type %edx %ecx %esi) # => eax + 7423 # var tmp/ecx + 7424 51/push-ecx + 7425 $populate-mu-type:create-typeinfo-fields: + 7426 # var r/ebx: (handle typeinfo-entry) + 7427 (find-or-create-typeinfo-fields %edi %edx %ebx) + 7428 # r->index = curr-index + 7429 (lookup *ebx *(ebx+4)) # => eax + 7430 8b/-> *(ebp-4) 1/r32/ecx + 7431 #? (write-buffered Stderr "saving index ") + 7432 #? (print-int32-buffered Stderr %ecx) + 7433 #? (write-buffered Stderr " at ") + 7434 #? (print-int32-buffered Stderr %edi) + 7435 #? (write-buffered Stderr Newline) + 7436 #? (flush Stderr) + 7437 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index + 7438 # ++curr-index + 7439 ff 0/subop/increment *(ebp-4) + 7440 $populate-mu-type:set-input-type: + 7441 # r->input-var = v + 7442 8b/-> *esi 1/r32/ecx + 7443 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var + 7444 8b/-> *(esi+4) 1/r32/ecx + 7445 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var + 7446 59/pop-to-ecx + 7447 { + 7448 $populate-mu-type:create-output-type: + 7449 # if (r->output-var == 0) create a new var with some placeholder data + 7450 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var + 7451 75/jump-if-!= break/disp8 + 7452 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var + 7453 (new-literal Heap %edx %eax) + 7454 } + 7455 e9/jump loop/disp32 + 7456 } + 7457 $populate-mu-type:invalidate-total-size-in-bytes: + 7458 # Offsets and total size may not be accurate here since we may not yet + 7459 # have encountered the element types. + 7460 # We'll recompute them separately after parsing the entire program. + 7461 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes + 7462 $populate-mu-type:end: + 7463 # . reclaim locals + 7464 81 0/subop/add %esp 0x224/imm32 + 7465 # . restore registers + 7466 5f/pop-to-edi + 7467 5e/pop-to-esi + 7468 5b/pop-to-ebx + 7469 5a/pop-to-edx + 7470 59/pop-to-ecx + 7471 58/pop-to-eax + 7472 # reclaim curr-index + 7473 81 0/subop/add %esp 4/imm32 + 7474 # . epilogue + 7475 89/<- %esp 5/r32/ebp + 7476 5d/pop-to-ebp + 7477 c3/return + 7478 + 7479 $populate-mu-type:abort: + 7480 # error("unexpected top-level command: " word-slice "\n") + 7481 (write-buffered Stderr "incomplete type definition '") + 7482 (type-name *edi) # Typeinfo-id => eax + 7483 (write-buffered Stderr %eax) + 7484 (write-buffered Stderr "\n") + 7485 (flush Stderr) + 7486 # . syscall(exit, 1) + 7487 bb/copy-to-ebx 1/imm32 + 7488 b8/copy-to-eax 1/imm32/exit + 7489 cd/syscall 0x80/imm8 + 7490 # never gets here + 7491 + 7492 type-name: # index: int -> result/eax: (addr array byte) + 7493 # . prologue + 7494 55/push-ebp + 7495 89/<- %ebp 4/r32/esp + 7496 # + 7497 (index Type-id *(ebp+8)) + 7498 $type-name:end: + 7499 # . epilogue + 7500 89/<- %esp 5/r32/ebp + 7501 5d/pop-to-ebp + 7502 c3/return + 7503 + 7504 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) + 7505 # . prologue + 7506 55/push-ebp + 7507 89/<- %ebp 4/r32/esp + 7508 # . save registers + 7509 56/push-esi + 7510 # TODO: bounds-check index + 7511 # esi = arr + 7512 8b/-> *(ebp+8) 6/r32/esi + 7513 # eax = index + 7514 8b/-> *(ebp+0xc) 0/r32/eax + 7515 # eax = *(arr + 12 + index) + 7516 8b/-> *(esi+eax+0xc) 0/r32/eax + 7517 $index:end: + 7518 # . restore registers + 7519 5e/pop-to-esi + 7520 # . epilogue + 7521 89/<- %esp 5/r32/ebp + 7522 5d/pop-to-ebp + 7523 c3/return + 7524 + 7525 ####################################################### + 7526 # Compute type sizes + 7527 ####################################################### + 7528 + 7529 # Compute the sizes of all user-defined types. + 7530 # We'll need the sizes of their elements, which may be other user-defined + 7531 # types, which we will compute as needed. + 7532 + 7533 # Initially, all user-defined types have their sizes set to -2 (invalid) + 7534 populate-mu-type-sizes: + 7535 # . prologue + 7536 55/push-ebp + 7537 89/<- %ebp 4/r32/esp + 7538 $populate-mu-type-sizes:total-sizes: + 7539 # var curr/eax: (addr typeinfo) = lookup(Program->types) + 7540 (lookup *_Program-types *_Program-types->payload) # => eax + 7541 { + 7542 # if (curr == null) break + 7543 3d/compare-eax-and 0/imm32/null + 7544 74/jump-if-= break/disp8 + 7545 (populate-mu-type-sizes-in-type %eax) + 7546 # curr = lookup(curr->next) + 7547 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax + 7548 eb/jump loop/disp8 + 7549 } + 7550 $populate-mu-type-sizes:offsets: + 7551 # curr = *Program->types + 7552 (lookup *_Program-types *_Program-types->payload) # => eax + 7553 { + 7554 # if (curr == null) break + 7555 3d/compare-eax-and 0/imm32/null + 7556 74/jump-if-= break/disp8 + 7557 (populate-mu-type-offsets %eax) + 7558 # curr = curr->next + 7559 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax + 7560 eb/jump loop/disp8 + 7561 } + 7562 $populate-mu-type-sizes:end: + 7563 # . epilogue + 7564 89/<- %esp 5/r32/ebp + 7565 5d/pop-to-ebp + 7566 c3/return + 7567 + 7568 # compute sizes of all fields, recursing as necessary + 7569 # sum up all their sizes to arrive at total size + 7570 # fields may be out of order, but that doesn't affect the answer + 7571 populate-mu-type-sizes-in-type: # T: (addr typeinfo) + 7572 # . prologue + 7573 55/push-ebp + 7574 89/<- %ebp 4/r32/esp + 7575 # . save registers + 7576 50/push-eax + 7577 51/push-ecx + 7578 52/push-edx + 7579 56/push-esi + 7580 57/push-edi + 7581 # esi = T + 7582 8b/-> *(ebp+8) 6/r32/esi + 7583 # if T is already computed, return + 7584 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes + 7585 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 + 7586 # if T is being computed, abort + 7587 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes + 7588 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 + 7589 # tag T (-2 to -1) to avoid infinite recursion + 7590 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes + 7591 # var total-size/edi: int = 0 + 7592 bf/copy-to-edi 0/imm32 + 7593 # - for every field, if it's a user-defined type, compute its size + 7594 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) + 7595 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax + 7596 89/<- %ecx 0/r32/eax + 7597 # var table-size/edx: int = table->write + 7598 8b/-> *ecx 2/r32/edx # stream-write + 7599 # var curr/ecx: (addr table_row) = table->data + 7600 8d/copy-address *(ecx+0xc) 1/r32/ecx + 7601 # var max/edx: (addr table_row) = table->data + table->write + 7602 8d/copy-address *(ecx+edx) 2/r32/edx + 7603 { + 7604 $populate-mu-type-sizes-in-type:loop: + 7605 # if (curr >= max) break + 7606 39/compare %ecx 2/r32/edx + 7607 73/jump-if-addr>= break/disp8 + 7608 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) + 7609 (lookup *(ecx+8) *(ecx+0xc)) # => eax + 7610 # compute size of t->input-var + 7611 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax + 7612 (compute-size-of-var %eax) # => eax + 7613 # result += eax + 7614 01/add-to %edi 0/r32/eax + 7615 # curr += row-size + 7616 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size + 7617 # + 7618 eb/jump loop/disp8 + 7619 } + 7620 # - save result + 7621 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes + 7622 $populate-mu-type-sizes-in-type:end: + 7623 # . restore registers + 7624 5f/pop-to-edi + 7625 5e/pop-to-esi + 7626 5a/pop-to-edx + 7627 59/pop-to-ecx + 7628 58/pop-to-eax + 7629 # . epilogue + 7630 89/<- %esp 5/r32/ebp + 7631 5d/pop-to-ebp + 7632 c3/return + 7633 + 7634 $populate-mu-type-sizes-in-type:abort: + 7635 (write-buffered Stderr "cycle in type definitions\n") + 7636 (flush Stderr) + 7637 # . syscall(exit, 1) + 7638 bb/copy-to-ebx 1/imm32 + 7639 b8/copy-to-eax 1/imm32/exit + 7640 cd/syscall 0x80/imm8 + 7641 # never gets here + 7642 + 7643 # Analogous to size-of, except we need to compute what size-of can just read + 7644 # off the right data structures. + 7645 compute-size-of-var: # in: (addr var) -> result/eax: int + 7646 # . prologue + 7647 55/push-ebp + 7648 89/<- %ebp 4/r32/esp + 7649 # . push registers + 7650 51/push-ecx + 7651 # var t/ecx: (addr tree type-id) = lookup(v->type) + 7652 8b/-> *(ebp+8) 1/r32/ecx + 7653 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 7654 89/<- %ecx 0/r32/eax + 7655 # if (t->is-atom == false) t = lookup(t->left) + 7656 { + 7657 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom + 7658 75/jump-if-!= break/disp8 + 7659 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax + 7660 89/<- %ecx 0/r32/eax + 7661 } + 7662 # TODO: ensure t is an atom + 7663 (compute-size-of-type-id *(ecx+4)) # Tree-value => eax + 7664 $compute-size-of-var:end: + 7665 # . restore registers + 7666 59/pop-to-ecx + 7667 # . epilogue + 7668 89/<- %esp 5/r32/ebp + 7669 5d/pop-to-ebp + 7670 c3/return + 7671 + 7672 compute-size-of-type-id: # t: type-id -> result/eax: int + 7673 # . prologue + 7674 55/push-ebp + 7675 89/<- %ebp 4/r32/esp + 7676 # . save registers + 7677 51/push-ecx + 7678 # var out/ecx: (handle typeinfo) + 7679 68/push 0/imm32 + 7680 68/push 0/imm32 + 7681 89/<- %ecx 4/r32/esp + 7682 # eax = t + 7683 8b/-> *(ebp+8) 0/r32/eax + 7684 # if v is a literal, return 0 + 7685 3d/compare-eax-and 0/imm32 + 7686 74/jump-if-= $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int + 7687 # if v has a user-defined type, compute its size + 7688 # TODO: support non-atom type + 7689 (find-typeinfo %eax %ecx) + 7690 { + 7691 81 7/subop/compare *ecx 0/imm32 + 7692 74/jump-if-= break/disp8 + 7693 $compute-size-of-type-id:user-defined: + 7694 (populate-mu-type-sizes %eax) + 7695 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes + 7696 eb/jump $compute-size-of-type-id:end/disp8 + 7697 } + 7698 # otherwise return the word size + 7699 b8/copy-to-eax 4/imm32 + 7700 $compute-size-of-type-id:end: + 7701 # . reclaim locals + 7702 81 0/subop/add %esp 8/imm32 + 7703 # . restore registers + 7704 59/pop-to-ecx + 7705 # . epilogue + 7706 89/<- %esp 5/r32/ebp + 7707 5d/pop-to-ebp + 7708 c3/return + 7709 + 7710 # at this point we have total sizes for all user-defined types + 7711 # compute offsets for each element + 7712 # complication: fields may be out of order + 7713 populate-mu-type-offsets: # in: (addr typeinfo) + 7714 # . prologue + 7715 55/push-ebp + 7716 89/<- %ebp 4/r32/esp + 7717 # . save registers + 7718 50/push-eax + 7719 51/push-ecx + 7720 52/push-edx + 7721 53/push-ebx + 7722 56/push-esi + 7723 57/push-edi + 7724 #? (dump-typeinfos "aaa\n") + 7725 # var curr-offset/edi: int = 0 + 7726 bf/copy-to-edi 0/imm32 + 7727 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) + 7728 8b/-> *(ebp+8) 1/r32/ecx + 7729 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax + 7730 89/<- %ecx 0/r32/eax + 7731 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size + 7732 8b/-> *ecx 2/r32/edx # stream-write + 7733 c1 5/subop/shift-right-logical %edx 4/imm8 + 7734 # var i/ebx: int = 0 + 7735 bb/copy-to-ebx 0/imm32 + 7736 { + 7737 $populate-mu-type-offsets:loop: + 7738 39/compare %ebx 2/r32/edx + 7739 7d/jump-if->= break/disp8 + 7740 #? (write-buffered Stderr "looking up index ") + 7741 #? (print-int32-buffered Stderr %ebx) + 7742 #? (write-buffered Stderr " in ") + 7743 #? (print-int32-buffered Stderr *(ebp+8)) + 7744 #? (write-buffered Stderr Newline) + 7745 #? (flush Stderr) + 7746 # var v/esi: (addr typeinfo-entry) + 7747 (locate-typeinfo-entry-with-index %ecx %ebx) # => eax + 7748 89/<- %esi 0/r32/eax + 7749 # v->output-var->offset = curr-offset + 7750 # . eax: (addr var) + 7751 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax + 7752 89/<- *(eax+0x14) 7/r32/edi # Var-offset + 7753 # curr-offset += size-of(v->input-var) + 7754 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax + 7755 (size-of %eax) # => eax + 7756 01/add-to %edi 0/r32/eax + 7757 # ++i + 7758 43/increment-ebx + 7759 eb/jump loop/disp8 + 7760 } + 7761 $populate-mu-type-offsets:end: + 7762 # . restore registers + 7763 5f/pop-to-edi + 7764 5e/pop-to-esi + 7765 5b/pop-to-ebx + 7766 5a/pop-to-edx + 7767 59/pop-to-ecx + 7768 58/pop-to-eax + 7769 # . epilogue + 7770 89/<- %esp 5/r32/ebp + 7771 5d/pop-to-ebp + 7772 c3/return + 7773 + 7774 locate-typeinfo-entry-with-index: # table: (addr table (handle array byte) (handle typeinfo-entry)), idx: int -> result/eax: (addr typeinfo-entry) + 7775 # . prologue + 7776 55/push-ebp + 7777 89/<- %ebp 4/r32/esp + 7778 # . save registers + 7779 51/push-ecx + 7780 52/push-edx + 7781 53/push-ebx + 7782 56/push-esi + 7783 57/push-edi + 7784 # esi = table + 7785 8b/-> *(ebp+8) 6/r32/esi + 7786 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data + 7787 8d/copy-address *(esi+0xc) 1/r32/ecx + 7788 # var max/edx: (addr byte) = &table->data[table->write] + 7789 8b/-> *esi 2/r32/edx + 7790 8d/copy-address *(ecx+edx) 2/r32/edx + 7791 { + 7792 $locate-typeinfo-entry-with-index:loop: + 7793 39/compare %ecx 2/r32/edx + 7794 73/jump-if-addr>= $locate-typeinfo-entry-with-index:abort/disp8 + 7795 # var v/eax: (addr typeinfo-entry) + 7796 (lookup *(ecx+8) *(ecx+0xc)) # => eax + 7797 # if (v->index == idx) return v + 7798 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index + 7799 #? (write-buffered Stderr "comparing ") + 7800 #? (print-int32-buffered Stderr %ebx) + 7801 #? (write-buffered Stderr " and ") + 7802 #? (print-int32-buffered Stderr *(ebp+0xc)) + 7803 #? (write-buffered Stderr Newline) + 7804 #? (flush Stderr) + 7805 39/compare *(ebp+0xc) 3/r32/ebx + 7806 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 + 7807 # curr += Typeinfo-entry-size + 7808 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size + 7809 # + 7810 eb/jump loop/disp8 + 7811 } + 7812 # return 0 + 7813 b8/copy-to-eax 0/imm32 + 7814 $locate-typeinfo-entry-with-index:end: + 7815 #? (write-buffered Stderr "returning ") + 7816 #? (print-int32-buffered Stderr %eax) + 7817 #? (write-buffered Stderr Newline) + 7818 #? (flush Stderr) + 7819 # . restore registers + 7820 5f/pop-to-edi + 7821 5e/pop-to-esi + 7822 5b/pop-to-ebx + 7823 5a/pop-to-edx + 7824 59/pop-to-ecx + 7825 # . epilogue + 7826 89/<- %esp 5/r32/ebp + 7827 5d/pop-to-ebp + 7828 c3/return + 7829 + 7830 $locate-typeinfo-entry-with-index:abort: + 7831 (write-buffered Stderr "overflowing typeinfo-entry->index ") + 7832 (print-int32-buffered Stderr %ecx) + 7833 (write-buffered Stderr "\n") + 7834 (flush Stderr) + 7835 # . syscall(exit, 1) + 7836 bb/copy-to-ebx 1/imm32 + 7837 b8/copy-to-eax 1/imm32/exit + 7838 cd/syscall 0x80/imm8 + 7839 # never gets here + 7840 + 7841 dump-typeinfos: # hdr: (addr array byte) + 7842 # . prologue + 7843 55/push-ebp + 7844 89/<- %ebp 4/r32/esp + 7845 # . save registers + 7846 50/push-eax + 7847 # + 7848 (write-buffered Stderr *(ebp+8)) + 7849 (flush Stderr) + 7850 # var curr/eax: (addr typeinfo) = lookup(Program->types) + 7851 (lookup *_Program-types *_Program-types->payload) # => eax + 7852 { + 7853 # if (curr == null) break + 7854 3d/compare-eax-and 0/imm32 + 7855 74/jump-if-= break/disp8 + 7856 (write-buffered Stderr "---\n") + 7857 (flush Stderr) + 7858 (dump-typeinfo %eax) + 7859 # curr = lookup(curr->next) + 7860 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax + 7861 eb/jump loop/disp8 + 7862 } + 7863 $dump-typeinfos:end: + 7864 # . restore registers + 7865 58/pop-to-eax + 7866 # . epilogue + 7867 89/<- %esp 5/r32/ebp + 7868 5d/pop-to-ebp + 7869 c3/return + 7870 + 7871 dump-typeinfo: # in: (addr typeinfo) + 7872 # . prologue + 7873 55/push-ebp + 7874 89/<- %ebp 4/r32/esp + 7875 # . save registers + 7876 50/push-eax 7877 51/push-ecx - 7878 # ecx = t - 7879 8b/-> *(ebp+8) 1/r32/ecx - 7880 # if t->is-atom?, return false - 7881 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom - 7882 75/jump-if-!= $is-mu-array?:return-false/disp8 - 7883 # if !t->left->is-atom?, return false - 7884 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax - 7885 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom - 7886 74/jump-if-= $is-mu-array?:return-false/disp8 - 7887 # return t->left->value == array - 7888 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Tree-value - 7889 0f 94/set-if-= %al - 7890 81 4/subop/and %eax 0xff/imm32 - 7891 eb/jump $is-mu-array?:end/disp8 - 7892 $is-mu-array?:return-false: - 7893 b8/copy-to-eax 0/imm32/false - 7894 $is-mu-array?:end: - 7895 # . restore registers - 7896 59/pop-to-ecx - 7897 # . epilogue - 7898 89/<- %esp 5/r32/ebp - 7899 5d/pop-to-ebp - 7900 c3/return - 7901 - 7902 size-of-array: # a: (addr tree type-id) -> result/eax: int - 7903 # . prologue - 7904 55/push-ebp - 7905 89/<- %ebp 4/r32/esp - 7906 # . save registers - 7907 51/push-ecx - 7908 52/push-edx - 7909 # - 7910 8b/-> *(ebp+8) 1/r32/ecx - 7911 # TODO: assert that a->left is 'array' - 7912 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax - 7913 89/<- %ecx 0/r32/eax - 7914 # var elem-type/edx: type-id = a->right->left->value - 7915 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax - 7916 8b/-> *(eax+4) 2/r32/edx # Tree-value - 7917 # var array-size/ecx: int = a->right->right->left->value - 7918 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax - 7919 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax - 7920 8b/-> *(eax+4) 1/r32/ecx # Tree-value - 7921 # return array-size * size-of(elem-type) - 7922 (size-of-type-id %edx) # => eax - 7923 f7 4/subop/multiply-into-eax %ecx - 7924 05/add-to-eax 4/imm32 # for array size - 7925 $size-of-array:end: - 7926 # . restore registers - 7927 5a/pop-to-edx - 7928 59/pop-to-ecx - 7929 # . epilogue - 7930 89/<- %esp 5/r32/ebp - 7931 5d/pop-to-ebp - 7932 c3/return - 7933 - 7934 size-of-type-id: # t: type-id -> result/eax: int - 7935 # . prologue - 7936 55/push-ebp - 7937 89/<- %ebp 4/r32/esp - 7938 # . save registers - 7939 51/push-ecx - 7940 # var out/ecx: (handle typeinfo) - 7941 68/push 0/imm32 - 7942 68/push 0/imm32 - 7943 89/<- %ecx 4/r32/esp - 7944 # eax = t - 7945 8b/-> *(ebp+8) 0/r32/eax - 7946 # if t is a literal, return 0 - 7947 3d/compare-eax-and 0/imm32 - 7948 74/jump-if-= $size-of-type-id:end/disp8 # eax changes type from type-id to int - 7949 # if t is a handle, return 8 - 7950 3d/compare-eax-and 4/imm32/handle - 7951 { - 7952 75/jump-if-!= break/disp8 - 7953 b8/copy-to-eax 8/imm32 - 7954 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int - 7955 } - 7956 # if t is a user-defined type, return its size - 7957 # TODO: support non-atom type - 7958 (find-typeinfo %eax %ecx) - 7959 { - 7960 81 7/subop/compare *ecx 0/imm32 - 7961 74/jump-if-= break/disp8 - 7962 $size-of-type-id:user-defined: - 7963 (lookup *ecx *(ecx+4)) # => eax - 7964 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes - 7965 eb/jump $size-of-type-id:end/disp8 - 7966 } - 7967 # otherwise return the word size - 7968 b8/copy-to-eax 4/imm32 - 7969 $size-of-type-id:end: - 7970 # . reclaim locals - 7971 81 0/subop/add %esp 8/imm32 - 7972 # . restore registers - 7973 59/pop-to-ecx - 7974 # . epilogue - 7975 89/<- %esp 5/r32/ebp - 7976 5d/pop-to-ebp - 7977 c3/return - 7978 - 7979 type-equal?: # a: (addr tree type-id), b: (addr tree type-id) -> result/eax: boolean - 7980 # . prologue - 7981 55/push-ebp - 7982 89/<- %ebp 4/r32/esp - 7983 # . save registers - 7984 51/push-ecx - 7985 52/push-edx - 7986 # ecx = a - 7987 8b/-> *(ebp+8) 1/r32/ecx - 7988 # edx = b - 7989 8b/-> *(ebp+0xc) 2/r32/edx - 7990 # if (a == b) return true - 7991 8b/-> %ecx 0/r32/eax # Var-type - 7992 39/compare %edx 0/r32/eax # Var-type - 7993 b8/copy-to-eax 1/imm32/true - 7994 74/jump-if-= $type-equal?:end/disp8 - 7995 # if (a < MAX_TYPE_ID) return false - 7996 81 7/subop/compare %ecx 0x10000/imm32 - 7997 b8/copy-to-eax 0/imm32/false - 7998 72/jump-if-addr< $type-equal?:end/disp8 - 7999 # if (b < MAX_TYPE_ID) return false - 8000 81 7/subop/compare %edx 0x10000/imm32 - 8001 b8/copy-to-eax 0/imm32/false - 8002 72/jump-if-addr< $type-equal?:end/disp8 - 8003 # if (!type-equal?(a->left, b->left)) return false - 8004 (type-equal? *(ecx+4) *(edx+4)) # Tree-left, Tree-left => eax - 8005 3d/compare-eax-and 0/imm32/false - 8006 74/jump-if-= $type-equal?:end/disp8 - 8007 # return type-equal?(a->right, b->right) - 8008 (type-equal? *(ecx+8) *(edx+8)) # Tree-right, Tree-right => eax - 8009 $type-equal?:end: - 8010 # . restore registers - 8011 5a/pop-to-edx - 8012 59/pop-to-ecx - 8013 # . epilogue - 8014 89/<- %esp 5/r32/ebp - 8015 5d/pop-to-ebp - 8016 c3/return - 8017 - 8018 ####################################################### - 8019 # Code-generation - 8020 ####################################################### - 8021 - 8022 == data - 8023 - 8024 Curr-block-depth: # (addr int) - 8025 0/imm32 - 8026 Curr-local-stack-offset: # (addr int) - 8027 0/imm32 - 8028 - 8029 == code - 8030 - 8031 emit-subx: # out: (addr buffered-file) - 8032 # . prologue - 8033 55/push-ebp - 8034 89/<- %ebp 4/r32/esp - 8035 # . save registers - 8036 50/push-eax - 8037 # var curr/eax: (addr function) = *Program->functions - 8038 (lookup *_Program-functions *_Program-functions->payload) # => eax - 8039 { - 8040 # if (curr == null) break - 8041 3d/compare-eax-and 0/imm32 - 8042 0f 84/jump-if-= break/disp32 - 8043 (emit-subx-function *(ebp+8) %eax) - 8044 # curr = lookup(curr->next) - 8045 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax - 8046 e9/jump loop/disp32 - 8047 } - 8048 $emit-subx:end: - 8049 # . restore registers - 8050 58/pop-to-eax - 8051 # . epilogue - 8052 89/<- %esp 5/r32/ebp - 8053 5d/pop-to-ebp - 8054 c3/return - 8055 - 8056 emit-subx-function: # out: (addr buffered-file), f: (addr function) - 8057 # . prologue - 8058 55/push-ebp - 8059 89/<- %ebp 4/r32/esp - 8060 # some preprocessing - 8061 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) - 8062 # . save registers - 8063 50/push-eax - 8064 51/push-ecx - 8065 52/push-edx - 8066 57/push-edi - 8067 # edi = out - 8068 8b/-> *(ebp+8) 7/r32/edi - 8069 # ecx = f - 8070 8b/-> *(ebp+0xc) 1/r32/ecx - 8071 # var vars/edx: (stack (addr var) 256) - 8072 81 5/subop/subtract %esp 0x800/imm32 - 8073 68/push 0x800/imm32/size - 8074 68/push 0/imm32/top - 8075 89/<- %edx 4/r32/esp - 8076 # - 8077 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 8078 (write-buffered %edi %eax) - 8079 (write-buffered %edi ":\n") - 8080 # initialize some global state - 8081 c7 0/subop/copy *Curr-block-depth 1/imm32 - 8082 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 - 8083 # - 8084 (emit-subx-prologue %edi) - 8085 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax - 8086 (emit-subx-block %edi %eax %edx) - 8087 (emit-subx-epilogue %edi) - 8088 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have - 8089 # been cleaned up - 8090 $emit-subx-function:end: - 8091 # . reclaim locals - 8092 81 0/subop/add %esp 808/imm32 - 8093 # . restore registers - 8094 5f/pop-to-edi - 8095 5a/pop-to-edx - 8096 59/pop-to-ecx - 8097 58/pop-to-eax - 8098 # . epilogue - 8099 89/<- %esp 5/r32/ebp - 8100 5d/pop-to-ebp - 8101 c3/return - 8102 - 8103 populate-mu-type-offsets-in-inouts: # f: (addr function) - 8104 # . prologue - 8105 55/push-ebp - 8106 89/<- %ebp 4/r32/esp - 8107 # . save registers - 8108 50/push-eax - 8109 51/push-ecx - 8110 52/push-edx - 8111 53/push-ebx - 8112 57/push-edi - 8113 # var next-offset/edx: int = 8 - 8114 ba/copy-to-edx 8/imm32 - 8115 # var curr/ecx: (addr list var) = lookup(f->inouts) - 8116 8b/-> *(ebp+8) 1/r32/ecx - 8117 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 8118 89/<- %ecx 0/r32/eax - 8119 { - 8120 $populate-mu-type-offsets-in-inouts:loop: - 8121 81 7/subop/compare %ecx 0/imm32 - 8122 74/jump-if-= break/disp8 - 8123 # var v/ebx: (addr var) = lookup(curr->value) - 8124 (lookup *ecx *(ecx+4)) # List-value List-value => eax - 8125 89/<- %ebx 0/r32/eax - 8126 #? (lookup *ebx *(ebx+4)) - 8127 #? (write-buffered Stderr "setting offset of fn inout ") - 8128 #? (write-buffered Stderr %eax) - 8129 #? (write-buffered Stderr "@") - 8130 #? (print-int32-buffered Stderr %ebx) - 8131 #? (write-buffered Stderr " to ") - 8132 #? (print-int32-buffered Stderr %edx) - 8133 #? (write-buffered Stderr Newline) - 8134 #? (flush Stderr) - 8135 # v->offset = next-offset - 8136 89/<- *(ebx+0x14) 2/r32/edx # Var-offset - 8137 # next-offset += size-of(v) - 8138 (size-of %ebx) # => eax - 8139 01/add-to %edx 0/r32/eax - 8140 # curr = lookup(curr->next) - 8141 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax - 8142 89/<- %ecx 0/r32/eax - 8143 # - 8144 eb/jump loop/disp8 - 8145 } - 8146 $populate-mu-type-offsets-in-inouts:end: - 8147 # . restore registers - 8148 5f/pop-to-edi - 8149 5b/pop-to-ebx - 8150 5a/pop-to-edx - 8151 59/pop-to-ecx - 8152 58/pop-to-eax - 8153 # . epilogue - 8154 89/<- %esp 5/r32/ebp - 8155 5d/pop-to-ebp - 8156 c3/return - 8157 - 8158 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (addr list stmt), vars: (addr stack (handle var)) - 8159 # . prologue - 8160 55/push-ebp - 8161 89/<- %ebp 4/r32/esp - 8162 # . save registers - 8163 50/push-eax - 8164 51/push-ecx - 8165 52/push-edx - 8166 53/push-ebx - 8167 56/push-esi - 8168 # esi = stmts - 8169 8b/-> *(ebp+0xc) 6/r32/esi - 8170 # var var-seen?/edx: boolean <- copy false - 8171 ba/copy-to-edx 0/imm32/false - 8172 # - 8173 { - 8174 $emit-subx-stmt-list:loop: - 8175 81 7/subop/compare %esi 0/imm32 - 8176 0f 84/jump-if-= break/disp32 - 8177 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) - 8178 (lookup *esi *(esi+4)) # List-value List-value => eax - 8179 89/<- %ecx 0/r32/eax - 8180 { - 8181 $emit-subx-stmt-list:check-for-block: - 8182 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag - 8183 75/jump-if-!= break/disp8 - 8184 $emit-subx-stmt-list:block: - 8185 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10)) - 8186 } - 8187 { - 8188 $emit-subx-stmt-list:check-for-stmt: - 8189 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag - 8190 0f 85/jump-if-!= break/disp32 - 8191 $emit-subx-stmt-list:stmt1: - 8192 { - 8193 (is-mu-branch? %ecx) # => eax - 8194 3d/compare-eax-and 0/imm32/false - 8195 0f 84/jump-if-= break/disp32 - 8196 $emit-subx-stmt-list:branch-stmt: - 8197 # if !var-seen? break - 8198 81 7/subop/compare %edx 0/imm32/false - 8199 0f 84/jump-if-= break/disp32 - 8200 $emit-subx-stmt-list:branch-stmt-and-var-seen: - 8201 +-- 27 lines: # unconditional loops ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 8228 +-- 16 lines: # unconditional breaks --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 8244 +-- 38 lines: # simple conditional branches without a target --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 8282 +-- 19 lines: # conditional branches with an explicit target --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 8301 } - 8302 $emit-subx-stmt-list:1-to-1: - 8303 (emit-subx-stmt *(ebp+8) %ecx Primitives) - 8304 e9/jump $emit-subx-stmt-list:continue/disp32 - 8305 } - 8306 { - 8307 $emit-subx-stmt-list:check-for-var-def: - 8308 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag - 8309 75/jump-if-!= break/disp8 - 8310 $emit-subx-stmt-list:var-def: - 8311 (emit-subx-var-def *(ebp+8) %ecx) - 8312 (push *(ebp+0x10) *(ecx+4)) # Vardef-var - 8313 (push *(ebp+0x10) *(ecx+8)) # Vardef-var - 8314 # var-seen? = true - 8315 ba/copy-to-edx 1/imm32/true - 8316 eb/jump $emit-subx-stmt-list:continue/disp8 - 8317 } - 8318 { - 8319 $emit-subx-stmt-list:check-for-reg-var-def: - 8320 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag - 8321 0f 85/jump-if-!= break/disp32 - 8322 $emit-subx-stmt-list:reg-var-def: - 8323 # TODO: ensure that there's exactly one output - 8324 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10)) - 8325 # emit the instruction as usual - 8326 (emit-subx-stmt *(ebp+8) %ecx Primitives) - 8327 # var-seen? = true - 8328 ba/copy-to-edx 1/imm32/true - 8329 eb/jump $emit-subx-stmt-list:continue/disp8 - 8330 } - 8331 $emit-subx-stmt-list:continue: - 8332 # TODO: raise an error on unrecognized Stmt-tag - 8333 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax - 8334 89/<- %esi 0/r32/eax - 8335 e9/jump loop/disp32 - 8336 } - 8337 $emit-subx-stmt-list:emit-cleanup: - 8338 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) - 8339 $emit-subx-stmt-list:clean-up: - 8340 (clean-up-blocks *(ebp+0x10) *Curr-block-depth) - 8341 $emit-subx-stmt-list:end: - 8342 # . restore registers - 8343 5e/pop-to-esi - 8344 5b/pop-to-ebx - 8345 5a/pop-to-edx - 8346 59/pop-to-ecx - 8347 58/pop-to-eax - 8348 # . epilogue - 8349 89/<- %esp 5/r32/ebp - 8350 5d/pop-to-ebp - 8351 c3/return - 8352 - 8353 push-output-and-maybe-emit-spill: # out: (addr buffered-file), stmt: (addr reg-var-def), vars: (addr stack (handle var)) - 8354 # . prologue - 8355 55/push-ebp - 8356 89/<- %ebp 4/r32/esp - 8357 # . save registers - 8358 50/push-eax - 8359 51/push-ecx - 8360 # ecx = stmt - 8361 8b/-> *(ebp+0xc) 1/r32/ecx - 8362 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) - 8363 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax - 8364 # TODO: assert !sv->is-deref? - 8365 # var v/ecx: (addr var) = lookup(sv->value) - 8366 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 8367 89/<- %ecx 0/r32/eax - 8368 # v->block-depth = *Curr-block-depth - 8369 8b/-> *Curr-block-depth 0/r32/eax - 8370 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth - 8371 #? (write-buffered Stderr "var ") - 8372 #? (lookup *ecx *(ecx+4)) - 8373 #? (write-buffered Stderr %eax) - 8374 #? (write-buffered Stderr " at depth ") - 8375 #? (print-int32-buffered Stderr *(ecx+0x10)) - 8376 #? (write-buffered Stderr Newline) - 8377 #? (flush Stderr) - 8378 # ensure that v is in a register - 8379 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register - 8380 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 - 8381 # if !already-spilled-this-block?(reg, vars) emit code to spill reg - 8382 (already-spilled-this-block? %ecx *(ebp+0x10)) # => eax - 8383 3d/compare-eax-and 0/imm32/false - 8384 75/jump-if-!= $push-output-and-maybe-emit-spill:push/disp8 - 8385 # TODO: assert(size-of(output) == 4) - 8386 # *Curr-local-stack-offset -= 4 - 8387 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 - 8388 # emit spill - 8389 (emit-indent *(ebp+8) *Curr-block-depth) - 8390 (write-buffered *(ebp+8) "ff 6/subop/push %") - 8391 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 8392 (write-buffered *(ebp+8) %eax) - 8393 (write-buffered *(ebp+8) Newline) - 8394 $push-output-and-maybe-emit-spill:push: - 8395 8b/-> *(ebp+0xc) 1/r32/ecx - 8396 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax - 8397 # push(vars, sv->value) - 8398 (push *(ebp+0x10) *eax) # Stmt-var-value - 8399 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value - 8400 $push-output-and-maybe-emit-spill:end: - 8401 # . restore registers - 8402 59/pop-to-ecx - 8403 58/pop-to-eax - 8404 # . epilogue - 8405 89/<- %esp 5/r32/ebp - 8406 5d/pop-to-ebp - 8407 c3/return - 8408 - 8409 $push-output-and-maybe-emit-spill:abort: - 8410 # error("var '" var->name "' initialized from an instruction must live in a register\n") - 8411 (write-buffered Stderr "var '") - 8412 (write-buffered Stderr *eax) # Var-name - 8413 (write-buffered Stderr "' initialized from an instruction must live in a register\n") - 8414 (flush Stderr) - 8415 # . syscall(exit, 1) - 8416 bb/copy-to-ebx 1/imm32 - 8417 b8/copy-to-eax 1/imm32/exit - 8418 cd/syscall 0x80/imm8 - 8419 # never gets here - 8420 - 8421 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack (handle var)) - 8422 # . prologue - 8423 55/push-ebp - 8424 89/<- %ebp 4/r32/esp - 8425 # . save registers - 8426 50/push-eax - 8427 51/push-ecx - 8428 # ecx = stmt - 8429 8b/-> *(ebp+0xc) 1/r32/ecx - 8430 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name - 8431 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 8432 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 8433 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 8434 # clean up until target block - 8435 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) - 8436 # emit jump to target block - 8437 (emit-indent *(ebp+8) *Curr-block-depth) - 8438 (write-buffered *(ebp+8) "e9/jump ") - 8439 (write-buffered *(ebp+8) %eax) - 8440 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax - 8441 (string-starts-with? %eax "break") - 8442 3d/compare-eax-and 0/imm32/false - 8443 { - 8444 74/jump-if-= break/disp8 - 8445 (write-buffered *(ebp+8) ":break/disp32\n") - 8446 } - 8447 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags - 8448 { - 8449 75/jump-if-!= break/disp8 - 8450 (write-buffered *(ebp+8) ":loop/disp32\n") - 8451 } - 8452 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: - 8453 # . restore registers - 8454 59/pop-to-ecx - 8455 58/pop-to-eax - 8456 # . epilogue - 8457 89/<- %esp 5/r32/ebp - 8458 5d/pop-to-ebp - 8459 c3/return - 8460 - 8461 is-mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean - 8462 # . prologue - 8463 55/push-ebp - 8464 89/<- %ebp 4/r32/esp - 8465 # . save registers - 8466 51/push-ecx - 8467 # ecx = lookup(stmt->operation) - 8468 8b/-> *(ebp+8) 1/r32/ecx - 8469 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax - 8470 89/<- %ecx 0/r32/eax - 8471 # if (stmt->operation starts with "loop") return true - 8472 (string-starts-with? %ecx "loop") # => eax - 8473 3d/compare-eax-and 0/imm32/false - 8474 75/jump-if-not-equal $is-mu-branch?:end/disp8 - 8475 # otherwise return (stmt->operation starts with "break") - 8476 (string-starts-with? %ecx "break") # => eax - 8477 $is-mu-branch?:end: - 8478 # . restore registers - 8479 59/pop-to-ecx - 8480 # . epilogue - 8481 89/<- %esp 5/r32/ebp - 8482 5d/pop-to-ebp - 8483 c3/return - 8484 - 8485 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) - 8486 # . prologue - 8487 55/push-ebp - 8488 89/<- %ebp 4/r32/esp - 8489 # . save registers - 8490 50/push-eax - 8491 # eax = stmt - 8492 8b/-> *(ebp+0xc) 0/r32/eax - 8493 # - 8494 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax - 8495 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) - 8496 (emit-indent *(ebp+8) *Curr-block-depth) - 8497 (lookup *eax *(eax+4)) # => eax - 8498 (write-buffered *(ebp+8) %eax) - 8499 (write-buffered *(ebp+8) " break/disp32\n") - 8500 $emit-reverse-break:end: - 8501 # . restore registers - 8502 58/pop-to-eax - 8503 # . epilogue - 8504 89/<- %esp 5/r32/ebp - 8505 5d/pop-to-ebp - 8506 c3/return - 8507 - 8508 == data - 8509 - 8510 # Table from Mu branch instructions to the reverse SubX opcodes for them. - 8511 Reverse-branch: # (table (handle array byte) (handle array byte)) - 8512 # a table is a stream - 8513 0x140/imm32/write - 8514 0/imm32/read - 8515 0x140/imm32/size - 8516 # data - 8517 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 - 8518 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 - 8519 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 - 8520 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 - 8521 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 - 8522 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 - 8523 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 - 8524 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 - 8525 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 - 8526 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 - 8527 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 - 8528 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 - 8529 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 - 8530 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 - 8531 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 - 8532 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 - 8533 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 - 8534 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 - 8535 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 - 8536 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 - 8537 - 8538 == code - 8539 - 8540 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack (handle var)), depth: int, label-suffix: (addr array byte) - 8541 # . prologue - 8542 55/push-ebp - 8543 89/<- %ebp 4/r32/esp - 8544 # . save registers - 8545 50/push-eax - 8546 51/push-ecx - 8547 52/push-edx - 8548 53/push-ebx - 8549 56/push-esi - 8550 # ecx = vars - 8551 8b/-> *(ebp+0xc) 1/r32/ecx - 8552 # var eax: int = vars->top - 8553 8b/-> *ecx 0/r32/eax - 8554 # var curr/esi: (addr handle var) = &vars->data[vars->top - 8] - 8555 8d/copy-address *(ecx+eax) 6/r32/esi # vars + 8 + vars->top - 8 - 8556 # var min/ecx: (addr handle var) = vars->data - 8557 81 0/subop/add %ecx 8/imm32 - 8558 # edx = depth - 8559 8b/-> *(ebp+0x10) 2/r32/edx - 8560 { - 8561 $emit-unconditional-jump-to-depth:loop: - 8562 # if (curr < min) break - 8563 39/compare %esi 1/r32/ecx - 8564 0f 82/jump-if-addr< break/disp32 - 8565 # var v/ebx: (addr var) = lookup(*curr) - 8566 (lookup *esi *(esi+4)) # => eax - 8567 89/<- %ebx 0/r32/eax - 8568 # if (v->block-depth < until-block-depth) break - 8569 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth - 8570 0f 8c/jump-if-< break/disp32 - 8571 { - 8572 $emit-unconditional-jump-to-depth:check: - 8573 # if v->block-depth != until-block-depth, continue - 8574 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth - 8575 0f 85/jump-if-!= break/disp32 - 8576 $emit-unconditional-jump-to-depth:depth-found: - 8577 # if v is not a literal, continue - 8578 (size-of %ebx) # => eax - 8579 3d/compare-eax-and 0/imm32 - 8580 0f 85/jump-if-!= break/disp32 - 8581 $emit-unconditional-jump-to-depth:label-found: - 8582 # emit unconditional jump, then return - 8583 (emit-indent *(ebp+8) *Curr-block-depth) - 8584 (write-buffered *(ebp+8) "e9/jump ") - 8585 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 8586 (write-buffered *(ebp+8) %eax) - 8587 (write-buffered *(ebp+8) ":") - 8588 (write-buffered *(ebp+8) *(ebp+0x14)) - 8589 (write-buffered *(ebp+8) "/disp32\n") - 8590 eb/jump $emit-unconditional-jump-to-depth:end/disp8 - 8591 } - 8592 # curr -= 8 - 8593 81 5/subop/subtract %esi 8/imm32 - 8594 e9/jump loop/disp32 - 8595 } - 8596 # TODO: error if no label at 'depth' was found - 8597 $emit-unconditional-jump-to-depth:end: - 8598 # . restore registers - 8599 5e/pop-to-esi - 8600 5b/pop-to-ebx - 8601 5a/pop-to-edx - 8602 59/pop-to-ecx - 8603 58/pop-to-eax - 8604 # . epilogue - 8605 89/<- %esp 5/r32/ebp - 8606 5d/pop-to-ebp - 8607 c3/return - 8608 - 8609 # emit clean-up code for 'vars' until some block depth - 8610 # doesn't actually modify 'vars' so we need traverse manually inside the stack - 8611 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack (handle var)), until-block-depth: int - 8612 # . prologue - 8613 55/push-ebp - 8614 89/<- %ebp 4/r32/esp - 8615 # . save registers - 8616 50/push-eax - 8617 51/push-ecx - 8618 52/push-edx - 8619 53/push-ebx - 8620 56/push-esi - 8621 #? (write-buffered Stderr "--- cleanup\n") - 8622 #? (flush Stderr) - 8623 # ecx = vars - 8624 8b/-> *(ebp+0xc) 1/r32/ecx - 8625 # var esi: int = vars->top - 8626 8b/-> *ecx 6/r32/esi - 8627 # var curr/esi: (addr handle var) = &vars->data[vars->top - 8] - 8628 8d/copy-address *(ecx+esi) 6/r32/esi # vars + 8 + vars->top - 8 - 8629 # var min/ecx: (addr handle var) = vars->data - 8630 81 0/subop/add %ecx 8/imm32 - 8631 # edx = until-block-depth - 8632 8b/-> *(ebp+0x10) 2/r32/edx - 8633 { - 8634 $emit-cleanup-code-until-depth:loop: - 8635 # if (curr < min) break - 8636 39/compare %esi 1/r32/ecx - 8637 0f 82/jump-if-addr< break/disp32 - 8638 # var v/ebx: (addr var) = lookup(*curr) - 8639 (lookup *esi *(esi+4)) # => eax - 8640 89/<- %ebx 0/r32/eax - 8641 #? (lookup *ebx *(ebx+4)) # Var-name - 8642 #? (write-buffered Stderr "var ") - 8643 #? (write-buffered Stderr %eax) - 8644 #? (write-buffered Stderr Newline) - 8645 #? (flush Stderr) - 8646 # if (v->block-depth < until-block-depth) break - 8647 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth - 8648 0f 8c/jump-if-< break/disp32 - 8649 # if v is in a register - 8650 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register - 8651 { - 8652 0f 84/jump-if-= break/disp32 - 8653 { - 8654 $emit-cleanup-code-until-depth:check-for-previous-spill: - 8655 (same-register-spilled-before? %ebx *(ebp+0xc) %esi) # => eax - 8656 3d/compare-eax-and 0/imm32/false - 8657 0f 85/jump-if-!= break/disp32 - 8658 $emit-cleanup-code-until-depth:reclaim-var-in-register: - 8659 (emit-indent *(ebp+8) *Curr-block-depth) - 8660 (write-buffered *(ebp+8) "8f 0/subop/pop %") - 8661 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 8662 (write-buffered *(ebp+8) %eax) - 8663 (write-buffered *(ebp+8) Newline) - 8664 } - 8665 eb/jump $emit-cleanup-code-until-depth:continue/disp8 - 8666 } - 8667 # otherwise v is on the stack - 8668 { - 8669 75/jump-if-!= break/disp8 - 8670 $emit-cleanup-code-until-depth:var-on-stack: - 8671 (size-of %ebx) # => eax - 8672 # don't emit code for labels - 8673 3d/compare-eax-and 0/imm32 - 8674 74/jump-if-= break/disp8 - 8675 $emit-cleanup-code-until-depth:reclaim-var-on-stack: - 8676 (emit-indent *(ebp+8) *Curr-block-depth) - 8677 (write-buffered *(ebp+8) "81 0/subop/add %esp ") - 8678 (print-int32-buffered *(ebp+8) %eax) - 8679 (write-buffered *(ebp+8) "/imm32\n") - 8680 } - 8681 $emit-cleanup-code-until-depth:continue: - 8682 # curr -= 8 - 8683 81 5/subop/subtract %esi 8/imm32 - 8684 e9/jump loop/disp32 - 8685 } - 8686 $emit-cleanup-code-until-depth:end: - 8687 # . restore registers - 8688 5e/pop-to-esi - 8689 5b/pop-to-ebx - 8690 5a/pop-to-edx - 8691 59/pop-to-ecx - 8692 58/pop-to-eax - 8693 # . epilogue - 8694 89/<- %esp 5/r32/ebp - 8695 5d/pop-to-ebp - 8696 c3/return - 8697 - 8698 # emit clean-up code for 'vars' until a given label is encountered - 8699 # doesn't actually modify 'vars' so we need traverse manually inside the stack - 8700 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack (handle var)), until-block-label: (addr array byte) - 8701 # . prologue - 8702 55/push-ebp - 8703 89/<- %ebp 4/r32/esp - 8704 # . save registers - 8705 50/push-eax - 8706 51/push-ecx - 8707 52/push-edx - 8708 53/push-ebx - 8709 # ecx = vars - 8710 8b/-> *(ebp+0xc) 1/r32/ecx - 8711 # var eax: int = vars->top - 8712 8b/-> *ecx 0/r32/eax - 8713 # var curr/edx: (addr handle var) = &vars->data[vars->top - 8] - 8714 8d/copy-address *(ecx+eax) 2/r32/edx # vars + 8 + vars->top - 8 - 8715 # var min/ecx: (addr handle var) = vars->data - 8716 81 0/subop/add %ecx 8/imm32 - 8717 { - 8718 $emit-cleanup-code-until-target:loop: - 8719 # if (curr < min) break - 8720 39/compare %edx 1/r32/ecx - 8721 0f 82/jump-if-addr< break/disp32 - 8722 # var v/ebx: (handle var) = lookup(*curr) - 8723 (lookup *edx *(edx+4)) # => eax - 8724 89/<- %ebx 0/r32/eax - 8725 # if (v->name == until-block-label) break - 8726 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 8727 (string-equal? %eax *(ebp+0x10)) # => eax - 8728 3d/compare-eax-and 0/imm32/false - 8729 0f 85/jump-if-!= break/disp32 - 8730 # if v is in a register - 8731 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register - 8732 { - 8733 0f 84/jump-if-= break/disp32 - 8734 { - 8735 $emit-cleanup-code-until-target:check-for-previous-spill: - 8736 (same-register-spilled-before? %ebx *(ebp+0xc) %edx) # => eax - 8737 3d/compare-eax-and 0/imm32/false - 8738 75/jump-if-!= break/disp8 - 8739 $emit-cleanup-code-until-target:reclaim-var-in-register: - 8740 (emit-indent *(ebp+8) *Curr-block-depth) - 8741 (write-buffered *(ebp+8) "8f 0/subop/pop %") - 8742 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 8743 (write-buffered *(ebp+8) %eax) - 8744 (write-buffered *(ebp+8) Newline) - 8745 } - 8746 eb/jump $emit-cleanup-code-until-target:continue/disp8 - 8747 } - 8748 # otherwise v is on the stack - 8749 { - 8750 75/jump-if-!= break/disp8 - 8751 $emit-cleanup-code-until-target:reclaim-var-on-stack: - 8752 (size-of %ebx) # => eax - 8753 # don't emit code for labels - 8754 3d/compare-eax-and 0/imm32 - 8755 74/jump-if-= break/disp8 - 8756 # - 8757 (emit-indent *(ebp+8) *Curr-block-depth) - 8758 (write-buffered *(ebp+8) "81 0/subop/add %esp ") - 8759 (print-int32-buffered *(ebp+8) %eax) - 8760 (write-buffered *(ebp+8) "/imm32\n") - 8761 } - 8762 $emit-cleanup-code-until-target:continue: - 8763 # curr -= 8 - 8764 81 5/subop/subtract %edx 8/imm32 - 8765 e9/jump loop/disp32 - 8766 } - 8767 $emit-cleanup-code-until-target:end: - 8768 # . restore registers - 8769 5b/pop-to-ebx - 8770 5a/pop-to-edx - 8771 59/pop-to-ecx - 8772 58/pop-to-eax - 8773 # . epilogue - 8774 89/<- %esp 5/r32/ebp - 8775 5d/pop-to-ebp - 8776 c3/return - 8777 - 8778 # is there already a var with the same block-depth and register as 'v' on the 'vars' stack? - 8779 # v is guaranteed not to be within vars - 8780 already-spilled-this-block?: # v: (addr var), vars: (addr stack (handle var)) -> result/eax: boolean - 8781 # . prologue - 8782 55/push-ebp - 8783 89/<- %ebp 4/r32/esp - 8784 # . save registers - 8785 51/push-ecx - 8786 52/push-edx - 8787 53/push-ebx - 8788 56/push-esi - 8789 57/push-edi - 8790 # ecx = vars - 8791 8b/-> *(ebp+0xc) 1/r32/ecx - 8792 # var eax: int = vars->top - 8793 8b/-> *ecx 0/r32/eax - 8794 # var min/ecx: (addr handle var) = vars->data - 8795 81 0/subop/add %ecx 8/imm32 - 8796 # var curr/edx: (addr handle var) = &vars->data[vars->top - 8] - 8797 81 5/subop/subtract %eax 8/imm32 - 8798 8d/copy-address *(ecx+eax) 2/r32/edx - 8799 # var depth/ebx: int = v->block-depth - 8800 8b/-> *(ebp+8) 3/r32/ebx - 8801 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth - 8802 # var needle/esi: (addr array byte) = v->register - 8803 8b/-> *(ebp+8) 6/r32/esi - 8804 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax - 8805 89/<- %esi 0/r32/eax - 8806 { - 8807 $already-spilled-this-block?:loop: - 8808 # if (curr < min) break - 8809 39/compare %edx 1/r32/ecx - 8810 0f 82/jump-if-addr< break/disp32 - 8811 # var cand/edi: (addr var) = lookup(*curr) - 8812 (lookup *edx *(edx+4)) # => eax - 8813 89/<- %edi 0/r32/eax - 8814 # if (cand->block-depth < depth) break - 8815 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth - 8816 0f 8c/jump-if-< break/disp32 - 8817 # var cand-reg/edi: (array array byte) = cand->reg - 8818 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax - 8819 89/<- %edi 0/r32/eax - 8820 # if (cand-reg == null) continue - 8821 { - 8822 $already-spilled-this-block?:check-reg: - 8823 81 7/subop/compare %edi 0/imm32 - 8824 0f 84/jump-if-= break/disp32 - 8825 # if (cand-reg == needle) return true - 8826 (string-equal? %esi %edi) # => eax - 8827 3d/compare-eax-and 0/imm32/false - 8828 74/jump-if-= break/disp8 - 8829 $already-spilled-this-block?:return-true: - 8830 b8/copy-to-eax 1/imm32/true - 8831 eb/jump $already-spilled-this-block?:end/disp8 - 8832 } - 8833 $already-spilled-this-block?:continue: - 8834 # curr -= 8 - 8835 81 5/subop/subtract %edx 8/imm32 - 8836 e9/jump loop/disp32 - 8837 } - 8838 # return false - 8839 b8/copy-to-eax 0/imm32/false - 8840 $already-spilled-this-block?:end: - 8841 # . restore registers - 8842 5f/pop-to-edi - 8843 5e/pop-to-esi - 8844 5b/pop-to-ebx - 8845 5a/pop-to-edx - 8846 59/pop-to-ecx - 8847 # . epilogue - 8848 89/<- %esp 5/r32/ebp - 8849 5d/pop-to-ebp - 8850 c3/return - 8851 - 8852 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? - 8853 # v is guaranteed to be within vars - 8854 # 'start' is provided as an optimization, a pointer within vars - 8855 # *start == v - 8856 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean - 8857 # . prologue - 8858 55/push-ebp - 8859 89/<- %ebp 4/r32/esp - 8860 # . save registers - 8861 51/push-ecx - 8862 52/push-edx - 8863 53/push-ebx - 8864 56/push-esi - 8865 57/push-edi - 8866 # ecx = v - 8867 8b/-> *(ebp+8) 1/r32/ecx - 8868 # var reg/edx: (addr array byte) = lookup(v->register) - 8869 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 8870 89/<- %edx 0/r32/eax - 8871 # var depth/ebx: int = v->block-depth - 8872 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth - 8873 # var min/ecx: (addr handle var) = vars->data - 8874 8b/-> *(ebp+0xc) 1/r32/ecx - 8875 81 0/subop/add %ecx 8/imm32 - 8876 # TODO: check that start >= min and start < &vars->data[top] - 8877 # TODO: check that *start == v - 8878 # var curr/esi: (addr handle var) = start - 8879 8b/-> *(ebp+0x10) 6/r32/esi - 8880 # curr -= 8 - 8881 81 5/subop/subtract %esi 8/imm32 - 8882 { - 8883 $same-register-spilled-before?:loop: - 8884 # if (curr < min) break - 8885 39/compare %esi 1/r32/ecx - 8886 0f 82/jump-if-addr< break/disp32 - 8887 # var x/eax: (addr var) = lookup(*curr) - 8888 (lookup *esi *(esi+4)) # => eax - 8889 # if (x->block-depth < depth) break - 8890 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth - 8891 0f 8c/jump-if-< break/disp32 - 8892 # if (x->register == 0) continue - 8893 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 8894 74/jump-if-= $same-register-spilled-before?:continue/disp8 - 8895 # if (x->register == reg) return true - 8896 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 8897 (string-equal? %eax %edx) # => eax - 8898 3d/compare-eax-and 0/imm32/false - 8899 b8/copy-to-eax 1/imm32/true - 8900 75/jump-if-!= $same-register-spilled-before?:end/disp8 - 8901 $same-register-spilled-before?:continue: - 8902 # curr -= 8 - 8903 81 5/subop/subtract %esi 8/imm32 - 8904 e9/jump loop/disp32 - 8905 } - 8906 $same-register-spilled-before?:false: - 8907 b8/copy-to-eax 0/imm32/false - 8908 $same-register-spilled-before?:end: - 8909 # . restore registers - 8910 5f/pop-to-edi - 8911 5e/pop-to-esi - 8912 5b/pop-to-ebx - 8913 5a/pop-to-edx - 8914 59/pop-to-ecx - 8915 # . epilogue - 8916 89/<- %esp 5/r32/ebp - 8917 5d/pop-to-ebp - 8918 c3/return - 8919 - 8920 # clean up global state for 'vars' until some block depth - 8921 clean-up-blocks: # vars: (addr stack (handle var)), until-block-depth: int - 8922 # . prologue - 8923 55/push-ebp - 8924 89/<- %ebp 4/r32/esp - 8925 # . save registers - 8926 50/push-eax - 8927 51/push-ecx - 8928 56/push-esi - 8929 # esi = vars - 8930 8b/-> *(ebp+8) 6/r32/esi - 8931 # ecx = until-block-depth - 8932 8b/-> *(ebp+0xc) 1/r32/ecx - 8933 { - 8934 $clean-up-blocks:reclaim-loop: - 8935 # if (vars->top <= 0) break - 8936 8b/-> *esi 0/r32/eax # Stack-top - 8937 3d/compare-eax-and 0/imm32 - 8938 7e/jump-if-<= break/disp8 - 8939 # var v/eax: (addr var) = lookup(vars[vars->top-8]) - 8940 (lookup *(esi+eax) *(esi+eax+4)) # vars + 8 + vars->top - 8 => eax - 8941 # if (v->block-depth < until-block-depth) break - 8942 39/compare *(eax+0x10) 1/r32/ecx # Var-block-depth - 8943 7c/jump-if-< break/disp8 - 8944 # if v is on the stack, update Curr-local-stack-offset - 8945 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 8946 { - 8947 75/jump-if-!= break/disp8 - 8948 $clean-up-blocks:reclaim-var-on-stack: - 8949 (size-of %eax) # => eax - 8950 01/add-to *Curr-local-stack-offset 0/r32/eax - 8951 } - 8952 (pop %esi) # => eax - 8953 (pop %esi) # => eax - 8954 e9/jump loop/disp32 - 8955 } - 8956 $clean-up-blocks:end: - 8957 # . restore registers - 8958 5e/pop-to-esi - 8959 59/pop-to-ecx - 8960 58/pop-to-eax - 8961 # . epilogue - 8962 89/<- %esp 5/r32/ebp - 8963 5d/pop-to-ebp - 8964 c3/return - 8965 - 8966 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt) - 8967 # . prologue - 8968 55/push-ebp - 8969 89/<- %ebp 4/r32/esp - 8970 # . save registers - 8971 50/push-eax - 8972 51/push-ecx - 8973 52/push-edx - 8974 # eax = stmt - 8975 8b/-> *(ebp+0xc) 0/r32/eax - 8976 # var v/ecx: (addr var) - 8977 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax - 8978 89/<- %ecx 0/r32/eax - 8979 # v->block-depth = *Curr-block-depth - 8980 8b/-> *Curr-block-depth 0/r32/eax - 8981 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth - 8982 # var n/edx: int = size-of(stmt->var) - 8983 (size-of %ecx) # => eax - 8984 89/<- %edx 0/r32/eax - 8985 # *Curr-local-stack-offset -= n - 8986 29/subtract-from *Curr-local-stack-offset 2/r32/edx - 8987 # v->offset = *Curr-local-stack-offset - 8988 8b/-> *Curr-local-stack-offset 0/r32/eax - 8989 89/<- *(ecx+0x14) 0/r32/eax # Var-offset - 8990 # if v is an array, do something special - 8991 { - 8992 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 8993 (is-mu-array? %eax) # => eax - 8994 3d/compare-eax-and 0/imm32/false - 8995 0f 84/jump-if-= break/disp32 - 8996 # var array-size-without-size/edx: int = n-4 - 8997 81 5/subop/subtract %edx 4/imm32 - 8998 (emit-indent *(ebp+8) *Curr-block-depth) - 8999 (write-buffered *(ebp+8) "(push-n-zero-bytes ") - 9000 (print-int32-buffered *(ebp+8) %edx) - 9001 (write-buffered *(ebp+8) ")\n") - 9002 (emit-indent *(ebp+8) *Curr-block-depth) - 9003 (write-buffered *(ebp+8) "68/push ") - 9004 (print-int32-buffered *(ebp+8) %edx) - 9005 (write-buffered *(ebp+8) "/imm32\n") - 9006 eb/jump $emit-subx-var-def:end/disp8 - 9007 } - 9008 # while n > 0 - 9009 { - 9010 81 7/subop/compare %edx 0/imm32 - 9011 7e/jump-if-<= break/disp8 - 9012 (emit-indent *(ebp+8) *Curr-block-depth) - 9013 (write-buffered *(ebp+8) "68/push 0/imm32\n") - 9014 # n -= 4 - 9015 81 5/subop/subtract %edx 4/imm32 - 9016 # - 9017 eb/jump loop/disp8 - 9018 } - 9019 $emit-subx-var-def:end: - 9020 # . restore registers - 9021 5a/pop-to-edx - 9022 59/pop-to-ecx - 9023 58/pop-to-eax - 9024 # . epilogue - 9025 89/<- %esp 5/r32/ebp - 9026 5d/pop-to-ebp - 9027 c3/return - 9028 - 9029 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive) - 9030 # . prologue - 9031 55/push-ebp - 9032 89/<- %ebp 4/r32/esp - 9033 # . save registers - 9034 50/push-eax - 9035 51/push-ecx - 9036 # - some special-case primitives that don't actually use the 'primitives' data structure - 9037 # var op/ecx: (addr array byte) = lookup(stmt->operation) - 9038 8b/-> *(ebp+0xc) 1/r32/ecx - 9039 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax - 9040 89/<- %ecx 0/r32/eax - 9041 # array size - 9042 { - 9043 # if (!string-equal?(stmt->operation, "length")) break - 9044 (string-equal? %ecx "length") # => eax - 9045 3d/compare-eax-and 0/imm32 - 9046 0f 84/jump-if-= break/disp32 - 9047 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc)) - 9048 e9/jump $emit-subx-stmt:end/disp32 - 9049 } - 9050 # index into array - 9051 { - 9052 # if (!string-equal?(stmt->operation, "index")) break - 9053 (string-equal? %ecx "index") # => eax - 9054 3d/compare-eax-and 0/imm32 - 9055 0f 84/jump-if-= break/disp32 - 9056 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc)) - 9057 e9/jump $emit-subx-stmt:end/disp32 - 9058 } - 9059 # compute-offset for index into array - 9060 { - 9061 # if (!string-equal?(stmt->operation, "compute-offset")) break - 9062 (string-equal? %ecx "compute-offset") # => eax - 9063 3d/compare-eax-and 0/imm32 - 9064 0f 84/jump-if-= break/disp32 - 9065 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc)) - 9066 e9/jump $emit-subx-stmt:end/disp32 - 9067 } - 9068 # get field from record - 9069 { - 9070 # if (!string-equal?(stmt->operation, "get")) break - 9071 (string-equal? %ecx "get") # => eax - 9072 3d/compare-eax-and 0/imm32 - 9073 0f 84/jump-if-= break/disp32 - 9074 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) - 9075 e9/jump $emit-subx-stmt:end/disp32 - 9076 } - 9077 # - if stmt matches a primitive, emit it - 9078 { - 9079 $emit-subx-stmt:check-for-primitive: - 9080 # var curr/eax: (addr primitive) - 9081 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax - 9082 3d/compare-eax-and 0/imm32 - 9083 74/jump-if-= break/disp8 - 9084 $emit-subx-stmt:primitive: - 9085 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr - 9086 e9/jump $emit-subx-stmt:end/disp32 - 9087 } - 9088 # - otherwise emit a call - 9089 # TODO: type-checking - 9090 $emit-subx-stmt:call: - 9091 (emit-call *(ebp+8) *(ebp+0xc)) - 9092 $emit-subx-stmt:end: - 9093 # . restore registers - 9094 59/pop-to-ecx - 9095 58/pop-to-eax - 9096 # . epilogue - 9097 89/<- %esp 5/r32/ebp - 9098 5d/pop-to-ebp - 9099 c3/return - 9100 - 9101 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt) - 9102 # . prologue - 9103 55/push-ebp - 9104 89/<- %ebp 4/r32/esp - 9105 # . save registers - 9106 50/push-eax - 9107 51/push-ecx - 9108 52/push-edx - 9109 53/push-ebx - 9110 56/push-esi - 9111 # esi = stmt - 9112 8b/-> *(ebp+0xc) 6/r32/esi - 9113 # var base/ebx: (addr var) = stmt->inouts[0]->value - 9114 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9115 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9116 89/<- %ebx 0/r32/eax - 9117 # var elemsize/ecx: int = element-size(base) - 9118 (array-element-type-id %ebx) # => eax - 9119 (size-of-type-id %eax) # => eax - 9120 89/<- %ecx 0/r32/eax - 9121 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register - 9122 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 9123 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9124 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 9125 89/<- %edx 0/r32/eax - 9126 # if elemsize == 1 - 9127 { - 9128 81 7/subop/compare %ecx 1/imm32 - 9129 75/jump-if-!= break/disp8 - 9130 (emit-save-size-to *(ebp+8) %ebx %edx) - 9131 e9/jump $translate-mu-length-stmt:end/disp32 - 9132 } - 9133 # if elemsize is a power of 2 less than 256 - 9134 { - 9135 (power-of-2? %ecx) # => eax - 9136 3d/compare-eax-and 0/imm32/false - 9137 74/jump-if-= break/disp8 - 9138 81 7/subop/compare %ecx 0xff/imm32 - 9139 7f/jump-if-> break/disp8 - 9140 (emit-save-size-to *(ebp+8) %ebx %edx) - 9141 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) - 9142 e9/jump $translate-mu-length-stmt:end/disp32 - 9143 } - 9144 # otherwise, the complex case - 9145 # . emit register spills - 9146 { - 9147 (string-equal? %edx "eax") # => eax - 9148 3d/compare-eax-and 0/imm32/false - 9149 75/break-if-!= break/disp8 - 9150 (emit-indent *(ebp+8) *Curr-block-depth) - 9151 (write-buffered *(ebp+8) "50/push-eax\n") - 9152 } - 9153 { - 9154 (string-equal? %edx "ecx") # => eax - 9155 3d/compare-eax-and 0/imm32/false - 9156 75/break-if-!= break/disp8 - 9157 (emit-indent *(ebp+8) *Curr-block-depth) - 9158 (write-buffered *(ebp+8) "51/push-ecx\n") - 9159 } - 9160 { - 9161 (string-equal? %edx "edx") # => eax - 9162 3d/compare-eax-and 0/imm32/false - 9163 75/break-if-!= break/disp8 - 9164 (emit-indent *(ebp+8) *Curr-block-depth) - 9165 (write-buffered *(ebp+8) "52/push-edx\n") - 9166 } - 9167 # . - 9168 (emit-save-size-to *(ebp+8) %ebx "eax") - 9169 (emit-indent *(ebp+8) *Curr-block-depth) - 9170 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") - 9171 (emit-indent *(ebp+8) *Curr-block-depth) - 9172 (write-buffered *(ebp+8) "b9/copy-to-ecx ") - 9173 (print-int32-buffered *(ebp+8) %ecx) - 9174 (write-buffered *(ebp+8) "/imm32\n") - 9175 (emit-indent *(ebp+8) *Curr-block-depth) - 9176 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") - 9177 { - 9178 (string-equal? %edx "eax") # => eax - 9179 3d/compare-eax-and 0/imm32/false - 9180 75/break-if-!= break/disp8 - 9181 (emit-indent *(ebp+8) *Curr-block-depth) - 9182 (write-buffered *(ebp+8) "89/<- %") - 9183 (write-buffered *(ebp+8) %edx) - 9184 (write-buffered *(ebp+8) " 0/r32/eax\n") - 9185 } - 9186 # . emit register restores - 9187 { - 9188 (string-equal? %edx "edx") # => eax - 9189 3d/compare-eax-and 0/imm32/false - 9190 75/break-if-!= break/disp8 - 9191 (emit-indent *(ebp+8) *Curr-block-depth) - 9192 (write-buffered *(ebp+8) "5a/pop-to-edx\n") - 9193 } - 9194 { - 9195 (string-equal? %edx "ecx") # => eax - 9196 3d/compare-eax-and 0/imm32/false - 9197 75/break-if-!= break/disp8 - 9198 (emit-indent *(ebp+8) *Curr-block-depth) - 9199 (write-buffered *(ebp+8) "59/pop-to-ecx\n") - 9200 } - 9201 { - 9202 (string-equal? %edx "eax") # => eax - 9203 3d/compare-eax-and 0/imm32/false - 9204 75/break-if-!= break/disp8 - 9205 (emit-indent *(ebp+8) *Curr-block-depth) - 9206 (write-buffered *(ebp+8) "58/pop-to-eax\n") - 9207 } - 9208 $translate-mu-length-stmt:end: - 9209 # . restore registers - 9210 5e/pop-to-esi - 9211 5b/pop-to-ebx - 9212 5a/pop-to-edx - 9213 59/pop-to-ecx - 9214 58/pop-to-eax - 9215 # . epilogue - 9216 89/<- %esp 5/r32/ebp - 9217 5d/pop-to-ebp - 9218 c3/return - 9219 - 9220 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) - 9221 # . prologue - 9222 55/push-ebp - 9223 89/<- %ebp 4/r32/esp - 9224 # . save registers - 9225 50/push-eax - 9226 53/push-ebx - 9227 # ebx = base - 9228 8b/-> *(ebp+0xc) 3/r32/ebx - 9229 (emit-indent *(ebp+8) *Curr-block-depth) - 9230 (write-buffered *(ebp+8) "8b/-> *") - 9231 # if base is an (addr array ...) in a register - 9232 { - 9233 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register - 9234 74/jump-if-= break/disp8 - 9235 $emit-save-size-to:emit-base-from-register: - 9236 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 9237 (write-buffered *(ebp+8) %eax) - 9238 eb/jump $emit-save-size-to:emit-output/disp8 - 9239 } - 9240 # otherwise if base is an (array ...) on the stack - 9241 { - 9242 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset - 9243 74/jump-if-= break/disp8 - 9244 $emit-save-size-to:emit-base-from-stack: - 9245 (write-buffered *(ebp+8) "(ebp+") - 9246 (print-int32-buffered *(ebp+8) *(ebx+0x14)) # Var-offset - 9247 (write-buffered *(ebp+8) ")") - 9248 } - 9249 $emit-save-size-to:emit-output: - 9250 (write-buffered *(ebp+8) " ") - 9251 (get Registers *(ebp+0x10) 0xc "Registers") # => eax - 9252 (print-int32-buffered *(ebp+8) *eax) - 9253 (write-buffered *(ebp+8) "/r32\n") - 9254 $emit-save-size-to:end: - 9255 # . restore registers - 9256 5b/pop-to-ebx - 9257 58/pop-to-eax - 9258 # . epilogue - 9259 89/<- %esp 5/r32/ebp - 9260 5d/pop-to-ebp - 9261 c3/return - 9262 - 9263 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int - 9264 # . prologue - 9265 55/push-ebp - 9266 89/<- %ebp 4/r32/esp - 9267 # . save registers - 9268 50/push-eax - 9269 # - 9270 (emit-indent *(ebp+8) *Curr-block-depth) - 9271 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") - 9272 (write-buffered *(ebp+8) *(ebp+0xc)) - 9273 (write-buffered *(ebp+8) Space) - 9274 (num-shift-rights *(ebp+0x10)) # => eax - 9275 (print-int32-buffered *(ebp+8) %eax) - 9276 (write-buffered *(ebp+8) "/imm8\n") - 9277 $emit-divide-by-shift-right:end: - 9278 # . restore registers - 9279 58/pop-to-eax - 9280 # . epilogue - 9281 89/<- %esp 5/r32/ebp - 9282 5d/pop-to-ebp - 9283 c3/return - 9284 - 9285 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt) - 9286 # . prologue - 9287 55/push-ebp - 9288 89/<- %ebp 4/r32/esp - 9289 # . save registers - 9290 51/push-ecx - 9291 # ecx = stmt - 9292 8b/-> *(ebp+0xc) 1/r32/ecx - 9293 # var base/ecx: (addr var) = stmt->inouts[0] - 9294 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9295 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9296 89/<- %ecx 0/r32/eax - 9297 # if (var->register) do one thing - 9298 { - 9299 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register - 9300 74/jump-if-= break/disp8 - 9301 # TODO: ensure there's no dereference - 9302 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc)) - 9303 eb/jump $translate-mu-index-stmt:end/disp8 - 9304 } - 9305 # if (var->offset) do a different thing - 9306 { - 9307 81 7/subop/compare *(ecx+0x14) 0/imm32 # Var-offset - 9308 74/jump-if-= break/disp8 - 9309 # TODO: ensure there's no dereference - 9310 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc)) - 9311 eb/jump $translate-mu-index-stmt:end/disp8 - 9312 } - 9313 $translate-mu-index-stmt:end: - 9314 # . restore registers - 9315 59/pop-to-ecx - 9316 # . epilogue - 9317 89/<- %esp 5/r32/ebp - 9318 5d/pop-to-ebp - 9319 c3/return - 9320 - 9321 $translate-mu-index-stmt-with-array:error1: - 9322 (write-buffered Stderr "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") - 9323 (flush Stderr) - 9324 # . syscall(exit, 1) - 9325 bb/copy-to-ebx 1/imm32 - 9326 b8/copy-to-eax 1/imm32/exit - 9327 cd/syscall 0x80/imm8 - 9328 # never gets here - 9329 - 9330 $translate-mu-index-stmt-with-array:error2: - 9331 (write-buffered Stderr "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") - 9332 (flush Stderr) - 9333 # . syscall(exit, 1) - 9334 bb/copy-to-ebx 1/imm32 - 9335 b8/copy-to-eax 1/imm32/exit - 9336 cd/syscall 0x80/imm8 - 9337 # never gets here - 9338 - 9339 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt) - 9340 # . prologue - 9341 55/push-ebp - 9342 89/<- %ebp 4/r32/esp - 9343 # . save registers - 9344 50/push-eax - 9345 51/push-ecx - 9346 52/push-edx - 9347 53/push-ebx - 9348 # - 9349 (emit-indent *(ebp+8) *Curr-block-depth) - 9350 (write-buffered *(ebp+8) "8d/copy-address *(") - 9351 # TODO: ensure inouts[0] is in a register and not dereferenced - 9352 $translate-mu-index-stmt-with-array-in-register:emit-base: - 9353 # ecx = stmt - 9354 8b/-> *(ebp+0xc) 1/r32/ecx - 9355 # var base/ebx: (addr var) = inouts[0] - 9356 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9357 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9358 89/<- %ebx 0/r32/eax - 9359 # print base->register " + " - 9360 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 9361 (write-buffered *(ebp+8) %eax) - 9362 (write-buffered *(ebp+8) " + ") - 9363 # var index/edx: (addr var) = inouts[1] - 9364 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9365 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax - 9366 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9367 89/<- %edx 0/r32/eax - 9368 # if index->register - 9369 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register - 9370 { - 9371 0f 84/jump-if-= break/disp32 - 9372 $translate-mu-index-stmt-with-array-in-register:emit-register-index: - 9373 # if index is an int - 9374 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 9375 (is-simple-mu-type? %eax 1) # int => eax - 9376 3d/compare-eax-and 0/imm32/false - 9377 { - 9378 0f 84/jump-if-= break/disp32 - 9379 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: - 9380 # print index->register "<<" log2(size-of(element(base->type))) " + 4) " - 9381 # . index->register "<<" - 9382 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 9383 (write-buffered *(ebp+8) %eax) - 9384 (write-buffered *(ebp+8) "<<") - 9385 # . log2(size-of(element(base->type))) - 9386 # TODO: ensure size is a power of 2 - 9387 (array-element-type-id %ebx) # => eax - 9388 (size-of-type-id %eax) # => eax - 9389 (num-shift-rights %eax) # => eax - 9390 (print-int32-buffered *(ebp+8) %eax) - 9391 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 + 7878 52/push-edx + 7879 53/push-ebx + 7880 56/push-esi + 7881 57/push-edi + 7882 # esi = in + 7883 8b/-> *(ebp+8) 6/r32/esi + 7884 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) + 7885 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax + 7886 89/<- %ecx 0/r32/eax + 7887 (write-buffered Stderr "id:") + 7888 (print-int32-buffered Stderr *esi) + 7889 (write-buffered Stderr "\n") + 7890 (write-buffered Stderr "fields @ ") + 7891 (print-int32-buffered Stderr %ecx) + 7892 (write-buffered Stderr Newline) + 7893 (flush Stderr) + 7894 (write-buffered Stderr " write: ") + 7895 (print-int32-buffered Stderr *ecx) + 7896 (write-buffered Stderr Newline) + 7897 (flush Stderr) + 7898 (write-buffered Stderr " read: ") + 7899 (print-int32-buffered Stderr *(ecx+4)) + 7900 (write-buffered Stderr Newline) + 7901 (flush Stderr) + 7902 (write-buffered Stderr " size: ") + 7903 (print-int32-buffered Stderr *(ecx+8)) + 7904 (write-buffered Stderr Newline) + 7905 (flush Stderr) + 7906 # var table-size/edx: int = table->write + 7907 8b/-> *ecx 2/r32/edx # stream-write + 7908 # var curr/ecx: (addr table_row) = table->data + 7909 8d/copy-address *(ecx+0xc) 1/r32/ecx + 7910 # var max/edx: (addr table_row) = table->data + table->write + 7911 8d/copy-address *(ecx+edx) 2/r32/edx + 7912 { + 7913 $dump-typeinfo:loop: + 7914 # if (curr >= max) break + 7915 39/compare %ecx 2/r32/edx + 7916 0f 83/jump-if-addr>= break/disp32 + 7917 (write-buffered Stderr " row:\n") + 7918 (write-buffered Stderr " key: ") + 7919 (print-int32-buffered Stderr *ecx) + 7920 (write-buffered Stderr ",") + 7921 (print-int32-buffered Stderr *(ecx+4)) + 7922 (write-buffered Stderr " = '") + 7923 (lookup *ecx *(ecx+4)) + 7924 (write-buffered Stderr %eax) + 7925 (write-buffered Stderr "' @ ") + 7926 (print-int32-buffered Stderr %eax) + 7927 (write-buffered Stderr Newline) + 7928 (flush Stderr) + 7929 (write-buffered Stderr " value: ") + 7930 (print-int32-buffered Stderr *(ecx+8)) + 7931 (write-buffered Stderr ",") + 7932 (print-int32-buffered Stderr *(ecx+0xc)) + 7933 (write-buffered Stderr " = typeinfo-entry@") + 7934 (lookup *(ecx+8) *(ecx+0xc)) + 7935 (print-int32-buffered Stderr %eax) + 7936 (write-buffered Stderr Newline) + 7937 (flush Stderr) + 7938 (write-buffered Stderr " input var@") + 7939 (print-int32-buffered Stderr *eax) + 7940 (write-buffered Stderr ",") + 7941 (print-int32-buffered Stderr *(eax+4)) + 7942 (write-buffered Stderr "->") + 7943 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var + 7944 (print-int32-buffered Stderr %eax) + 7945 { + 7946 3d/compare-eax-and 0/imm32 + 7947 74/jump-if-= break/disp8 + 7948 (write-buffered Stderr " ") + 7949 # TODO + 7950 } + 7951 (write-buffered Stderr Newline) + 7952 (flush Stderr) + 7953 (lookup *(ecx+8) *(ecx+0xc)) + 7954 (write-buffered Stderr " index: ") + 7955 (print-int32-buffered Stderr *(eax+8)) + 7956 (write-buffered Stderr Newline) + 7957 (flush Stderr) + 7958 (write-buffered Stderr " output var@") + 7959 (print-int32-buffered Stderr *(eax+0xc)) + 7960 (write-buffered Stderr ",") + 7961 (print-int32-buffered Stderr *(eax+0x10)) + 7962 (write-buffered Stderr "->") + 7963 (lookup *(eax+0xc) *(eax+0x10)) # Typeinfo-entry-output-var + 7964 (print-int32-buffered Stderr %eax) + 7965 (write-buffered Stderr Newline) + 7966 (flush Stderr) + 7967 { + 7968 3d/compare-eax-and 0/imm32 + 7969 0f 84/jump-if-= break/disp32 + 7970 (write-buffered Stderr " name: ") + 7971 89/<- %ebx 0/r32/eax + 7972 (print-int32-buffered Stderr *ebx) # Var-name + 7973 (write-buffered Stderr ",") + 7974 (print-int32-buffered Stderr *(ebx+4)) # Var-name + 7975 (write-buffered Stderr "->") + 7976 (lookup *ebx *(ebx+4)) # Var-name + 7977 (print-int32-buffered Stderr %eax) + 7978 { + 7979 3d/compare-eax-and 0/imm32 + 7980 74/jump-if-= break/disp8 + 7981 (write-buffered Stderr Space) + 7982 (write-buffered Stderr %eax) + 7983 } + 7984 (write-buffered Stderr Newline) + 7985 (flush Stderr) + 7986 (write-buffered Stderr " block depth: ") + 7987 (print-int32-buffered Stderr *(ebx+0x10)) # Var-block-depth + 7988 (write-buffered Stderr Newline) + 7989 (flush Stderr) + 7990 (write-buffered Stderr " stack offset: ") + 7991 (print-int32-buffered Stderr *(ebx+0x14)) # Var-offset + 7992 (write-buffered Stderr Newline) + 7993 (flush Stderr) + 7994 (write-buffered Stderr " reg: ") + 7995 (print-int32-buffered Stderr *(ebx+0x18)) # Var-register + 7996 (write-buffered Stderr ",") + 7997 (print-int32-buffered Stderr *(ebx+0x1c)) # Var-register + 7998 (write-buffered Stderr "->") + 7999 (flush Stderr) + 8000 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register + 8001 (print-int32-buffered Stderr %eax) + 8002 { + 8003 3d/compare-eax-and 0/imm32 + 8004 74/jump-if-= break/disp8 + 8005 (write-buffered Stderr Space) + 8006 (write-buffered Stderr %eax) + 8007 } + 8008 (write-buffered Stderr Newline) + 8009 (flush Stderr) + 8010 } + 8011 (flush Stderr) + 8012 # curr += row-size + 8013 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size + 8014 # + 8015 e9/jump loop/disp32 + 8016 } + 8017 $dump-typeinfo:end: + 8018 # . restore registers + 8019 5f/pop-to-edi + 8020 5e/pop-to-esi + 8021 5b/pop-to-ebx + 8022 5a/pop-to-edx + 8023 59/pop-to-ecx + 8024 58/pop-to-eax + 8025 # . epilogue + 8026 89/<- %esp 5/r32/ebp + 8027 5d/pop-to-ebp + 8028 c3/return + 8029 + 8030 ####################################################### + 8031 # Type-checking + 8032 ####################################################### + 8033 + 8034 check-mu-types: + 8035 # . prologue + 8036 55/push-ebp + 8037 89/<- %ebp 4/r32/esp + 8038 # + 8039 $check-mu-types:end: + 8040 # . epilogue + 8041 89/<- %esp 5/r32/ebp + 8042 5d/pop-to-ebp + 8043 c3/return + 8044 + 8045 size-of: # v: (addr var) -> result/eax: int + 8046 # . prologue + 8047 55/push-ebp + 8048 89/<- %ebp 4/r32/esp + 8049 # . save registers + 8050 51/push-ecx + 8051 # var t/ecx: (addr tree type-id) = lookup(v->type) + 8052 8b/-> *(ebp+8) 1/r32/ecx + 8053 #? (write-buffered Stderr "size-of ") + 8054 #? (print-int32-buffered Stderr %ecx) + 8055 #? (write-buffered Stderr Newline) + 8056 #? (write-buffered Stderr "type allocid: ") + 8057 #? (print-int32-buffered Stderr *(ecx+8)) + 8058 #? (write-buffered Stderr Newline) + 8059 #? (flush Stderr) + 8060 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 8061 89/<- %ecx 0/r32/eax + 8062 # if is-mu-array?(t) return size-of-array(t) + 8063 { + 8064 (is-mu-array? %ecx) # => eax + 8065 3d/compare-eax-and 0/imm32/false + 8066 74/jump-if-= break/disp8 + 8067 (size-of-array %ecx) # => eax + 8068 eb/jump $size-of:end/disp8 + 8069 } + 8070 # if (!t->is-atom?) t = lookup(t->left) + 8071 { + 8072 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom + 8073 75/jump-if-!= break/disp8 + 8074 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax + 8075 89/<- %ecx 0/r32/eax + 8076 } + 8077 # TODO: assert t->is-atom? + 8078 (size-of-type-id *(ecx+4)) # Tree-value => eax + 8079 $size-of:end: + 8080 # . restore registers + 8081 59/pop-to-ecx + 8082 # . epilogue + 8083 89/<- %esp 5/r32/ebp + 8084 5d/pop-to-ebp + 8085 c3/return + 8086 + 8087 size-of-deref: # v: (addr var) -> result/eax: int + 8088 # . prologue + 8089 55/push-ebp + 8090 89/<- %ebp 4/r32/esp + 8091 # . save registers + 8092 51/push-ecx + 8093 # var t/ecx: (addr tree type-id) = lookup(v->type) + 8094 8b/-> *(ebp+8) 1/r32/ecx + 8095 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 8096 89/<- %ecx 0/r32/eax + 8097 # TODO: assert(t is an addr) + 8098 # t = lookup(t->right) + 8099 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax + 8100 89/<- %ecx 0/r32/eax + 8101 # if is-mu-array?(t) return size-of-array(t) + 8102 { + 8103 (is-mu-array? %ecx) # => eax + 8104 3d/compare-eax-and 0/imm32/false + 8105 74/jump-if-= break/disp8 + 8106 (size-of-array %ecx) # => eax + 8107 eb/jump $size-of:end/disp8 + 8108 } + 8109 # if (!t->is-atom?) t = lookup(t->left) + 8110 { + 8111 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom + 8112 75/jump-if-!= break/disp8 + 8113 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax + 8114 89/<- %ecx 0/r32/eax + 8115 } + 8116 # TODO: assert t->is-atom? + 8117 (size-of-type-id *(ecx+4)) # Tree-value => eax + 8118 $size-of-deref:end: + 8119 # . restore registers + 8120 59/pop-to-ecx + 8121 # . epilogue + 8122 89/<- %esp 5/r32/ebp + 8123 5d/pop-to-ebp + 8124 c3/return + 8125 + 8126 is-mu-array?: # t: (addr tree type-id) -> result/eax: boolean + 8127 # . prologue + 8128 55/push-ebp + 8129 89/<- %ebp 4/r32/esp + 8130 # . save registers + 8131 51/push-ecx + 8132 # ecx = t + 8133 8b/-> *(ebp+8) 1/r32/ecx + 8134 # if t->is-atom?, return false + 8135 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom + 8136 75/jump-if-!= $is-mu-array?:return-false/disp8 + 8137 # if !t->left->is-atom?, return false + 8138 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax + 8139 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom + 8140 74/jump-if-= $is-mu-array?:return-false/disp8 + 8141 # return t->left->value == array + 8142 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Tree-value + 8143 0f 94/set-if-= %al + 8144 81 4/subop/and %eax 0xff/imm32 + 8145 eb/jump $is-mu-array?:end/disp8 + 8146 $is-mu-array?:return-false: + 8147 b8/copy-to-eax 0/imm32/false + 8148 $is-mu-array?:end: + 8149 # . restore registers + 8150 59/pop-to-ecx + 8151 # . epilogue + 8152 89/<- %esp 5/r32/ebp + 8153 5d/pop-to-ebp + 8154 c3/return + 8155 + 8156 size-of-array: # a: (addr tree type-id) -> result/eax: int + 8157 # . prologue + 8158 55/push-ebp + 8159 89/<- %ebp 4/r32/esp + 8160 # . save registers + 8161 51/push-ecx + 8162 52/push-edx + 8163 # + 8164 8b/-> *(ebp+8) 1/r32/ecx + 8165 # TODO: assert that a->left is 'array' + 8166 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax + 8167 89/<- %ecx 0/r32/eax + 8168 # var elem-type/edx: type-id = a->right->left->value + 8169 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax + 8170 8b/-> *(eax+4) 2/r32/edx # Tree-value + 8171 # var array-size/ecx: int = a->right->right->left->value + 8172 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax + 8173 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax + 8174 8b/-> *(eax+4) 1/r32/ecx # Tree-value + 8175 # return array-size * size-of(elem-type) + 8176 (size-of-type-id %edx) # => eax + 8177 f7 4/subop/multiply-into-eax %ecx + 8178 05/add-to-eax 4/imm32 # for array size + 8179 $size-of-array:end: + 8180 # . restore registers + 8181 5a/pop-to-edx + 8182 59/pop-to-ecx + 8183 # . epilogue + 8184 89/<- %esp 5/r32/ebp + 8185 5d/pop-to-ebp + 8186 c3/return + 8187 + 8188 size-of-type-id: # t: type-id -> result/eax: int + 8189 # . prologue + 8190 55/push-ebp + 8191 89/<- %ebp 4/r32/esp + 8192 # . save registers + 8193 51/push-ecx + 8194 # var out/ecx: (handle typeinfo) + 8195 68/push 0/imm32 + 8196 68/push 0/imm32 + 8197 89/<- %ecx 4/r32/esp + 8198 # eax = t + 8199 8b/-> *(ebp+8) 0/r32/eax + 8200 # if t is a literal, return 0 + 8201 3d/compare-eax-and 0/imm32 + 8202 74/jump-if-= $size-of-type-id:end/disp8 # eax changes type from type-id to int + 8203 # if t is a handle, return 8 + 8204 3d/compare-eax-and 4/imm32/handle + 8205 { + 8206 75/jump-if-!= break/disp8 + 8207 b8/copy-to-eax 8/imm32 + 8208 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int + 8209 } + 8210 # if t is a user-defined type, return its size + 8211 # TODO: support non-atom type + 8212 (find-typeinfo %eax %ecx) + 8213 { + 8214 81 7/subop/compare *ecx 0/imm32 + 8215 74/jump-if-= break/disp8 + 8216 $size-of-type-id:user-defined: + 8217 (lookup *ecx *(ecx+4)) # => eax + 8218 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes + 8219 eb/jump $size-of-type-id:end/disp8 + 8220 } + 8221 # otherwise return the word size + 8222 b8/copy-to-eax 4/imm32 + 8223 $size-of-type-id:end: + 8224 # . reclaim locals + 8225 81 0/subop/add %esp 8/imm32 + 8226 # . restore registers + 8227 59/pop-to-ecx + 8228 # . epilogue + 8229 89/<- %esp 5/r32/ebp + 8230 5d/pop-to-ebp + 8231 c3/return + 8232 + 8233 type-equal?: # a: (addr tree type-id), b: (addr tree type-id) -> result/eax: boolean + 8234 # . prologue + 8235 55/push-ebp + 8236 89/<- %ebp 4/r32/esp + 8237 # . save registers + 8238 51/push-ecx + 8239 52/push-edx + 8240 # ecx = a + 8241 8b/-> *(ebp+8) 1/r32/ecx + 8242 # edx = b + 8243 8b/-> *(ebp+0xc) 2/r32/edx + 8244 # if (a == b) return true + 8245 8b/-> %ecx 0/r32/eax # Var-type + 8246 39/compare %edx 0/r32/eax # Var-type + 8247 b8/copy-to-eax 1/imm32/true + 8248 74/jump-if-= $type-equal?:end/disp8 + 8249 # if (a < MAX_TYPE_ID) return false + 8250 81 7/subop/compare %ecx 0x10000/imm32 + 8251 b8/copy-to-eax 0/imm32/false + 8252 72/jump-if-addr< $type-equal?:end/disp8 + 8253 # if (b < MAX_TYPE_ID) return false + 8254 81 7/subop/compare %edx 0x10000/imm32 + 8255 b8/copy-to-eax 0/imm32/false + 8256 72/jump-if-addr< $type-equal?:end/disp8 + 8257 # if (!type-equal?(a->left, b->left)) return false + 8258 (type-equal? *(ecx+4) *(edx+4)) # Tree-left, Tree-left => eax + 8259 3d/compare-eax-and 0/imm32/false + 8260 74/jump-if-= $type-equal?:end/disp8 + 8261 # return type-equal?(a->right, b->right) + 8262 (type-equal? *(ecx+8) *(edx+8)) # Tree-right, Tree-right => eax + 8263 $type-equal?:end: + 8264 # . restore registers + 8265 5a/pop-to-edx + 8266 59/pop-to-ecx + 8267 # . epilogue + 8268 89/<- %esp 5/r32/ebp + 8269 5d/pop-to-ebp + 8270 c3/return + 8271 + 8272 ####################################################### + 8273 # Code-generation + 8274 ####################################################### + 8275 + 8276 == data + 8277 + 8278 Curr-block-depth: # (addr int) + 8279 0/imm32 + 8280 Curr-local-stack-offset: # (addr int) + 8281 0/imm32 + 8282 + 8283 == code + 8284 + 8285 emit-subx: # out: (addr buffered-file) + 8286 # . prologue + 8287 55/push-ebp + 8288 89/<- %ebp 4/r32/esp + 8289 # . save registers + 8290 50/push-eax + 8291 # var curr/eax: (addr function) = *Program->functions + 8292 (lookup *_Program-functions *_Program-functions->payload) # => eax + 8293 { + 8294 # if (curr == null) break + 8295 3d/compare-eax-and 0/imm32 + 8296 0f 84/jump-if-= break/disp32 + 8297 (emit-subx-function *(ebp+8) %eax) + 8298 # curr = lookup(curr->next) + 8299 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax + 8300 e9/jump loop/disp32 + 8301 } + 8302 $emit-subx:end: + 8303 # . restore registers + 8304 58/pop-to-eax + 8305 # . epilogue + 8306 89/<- %esp 5/r32/ebp + 8307 5d/pop-to-ebp + 8308 c3/return + 8309 + 8310 emit-subx-function: # out: (addr buffered-file), f: (addr function) + 8311 # . prologue + 8312 55/push-ebp + 8313 89/<- %ebp 4/r32/esp + 8314 # some preprocessing + 8315 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) + 8316 # . save registers + 8317 50/push-eax + 8318 51/push-ecx + 8319 52/push-edx + 8320 57/push-edi + 8321 # initialize some global state + 8322 c7 0/subop/copy *Curr-block-depth 1/imm32 + 8323 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 + 8324 # ecx = f + 8325 8b/-> *(ebp+0xc) 1/r32/ecx + 8326 # var vars/edx: (stack (addr var) 256) + 8327 81 5/subop/subtract %esp 0xc00/imm32 + 8328 68/push 0xc00/imm32/size + 8329 68/push 0/imm32/top + 8330 89/<- %edx 4/r32/esp + 8331 # var name/eax: (addr array byte) = lookup(f->name) + 8332 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 8333 # + 8334 (write-buffered *(ebp+8) %eax) + 8335 (write-buffered *(ebp+8) ":\n") + 8336 (emit-subx-prologue *(ebp+8)) + 8337 # var outputs/edi: (addr list var) = lookup(f->outputs) + 8338 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax + 8339 89/<- %edi 0/r32/eax + 8340 # var body/eax: (addr block) = lookup(f->body) + 8341 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax + 8342 # + 8343 (emit-subx-block *(ebp+8) %eax %edx %edi) + 8344 (emit-subx-epilogue *(ebp+8)) + 8345 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have + 8346 # been cleaned up + 8347 $emit-subx-function:end: + 8348 # . reclaim locals + 8349 81 0/subop/add %esp 0xc08/imm32 + 8350 # . restore registers + 8351 5f/pop-to-edi + 8352 5a/pop-to-edx + 8353 59/pop-to-ecx + 8354 58/pop-to-eax + 8355 # . epilogue + 8356 89/<- %esp 5/r32/ebp + 8357 5d/pop-to-ebp + 8358 c3/return + 8359 + 8360 populate-mu-type-offsets-in-inouts: # f: (addr function) + 8361 # . prologue + 8362 55/push-ebp + 8363 89/<- %ebp 4/r32/esp + 8364 # . save registers + 8365 50/push-eax + 8366 51/push-ecx + 8367 52/push-edx + 8368 53/push-ebx + 8369 57/push-edi + 8370 # var next-offset/edx: int = 8 + 8371 ba/copy-to-edx 8/imm32 + 8372 # var curr/ecx: (addr list var) = lookup(f->inouts) + 8373 8b/-> *(ebp+8) 1/r32/ecx + 8374 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 8375 89/<- %ecx 0/r32/eax + 8376 { + 8377 $populate-mu-type-offsets-in-inouts:loop: + 8378 81 7/subop/compare %ecx 0/imm32 + 8379 74/jump-if-= break/disp8 + 8380 # var v/ebx: (addr var) = lookup(curr->value) + 8381 (lookup *ecx *(ecx+4)) # List-value List-value => eax + 8382 89/<- %ebx 0/r32/eax + 8383 #? (lookup *ebx *(ebx+4)) + 8384 #? (write-buffered Stderr "setting offset of fn inout ") + 8385 #? (write-buffered Stderr %eax) + 8386 #? (write-buffered Stderr "@") + 8387 #? (print-int32-buffered Stderr %ebx) + 8388 #? (write-buffered Stderr " to ") + 8389 #? (print-int32-buffered Stderr %edx) + 8390 #? (write-buffered Stderr Newline) + 8391 #? (flush Stderr) + 8392 # v->offset = next-offset + 8393 89/<- *(ebx+0x14) 2/r32/edx # Var-offset + 8394 # next-offset += size-of(v) + 8395 (size-of %ebx) # => eax + 8396 01/add-to %edx 0/r32/eax + 8397 # curr = lookup(curr->next) + 8398 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax + 8399 89/<- %ecx 0/r32/eax + 8400 # + 8401 eb/jump loop/disp8 + 8402 } + 8403 $populate-mu-type-offsets-in-inouts:end: + 8404 # . restore registers + 8405 5f/pop-to-edi + 8406 5b/pop-to-ebx + 8407 5a/pop-to-edx + 8408 59/pop-to-ecx + 8409 58/pop-to-eax + 8410 # . epilogue + 8411 89/<- %esp 5/r32/ebp + 8412 5d/pop-to-ebp + 8413 c3/return + 8414 + 8415 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (addr list stmt), vars: (addr stack live-var), fn-outputs: (addr list var) + 8416 # . prologue + 8417 55/push-ebp + 8418 89/<- %ebp 4/r32/esp + 8419 # . save registers + 8420 50/push-eax + 8421 51/push-ecx + 8422 53/push-ebx + 8423 56/push-esi + 8424 # esi = stmts + 8425 8b/-> *(ebp+0xc) 6/r32/esi + 8426 # + 8427 { + 8428 $emit-subx-stmt-list:loop: + 8429 81 7/subop/compare %esi 0/imm32 + 8430 0f 84/jump-if-= break/disp32 + 8431 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) + 8432 (lookup *esi *(esi+4)) # List-value List-value => eax + 8433 89/<- %ecx 0/r32/eax + 8434 { + 8435 $emit-subx-stmt-list:check-for-block: + 8436 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag + 8437 75/jump-if-!= break/disp8 + 8438 $emit-subx-stmt-list:block: + 8439 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14)) + 8440 } + 8441 { + 8442 $emit-subx-stmt-list:check-for-stmt: + 8443 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag + 8444 0f 85/jump-if-!= break/disp32 + 8445 $emit-subx-stmt-list:stmt1: + 8446 { + 8447 (is-mu-branch? %ecx) # => eax + 8448 3d/compare-eax-and 0/imm32/false + 8449 0f 84/jump-if-= break/disp32 + 8450 $emit-subx-stmt-list:branch-stmt: + 8451 +-- 27 lines: # unconditional loops ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + 8478 +-- 16 lines: # unconditional breaks --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + 8494 +-- 38 lines: # simple conditional branches without a target --------------------------------------------------------------------------------------------------------------------------------------------------- + 8532 +-- 19 lines: # conditional branches with an explicit target --------------------------------------------------------------------------------------------------------------------------------------------------- + 8551 } + 8552 $emit-subx-stmt-list:1-to-1: + 8553 (emit-subx-stmt *(ebp+8) %ecx Primitives) + 8554 e9/jump $emit-subx-stmt-list:continue/disp32 + 8555 } + 8556 { + 8557 $emit-subx-stmt-list:check-for-var-def: + 8558 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag + 8559 75/jump-if-!= break/disp8 + 8560 $emit-subx-stmt-list:var-def: + 8561 (emit-subx-var-def *(ebp+8) %ecx) + 8562 (push *(ebp+0x10) *(ecx+4)) # Vardef-var + 8563 (push *(ebp+0x10) *(ecx+8)) # Vardef-var + 8564 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack + 8565 # + 8566 eb/jump $emit-subx-stmt-list:continue/disp8 + 8567 } + 8568 { + 8569 $emit-subx-stmt-list:check-for-reg-var-def: + 8570 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag + 8571 0f 85/jump-if-!= break/disp32 + 8572 $emit-subx-stmt-list:reg-var-def: + 8573 # TODO: ensure that there's exactly one output + 8574 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14)) + 8575 # emit the instruction as usual + 8576 (emit-subx-stmt *(ebp+8) %ecx Primitives) + 8577 # + 8578 eb/jump $emit-subx-stmt-list:continue/disp8 + 8579 } + 8580 $emit-subx-stmt-list:continue: + 8581 # TODO: raise an error on unrecognized Stmt-tag + 8582 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax + 8583 89/<- %esi 0/r32/eax + 8584 e9/jump loop/disp32 + 8585 } + 8586 $emit-subx-stmt-list:emit-cleanup: + 8587 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) + 8588 $emit-subx-stmt-list:clean-up: + 8589 (clean-up-blocks *(ebp+0x10) *Curr-block-depth) + 8590 $emit-subx-stmt-list:end: + 8591 # . restore registers + 8592 5e/pop-to-esi + 8593 5b/pop-to-ebx + 8594 59/pop-to-ecx + 8595 58/pop-to-eax + 8596 # . epilogue + 8597 89/<- %esp 5/r32/ebp + 8598 5d/pop-to-ebp + 8599 c3/return + 8600 + 8601 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. + 8602 push-output-and-maybe-emit-spill: # out: (addr buffered-file), stmt: (addr reg-var-def), vars: (addr stack (handle var)), later-stmts: (addr list stmt), fn-outputs: (addr list var) + 8603 # . prologue + 8604 55/push-ebp + 8605 89/<- %ebp 4/r32/esp + 8606 # . save registers + 8607 50/push-eax + 8608 51/push-ecx + 8609 52/push-edx + 8610 # ecx = stmt + 8611 8b/-> *(ebp+0xc) 1/r32/ecx + 8612 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) + 8613 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax + 8614 # TODO: assert !sv->is-deref? + 8615 # var v/ecx: (addr var) = lookup(sv->value) + 8616 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 8617 89/<- %ecx 0/r32/eax + 8618 # v->block-depth = *Curr-block-depth + 8619 8b/-> *Curr-block-depth 0/r32/eax + 8620 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth + 8621 #? (write-buffered Stderr "var ") + 8622 #? (lookup *ecx *(ecx+4)) + 8623 #? (write-buffered Stderr %eax) + 8624 #? (write-buffered Stderr " at depth ") + 8625 #? (print-int32-buffered Stderr *(ecx+0x10)) + 8626 #? (write-buffered Stderr Newline) + 8627 #? (flush Stderr) + 8628 # ensure that v is in a register + 8629 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register + 8630 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 + 8631 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn-outputs) + 8632 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax + 8633 89/<- %edx 0/r32/eax + 8634 3d/compare-eax-and 0/imm32/false + 8635 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 + 8636 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax + 8637 89/<- %edx 0/r32/eax + 8638 # check emit-spill? + 8639 3d/compare-eax-and 0/imm32/false + 8640 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 + 8641 # TODO: assert(size-of(output) == 4) + 8642 # *Curr-local-stack-offset -= 4 + 8643 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 + 8644 # emit spill + 8645 (emit-indent *(ebp+8) *Curr-block-depth) + 8646 (write-buffered *(ebp+8) "ff 6/subop/push %") + 8647 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 8648 (write-buffered *(ebp+8) %eax) + 8649 (write-buffered *(ebp+8) Newline) + 8650 $push-output-and-maybe-emit-spill:push: + 8651 8b/-> *(ebp+0xc) 1/r32/ecx + 8652 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax + 8653 # push(vars, {sv->value, emit-spill?}) + 8654 (push *(ebp+0x10) *eax) # Stmt-var-value + 8655 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value + 8656 (push *(ebp+0x10) %edx) + 8657 $push-output-and-maybe-emit-spill:end: + 8658 # . restore registers + 8659 5a/pop-to-edx + 8660 59/pop-to-ecx + 8661 58/pop-to-eax + 8662 # . epilogue + 8663 89/<- %esp 5/r32/ebp + 8664 5d/pop-to-ebp + 8665 c3/return + 8666 + 8667 $push-output-and-maybe-emit-spill:abort: + 8668 # error("var '" var->name "' initialized from an instruction must live in a register\n") + 8669 (write-buffered Stderr "var '") + 8670 (write-buffered Stderr *eax) # Var-name + 8671 (write-buffered Stderr "' initialized from an instruction must live in a register\n") + 8672 (flush Stderr) + 8673 # . syscall(exit, 1) + 8674 bb/copy-to-ebx 1/imm32 + 8675 b8/copy-to-eax 1/imm32/exit + 8676 cd/syscall 0x80/imm8 + 8677 # never gets here + 8678 + 8679 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) + 8680 # . prologue + 8681 55/push-ebp + 8682 89/<- %ebp 4/r32/esp + 8683 # . save registers + 8684 50/push-eax + 8685 51/push-ecx + 8686 # ecx = stmt + 8687 8b/-> *(ebp+0xc) 1/r32/ecx + 8688 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name + 8689 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 8690 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 8691 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8692 # clean up until target block + 8693 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) + 8694 # emit jump to target block + 8695 (emit-indent *(ebp+8) *Curr-block-depth) + 8696 (write-buffered *(ebp+8) "e9/jump ") + 8697 (write-buffered *(ebp+8) %eax) + 8698 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax + 8699 (string-starts-with? %eax "break") + 8700 3d/compare-eax-and 0/imm32/false + 8701 { + 8702 74/jump-if-= break/disp8 + 8703 (write-buffered *(ebp+8) ":break/disp32\n") + 8704 } + 8705 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags + 8706 { + 8707 75/jump-if-!= break/disp8 + 8708 (write-buffered *(ebp+8) ":loop/disp32\n") + 8709 } + 8710 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: + 8711 # . restore registers + 8712 59/pop-to-ecx + 8713 58/pop-to-eax + 8714 # . epilogue + 8715 89/<- %esp 5/r32/ebp + 8716 5d/pop-to-ebp + 8717 c3/return + 8718 + 8719 is-mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean + 8720 # . prologue + 8721 55/push-ebp + 8722 89/<- %ebp 4/r32/esp + 8723 # . save registers + 8724 51/push-ecx + 8725 # ecx = lookup(stmt->operation) + 8726 8b/-> *(ebp+8) 1/r32/ecx + 8727 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax + 8728 89/<- %ecx 0/r32/eax + 8729 # if (stmt->operation starts with "loop") return true + 8730 (string-starts-with? %ecx "loop") # => eax + 8731 3d/compare-eax-and 0/imm32/false + 8732 75/jump-if-not-equal $is-mu-branch?:end/disp8 + 8733 # otherwise return (stmt->operation starts with "break") + 8734 (string-starts-with? %ecx "break") # => eax + 8735 $is-mu-branch?:end: + 8736 # . restore registers + 8737 59/pop-to-ecx + 8738 # . epilogue + 8739 89/<- %esp 5/r32/ebp + 8740 5d/pop-to-ebp + 8741 c3/return + 8742 + 8743 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) + 8744 # . prologue + 8745 55/push-ebp + 8746 89/<- %ebp 4/r32/esp + 8747 # . save registers + 8748 50/push-eax + 8749 # eax = stmt + 8750 8b/-> *(ebp+0xc) 0/r32/eax + 8751 # + 8752 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax + 8753 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) + 8754 (emit-indent *(ebp+8) *Curr-block-depth) + 8755 (lookup *eax *(eax+4)) # => eax + 8756 (write-buffered *(ebp+8) %eax) + 8757 (write-buffered *(ebp+8) " break/disp32\n") + 8758 $emit-reverse-break:end: + 8759 # . restore registers + 8760 58/pop-to-eax + 8761 # . epilogue + 8762 89/<- %esp 5/r32/ebp + 8763 5d/pop-to-ebp + 8764 c3/return + 8765 + 8766 == data + 8767 + 8768 # Table from Mu branch instructions to the reverse SubX opcodes for them. + 8769 Reverse-branch: # (table (handle array byte) (handle array byte)) + 8770 # a table is a stream + 8771 0x140/imm32/write + 8772 0/imm32/read + 8773 0x140/imm32/size + 8774 # data + 8775 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 + 8776 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 + 8777 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 + 8778 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 + 8779 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 + 8780 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 + 8781 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 + 8782 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 + 8783 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 + 8784 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 + 8785 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 + 8786 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 + 8787 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 + 8788 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 + 8789 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 + 8790 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 + 8791 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 + 8792 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 + 8793 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 + 8794 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 + 8795 + 8796 == code + 8797 + 8798 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) + 8799 # . prologue + 8800 55/push-ebp + 8801 89/<- %ebp 4/r32/esp + 8802 # . save registers + 8803 50/push-eax + 8804 51/push-ecx + 8805 52/push-edx + 8806 53/push-ebx + 8807 56/push-esi + 8808 # ecx = vars + 8809 8b/-> *(ebp+0xc) 1/r32/ecx + 8810 # var eax: int = vars->top + 8811 8b/-> *ecx 0/r32/eax + 8812 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] + 8813 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size + 8814 # var min/ecx: (addr handle var) = vars->data + 8815 8d/copy-address *(ecx+8) 1/r32/ecx + 8816 # edx = depth + 8817 8b/-> *(ebp+0x10) 2/r32/edx + 8818 { + 8819 $emit-unconditional-jump-to-depth:loop: + 8820 # if (curr < min) break + 8821 39/compare %esi 1/r32/ecx + 8822 0f 82/jump-if-addr< break/disp32 + 8823 # var v/ebx: (addr var) = lookup(*curr) + 8824 (lookup *esi *(esi+4)) # => eax + 8825 89/<- %ebx 0/r32/eax + 8826 # if (v->block-depth < until-block-depth) break + 8827 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth + 8828 0f 8c/jump-if-< break/disp32 + 8829 { + 8830 $emit-unconditional-jump-to-depth:check: + 8831 # if v->block-depth != until-block-depth, continue + 8832 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth + 8833 0f 85/jump-if-!= break/disp32 + 8834 $emit-unconditional-jump-to-depth:depth-found: + 8835 # if v is not a literal, continue + 8836 (size-of %ebx) # => eax + 8837 3d/compare-eax-and 0/imm32 + 8838 0f 85/jump-if-!= break/disp32 + 8839 $emit-unconditional-jump-to-depth:label-found: + 8840 # emit unconditional jump, then return + 8841 (emit-indent *(ebp+8) *Curr-block-depth) + 8842 (write-buffered *(ebp+8) "e9/jump ") + 8843 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8844 (write-buffered *(ebp+8) %eax) + 8845 (write-buffered *(ebp+8) ":") + 8846 (write-buffered *(ebp+8) *(ebp+0x14)) + 8847 (write-buffered *(ebp+8) "/disp32\n") + 8848 eb/jump $emit-unconditional-jump-to-depth:end/disp8 + 8849 } + 8850 # curr -= 12 + 8851 81 5/subop/subtract %esi 0xc/imm32 + 8852 e9/jump loop/disp32 + 8853 } + 8854 # TODO: error if no label at 'depth' was found + 8855 $emit-unconditional-jump-to-depth:end: + 8856 # . restore registers + 8857 5e/pop-to-esi + 8858 5b/pop-to-ebx + 8859 5a/pop-to-edx + 8860 59/pop-to-ecx + 8861 58/pop-to-eax + 8862 # . epilogue + 8863 89/<- %esp 5/r32/ebp + 8864 5d/pop-to-ebp + 8865 c3/return + 8866 + 8867 # emit clean-up code for 'vars' until some block depth + 8868 # doesn't actually modify 'vars' so we need traverse manually inside the stack + 8869 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int + 8870 # . prologue + 8871 55/push-ebp + 8872 89/<- %ebp 4/r32/esp + 8873 # . save registers + 8874 50/push-eax + 8875 51/push-ecx + 8876 52/push-edx + 8877 53/push-ebx + 8878 56/push-esi + 8879 #? (write-buffered Stderr "--- cleanup\n") + 8880 #? (flush Stderr) + 8881 # ecx = vars + 8882 8b/-> *(ebp+0xc) 1/r32/ecx + 8883 # var esi: int = vars->top + 8884 8b/-> *ecx 6/r32/esi + 8885 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] + 8886 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size + 8887 # var min/ecx: (addr handle var) = vars->data + 8888 81 0/subop/add %ecx 8/imm32 + 8889 # edx = until-block-depth + 8890 8b/-> *(ebp+0x10) 2/r32/edx + 8891 { + 8892 $emit-cleanup-code-until-depth:loop: + 8893 # if (curr < min) break + 8894 39/compare %esi 1/r32/ecx + 8895 0f 82/jump-if-addr< break/disp32 + 8896 # var v/ebx: (addr var) = lookup(*curr) + 8897 (lookup *esi *(esi+4)) # => eax + 8898 89/<- %ebx 0/r32/eax + 8899 #? (lookup *ebx *(ebx+4)) # Var-name + 8900 #? (write-buffered Stderr "var ") + 8901 #? (write-buffered Stderr %eax) + 8902 #? (write-buffered Stderr Newline) + 8903 #? (flush Stderr) + 8904 # if (v->block-depth < until-block-depth) break + 8905 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth + 8906 0f 8c/jump-if-< break/disp32 + 8907 # if v is in a register + 8908 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register + 8909 { + 8910 0f 84/jump-if-= break/disp32 + 8911 { + 8912 $emit-cleanup-code-until-depth:check-for-previous-spill: + 8913 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled + 8914 3d/compare-eax-and 0/imm32/false + 8915 74/jump-if-= break/disp8 + 8916 $emit-cleanup-code-until-depth:reclaim-var-in-register: + 8917 (emit-indent *(ebp+8) *Curr-block-depth) + 8918 (write-buffered *(ebp+8) "8f 0/subop/pop %") + 8919 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 8920 (write-buffered *(ebp+8) %eax) + 8921 (write-buffered *(ebp+8) Newline) + 8922 } + 8923 eb/jump $emit-cleanup-code-until-depth:continue/disp8 + 8924 } + 8925 # otherwise v is on the stack + 8926 { + 8927 75/jump-if-!= break/disp8 + 8928 $emit-cleanup-code-until-depth:var-on-stack: + 8929 (size-of %ebx) # => eax + 8930 # don't emit code for labels + 8931 3d/compare-eax-and 0/imm32 + 8932 74/jump-if-= break/disp8 + 8933 $emit-cleanup-code-until-depth:reclaim-var-on-stack: + 8934 (emit-indent *(ebp+8) *Curr-block-depth) + 8935 (write-buffered *(ebp+8) "81 0/subop/add %esp ") + 8936 (print-int32-buffered *(ebp+8) %eax) + 8937 (write-buffered *(ebp+8) "/imm32\n") + 8938 } + 8939 $emit-cleanup-code-until-depth:continue: + 8940 # curr -= 12 + 8941 81 5/subop/subtract %esi 0xc/imm32 + 8942 e9/jump loop/disp32 + 8943 } + 8944 $emit-cleanup-code-until-depth:end: + 8945 # . restore registers + 8946 5e/pop-to-esi + 8947 5b/pop-to-ebx + 8948 5a/pop-to-edx + 8949 59/pop-to-ecx + 8950 58/pop-to-eax + 8951 # . epilogue + 8952 89/<- %esp 5/r32/ebp + 8953 5d/pop-to-ebp + 8954 c3/return + 8955 + 8956 # emit clean-up code for 'vars' until a given label is encountered + 8957 # doesn't actually modify 'vars' so we need traverse manually inside the stack + 8958 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) + 8959 # . prologue + 8960 55/push-ebp + 8961 89/<- %ebp 4/r32/esp + 8962 # . save registers + 8963 50/push-eax + 8964 51/push-ecx + 8965 52/push-edx + 8966 53/push-ebx + 8967 # ecx = vars + 8968 8b/-> *(ebp+0xc) 1/r32/ecx + 8969 # var eax: int = vars->top + 8970 8b/-> *ecx 0/r32/eax + 8971 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] + 8972 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size + 8973 # var min/ecx: (addr handle var) = vars->data + 8974 81 0/subop/add %ecx 8/imm32 + 8975 { + 8976 $emit-cleanup-code-until-target:loop: + 8977 # if (curr < min) break + 8978 39/compare %edx 1/r32/ecx + 8979 0f 82/jump-if-addr< break/disp32 + 8980 # var v/ebx: (handle var) = lookup(*curr) + 8981 (lookup *edx *(edx+4)) # => eax + 8982 89/<- %ebx 0/r32/eax + 8983 # if (v->name == until-block-label) break + 8984 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8985 (string-equal? %eax *(ebp+0x10)) # => eax + 8986 3d/compare-eax-and 0/imm32/false + 8987 0f 85/jump-if-!= break/disp32 + 8988 # if v is in a register + 8989 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register + 8990 { + 8991 0f 84/jump-if-= break/disp32 + 8992 { + 8993 $emit-cleanup-code-until-target:check-for-previous-spill: + 8994 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled + 8995 3d/compare-eax-and 0/imm32/false + 8996 74/jump-if-= break/disp8 + 8997 $emit-cleanup-code-until-target:reclaim-var-in-register: + 8998 (emit-indent *(ebp+8) *Curr-block-depth) + 8999 (write-buffered *(ebp+8) "8f 0/subop/pop %") + 9000 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 9001 (write-buffered *(ebp+8) %eax) + 9002 (write-buffered *(ebp+8) Newline) + 9003 } + 9004 eb/jump $emit-cleanup-code-until-target:continue/disp8 + 9005 } + 9006 # otherwise v is on the stack + 9007 { + 9008 75/jump-if-!= break/disp8 + 9009 $emit-cleanup-code-until-target:reclaim-var-on-stack: + 9010 (size-of %ebx) # => eax + 9011 # don't emit code for labels + 9012 3d/compare-eax-and 0/imm32 + 9013 74/jump-if-= break/disp8 + 9014 # + 9015 (emit-indent *(ebp+8) *Curr-block-depth) + 9016 (write-buffered *(ebp+8) "81 0/subop/add %esp ") + 9017 (print-int32-buffered *(ebp+8) %eax) + 9018 (write-buffered *(ebp+8) "/imm32\n") + 9019 } + 9020 $emit-cleanup-code-until-target:continue: + 9021 # curr -= 12 + 9022 81 5/subop/subtract %edx 0xc/imm32 + 9023 e9/jump loop/disp32 + 9024 } + 9025 $emit-cleanup-code-until-target:end: + 9026 # . restore registers + 9027 5b/pop-to-ebx + 9028 5a/pop-to-edx + 9029 59/pop-to-ecx + 9030 58/pop-to-eax + 9031 # . epilogue + 9032 89/<- %esp 5/r32/ebp + 9033 5d/pop-to-ebp + 9034 c3/return + 9035 + 9036 # Return true if there isn't a variable in 'vars' with the same block-depth + 9037 # and register as 'v'. + 9038 # 'v' is guaranteed not to be within 'vars'. + 9039 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean + 9040 # . prologue + 9041 55/push-ebp + 9042 89/<- %ebp 4/r32/esp + 9043 # . save registers + 9044 51/push-ecx + 9045 52/push-edx + 9046 53/push-ebx + 9047 56/push-esi + 9048 57/push-edi + 9049 # ecx = vars + 9050 8b/-> *(ebp+0xc) 1/r32/ecx + 9051 # var eax: int = vars->top + 9052 8b/-> *ecx 0/r32/eax + 9053 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] + 9054 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size + 9055 # var min/ecx: (addr handle var) = vars->data + 9056 8d/copy-address *(ecx+8) 1/r32/ecx + 9057 # var depth/ebx: int = v->block-depth + 9058 8b/-> *(ebp+8) 3/r32/ebx + 9059 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth + 9060 # var needle/esi: (addr array byte) = v->register + 9061 8b/-> *(ebp+8) 6/r32/esi + 9062 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax + 9063 89/<- %esi 0/r32/eax + 9064 { + 9065 $not-yet-spilled-this-block?:loop: + 9066 # if (curr < min) break + 9067 39/compare %edx 1/r32/ecx + 9068 0f 82/jump-if-addr< break/disp32 + 9069 # var cand/edi: (addr var) = lookup(*curr) + 9070 (lookup *edx *(edx+4)) # => eax + 9071 89/<- %edi 0/r32/eax + 9072 # if (cand->block-depth < depth) break + 9073 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth + 9074 0f 8c/jump-if-< break/disp32 + 9075 # var cand-reg/edi: (array array byte) = cand->reg + 9076 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax + 9077 89/<- %edi 0/r32/eax + 9078 # if (cand-reg == null) continue + 9079 { + 9080 $not-yet-spilled-this-block?:check-reg: + 9081 81 7/subop/compare %edi 0/imm32 + 9082 0f 84/jump-if-= break/disp32 + 9083 # if (cand-reg == needle) return true + 9084 (string-equal? %esi %edi) # => eax + 9085 3d/compare-eax-and 0/imm32/false + 9086 74/jump-if-= break/disp8 + 9087 $not-yet-spilled-this-block?:return-false: + 9088 b8/copy-to-eax 0/imm32/false + 9089 eb/jump $not-yet-spilled-this-block?:end/disp8 + 9090 } + 9091 $not-yet-spilled-this-block?:continue: + 9092 # curr -= 12 + 9093 81 5/subop/subtract %edx 0xc/imm32 + 9094 e9/jump loop/disp32 + 9095 } + 9096 $not-yet-spilled-this-block?:return-true: + 9097 # return true + 9098 b8/copy-to-eax 1/imm32/true + 9099 $not-yet-spilled-this-block?:end: + 9100 # . restore registers + 9101 5f/pop-to-edi + 9102 5e/pop-to-esi + 9103 5b/pop-to-ebx + 9104 5a/pop-to-edx + 9105 59/pop-to-ecx + 9106 # . epilogue + 9107 89/<- %esp 5/r32/ebp + 9108 5d/pop-to-ebp + 9109 c3/return + 9110 + 9111 # could the register of 'v' ever be written to by one of the vars in fn-outputs? + 9112 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn-outputs: (addr list var) -> result/eax: boolean + 9113 # . prologue + 9114 55/push-ebp + 9115 89/<- %ebp 4/r32/esp + 9116 # eax = v + 9117 8b/-> *(ebp+8) 0/r32/eax + 9118 # var reg/eax: (addr array byte) = lookup(v->register) + 9119 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax + 9120 # var target/eax: (addr var) = find-register(fn-outputs, reg) + 9121 (find-register *(ebp+0x10) %eax) # => eax + 9122 # if (target == 0) return true + 9123 { + 9124 3d/compare-eax-and 0/imm32 + 9125 75/jump-if-!= break/disp8 + 9126 b8/copy-to-eax 1/imm32/true + 9127 eb/jump $will-not-write-some-register?:end/disp8 + 9128 } + 9129 # return !assigns-in-stmts?(stmts, target) + 9130 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax + 9131 3d/compare-eax-and 0/imm32/false + 9132 # assume: true = 1, so no need to mask with 0x000000ff + 9133 0f 94/set-if-= %al + 9134 $will-not-write-some-register?:end: + 9135 # . epilogue + 9136 89/<- %esp 5/r32/ebp + 9137 5d/pop-to-ebp + 9138 c3/return + 9139 + 9140 # return output var with matching register + 9141 # always returns false if 'reg' is null + 9142 find-register: # fn-outputs: (addr list var), reg: (addr array byte) -> result/eax: (addr var) + 9143 # . prologue + 9144 55/push-ebp + 9145 89/<- %ebp 4/r32/esp + 9146 # . save registers + 9147 51/push-ecx + 9148 # var curr/ecx: (addr list var) = fn-outputs + 9149 8b/-> *(ebp+8) 1/r32/ecx + 9150 { + 9151 $find-register:loop: + 9152 # if (curr == 0) break + 9153 81 7/subop/compare %ecx 0/imm32 + 9154 74/jump-if-= break/disp8 + 9155 # eax = curr->value->register + 9156 (lookup *ecx *(ecx+4)) # List-value List-value => eax + 9157 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax + 9158 # if (eax == reg) return curr->value + 9159 $find-register:compare: + 9160 (string-equal? *(ebp+0xc) %eax) # => eax + 9161 { + 9162 3d/compare-eax-and 0/imm32/false + 9163 74/jump-if-= break/disp8 + 9164 $find-register:found: + 9165 (lookup *ecx *(ecx+4)) # List-value List-value => eax + 9166 eb/jump $find-register:end/disp8 + 9167 } + 9168 # curr = lookup(curr->next) + 9169 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax + 9170 89/<- %ecx 0/r32/eax + 9171 # + 9172 eb/jump loop/disp8 + 9173 } + 9174 $find-register:end: + 9175 # . restore registers + 9176 59/pop-to-ecx + 9177 # . epilogue + 9178 89/<- %esp 5/r32/ebp + 9179 5d/pop-to-ebp + 9180 c3/return + 9181 + 9182 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean + 9183 # . prologue + 9184 55/push-ebp + 9185 89/<- %ebp 4/r32/esp + 9186 # . save registers + 9187 51/push-ecx + 9188 # var curr/ecx: (addr list stmt) = stmts + 9189 8b/-> *(ebp+8) 1/r32/ecx + 9190 { + 9191 # if (curr == 0) break + 9192 81 7/subop/compare %ecx 0/imm32 + 9193 74/jump-if-= break/disp8 + 9194 # if assigns-in-stmt?(curr->value, v) return true + 9195 (lookup *ecx *(ecx+4)) # List-value List-value => eax + 9196 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax + 9197 3d/compare-eax-and 0/imm32/false + 9198 75/jump-if-!= break/disp8 + 9199 # curr = lookup(curr->next) + 9200 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax + 9201 89/<- %ecx 0/r32/eax + 9202 # + 9203 eb/jump loop/disp8 + 9204 } + 9205 $assigns-in-stmts?:end: + 9206 # . restore registers + 9207 59/pop-to-ecx + 9208 # . epilogue + 9209 89/<- %esp 5/r32/ebp + 9210 5d/pop-to-ebp + 9211 c3/return + 9212 + 9213 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean + 9214 # . prologue + 9215 55/push-ebp + 9216 89/<- %ebp 4/r32/esp + 9217 # . save registers + 9218 51/push-ecx + 9219 # ecx = stmt + 9220 8b/-> *(ebp+8) 1/r32/ecx + 9221 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) + 9222 { + 9223 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag + 9224 75/jump-if-!= break/disp8 + 9225 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax + 9226 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax + 9227 eb/jump $assigns-in-stmt?:end/disp8 + 9228 } + 9229 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) + 9230 { + 9231 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag + 9232 75/jump-if-!= break/disp8 + 9233 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax + 9234 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax + 9235 eb/jump $assigns-in-stmt?:end/disp8 + 9236 } + 9237 # otherwise return false + 9238 b8/copy 0/imm32/false + 9239 $assigns-in-stmt?:end: + 9240 # . restore registers + 9241 59/pop-to-ecx + 9242 # . epilogue + 9243 89/<- %esp 5/r32/ebp + 9244 5d/pop-to-ebp + 9245 c3/return + 9246 + 9247 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean + 9248 # . prologue + 9249 55/push-ebp + 9250 89/<- %ebp 4/r32/esp + 9251 # . save registers + 9252 51/push-ecx + 9253 # var curr/ecx: (addr stmt-var) = stmt-var + 9254 8b/-> *(ebp+8) 1/r32/ecx + 9255 { + 9256 # if (curr == 0) break + 9257 81 7/subop/compare %ecx 0/imm32 + 9258 74/jump-if-= break/disp8 + 9259 # eax = lookup(curr->value) + 9260 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax + 9261 # if (eax == v && curr->is-deref? == false) return true + 9262 { + 9263 39/compare *(ebp+0xc) 0/r32/eax + 9264 75/jump-if-!= break/disp8 + 9265 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref + 9266 75/jump-if-!= break/disp8 + 9267 b8/copy-to-eax 1/imm32/true + 9268 eb/jump $assigns-in-stmt-vars?:end/disp8 + 9269 } + 9270 # curr = lookup(curr->next) + 9271 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax + 9272 89/<- %ecx 0/r32/eax + 9273 # + 9274 eb/jump loop/disp8 + 9275 } + 9276 $assigns-in-stmt-vars?:end: + 9277 # . restore registers + 9278 59/pop-to-ecx + 9279 # . epilogue + 9280 89/<- %esp 5/r32/ebp + 9281 5d/pop-to-ebp + 9282 c3/return + 9283 + 9284 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? + 9285 # v is guaranteed to be within vars + 9286 # 'start' is provided as an optimization, a pointer within vars + 9287 # *start == v + 9288 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean + 9289 # . prologue + 9290 55/push-ebp + 9291 89/<- %ebp 4/r32/esp + 9292 # . save registers + 9293 51/push-ecx + 9294 52/push-edx + 9295 53/push-ebx + 9296 56/push-esi + 9297 57/push-edi + 9298 # ecx = v + 9299 8b/-> *(ebp+8) 1/r32/ecx + 9300 # var reg/edx: (addr array byte) = lookup(v->register) + 9301 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 9302 89/<- %edx 0/r32/eax + 9303 # var depth/ebx: int = v->block-depth + 9304 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth + 9305 # var min/ecx: (addr handle var) = vars->data + 9306 8b/-> *(ebp+0xc) 1/r32/ecx + 9307 81 0/subop/add %ecx 8/imm32 + 9308 # TODO: check that start >= min and start < &vars->data[top] + 9309 # TODO: check that *start == v + 9310 # var curr/esi: (addr handle var) = start + 9311 8b/-> *(ebp+0x10) 6/r32/esi + 9312 # curr -= 8 + 9313 81 5/subop/subtract %esi 8/imm32 + 9314 { + 9315 $same-register-spilled-before?:loop: + 9316 # if (curr < min) break + 9317 39/compare %esi 1/r32/ecx + 9318 0f 82/jump-if-addr< break/disp32 + 9319 # var x/eax: (addr var) = lookup(*curr) + 9320 (lookup *esi *(esi+4)) # => eax + 9321 # if (x->block-depth < depth) break + 9322 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth + 9323 0f 8c/jump-if-< break/disp32 + 9324 # if (x->register == 0) continue + 9325 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 9326 74/jump-if-= $same-register-spilled-before?:continue/disp8 + 9327 # if (x->register == reg) return true + 9328 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax + 9329 (string-equal? %eax %edx) # => eax + 9330 3d/compare-eax-and 0/imm32/false + 9331 b8/copy-to-eax 1/imm32/true + 9332 75/jump-if-!= $same-register-spilled-before?:end/disp8 + 9333 $same-register-spilled-before?:continue: + 9334 # curr -= 8 + 9335 81 5/subop/subtract %esi 8/imm32 + 9336 e9/jump loop/disp32 + 9337 } + 9338 $same-register-spilled-before?:false: + 9339 b8/copy-to-eax 0/imm32/false + 9340 $same-register-spilled-before?:end: + 9341 # . restore registers + 9342 5f/pop-to-edi + 9343 5e/pop-to-esi + 9344 5b/pop-to-ebx + 9345 5a/pop-to-edx + 9346 59/pop-to-ecx + 9347 # . epilogue + 9348 89/<- %esp 5/r32/ebp + 9349 5d/pop-to-ebp + 9350 c3/return + 9351 + 9352 # clean up global state for 'vars' until some block depth + 9353 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int + 9354 # . prologue + 9355 55/push-ebp + 9356 89/<- %ebp 4/r32/esp + 9357 # . save registers + 9358 50/push-eax + 9359 51/push-ecx + 9360 56/push-esi + 9361 # esi = vars + 9362 8b/-> *(ebp+8) 6/r32/esi + 9363 # ecx = until-block-depth + 9364 8b/-> *(ebp+0xc) 1/r32/ecx + 9365 { + 9366 $clean-up-blocks:reclaim-loop: + 9367 # if (vars->top <= 0) break + 9368 8b/-> *esi 0/r32/eax # Stack-top + 9369 3d/compare-eax-and 0/imm32 + 9370 0f 8e/jump-if-<= break/disp32 + 9371 # var v/eax: (addr var) = lookup(vars[vars->top-12]) + 9372 #? (print-int32-buffered Stderr %eax) + 9373 #? (write-buffered Stderr ": ") + 9374 #? (print-int32-buffered Stderr *(esi+eax-4)) + 9375 #? (write-buffered Stderr " ") + 9376 #? (print-int32-buffered Stderr *(esi+eax)) + 9377 #? (write-buffered Stderr " ") + 9378 #? (print-int32-buffered Stderr *(esi+eax+4)) + 9379 #? (write-buffered Stderr Newline) + 9380 #? (flush Stderr) + 9381 (lookup *(esi+eax-4) *(esi+eax)) # vars + 8 + vars->top - 12 => eax + 9382 # if (v->block-depth < until-block-depth) break + 9383 39/compare *(eax+0x10) 1/r32/ecx # Var-block-depth + 9384 7c/jump-if-< break/disp8 + 9385 # if v is on the stack, update Curr-local-stack-offset + 9386 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 9387 { + 9388 75/jump-if-!= break/disp8 + 9389 $clean-up-blocks:reclaim-var-on-stack: + 9390 (size-of %eax) # => eax + 9391 01/add-to *Curr-local-stack-offset 0/r32/eax 9392 } - 9393 # if index->type is any other atom, abort - 9394 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 9395 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom - 9396 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 - 9397 # if index has type (offset ...) - 9398 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax - 9399 (is-simple-mu-type? %eax 7) # => eax - 9400 3d/compare-eax-and 0/imm32/false - 9401 { - 9402 0f 84/jump-if-= break/disp32 - 9403 # print index->register - 9404 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: - 9405 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 9406 (write-buffered *(ebp+8) %eax) - 9407 } - 9408 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: - 9409 (write-buffered *(ebp+8) " + 4) ") - 9410 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 - 9411 } - 9412 # otherwise if index is a literal - 9413 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 9414 (is-simple-mu-type? %eax 0) # => eax - 9415 3d/compare-eax-and 0/imm32/false - 9416 { - 9417 0f 84/jump-if-= break/disp32 - 9418 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: - 9419 # var index-value/edx: int = parse-hex-int(index->name) - 9420 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 9421 (parse-hex-int %eax) # => eax - 9422 89/<- %edx 0/r32/eax - 9423 # offset = idx-value * size-of(element(base->type)) - 9424 (array-element-type-id %ebx) # => eax - 9425 (size-of-type-id %eax) # => eax - 9426 f7 4/subop/multiply-into-eax %edx # clobbers edx - 9427 # offset += 4 for array size - 9428 05/add-to-eax 4/imm32 - 9429 # TODO: check edx for overflow - 9430 # print offset - 9431 (print-int32-buffered *(ebp+8) %eax) - 9432 (write-buffered *(ebp+8) ") ") - 9433 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 - 9434 } - 9435 # otherwise abort - 9436 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 - 9437 $translate-mu-index-stmt-with-array-in-register:emit-output: - 9438 # outputs[0] "/r32" - 9439 8b/-> *(ebp+0xc) 1/r32/ecx - 9440 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 9441 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9442 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 9443 (get Registers %eax 0xc "Registers") # => eax: (addr int) - 9444 (print-int32-buffered *(ebp+8) *eax) - 9445 (write-buffered *(ebp+8) "/r32\n") - 9446 $translate-mu-index-stmt-with-array-in-register:end: - 9447 # . restore registers - 9448 5b/pop-to-ebx - 9449 5a/pop-to-edx - 9450 59/pop-to-ecx - 9451 58/pop-to-eax - 9452 # . epilogue - 9453 89/<- %esp 5/r32/ebp - 9454 5d/pop-to-ebp - 9455 c3/return - 9456 - 9457 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt) - 9458 # . prologue - 9459 55/push-ebp - 9460 89/<- %ebp 4/r32/esp - 9461 # . save registers - 9462 50/push-eax - 9463 51/push-ecx - 9464 52/push-edx - 9465 53/push-ebx - 9466 # - 9467 (emit-indent *(ebp+8) *Curr-block-depth) - 9468 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") - 9469 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) - 9470 8b/-> *(ebp+0xc) 0/r32/eax - 9471 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9472 89/<- %edx 0/r32/eax - 9473 # var base/ecx: (addr var) = lookup(curr->value) - 9474 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9475 89/<- %ecx 0/r32/eax - 9476 # var curr2/eax: (addr stmt-var) = lookup(curr->next) - 9477 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax - 9478 # var index/edx: (handle var) = curr2->value - 9479 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9480 89/<- %edx 0/r32/eax - 9481 # if index->register - 9482 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register - 9483 { - 9484 0f 84/jump-if-= break/disp32 - 9485 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: - 9486 # if index is an int - 9487 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 9488 (is-simple-mu-type? %eax 1) # int => eax - 9489 3d/compare-eax-and 0/imm32/false - 9490 { - 9491 0f 84/jump-if-= break/disp32 - 9492 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: - 9493 # print index->register "<<" log2(size-of(element-type(base))) " + " base->offset+4 - 9494 # . inouts[1]->register "<<" - 9495 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 9496 (write-buffered *(ebp+8) %eax) - 9497 (write-buffered *(ebp+8) "<<") - 9498 # . log2(size-of(element(base))) - 9499 # TODO: ensure size is a power of 2 - 9500 (array-element-type-id %ecx) # => eax - 9501 (size-of-type-id %eax) # => eax - 9502 (num-shift-rights %eax) # => eax - 9503 (print-int32-buffered *(ebp+8) %eax) - 9504 # - 9505 (write-buffered *(ebp+8) " + ") - 9506 # - 9507 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset - 9508 05/add-to-eax 4/imm32 # for array length - 9509 (print-int32-buffered *(ebp+8) %eax) - 9510 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 - 9511 } - 9512 # if index->type is any other atom, abort - 9513 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 9514 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom - 9515 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 - 9516 # if index has type (offset ...) - 9517 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax - 9518 (is-simple-mu-type? %eax 7) # => eax - 9519 3d/compare-eax-and 0/imm32/false - 9520 { - 9521 0f 84/jump-if-= break/disp32 - 9522 # print index->register - 9523 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: - 9524 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 9525 (write-buffered *(ebp+8) %eax) - 9526 } - 9527 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: - 9528 (write-buffered *(ebp+8) ") ") - 9529 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 - 9530 } - 9531 # otherwise if index is a literal - 9532 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 9533 (is-simple-mu-type? %eax 0) # => eax - 9534 3d/compare-eax-and 0/imm32/false - 9535 { - 9536 0f 84/jump-if-= break/disp32 - 9537 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: - 9538 # var idx-value/edx: int = parse-hex-int(index->name) - 9539 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 9540 (parse-hex-int %eax) # Var-name => eax - 9541 89/<- %edx 0/r32/eax - 9542 # offset = idx-value * size-of(element-type(base->type)) - 9543 (array-element-type-id %ecx) # => eax - 9544 (size-of-type-id %eax) # => eax - 9545 f7 4/subop/multiply-into-eax %edx # clobbers edx - 9546 # offset += base->offset - 9547 03/add *(ecx+0x14) 0/r32/eax # Var-offset - 9548 # offset += 4 for array size - 9549 05/add-to-eax 4/imm32 - 9550 # TODO: check edx for overflow - 9551 # print offset - 9552 (print-int32-buffered *(ebp+8) %eax) - 9553 (write-buffered *(ebp+8) ") ") - 9554 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 - 9555 } - 9556 # otherwise abort - 9557 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 - 9558 $translate-mu-index-stmt-with-array-on-stack:emit-output: - 9559 # outputs[0] "/r32" - 9560 8b/-> *(ebp+0xc) 0/r32/eax - 9561 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 9562 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9563 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 9564 (get Registers %eax 0xc "Registers") # => eax: (addr int) - 9565 (print-int32-buffered *(ebp+8) *eax) - 9566 (write-buffered *(ebp+8) "/r32\n") - 9567 $translate-mu-index-stmt-with-array-on-stack:end: - 9568 # . restore registers - 9569 5b/pop-to-ebx - 9570 5a/pop-to-edx - 9571 59/pop-to-ecx - 9572 58/pop-to-eax - 9573 # . epilogue - 9574 89/<- %esp 5/r32/ebp - 9575 5d/pop-to-ebp - 9576 c3/return - 9577 - 9578 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt) - 9579 # . prologue - 9580 55/push-ebp - 9581 89/<- %ebp 4/r32/esp - 9582 # . save registers - 9583 50/push-eax - 9584 51/push-ecx - 9585 52/push-edx - 9586 53/push-ebx - 9587 # - 9588 (emit-indent *(ebp+8) *Curr-block-depth) - 9589 (write-buffered *(ebp+8) "69/multiply") - 9590 # ecx = stmt - 9591 8b/-> *(ebp+0xc) 1/r32/ecx - 9592 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] - 9593 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9594 89/<- %ebx 0/r32/eax - 9595 $translate-mu-compute-index-stmt:emit-index: - 9596 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax - 9597 (emit-subx-var-as-rm32 *(ebp+8) %eax) - 9598 (write-buffered *(ebp+8) Space) - 9599 $translate-mu-compute-index-stmt:emit-elem-size: - 9600 # var base/ebx: (addr var) - 9601 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax - 9602 89/<- %ebx 0/r32/eax - 9603 # print size-of(element(base->type)) - 9604 (array-element-type-id %ebx) # => eax - 9605 (size-of-type-id %eax) # => eax - 9606 (print-int32-buffered *(ebp+8) %eax) - 9607 (write-buffered *(ebp+8) "/imm32 ") - 9608 $translate-mu-compute-index-stmt:emit-output: - 9609 # outputs[0] "/r32" - 9610 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 9611 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9612 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 9613 (get Registers %eax 0xc "Registers") # => eax: (addr int) - 9614 (print-int32-buffered *(ebp+8) *eax) - 9615 (write-buffered *(ebp+8) "/r32\n") - 9616 $translate-mu-compute-index-stmt:end: - 9617 # . restore registers - 9618 5b/pop-to-ebx - 9619 5a/pop-to-edx - 9620 59/pop-to-ecx - 9621 58/pop-to-eax - 9622 # . epilogue - 9623 89/<- %esp 5/r32/ebp - 9624 5d/pop-to-ebp - 9625 c3/return - 9626 - 9627 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) - 9628 # . prologue - 9629 55/push-ebp - 9630 89/<- %ebp 4/r32/esp - 9631 # . save registers - 9632 50/push-eax - 9633 51/push-ecx - 9634 52/push-edx - 9635 # - 9636 (emit-indent *(ebp+8) *Curr-block-depth) - 9637 (write-buffered *(ebp+8) "8d/copy-address ") - 9638 # ecx = stmt - 9639 8b/-> *(ebp+0xc) 1/r32/ecx - 9640 # var offset/edx: int = get offset of stmt - 9641 (mu-get-offset %ecx) # => eax - 9642 89/<- %edx 0/r32/eax - 9643 # var base/eax: (addr var) = stmt->inouts->value - 9644 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9645 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9646 # if base is in a register - 9647 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 9648 { - 9649 0f 84/jump-if-= break/disp32 - 9650 $translate-mu-get-stmt:emit-register-input: - 9651 # emit "*(" base->register " + " offset ") " - 9652 (write-buffered *(ebp+8) "*(") - 9653 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 9654 (write-buffered *(ebp+8) %eax) - 9655 (write-buffered *(ebp+8) " + ") - 9656 (print-int32-buffered *(ebp+8) %edx) - 9657 (write-buffered *(ebp+8) ") ") - 9658 e9/jump $translate-mu-get-stmt:emit-output/disp32 - 9659 } - 9660 # otherwise base is on the stack - 9661 { - 9662 $translate-mu-get-stmt:emit-stack-input: - 9663 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " - 9664 (write-buffered *(ebp+8) "*(ebp+") - 9665 03/add *(eax+0x14) 2/r32/edx # Var-offset - 9666 (print-int32-buffered *(ebp+8) %edx) - 9667 (write-buffered *(ebp+8) ") ") - 9668 eb/jump $translate-mu-get-stmt:emit-output/disp8 - 9669 } - 9670 $translate-mu-get-stmt:emit-output: - 9671 # var output/eax: (addr var) = stmt->outputs->value - 9672 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 9673 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9674 # emit offset->register "/r32" - 9675 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 9676 (get Registers %eax 0xc "Registers") # => eax: (addr int) - 9677 (print-int32-buffered *(ebp+8) *eax) - 9678 (write-buffered *(ebp+8) "/r32\n") - 9679 $translate-mu-get-stmt:end: - 9680 # . restore registers - 9681 5a/pop-to-edx - 9682 59/pop-to-ecx - 9683 58/pop-to-eax - 9684 # . epilogue - 9685 89/<- %esp 5/r32/ebp - 9686 5d/pop-to-ebp - 9687 c3/return - 9688 - 9689 array-element-type-id: # v: (addr var) -> result/eax: type-id - 9690 # precondition: n is positive - 9691 # . prologue - 9692 55/push-ebp - 9693 89/<- %ebp 4/r32/esp - 9694 # - 9695 8b/-> *(ebp+8) 0/r32/eax - 9696 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax - 9697 # TODO: ensure type->left is 'addr' - 9698 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax - 9699 # TODO: ensure that type->right is non-null - 9700 # TODO: ensure that type->right->left is 'array' - 9701 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax - 9702 # TODO: ensure that type->right->right is non-null - 9703 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax - 9704 8b/-> *(eax+4) 0/r32/eax # Tree-value - 9705 $array-element-type-id:end: - 9706 # . epilogue - 9707 89/<- %esp 5/r32/ebp - 9708 5d/pop-to-ebp - 9709 c3/return - 9710 - 9711 power-of-2?: # n: int -> result/eax: boolean - 9712 # precondition: n is positive - 9713 # . prologue - 9714 55/push-ebp - 9715 89/<- %ebp 4/r32/esp - 9716 # eax = n - 9717 8b/-> *(ebp+8) 0/r32/eax - 9718 # if (n < 0) abort - 9719 3d/compare-eax-with 0/imm32 - 9720 0f 8c/jump-if-< $power-of-2?:abort/disp32 - 9721 # var tmp/eax: int = n-1 - 9722 48/decrement-eax - 9723 # var tmp2/eax: int = n & tmp - 9724 23/and-> *(ebp+8) 0/r32/eax - 9725 # return (tmp2 == 0) - 9726 3d/compare-eax-and 0/imm32 - 9727 0f 94/set-byte-if-= %al - 9728 81 4/subop/and %eax 0xff/imm32 - 9729 $power-of-2?:end: - 9730 # . epilogue - 9731 89/<- %esp 5/r32/ebp - 9732 5d/pop-to-ebp - 9733 c3/return - 9734 - 9735 $power-of-2?:abort: - 9736 (write-buffered Stderr "power-of-2?: negative number\n") - 9737 (flush Stderr) - 9738 # . syscall(exit, 1) - 9739 bb/copy-to-ebx 1/imm32 - 9740 b8/copy-to-eax 1/imm32/exit - 9741 cd/syscall 0x80/imm8 - 9742 # never gets here - 9743 - 9744 num-shift-rights: # n: int -> result/eax: int - 9745 # precondition: n is a positive power of 2 - 9746 # . prologue - 9747 55/push-ebp - 9748 89/<- %ebp 4/r32/esp - 9749 # . save registers - 9750 51/push-ecx - 9751 # var curr/ecx: int = n - 9752 8b/-> *(ebp+8) 1/r32/ecx - 9753 # result = 0 - 9754 b8/copy-to-eax 0/imm32 - 9755 { - 9756 # if (curr <= 1) break - 9757 81 7/subop/compare %ecx 1/imm32 - 9758 7e/jump-if-<= break/disp8 - 9759 40/increment-eax - 9760 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 - 9761 eb/jump loop/disp8 - 9762 } - 9763 $num-shift-rights:end: - 9764 # . restore registers - 9765 59/pop-to-ecx - 9766 # . epilogue - 9767 89/<- %esp 5/r32/ebp - 9768 5d/pop-to-ebp - 9769 c3/return - 9770 - 9771 mu-get-offset: # stmt: (addr stmt) -> result/eax: int - 9772 # . prologue - 9773 55/push-ebp - 9774 89/<- %ebp 4/r32/esp - 9775 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next - 9776 8b/-> *(ebp+8) 0/r32/eax - 9777 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9778 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax - 9779 # var output-var/eax: (addr var) = second-inout->value - 9780 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9781 #? (write-buffered Stderr "mu-get-offset: ") - 9782 #? (print-int32-buffered Stderr %eax) - 9783 #? (write-buffered Stderr " name: ") - 9784 #? 50/push-eax - 9785 #? (lookup *eax *(eax+4)) # Var-name - 9786 #? (write-buffered Stderr %eax) - 9787 #? 58/pop-to-eax - 9788 #? (write-buffered Stderr Newline) - 9789 #? (flush Stderr) - 9790 # return output-var->stack-offset - 9791 8b/-> *(eax+0x14) 0/r32/eax # Var-offset - 9792 #? (write-buffered Stderr "=> ") - 9793 #? (print-int32-buffered Stderr %eax) - 9794 #? (write-buffered Stderr Newline) - 9795 #? (flush Stderr) - 9796 $emit-get-offset:end: - 9797 # . epilogue - 9798 89/<- %esp 5/r32/ebp - 9799 5d/pop-to-ebp - 9800 c3/return - 9801 - 9802 emit-subx-block: # out: (addr buffered-file), block: (addr block), vars: (addr stack (handle var)) - 9803 # . prologue - 9804 55/push-ebp - 9805 89/<- %ebp 4/r32/esp - 9806 # . save registers - 9807 50/push-eax - 9808 51/push-ecx - 9809 56/push-esi - 9810 # esi = block - 9811 8b/-> *(ebp+0xc) 6/r32/esi - 9812 # block->var->block-depth = *Curr-block-depth - 9813 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax - 9814 8b/-> *Curr-block-depth 1/r32/ecx - 9815 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth - 9816 # var stmts/eax: (addr list stmt) = lookup(block->statements) - 9817 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax - 9818 # - 9819 { - 9820 $emit-subx-block:check-empty: - 9821 3d/compare-eax-and 0/imm32 - 9822 0f 84/jump-if-= break/disp32 - 9823 (emit-indent *(ebp+8) *Curr-block-depth) - 9824 (write-buffered *(ebp+8) "{\n") - 9825 # var v/ecx: (addr var) = lookup(block->var) - 9826 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax - 9827 89/<- %ecx 0/r32/eax - 9828 # - 9829 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 9830 (write-buffered *(ebp+8) %eax) - 9831 (write-buffered *(ebp+8) ":loop:\n") - 9832 ff 0/subop/increment *Curr-block-depth - 9833 (push *(ebp+0x10) *(esi+0xc)) # Block-var - 9834 (push *(ebp+0x10) *(esi+0x10)) # Block-var - 9835 # emit block->statements - 9836 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax - 9837 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10)) - 9838 (pop *(ebp+0x10)) # => eax - 9839 (pop *(ebp+0x10)) # => eax - 9840 ff 1/subop/decrement *Curr-block-depth - 9841 (emit-indent *(ebp+8) *Curr-block-depth) - 9842 (write-buffered *(ebp+8) "}\n") - 9843 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 9844 (write-buffered *(ebp+8) %eax) - 9845 (write-buffered *(ebp+8) ":break:\n") - 9846 } - 9847 $emit-subx-block:end: - 9848 # . restore registers - 9849 5e/pop-to-esi - 9850 59/pop-to-ecx - 9851 58/pop-to-eax - 9852 # . epilogue - 9853 89/<- %esp 5/r32/ebp - 9854 5d/pop-to-ebp - 9855 c3/return - 9856 - 9857 # Primitives supported - 9858 # See mu_instructions for a summary of this linked-list data structure. - 9859 # - 9860 # For each operation, put variants with hard-coded registers before flexible ones. - 9861 # - 9862 # Unfortunately, our restrictions on addresses require that various fields in - 9863 # primitives be handles, which complicates these definitions. - 9864 # - we need to insert dummy fields all over the place for fake alloc-ids - 9865 # - we can't use our syntax sugar of quoted literals for string fields - 9866 # - 9867 # Fake alloc-ids are needed because our type definitions up top require - 9868 # handles but it's clearer to statically allocate these long-lived objects. - 9869 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. - 9870 # - 9871 # Every 'object' below starts with a fake alloc-id. It may also contain other - 9872 # fake alloc-ids for various handle fields. - 9873 # - 9874 # I think of objects starting with a fake alloc-id as having type 'payload'. - 9875 # It's not really intended to be created dynamically; for that use `allocate` - 9876 # as usual. - 9877 # - 9878 # Idea for a notation to simplify such definitions: - 9879 # _Primitive-increment-eax: # (payload primitive) - 9880 # 0x11/alloc-id:fake:payload - 9881 # 0x11 @(0x11 "increment") # name - 9882 # 0 0 # inouts - 9883 # 0x11 @(0x11/payload - 9884 # 0x11 @(0x11/payload # List-value - 9885 # 0 0 # Var-name - 9886 # 0x11 @(0x11 # Var-type - 9887 # 1/is-atom - 9888 # 1/value 0/unused # Tree-left - 9889 # 0 0 # Tree-right - 9890 # ) - 9891 # 1 # block-depth - 9892 # 0 # stack-offset - 9893 # 0x11 @(0x11 "eax") # Var-register - 9894 # ) - 9895 # 0 0) # List-next - 9896 # ... - 9897 # _Primitive-increment-ecx/imm32/next - 9898 # ... - 9899 # Awfully complex and non-obvious. But also clearly signals there's something - 9900 # to learn here, so may be worth trying. - 9901 # - 9902 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " - 9903 # - 9904 # For now we'll continue to just use comments and manually ensure they stay up - 9905 # to date. - 9906 == data - 9907 Primitives: # (addr primitive) - 9908 # - increment/decrement - 9909 _Primitive-increment-eax: # (addr primitive) - 9910 # var/eax <- increment => 40/increment-eax - 9911 0x11/imm32/alloc-id:fake - 9912 _string-increment/imm32/name - 9913 0/imm32/no-inouts - 9914 0/imm32/no-inouts - 9915 0x11/imm32/alloc-id:fake - 9916 Single-int-var-in-eax/imm32/outputs - 9917 0x11/imm32/alloc-id:fake - 9918 _string_40_increment_eax/imm32/subx-name - 9919 0/imm32/no-rm32 - 9920 0/imm32/no-r32 - 9921 0/imm32/no-imm32 - 9922 0/imm32/no-disp32 - 9923 0/imm32/output-is-write-only - 9924 0x11/imm32/alloc-id:fake - 9925 _Primitive-increment-ecx/imm32/next - 9926 _Primitive-increment-ecx: # (payload primitive) - 9927 0x11/imm32/alloc-id:fake:payload - 9928 # var/ecx <- increment => 41/increment-ecx - 9929 0x11/imm32/alloc-id:fake - 9930 _string-increment/imm32/name - 9931 0/imm32/no-inouts - 9932 0/imm32/no-inouts - 9933 0x11/imm32/alloc-id:fake - 9934 Single-int-var-in-ecx/imm32/outputs - 9935 0x11/imm32/alloc-id:fake - 9936 _string_41_increment_ecx/imm32/subx-name - 9937 0/imm32/no-rm32 - 9938 0/imm32/no-r32 - 9939 0/imm32/no-imm32 - 9940 0/imm32/no-disp32 - 9941 0/imm32/output-is-write-only - 9942 0x11/imm32/alloc-id:fake - 9943 _Primitive-increment-edx/imm32/next - 9944 _Primitive-increment-edx: # (payload primitive) - 9945 0x11/imm32/alloc-id:fake:payload - 9946 # var/edx <- increment => 42/increment-edx - 9947 0x11/imm32/alloc-id:fake - 9948 _string-increment/imm32/name - 9949 0/imm32/no-inouts - 9950 0/imm32/no-inouts - 9951 0x11/imm32/alloc-id:fake - 9952 Single-int-var-in-edx/imm32/outputs - 9953 0x11/imm32/alloc-id:fake - 9954 _string_42_increment_edx/imm32/subx-name - 9955 0/imm32/no-rm32 - 9956 0/imm32/no-r32 - 9957 0/imm32/no-imm32 - 9958 0/imm32/no-disp32 - 9959 0/imm32/output-is-write-only - 9960 0x11/imm32/alloc-id:fake - 9961 _Primitive-increment-ebx/imm32/next - 9962 _Primitive-increment-ebx: # (payload primitive) - 9963 0x11/imm32/alloc-id:fake:payload - 9964 # var/ebx <- increment => 43/increment-ebx - 9965 0x11/imm32/alloc-id:fake - 9966 _string-increment/imm32/name - 9967 0/imm32/no-inouts - 9968 0/imm32/no-inouts - 9969 0x11/imm32/alloc-id:fake - 9970 Single-int-var-in-ebx/imm32/outputs - 9971 0x11/imm32/alloc-id:fake - 9972 _string_43_increment_ebx/imm32/subx-name - 9973 0/imm32/no-rm32 - 9974 0/imm32/no-r32 - 9975 0/imm32/no-imm32 - 9976 0/imm32/no-disp32 - 9977 0/imm32/output-is-write-only - 9978 0x11/imm32/alloc-id:fake - 9979 _Primitive-increment-esi/imm32/next - 9980 _Primitive-increment-esi: # (payload primitive) - 9981 0x11/imm32/alloc-id:fake:payload - 9982 # var/esi <- increment => 46/increment-esi - 9983 0x11/imm32/alloc-id:fake - 9984 _string-increment/imm32/name - 9985 0/imm32/no-inouts - 9986 0/imm32/no-inouts - 9987 0x11/imm32/alloc-id:fake - 9988 Single-int-var-in-esi/imm32/outputs - 9989 0x11/imm32/alloc-id:fake - 9990 _string_46_increment_esi/imm32/subx-name - 9991 0/imm32/no-rm32 - 9992 0/imm32/no-r32 - 9993 0/imm32/no-imm32 - 9994 0/imm32/no-disp32 - 9995 0/imm32/output-is-write-only - 9996 0x11/imm32/alloc-id:fake - 9997 _Primitive-increment-edi/imm32/next - 9998 _Primitive-increment-edi: # (payload primitive) - 9999 0x11/imm32/alloc-id:fake:payload -10000 # var/edi <- increment => 47/increment-edi -10001 0x11/imm32/alloc-id:fake -10002 _string-increment/imm32/name -10003 0/imm32/no-inouts -10004 0/imm32/no-inouts -10005 0x11/imm32/alloc-id:fake -10006 Single-int-var-in-edi/imm32/outputs -10007 0x11/imm32/alloc-id:fake -10008 _string_47_increment_edi/imm32/subx-name -10009 0/imm32/no-rm32 -10010 0/imm32/no-r32 -10011 0/imm32/no-imm32 -10012 0/imm32/no-disp32 -10013 0/imm32/output-is-write-only -10014 0x11/imm32/alloc-id:fake -10015 _Primitive-decrement-eax/imm32/next -10016 _Primitive-decrement-eax: # (payload primitive) -10017 0x11/imm32/alloc-id:fake:payload -10018 # var/eax <- decrement => 48/decrement-eax -10019 0x11/imm32/alloc-id:fake -10020 _string-decrement/imm32/name -10021 0/imm32/no-inouts -10022 0/imm32/no-inouts -10023 0x11/imm32/alloc-id:fake -10024 Single-int-var-in-eax/imm32/outputs -10025 0x11/imm32/alloc-id:fake -10026 _string_48_decrement_eax/imm32/subx-name -10027 0/imm32/no-rm32 -10028 0/imm32/no-r32 -10029 0/imm32/no-imm32 -10030 0/imm32/no-disp32 -10031 0/imm32/output-is-write-only -10032 0x11/imm32/alloc-id:fake -10033 _Primitive-decrement-ecx/imm32/next -10034 _Primitive-decrement-ecx: # (payload primitive) -10035 0x11/imm32/alloc-id:fake:payload -10036 # var/ecx <- decrement => 49/decrement-ecx -10037 0x11/imm32/alloc-id:fake -10038 _string-decrement/imm32/name -10039 0/imm32/no-inouts -10040 0/imm32/no-inouts -10041 0x11/imm32/alloc-id:fake -10042 Single-int-var-in-ecx/imm32/outputs -10043 0x11/imm32/alloc-id:fake -10044 _string_49_decrement_ecx/imm32/subx-name -10045 0/imm32/no-rm32 -10046 0/imm32/no-r32 -10047 0/imm32/no-imm32 -10048 0/imm32/no-disp32 -10049 0/imm32/output-is-write-only -10050 0x11/imm32/alloc-id:fake -10051 _Primitive-decrement-edx/imm32/next -10052 _Primitive-decrement-edx: # (payload primitive) -10053 0x11/imm32/alloc-id:fake:payload -10054 # var/edx <- decrement => 4a/decrement-edx -10055 0x11/imm32/alloc-id:fake -10056 _string-decrement/imm32/name -10057 0/imm32/no-inouts -10058 0/imm32/no-inouts -10059 0x11/imm32/alloc-id:fake -10060 Single-int-var-in-edx/imm32/outputs -10061 0x11/imm32/alloc-id:fake -10062 _string_4a_decrement_edx/imm32/subx-name -10063 0/imm32/no-rm32 -10064 0/imm32/no-r32 -10065 0/imm32/no-imm32 -10066 0/imm32/no-disp32 -10067 0/imm32/output-is-write-only -10068 0x11/imm32/alloc-id:fake -10069 _Primitive-decrement-ebx/imm32/next -10070 _Primitive-decrement-ebx: # (payload primitive) -10071 0x11/imm32/alloc-id:fake:payload -10072 # var/ebx <- decrement => 4b/decrement-ebx -10073 0x11/imm32/alloc-id:fake -10074 _string-decrement/imm32/name -10075 0/imm32/no-inouts -10076 0/imm32/no-inouts -10077 0x11/imm32/alloc-id:fake -10078 Single-int-var-in-ebx/imm32/outputs -10079 0x11/imm32/alloc-id:fake -10080 _string_4b_decrement_ebx/imm32/subx-name -10081 0/imm32/no-rm32 -10082 0/imm32/no-r32 -10083 0/imm32/no-imm32 -10084 0/imm32/no-disp32 -10085 0/imm32/output-is-write-only -10086 0x11/imm32/alloc-id:fake -10087 _Primitive-decrement-esi/imm32/next -10088 _Primitive-decrement-esi: # (payload primitive) -10089 0x11/imm32/alloc-id:fake:payload -10090 # var/esi <- decrement => 4e/decrement-esi -10091 0x11/imm32/alloc-id:fake -10092 _string-decrement/imm32/name -10093 0/imm32/no-inouts -10094 0/imm32/no-inouts -10095 0x11/imm32/alloc-id:fake -10096 Single-int-var-in-esi/imm32/outputs -10097 0x11/imm32/alloc-id:fake -10098 _string_4e_decrement_esi/imm32/subx-name -10099 0/imm32/no-rm32 -10100 0/imm32/no-r32 -10101 0/imm32/no-imm32 -10102 0/imm32/no-disp32 -10103 0/imm32/output-is-write-only -10104 0x11/imm32/alloc-id:fake -10105 _Primitive-decrement-edi/imm32/next -10106 _Primitive-decrement-edi: # (payload primitive) -10107 0x11/imm32/alloc-id:fake:payload -10108 # var/edi <- decrement => 4f/decrement-edi -10109 0x11/imm32/alloc-id:fake -10110 _string-decrement/imm32/name -10111 0/imm32/no-inouts -10112 0/imm32/no-inouts -10113 0x11/imm32/alloc-id:fake -10114 Single-int-var-in-edi/imm32/outputs -10115 0x11/imm32/alloc-id:fake -10116 _string_4f_decrement_edi/imm32/subx-name -10117 0/imm32/no-rm32 -10118 0/imm32/no-r32 -10119 0/imm32/no-imm32 -10120 0/imm32/no-disp32 -10121 0/imm32/output-is-write-only -10122 0x11/imm32/alloc-id:fake -10123 _Primitive-increment-mem/imm32/next -10124 _Primitive-increment-mem: # (payload primitive) -10125 0x11/imm32/alloc-id:fake:payload -10126 # increment var => ff 0/subop/increment *(ebp+__) -10127 0x11/imm32/alloc-id:fake -10128 _string-increment/imm32/name -10129 0x11/imm32/alloc-id:fake -10130 Single-int-var-in-mem/imm32/inouts -10131 0/imm32/no-outputs -10132 0/imm32/no-outputs -10133 0x11/imm32/alloc-id:fake -10134 _string_ff_subop_increment/imm32/subx-name -10135 1/imm32/rm32-is-first-inout -10136 0/imm32/no-r32 -10137 0/imm32/no-imm32 -10138 0/imm32/no-disp32 -10139 0/imm32/output-is-write-only -10140 0x11/imm32/alloc-id:fake -10141 _Primitive-increment-reg/imm32/next -10142 _Primitive-increment-reg: # (payload primitive) -10143 0x11/imm32/alloc-id:fake:payload -10144 # var/reg <- increment => ff 0/subop/increment %__ -10145 0x11/imm32/alloc-id:fake -10146 _string-increment/imm32/name -10147 0/imm32/no-inouts -10148 0/imm32/no-inouts -10149 0x11/imm32/alloc-id:fake -10150 Single-int-var-in-some-register/imm32/outputs -10151 0x11/imm32/alloc-id:fake -10152 _string_ff_subop_increment/imm32/subx-name -10153 3/imm32/rm32-is-first-output -10154 0/imm32/no-r32 -10155 0/imm32/no-imm32 -10156 0/imm32/no-disp32 -10157 0/imm32/output-is-write-only -10158 0x11/imm32/alloc-id:fake -10159 _Primitive-decrement-mem/imm32/next -10160 _Primitive-decrement-mem: # (payload primitive) -10161 0x11/imm32/alloc-id:fake:payload -10162 # decrement var => ff 1/subop/decrement *(ebp+__) -10163 0x11/imm32/alloc-id:fake -10164 _string-decrement/imm32/name -10165 0x11/imm32/alloc-id:fake -10166 Single-int-var-in-mem/imm32/inouts -10167 0/imm32/no-outputs -10168 0/imm32/no-outputs -10169 0x11/imm32/alloc-id:fake -10170 _string_ff_subop_decrement/imm32/subx-name -10171 1/imm32/rm32-is-first-inout -10172 0/imm32/no-r32 -10173 0/imm32/no-imm32 -10174 0/imm32/no-disp32 -10175 0/imm32/output-is-write-only -10176 0x11/imm32/alloc-id:fake -10177 _Primitive-decrement-reg/imm32/next -10178 _Primitive-decrement-reg: # (payload primitive) -10179 0x11/imm32/alloc-id:fake:payload -10180 # var/reg <- decrement => ff 1/subop/decrement %__ -10181 0x11/imm32/alloc-id:fake -10182 _string-decrement/imm32/name -10183 0/imm32/no-inouts -10184 0/imm32/no-inouts -10185 0x11/imm32/alloc-id:fake -10186 Single-int-var-in-some-register/imm32/outputs -10187 0x11/imm32/alloc-id:fake -10188 _string_ff_subop_decrement/imm32/subx-name -10189 3/imm32/rm32-is-first-output -10190 0/imm32/no-r32 -10191 0/imm32/no-imm32 -10192 0/imm32/no-disp32 -10193 0/imm32/output-is-write-only -10194 0x11/imm32/alloc-id:fake -10195 _Primitive-add-to-eax/imm32/next -10196 # - add -10197 _Primitive-add-to-eax: # (payload primitive) -10198 0x11/imm32/alloc-id:fake:payload -10199 # var/eax <- add lit => 05/add-to-eax lit/imm32 -10200 0x11/imm32/alloc-id:fake -10201 _string-add/imm32/name -10202 0x11/imm32/alloc-id:fake -10203 Single-lit-var/imm32/inouts -10204 0x11/imm32/alloc-id:fake -10205 Single-int-var-in-eax/imm32/outputs -10206 0x11/imm32/alloc-id:fake -10207 _string_05_add_to_eax/imm32/subx-name -10208 0/imm32/no-rm32 -10209 0/imm32/no-r32 -10210 1/imm32/imm32-is-first-inout -10211 0/imm32/no-disp32 -10212 0/imm32/output-is-write-only -10213 0x11/imm32/alloc-id:fake -10214 _Primitive-add-reg-to-reg/imm32/next -10215 _Primitive-add-reg-to-reg: # (payload primitive) -10216 0x11/imm32/alloc-id:fake:payload -10217 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 -10218 0x11/imm32/alloc-id:fake -10219 _string-add/imm32/name -10220 0x11/imm32/alloc-id:fake -10221 Single-int-var-in-some-register/imm32/inouts -10222 0x11/imm32/alloc-id:fake -10223 Single-int-var-in-some-register/imm32/outputs -10224 0x11/imm32/alloc-id:fake -10225 _string_01_add_to/imm32/subx-name -10226 3/imm32/rm32-is-first-output -10227 1/imm32/r32-is-first-inout -10228 0/imm32/no-imm32 -10229 0/imm32/no-disp32 -10230 0/imm32/output-is-write-only -10231 0x11/imm32/alloc-id:fake -10232 _Primitive-add-reg-to-mem/imm32/next -10233 _Primitive-add-reg-to-mem: # (payload primitive) -10234 0x11/imm32/alloc-id:fake:payload -10235 # add-to var1 var2/reg => 01/add-to var1 var2/r32 -10236 0x11/imm32/alloc-id:fake -10237 _string-add-to/imm32/name -10238 0x11/imm32/alloc-id:fake -10239 Two-args-int-stack-int-reg/imm32/inouts -10240 0/imm32/no-outputs -10241 0/imm32/no-outputs -10242 0x11/imm32/alloc-id:fake -10243 _string_01_add_to/imm32/subx-name -10244 1/imm32/rm32-is-first-inout -10245 2/imm32/r32-is-second-inout -10246 0/imm32/no-imm32 -10247 0/imm32/no-disp32 -10248 0/imm32/output-is-write-only -10249 0x11/imm32/alloc-id:fake -10250 _Primitive-add-mem-to-reg/imm32/next -10251 _Primitive-add-mem-to-reg: # (payload primitive) -10252 0x11/imm32/alloc-id:fake:payload -10253 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 -10254 0x11/imm32/alloc-id:fake -10255 _string-add/imm32/name -10256 0x11/imm32/alloc-id:fake -10257 Single-int-var-in-mem/imm32/inouts -10258 0x11/imm32/alloc-id:fake -10259 Single-int-var-in-some-register/imm32/outputs -10260 0x11/imm32/alloc-id:fake -10261 _string_03_add/imm32/subx-name -10262 1/imm32/rm32-is-first-inout -10263 3/imm32/r32-is-first-output -10264 0/imm32/no-imm32 -10265 0/imm32/no-disp32 -10266 0/imm32/output-is-write-only -10267 0x11/imm32/alloc-id:fake -10268 _Primitive-add-lit-to-reg/imm32/next -10269 _Primitive-add-lit-to-reg: # (payload primitive) -10270 0x11/imm32/alloc-id:fake:payload -10271 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 -10272 0x11/imm32/alloc-id:fake -10273 _string-add/imm32/name -10274 0x11/imm32/alloc-id:fake -10275 Single-lit-var/imm32/inouts -10276 0x11/imm32/alloc-id:fake -10277 Single-int-var-in-some-register/imm32/outputs -10278 0x11/imm32/alloc-id:fake -10279 _string_81_subop_add/imm32/subx-name -10280 3/imm32/rm32-is-first-output -10281 0/imm32/no-r32 -10282 1/imm32/imm32-is-first-inout -10283 0/imm32/no-disp32 -10284 0/imm32/output-is-write-only -10285 0x11/imm32/alloc-id:fake -10286 _Primitive-add-lit-to-mem/imm32/next -10287 _Primitive-add-lit-to-mem: # (payload primitive) -10288 0x11/imm32/alloc-id:fake:payload -10289 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 -10290 0x11/imm32/alloc-id:fake -10291 _string-add-to/imm32/name -10292 0x11/imm32/alloc-id:fake -10293 Int-var-and-literal/imm32/inouts -10294 0/imm32/no-outputs -10295 0/imm32/no-outputs -10296 0x11/imm32/alloc-id:fake -10297 _string_81_subop_add/imm32/subx-name -10298 1/imm32/rm32-is-first-inout -10299 0/imm32/no-r32 -10300 2/imm32/imm32-is-second-inout -10301 0/imm32/no-disp32 -10302 0/imm32/output-is-write-only -10303 0x11/imm32/alloc-id:fake -10304 _Primitive-subtract-from-eax/imm32/next -10305 # - subtract -10306 _Primitive-subtract-from-eax: # (payload primitive) -10307 0x11/imm32/alloc-id:fake:payload -10308 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 -10309 0x11/imm32/alloc-id:fake -10310 _string-subtract/imm32/name -10311 0x11/imm32/alloc-id:fake -10312 Single-lit-var/imm32/inouts -10313 0x11/imm32/alloc-id:fake -10314 Single-int-var-in-eax/imm32/outputs -10315 0x11/imm32/alloc-id:fake -10316 _string_2d_subtract_from_eax/imm32/subx-name -10317 0/imm32/no-rm32 -10318 0/imm32/no-r32 -10319 1/imm32/imm32-is-first-inout -10320 0/imm32/no-disp32 -10321 0/imm32/output-is-write-only -10322 0x11/imm32/alloc-id:fake -10323 _Primitive-subtract-reg-from-reg/imm32/next -10324 _Primitive-subtract-reg-from-reg: # (payload primitive) -10325 0x11/imm32/alloc-id:fake:payload -10326 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 -10327 0x11/imm32/alloc-id:fake -10328 _string-subtract/imm32/name -10329 0x11/imm32/alloc-id:fake -10330 Single-int-var-in-some-register/imm32/inouts -10331 0x11/imm32/alloc-id:fake -10332 Single-int-var-in-some-register/imm32/outputs -10333 0x11/imm32/alloc-id:fake -10334 _string_29_subtract_from/imm32/subx-name -10335 3/imm32/rm32-is-first-output -10336 1/imm32/r32-is-first-inout -10337 0/imm32/no-imm32 -10338 0/imm32/no-disp32 -10339 0/imm32/output-is-write-only -10340 0x11/imm32/alloc-id:fake -10341 _Primitive-subtract-reg-from-mem/imm32/next -10342 _Primitive-subtract-reg-from-mem: # (payload primitive) -10343 0x11/imm32/alloc-id:fake:payload -10344 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 -10345 0x11/imm32/alloc-id:fake -10346 _string-subtract-from/imm32/name -10347 0x11/imm32/alloc-id:fake -10348 Two-args-int-stack-int-reg/imm32/inouts -10349 0/imm32/no-outputs -10350 0/imm32/no-outputs -10351 0x11/imm32/alloc-id:fake -10352 _string_29_subtract_from/imm32/subx-name -10353 1/imm32/rm32-is-first-inout -10354 2/imm32/r32-is-second-inout -10355 0/imm32/no-imm32 -10356 0/imm32/no-disp32 -10357 0/imm32/output-is-write-only -10358 0x11/imm32/alloc-id:fake -10359 _Primitive-subtract-mem-from-reg/imm32/next -10360 _Primitive-subtract-mem-from-reg: # (payload primitive) -10361 0x11/imm32/alloc-id:fake:payload -10362 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 -10363 0x11/imm32/alloc-id:fake -10364 _string-subtract/imm32/name -10365 0x11/imm32/alloc-id:fake -10366 Single-int-var-in-mem/imm32/inouts -10367 0x11/imm32/alloc-id:fake -10368 Single-int-var-in-some-register/imm32/outputs -10369 0x11/imm32/alloc-id:fake -10370 _string_2b_subtract/imm32/subx-name -10371 1/imm32/rm32-is-first-inout -10372 3/imm32/r32-is-first-output -10373 0/imm32/no-imm32 -10374 0/imm32/no-disp32 -10375 0/imm32/output-is-write-only -10376 0x11/imm32/alloc-id:fake -10377 _Primitive-subtract-lit-from-reg/imm32/next -10378 _Primitive-subtract-lit-from-reg: # (payload primitive) -10379 0x11/imm32/alloc-id:fake:payload -10380 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 -10381 0x11/imm32/alloc-id:fake -10382 _string-subtract/imm32/name -10383 0x11/imm32/alloc-id:fake -10384 Single-lit-var/imm32/inouts -10385 0x11/imm32/alloc-id:fake -10386 Single-int-var-in-some-register/imm32/outputs -10387 0x11/imm32/alloc-id:fake -10388 _string_81_subop_subtract/imm32/subx-name -10389 3/imm32/rm32-is-first-output -10390 0/imm32/no-r32 -10391 1/imm32/imm32-is-first-inout -10392 0/imm32/no-disp32 -10393 0/imm32/output-is-write-only -10394 0x11/imm32/alloc-id:fake -10395 _Primitive-subtract-lit-from-mem/imm32/next -10396 _Primitive-subtract-lit-from-mem: # (payload primitive) -10397 0x11/imm32/alloc-id:fake:payload -10398 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 -10399 0x11/imm32/alloc-id:fake -10400 _string-subtract-from/imm32/name -10401 0x11/imm32/alloc-id:fake -10402 Int-var-and-literal/imm32/inouts -10403 0/imm32/no-outputs -10404 0/imm32/no-outputs -10405 0x11/imm32/alloc-id:fake -10406 _string_81_subop_subtract/imm32/subx-name -10407 1/imm32/rm32-is-first-inout -10408 0/imm32/no-r32 -10409 2/imm32/imm32-is-first-inout -10410 0/imm32/no-disp32 -10411 0/imm32/output-is-write-only -10412 0x11/imm32/alloc-id:fake -10413 _Primitive-and-with-eax/imm32/next -10414 # - and -10415 _Primitive-and-with-eax: # (payload primitive) -10416 0x11/imm32/alloc-id:fake:payload -10417 # var/eax <- and lit => 25/and-with-eax lit/imm32 -10418 0x11/imm32/alloc-id:fake -10419 _string-and/imm32/name -10420 0x11/imm32/alloc-id:fake -10421 Single-lit-var/imm32/inouts + 9393 (pop %esi) # => eax + 9394 (pop %esi) # => eax + 9395 (pop %esi) # => eax + 9396 e9/jump loop/disp32 + 9397 } + 9398 $clean-up-blocks:end: + 9399 # . restore registers + 9400 5e/pop-to-esi + 9401 59/pop-to-ecx + 9402 58/pop-to-eax + 9403 # . epilogue + 9404 89/<- %esp 5/r32/ebp + 9405 5d/pop-to-ebp + 9406 c3/return + 9407 + 9408 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt) + 9409 # . prologue + 9410 55/push-ebp + 9411 89/<- %ebp 4/r32/esp + 9412 # . save registers + 9413 50/push-eax + 9414 51/push-ecx + 9415 52/push-edx + 9416 # eax = stmt + 9417 8b/-> *(ebp+0xc) 0/r32/eax + 9418 # var v/ecx: (addr var) + 9419 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax + 9420 89/<- %ecx 0/r32/eax + 9421 # v->block-depth = *Curr-block-depth + 9422 8b/-> *Curr-block-depth 0/r32/eax + 9423 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth + 9424 # var n/edx: int = size-of(stmt->var) + 9425 (size-of %ecx) # => eax + 9426 89/<- %edx 0/r32/eax + 9427 # *Curr-local-stack-offset -= n + 9428 29/subtract-from *Curr-local-stack-offset 2/r32/edx + 9429 # v->offset = *Curr-local-stack-offset + 9430 8b/-> *Curr-local-stack-offset 0/r32/eax + 9431 89/<- *(ecx+0x14) 0/r32/eax # Var-offset + 9432 # if v is an array, do something special + 9433 { + 9434 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 9435 (is-mu-array? %eax) # => eax + 9436 3d/compare-eax-and 0/imm32/false + 9437 0f 84/jump-if-= break/disp32 + 9438 # var array-size-without-size/edx: int = n-4 + 9439 81 5/subop/subtract %edx 4/imm32 + 9440 (emit-indent *(ebp+8) *Curr-block-depth) + 9441 (write-buffered *(ebp+8) "(push-n-zero-bytes ") + 9442 (print-int32-buffered *(ebp+8) %edx) + 9443 (write-buffered *(ebp+8) ")\n") + 9444 (emit-indent *(ebp+8) *Curr-block-depth) + 9445 (write-buffered *(ebp+8) "68/push ") + 9446 (print-int32-buffered *(ebp+8) %edx) + 9447 (write-buffered *(ebp+8) "/imm32\n") + 9448 eb/jump $emit-subx-var-def:end/disp8 + 9449 } + 9450 # while n > 0 + 9451 { + 9452 81 7/subop/compare %edx 0/imm32 + 9453 7e/jump-if-<= break/disp8 + 9454 (emit-indent *(ebp+8) *Curr-block-depth) + 9455 (write-buffered *(ebp+8) "68/push 0/imm32\n") + 9456 # n -= 4 + 9457 81 5/subop/subtract %edx 4/imm32 + 9458 # + 9459 eb/jump loop/disp8 + 9460 } + 9461 $emit-subx-var-def:end: + 9462 # . restore registers + 9463 5a/pop-to-edx + 9464 59/pop-to-ecx + 9465 58/pop-to-eax + 9466 # . epilogue + 9467 89/<- %esp 5/r32/ebp + 9468 5d/pop-to-ebp + 9469 c3/return + 9470 + 9471 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive) + 9472 # . prologue + 9473 55/push-ebp + 9474 89/<- %ebp 4/r32/esp + 9475 # . save registers + 9476 50/push-eax + 9477 51/push-ecx + 9478 # - some special-case primitives that don't actually use the 'primitives' data structure + 9479 # var op/ecx: (addr array byte) = lookup(stmt->operation) + 9480 8b/-> *(ebp+0xc) 1/r32/ecx + 9481 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax + 9482 89/<- %ecx 0/r32/eax + 9483 # array size + 9484 { + 9485 # if (!string-equal?(stmt->operation, "length")) break + 9486 (string-equal? %ecx "length") # => eax + 9487 3d/compare-eax-and 0/imm32 + 9488 0f 84/jump-if-= break/disp32 + 9489 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc)) + 9490 e9/jump $emit-subx-stmt:end/disp32 + 9491 } + 9492 # index into array + 9493 { + 9494 # if (!string-equal?(stmt->operation, "index")) break + 9495 (string-equal? %ecx "index") # => eax + 9496 3d/compare-eax-and 0/imm32 + 9497 0f 84/jump-if-= break/disp32 + 9498 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc)) + 9499 e9/jump $emit-subx-stmt:end/disp32 + 9500 } + 9501 # compute-offset for index into array + 9502 { + 9503 # if (!string-equal?(stmt->operation, "compute-offset")) break + 9504 (string-equal? %ecx "compute-offset") # => eax + 9505 3d/compare-eax-and 0/imm32 + 9506 0f 84/jump-if-= break/disp32 + 9507 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc)) + 9508 e9/jump $emit-subx-stmt:end/disp32 + 9509 } + 9510 # get field from record + 9511 { + 9512 # if (!string-equal?(stmt->operation, "get")) break + 9513 (string-equal? %ecx "get") # => eax + 9514 3d/compare-eax-and 0/imm32 + 9515 0f 84/jump-if-= break/disp32 + 9516 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) + 9517 e9/jump $emit-subx-stmt:end/disp32 + 9518 } + 9519 # - if stmt matches a primitive, emit it + 9520 { + 9521 $emit-subx-stmt:check-for-primitive: + 9522 # var curr/eax: (addr primitive) + 9523 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax + 9524 3d/compare-eax-and 0/imm32 + 9525 74/jump-if-= break/disp8 + 9526 $emit-subx-stmt:primitive: + 9527 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr + 9528 e9/jump $emit-subx-stmt:end/disp32 + 9529 } + 9530 # - otherwise emit a call + 9531 # TODO: type-checking + 9532 $emit-subx-stmt:call: + 9533 (emit-call *(ebp+8) *(ebp+0xc)) + 9534 $emit-subx-stmt:end: + 9535 # . restore registers + 9536 59/pop-to-ecx + 9537 58/pop-to-eax + 9538 # . epilogue + 9539 89/<- %esp 5/r32/ebp + 9540 5d/pop-to-ebp + 9541 c3/return + 9542 + 9543 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt) + 9544 # . prologue + 9545 55/push-ebp + 9546 89/<- %ebp 4/r32/esp + 9547 # . save registers + 9548 50/push-eax + 9549 51/push-ecx + 9550 52/push-edx + 9551 53/push-ebx + 9552 56/push-esi + 9553 # esi = stmt + 9554 8b/-> *(ebp+0xc) 6/r32/esi + 9555 # var base/ebx: (addr var) = stmt->inouts[0]->value + 9556 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9557 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9558 89/<- %ebx 0/r32/eax + 9559 # var elemsize/ecx: int = element-size(base) + 9560 (array-element-type-id %ebx) # => eax + 9561 (size-of-type-id %eax) # => eax + 9562 89/<- %ecx 0/r32/eax + 9563 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register + 9564 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax + 9565 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9566 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax + 9567 89/<- %edx 0/r32/eax + 9568 # if elemsize == 1 + 9569 { + 9570 81 7/subop/compare %ecx 1/imm32 + 9571 75/jump-if-!= break/disp8 + 9572 (emit-save-size-to *(ebp+8) %ebx %edx) + 9573 e9/jump $translate-mu-length-stmt:end/disp32 + 9574 } + 9575 # if elemsize is a power of 2 less than 256 + 9576 { + 9577 (power-of-2? %ecx) # => eax + 9578 3d/compare-eax-and 0/imm32/false + 9579 74/jump-if-= break/disp8 + 9580 81 7/subop/compare %ecx 0xff/imm32 + 9581 7f/jump-if-> break/disp8 + 9582 (emit-save-size-to *(ebp+8) %ebx %edx) + 9583 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) + 9584 e9/jump $translate-mu-length-stmt:end/disp32 + 9585 } + 9586 # otherwise, the complex case + 9587 # . emit register spills + 9588 { + 9589 (string-equal? %edx "eax") # => eax + 9590 3d/compare-eax-and 0/imm32/false + 9591 75/break-if-!= break/disp8 + 9592 (emit-indent *(ebp+8) *Curr-block-depth) + 9593 (write-buffered *(ebp+8) "50/push-eax\n") + 9594 } + 9595 { + 9596 (string-equal? %edx "ecx") # => eax + 9597 3d/compare-eax-and 0/imm32/false + 9598 75/break-if-!= break/disp8 + 9599 (emit-indent *(ebp+8) *Curr-block-depth) + 9600 (write-buffered *(ebp+8) "51/push-ecx\n") + 9601 } + 9602 { + 9603 (string-equal? %edx "edx") # => eax + 9604 3d/compare-eax-and 0/imm32/false + 9605 75/break-if-!= break/disp8 + 9606 (emit-indent *(ebp+8) *Curr-block-depth) + 9607 (write-buffered *(ebp+8) "52/push-edx\n") + 9608 } + 9609 # . + 9610 (emit-save-size-to *(ebp+8) %ebx "eax") + 9611 (emit-indent *(ebp+8) *Curr-block-depth) + 9612 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") + 9613 (emit-indent *(ebp+8) *Curr-block-depth) + 9614 (write-buffered *(ebp+8) "b9/copy-to-ecx ") + 9615 (print-int32-buffered *(ebp+8) %ecx) + 9616 (write-buffered *(ebp+8) "/imm32\n") + 9617 (emit-indent *(ebp+8) *Curr-block-depth) + 9618 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") + 9619 { + 9620 (string-equal? %edx "eax") # => eax + 9621 3d/compare-eax-and 0/imm32/false + 9622 75/break-if-!= break/disp8 + 9623 (emit-indent *(ebp+8) *Curr-block-depth) + 9624 (write-buffered *(ebp+8) "89/<- %") + 9625 (write-buffered *(ebp+8) %edx) + 9626 (write-buffered *(ebp+8) " 0/r32/eax\n") + 9627 } + 9628 # . emit register restores + 9629 { + 9630 (string-equal? %edx "edx") # => eax + 9631 3d/compare-eax-and 0/imm32/false + 9632 75/break-if-!= break/disp8 + 9633 (emit-indent *(ebp+8) *Curr-block-depth) + 9634 (write-buffered *(ebp+8) "5a/pop-to-edx\n") + 9635 } + 9636 { + 9637 (string-equal? %edx "ecx") # => eax + 9638 3d/compare-eax-and 0/imm32/false + 9639 75/break-if-!= break/disp8 + 9640 (emit-indent *(ebp+8) *Curr-block-depth) + 9641 (write-buffered *(ebp+8) "59/pop-to-ecx\n") + 9642 } + 9643 { + 9644 (string-equal? %edx "eax") # => eax + 9645 3d/compare-eax-and 0/imm32/false + 9646 75/break-if-!= break/disp8 + 9647 (emit-indent *(ebp+8) *Curr-block-depth) + 9648 (write-buffered *(ebp+8) "58/pop-to-eax\n") + 9649 } + 9650 $translate-mu-length-stmt:end: + 9651 # . restore registers + 9652 5e/pop-to-esi + 9653 5b/pop-to-ebx + 9654 5a/pop-to-edx + 9655 59/pop-to-ecx + 9656 58/pop-to-eax + 9657 # . epilogue + 9658 89/<- %esp 5/r32/ebp + 9659 5d/pop-to-ebp + 9660 c3/return + 9661 + 9662 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) + 9663 # . prologue + 9664 55/push-ebp + 9665 89/<- %ebp 4/r32/esp + 9666 # . save registers + 9667 50/push-eax + 9668 53/push-ebx + 9669 # ebx = base + 9670 8b/-> *(ebp+0xc) 3/r32/ebx + 9671 (emit-indent *(ebp+8) *Curr-block-depth) + 9672 (write-buffered *(ebp+8) "8b/-> *") + 9673 # if base is an (addr array ...) in a register + 9674 { + 9675 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register + 9676 74/jump-if-= break/disp8 + 9677 $emit-save-size-to:emit-base-from-register: + 9678 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 9679 (write-buffered *(ebp+8) %eax) + 9680 eb/jump $emit-save-size-to:emit-output/disp8 + 9681 } + 9682 # otherwise if base is an (array ...) on the stack + 9683 { + 9684 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset + 9685 74/jump-if-= break/disp8 + 9686 $emit-save-size-to:emit-base-from-stack: + 9687 (write-buffered *(ebp+8) "(ebp+") + 9688 (print-int32-buffered *(ebp+8) *(ebx+0x14)) # Var-offset + 9689 (write-buffered *(ebp+8) ")") + 9690 } + 9691 $emit-save-size-to:emit-output: + 9692 (write-buffered *(ebp+8) " ") + 9693 (get Registers *(ebp+0x10) 0xc "Registers") # => eax + 9694 (print-int32-buffered *(ebp+8) *eax) + 9695 (write-buffered *(ebp+8) "/r32\n") + 9696 $emit-save-size-to:end: + 9697 # . restore registers + 9698 5b/pop-to-ebx + 9699 58/pop-to-eax + 9700 # . epilogue + 9701 89/<- %esp 5/r32/ebp + 9702 5d/pop-to-ebp + 9703 c3/return + 9704 + 9705 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int + 9706 # . prologue + 9707 55/push-ebp + 9708 89/<- %ebp 4/r32/esp + 9709 # . save registers + 9710 50/push-eax + 9711 # + 9712 (emit-indent *(ebp+8) *Curr-block-depth) + 9713 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") + 9714 (write-buffered *(ebp+8) *(ebp+0xc)) + 9715 (write-buffered *(ebp+8) Space) + 9716 (num-shift-rights *(ebp+0x10)) # => eax + 9717 (print-int32-buffered *(ebp+8) %eax) + 9718 (write-buffered *(ebp+8) "/imm8\n") + 9719 $emit-divide-by-shift-right:end: + 9720 # . restore registers + 9721 58/pop-to-eax + 9722 # . epilogue + 9723 89/<- %esp 5/r32/ebp + 9724 5d/pop-to-ebp + 9725 c3/return + 9726 + 9727 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt) + 9728 # . prologue + 9729 55/push-ebp + 9730 89/<- %ebp 4/r32/esp + 9731 # . save registers + 9732 51/push-ecx + 9733 # ecx = stmt + 9734 8b/-> *(ebp+0xc) 1/r32/ecx + 9735 # var base/ecx: (addr var) = stmt->inouts[0] + 9736 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9737 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9738 89/<- %ecx 0/r32/eax + 9739 # if (var->register) do one thing + 9740 { + 9741 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register + 9742 74/jump-if-= break/disp8 + 9743 # TODO: ensure there's no dereference + 9744 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc)) + 9745 eb/jump $translate-mu-index-stmt:end/disp8 + 9746 } + 9747 # if (var->offset) do a different thing + 9748 { + 9749 81 7/subop/compare *(ecx+0x14) 0/imm32 # Var-offset + 9750 74/jump-if-= break/disp8 + 9751 # TODO: ensure there's no dereference + 9752 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc)) + 9753 eb/jump $translate-mu-index-stmt:end/disp8 + 9754 } + 9755 $translate-mu-index-stmt:end: + 9756 # . restore registers + 9757 59/pop-to-ecx + 9758 # . epilogue + 9759 89/<- %esp 5/r32/ebp + 9760 5d/pop-to-ebp + 9761 c3/return + 9762 + 9763 $translate-mu-index-stmt-with-array:error1: + 9764 (write-buffered Stderr "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") + 9765 (flush Stderr) + 9766 # . syscall(exit, 1) + 9767 bb/copy-to-ebx 1/imm32 + 9768 b8/copy-to-eax 1/imm32/exit + 9769 cd/syscall 0x80/imm8 + 9770 # never gets here + 9771 + 9772 $translate-mu-index-stmt-with-array:error2: + 9773 (write-buffered Stderr "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") + 9774 (flush Stderr) + 9775 # . syscall(exit, 1) + 9776 bb/copy-to-ebx 1/imm32 + 9777 b8/copy-to-eax 1/imm32/exit + 9778 cd/syscall 0x80/imm8 + 9779 # never gets here + 9780 + 9781 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt) + 9782 # . prologue + 9783 55/push-ebp + 9784 89/<- %ebp 4/r32/esp + 9785 # . save registers + 9786 50/push-eax + 9787 51/push-ecx + 9788 52/push-edx + 9789 53/push-ebx + 9790 # + 9791 (emit-indent *(ebp+8) *Curr-block-depth) + 9792 (write-buffered *(ebp+8) "8d/copy-address *(") + 9793 # TODO: ensure inouts[0] is in a register and not dereferenced + 9794 $translate-mu-index-stmt-with-array-in-register:emit-base: + 9795 # ecx = stmt + 9796 8b/-> *(ebp+0xc) 1/r32/ecx + 9797 # var base/ebx: (addr var) = inouts[0] + 9798 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9799 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9800 89/<- %ebx 0/r32/eax + 9801 # print base->register " + " + 9802 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 9803 (write-buffered *(ebp+8) %eax) + 9804 (write-buffered *(ebp+8) " + ") + 9805 # var index/edx: (addr var) = inouts[1] + 9806 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9807 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax + 9808 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9809 89/<- %edx 0/r32/eax + 9810 # if index->register + 9811 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register + 9812 { + 9813 0f 84/jump-if-= break/disp32 + 9814 $translate-mu-index-stmt-with-array-in-register:emit-register-index: + 9815 # if index is an int + 9816 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9817 (is-simple-mu-type? %eax 1) # int => eax + 9818 3d/compare-eax-and 0/imm32/false + 9819 { + 9820 0f 84/jump-if-= break/disp32 + 9821 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: + 9822 # print index->register "<<" log2(size-of(element(base->type))) " + 4) " + 9823 # . index->register "<<" + 9824 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 9825 (write-buffered *(ebp+8) %eax) + 9826 (write-buffered *(ebp+8) "<<") + 9827 # . log2(size-of(element(base->type))) + 9828 # TODO: ensure size is a power of 2 + 9829 (array-element-type-id %ebx) # => eax + 9830 (size-of-type-id %eax) # => eax + 9831 (num-shift-rights %eax) # => eax + 9832 (print-int32-buffered *(ebp+8) %eax) + 9833 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 + 9834 } + 9835 # if index->type is any other atom, abort + 9836 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9837 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom + 9838 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 + 9839 # if index has type (offset ...) + 9840 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax + 9841 (is-simple-mu-type? %eax 7) # => eax + 9842 3d/compare-eax-and 0/imm32/false + 9843 { + 9844 0f 84/jump-if-= break/disp32 + 9845 # print index->register + 9846 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: + 9847 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 9848 (write-buffered *(ebp+8) %eax) + 9849 } + 9850 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: + 9851 (write-buffered *(ebp+8) " + 4) ") + 9852 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 + 9853 } + 9854 # otherwise if index is a literal + 9855 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9856 (is-simple-mu-type? %eax 0) # => eax + 9857 3d/compare-eax-and 0/imm32/false + 9858 { + 9859 0f 84/jump-if-= break/disp32 + 9860 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: + 9861 # var index-value/edx: int = parse-hex-int(index->name) + 9862 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 9863 (parse-hex-int %eax) # => eax + 9864 89/<- %edx 0/r32/eax + 9865 # offset = idx-value * size-of(element(base->type)) + 9866 (array-element-type-id %ebx) # => eax + 9867 (size-of-type-id %eax) # => eax + 9868 f7 4/subop/multiply-into-eax %edx # clobbers edx + 9869 # offset += 4 for array size + 9870 05/add-to-eax 4/imm32 + 9871 # TODO: check edx for overflow + 9872 # print offset + 9873 (print-int32-buffered *(ebp+8) %eax) + 9874 (write-buffered *(ebp+8) ") ") + 9875 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 + 9876 } + 9877 # otherwise abort + 9878 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 + 9879 $translate-mu-index-stmt-with-array-in-register:emit-output: + 9880 # outputs[0] "/r32" + 9881 8b/-> *(ebp+0xc) 1/r32/ecx + 9882 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax + 9883 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9884 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax + 9885 (get Registers %eax 0xc "Registers") # => eax: (addr int) + 9886 (print-int32-buffered *(ebp+8) *eax) + 9887 (write-buffered *(ebp+8) "/r32\n") + 9888 $translate-mu-index-stmt-with-array-in-register:end: + 9889 # . restore registers + 9890 5b/pop-to-ebx + 9891 5a/pop-to-edx + 9892 59/pop-to-ecx + 9893 58/pop-to-eax + 9894 # . epilogue + 9895 89/<- %esp 5/r32/ebp + 9896 5d/pop-to-ebp + 9897 c3/return + 9898 + 9899 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt) + 9900 # . prologue + 9901 55/push-ebp + 9902 89/<- %ebp 4/r32/esp + 9903 # . save registers + 9904 50/push-eax + 9905 51/push-ecx + 9906 52/push-edx + 9907 53/push-ebx + 9908 # + 9909 (emit-indent *(ebp+8) *Curr-block-depth) + 9910 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") + 9911 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) + 9912 8b/-> *(ebp+0xc) 0/r32/eax + 9913 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9914 89/<- %edx 0/r32/eax + 9915 # var base/ecx: (addr var) = lookup(curr->value) + 9916 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9917 89/<- %ecx 0/r32/eax + 9918 # var curr2/eax: (addr stmt-var) = lookup(curr->next) + 9919 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax + 9920 # var index/edx: (handle var) = curr2->value + 9921 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9922 89/<- %edx 0/r32/eax + 9923 # if index->register + 9924 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register + 9925 { + 9926 0f 84/jump-if-= break/disp32 + 9927 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: + 9928 # if index is an int + 9929 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9930 (is-simple-mu-type? %eax 1) # int => eax + 9931 3d/compare-eax-and 0/imm32/false + 9932 { + 9933 0f 84/jump-if-= break/disp32 + 9934 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: + 9935 # print index->register "<<" log2(size-of(element-type(base))) " + " base->offset+4 + 9936 # . inouts[1]->register "<<" + 9937 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 9938 (write-buffered *(ebp+8) %eax) + 9939 (write-buffered *(ebp+8) "<<") + 9940 # . log2(size-of(element(base))) + 9941 # TODO: ensure size is a power of 2 + 9942 (array-element-type-id %ecx) # => eax + 9943 (size-of-type-id %eax) # => eax + 9944 (num-shift-rights %eax) # => eax + 9945 (print-int32-buffered *(ebp+8) %eax) + 9946 # + 9947 (write-buffered *(ebp+8) " + ") + 9948 # + 9949 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset + 9950 05/add-to-eax 4/imm32 # for array length + 9951 (print-int32-buffered *(ebp+8) %eax) + 9952 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 + 9953 } + 9954 # if index->type is any other atom, abort + 9955 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9956 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom + 9957 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 + 9958 # if index has type (offset ...) + 9959 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax + 9960 (is-simple-mu-type? %eax 7) # => eax + 9961 3d/compare-eax-and 0/imm32/false + 9962 { + 9963 0f 84/jump-if-= break/disp32 + 9964 # print index->register + 9965 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: + 9966 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 9967 (write-buffered *(ebp+8) %eax) + 9968 } + 9969 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: + 9970 (write-buffered *(ebp+8) ") ") + 9971 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 + 9972 } + 9973 # otherwise if index is a literal + 9974 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9975 (is-simple-mu-type? %eax 0) # => eax + 9976 3d/compare-eax-and 0/imm32/false + 9977 { + 9978 0f 84/jump-if-= break/disp32 + 9979 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: + 9980 # var idx-value/edx: int = parse-hex-int(index->name) + 9981 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 9982 (parse-hex-int %eax) # Var-name => eax + 9983 89/<- %edx 0/r32/eax + 9984 # offset = idx-value * size-of(element-type(base->type)) + 9985 (array-element-type-id %ecx) # => eax + 9986 (size-of-type-id %eax) # => eax + 9987 f7 4/subop/multiply-into-eax %edx # clobbers edx + 9988 # offset += base->offset + 9989 03/add *(ecx+0x14) 0/r32/eax # Var-offset + 9990 # offset += 4 for array size + 9991 05/add-to-eax 4/imm32 + 9992 # TODO: check edx for overflow + 9993 # print offset + 9994 (print-int32-buffered *(ebp+8) %eax) + 9995 (write-buffered *(ebp+8) ") ") + 9996 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 + 9997 } + 9998 # otherwise abort + 9999 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 +10000 $translate-mu-index-stmt-with-array-on-stack:emit-output: +10001 # outputs[0] "/r32" +10002 8b/-> *(ebp+0xc) 0/r32/eax +10003 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax +10004 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10005 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +10006 (get Registers %eax 0xc "Registers") # => eax: (addr int) +10007 (print-int32-buffered *(ebp+8) *eax) +10008 (write-buffered *(ebp+8) "/r32\n") +10009 $translate-mu-index-stmt-with-array-on-stack:end: +10010 # . restore registers +10011 5b/pop-to-ebx +10012 5a/pop-to-edx +10013 59/pop-to-ecx +10014 58/pop-to-eax +10015 # . epilogue +10016 89/<- %esp 5/r32/ebp +10017 5d/pop-to-ebp +10018 c3/return +10019 +10020 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt) +10021 # . prologue +10022 55/push-ebp +10023 89/<- %ebp 4/r32/esp +10024 # . save registers +10025 50/push-eax +10026 51/push-ecx +10027 52/push-edx +10028 53/push-ebx +10029 # +10030 (emit-indent *(ebp+8) *Curr-block-depth) +10031 (write-buffered *(ebp+8) "69/multiply") +10032 # ecx = stmt +10033 8b/-> *(ebp+0xc) 1/r32/ecx +10034 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] +10035 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +10036 89/<- %ebx 0/r32/eax +10037 $translate-mu-compute-index-stmt:emit-index: +10038 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax +10039 (emit-subx-var-as-rm32 *(ebp+8) %eax) +10040 (write-buffered *(ebp+8) Space) +10041 $translate-mu-compute-index-stmt:emit-elem-size: +10042 # var base/ebx: (addr var) +10043 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax +10044 89/<- %ebx 0/r32/eax +10045 # print size-of(element(base->type)) +10046 (array-element-type-id %ebx) # => eax +10047 (size-of-type-id %eax) # => eax +10048 (print-int32-buffered *(ebp+8) %eax) +10049 (write-buffered *(ebp+8) "/imm32 ") +10050 $translate-mu-compute-index-stmt:emit-output: +10051 # outputs[0] "/r32" +10052 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +10053 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10054 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +10055 (get Registers %eax 0xc "Registers") # => eax: (addr int) +10056 (print-int32-buffered *(ebp+8) *eax) +10057 (write-buffered *(ebp+8) "/r32\n") +10058 $translate-mu-compute-index-stmt:end: +10059 # . restore registers +10060 5b/pop-to-ebx +10061 5a/pop-to-edx +10062 59/pop-to-ecx +10063 58/pop-to-eax +10064 # . epilogue +10065 89/<- %esp 5/r32/ebp +10066 5d/pop-to-ebp +10067 c3/return +10068 +10069 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) +10070 # . prologue +10071 55/push-ebp +10072 89/<- %ebp 4/r32/esp +10073 # . save registers +10074 50/push-eax +10075 51/push-ecx +10076 52/push-edx +10077 # +10078 (emit-indent *(ebp+8) *Curr-block-depth) +10079 (write-buffered *(ebp+8) "8d/copy-address ") +10080 # ecx = stmt +10081 8b/-> *(ebp+0xc) 1/r32/ecx +10082 # var offset/edx: int = get offset of stmt +10083 (mu-get-offset %ecx) # => eax +10084 89/<- %edx 0/r32/eax +10085 # var base/eax: (addr var) = stmt->inouts->value +10086 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +10087 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10088 # if base is in a register +10089 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +10090 { +10091 0f 84/jump-if-= break/disp32 +10092 $translate-mu-get-stmt:emit-register-input: +10093 # emit "*(" base->register " + " offset ") " +10094 (write-buffered *(ebp+8) "*(") +10095 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +10096 (write-buffered *(ebp+8) %eax) +10097 (write-buffered *(ebp+8) " + ") +10098 (print-int32-buffered *(ebp+8) %edx) +10099 (write-buffered *(ebp+8) ") ") +10100 e9/jump $translate-mu-get-stmt:emit-output/disp32 +10101 } +10102 # otherwise base is on the stack +10103 { +10104 $translate-mu-get-stmt:emit-stack-input: +10105 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " +10106 (write-buffered *(ebp+8) "*(ebp+") +10107 03/add *(eax+0x14) 2/r32/edx # Var-offset +10108 (print-int32-buffered *(ebp+8) %edx) +10109 (write-buffered *(ebp+8) ") ") +10110 eb/jump $translate-mu-get-stmt:emit-output/disp8 +10111 } +10112 $translate-mu-get-stmt:emit-output: +10113 # var output/eax: (addr var) = stmt->outputs->value +10114 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +10115 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10116 # emit offset->register "/r32" +10117 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +10118 (get Registers %eax 0xc "Registers") # => eax: (addr int) +10119 (print-int32-buffered *(ebp+8) *eax) +10120 (write-buffered *(ebp+8) "/r32\n") +10121 $translate-mu-get-stmt:end: +10122 # . restore registers +10123 5a/pop-to-edx +10124 59/pop-to-ecx +10125 58/pop-to-eax +10126 # . epilogue +10127 89/<- %esp 5/r32/ebp +10128 5d/pop-to-ebp +10129 c3/return +10130 +10131 array-element-type-id: # v: (addr var) -> result/eax: type-id +10132 # precondition: n is positive +10133 # . prologue +10134 55/push-ebp +10135 89/<- %ebp 4/r32/esp +10136 # +10137 8b/-> *(ebp+8) 0/r32/eax +10138 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +10139 # TODO: ensure type->left is 'addr' +10140 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax +10141 # TODO: ensure that type->right is non-null +10142 # TODO: ensure that type->right->left is 'array' +10143 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax +10144 # TODO: ensure that type->right->right is non-null +10145 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +10146 8b/-> *(eax+4) 0/r32/eax # Tree-value +10147 $array-element-type-id:end: +10148 # . epilogue +10149 89/<- %esp 5/r32/ebp +10150 5d/pop-to-ebp +10151 c3/return +10152 +10153 power-of-2?: # n: int -> result/eax: boolean +10154 # precondition: n is positive +10155 # . prologue +10156 55/push-ebp +10157 89/<- %ebp 4/r32/esp +10158 # eax = n +10159 8b/-> *(ebp+8) 0/r32/eax +10160 # if (n < 0) abort +10161 3d/compare-eax-with 0/imm32 +10162 0f 8c/jump-if-< $power-of-2?:abort/disp32 +10163 # var tmp/eax: int = n-1 +10164 48/decrement-eax +10165 # var tmp2/eax: int = n & tmp +10166 23/and-> *(ebp+8) 0/r32/eax +10167 # return (tmp2 == 0) +10168 3d/compare-eax-and 0/imm32 +10169 0f 94/set-byte-if-= %al +10170 81 4/subop/and %eax 0xff/imm32 +10171 $power-of-2?:end: +10172 # . epilogue +10173 89/<- %esp 5/r32/ebp +10174 5d/pop-to-ebp +10175 c3/return +10176 +10177 $power-of-2?:abort: +10178 (write-buffered Stderr "power-of-2?: negative number\n") +10179 (flush Stderr) +10180 # . syscall(exit, 1) +10181 bb/copy-to-ebx 1/imm32 +10182 b8/copy-to-eax 1/imm32/exit +10183 cd/syscall 0x80/imm8 +10184 # never gets here +10185 +10186 num-shift-rights: # n: int -> result/eax: int +10187 # precondition: n is a positive power of 2 +10188 # . prologue +10189 55/push-ebp +10190 89/<- %ebp 4/r32/esp +10191 # . save registers +10192 51/push-ecx +10193 # var curr/ecx: int = n +10194 8b/-> *(ebp+8) 1/r32/ecx +10195 # result = 0 +10196 b8/copy-to-eax 0/imm32 +10197 { +10198 # if (curr <= 1) break +10199 81 7/subop/compare %ecx 1/imm32 +10200 7e/jump-if-<= break/disp8 +10201 40/increment-eax +10202 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 +10203 eb/jump loop/disp8 +10204 } +10205 $num-shift-rights:end: +10206 # . restore registers +10207 59/pop-to-ecx +10208 # . epilogue +10209 89/<- %esp 5/r32/ebp +10210 5d/pop-to-ebp +10211 c3/return +10212 +10213 mu-get-offset: # stmt: (addr stmt) -> result/eax: int +10214 # . prologue +10215 55/push-ebp +10216 89/<- %ebp 4/r32/esp +10217 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next +10218 8b/-> *(ebp+8) 0/r32/eax +10219 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +10220 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +10221 # var output-var/eax: (addr var) = second-inout->value +10222 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10223 #? (write-buffered Stderr "mu-get-offset: ") +10224 #? (print-int32-buffered Stderr %eax) +10225 #? (write-buffered Stderr " name: ") +10226 #? 50/push-eax +10227 #? (lookup *eax *(eax+4)) # Var-name +10228 #? (write-buffered Stderr %eax) +10229 #? 58/pop-to-eax +10230 #? (write-buffered Stderr Newline) +10231 #? (flush Stderr) +10232 # return output-var->stack-offset +10233 8b/-> *(eax+0x14) 0/r32/eax # Var-offset +10234 #? (write-buffered Stderr "=> ") +10235 #? (print-int32-buffered Stderr %eax) +10236 #? (write-buffered Stderr Newline) +10237 #? (flush Stderr) +10238 $emit-get-offset:end: +10239 # . epilogue +10240 89/<- %esp 5/r32/ebp +10241 5d/pop-to-ebp +10242 c3/return +10243 +10244 emit-subx-block: # out: (addr buffered-file), block: (addr block), vars: (addr stack live-var), fn-outputs: (addr list var) +10245 # . prologue +10246 55/push-ebp +10247 89/<- %ebp 4/r32/esp +10248 # . save registers +10249 50/push-eax +10250 51/push-ecx +10251 56/push-esi +10252 # esi = block +10253 8b/-> *(ebp+0xc) 6/r32/esi +10254 # block->var->block-depth = *Curr-block-depth +10255 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +10256 8b/-> *Curr-block-depth 1/r32/ecx +10257 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth +10258 # var stmts/eax: (addr list stmt) = lookup(block->statements) +10259 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +10260 # +10261 { +10262 $emit-subx-block:check-empty: +10263 3d/compare-eax-and 0/imm32 +10264 0f 84/jump-if-= break/disp32 +10265 (emit-indent *(ebp+8) *Curr-block-depth) +10266 (write-buffered *(ebp+8) "{\n") +10267 # var v/ecx: (addr var) = lookup(block->var) +10268 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +10269 89/<- %ecx 0/r32/eax +10270 # +10271 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +10272 (write-buffered *(ebp+8) %eax) +10273 (write-buffered *(ebp+8) ":loop:\n") +10274 ff 0/subop/increment *Curr-block-depth +10275 (push *(ebp+0x10) *(esi+0xc)) # Block-var +10276 (push *(ebp+0x10) *(esi+0x10)) # Block-var +10277 (push *(ebp+0x10) 0) # false +10278 # emit block->statements +10279 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +10280 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14)) +10281 (pop *(ebp+0x10)) # => eax +10282 (pop *(ebp+0x10)) # => eax +10283 (pop *(ebp+0x10)) # => eax +10284 ff 1/subop/decrement *Curr-block-depth +10285 (emit-indent *(ebp+8) *Curr-block-depth) +10286 (write-buffered *(ebp+8) "}\n") +10287 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +10288 (write-buffered *(ebp+8) %eax) +10289 (write-buffered *(ebp+8) ":break:\n") +10290 } +10291 $emit-subx-block:end: +10292 # . restore registers +10293 5e/pop-to-esi +10294 59/pop-to-ecx +10295 58/pop-to-eax +10296 # . epilogue +10297 89/<- %esp 5/r32/ebp +10298 5d/pop-to-ebp +10299 c3/return +10300 +10301 # Primitives supported +10302 # See mu_instructions for a summary of this linked-list data structure. +10303 # +10304 # For each operation, put variants with hard-coded registers before flexible ones. +10305 # +10306 # Unfortunately, our restrictions on addresses require that various fields in +10307 # primitives be handles, which complicates these definitions. +10308 # - we need to insert dummy fields all over the place for fake alloc-ids +10309 # - we can't use our syntax sugar of quoted literals for string fields +10310 # +10311 # Fake alloc-ids are needed because our type definitions up top require +10312 # handles but it's clearer to statically allocate these long-lived objects. +10313 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. +10314 # +10315 # Every 'object' below starts with a fake alloc-id. It may also contain other +10316 # fake alloc-ids for various handle fields. +10317 # +10318 # I think of objects starting with a fake alloc-id as having type 'payload'. +10319 # It's not really intended to be created dynamically; for that use `allocate` +10320 # as usual. +10321 # +10322 # Idea for a notation to simplify such definitions: +10323 # _Primitive-increment-eax: # (payload primitive) +10324 # 0x11/alloc-id:fake:payload +10325 # 0x11 @(0x11 "increment") # name +10326 # 0 0 # inouts +10327 # 0x11 @(0x11/payload +10328 # 0x11 @(0x11/payload # List-value +10329 # 0 0 # Var-name +10330 # 0x11 @(0x11 # Var-type +10331 # 1/is-atom +10332 # 1/value 0/unused # Tree-left +10333 # 0 0 # Tree-right +10334 # ) +10335 # 1 # block-depth +10336 # 0 # stack-offset +10337 # 0x11 @(0x11 "eax") # Var-register +10338 # ) +10339 # 0 0) # List-next +10340 # ... +10341 # _Primitive-increment-ecx/imm32/next +10342 # ... +10343 # Awfully complex and non-obvious. But also clearly signals there's something +10344 # to learn here, so may be worth trying. +10345 # +10346 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " +10347 # +10348 # For now we'll continue to just use comments and manually ensure they stay up +10349 # to date. +10350 == data +10351 Primitives: # (addr primitive) +10352 # - increment/decrement +10353 _Primitive-increment-eax: # (addr primitive) +10354 # var/eax <- increment => 40/increment-eax +10355 0x11/imm32/alloc-id:fake +10356 _string-increment/imm32/name +10357 0/imm32/no-inouts +10358 0/imm32/no-inouts +10359 0x11/imm32/alloc-id:fake +10360 Single-int-var-in-eax/imm32/outputs +10361 0x11/imm32/alloc-id:fake +10362 _string_40_increment_eax/imm32/subx-name +10363 0/imm32/no-rm32 +10364 0/imm32/no-r32 +10365 0/imm32/no-imm32 +10366 0/imm32/no-disp32 +10367 0/imm32/output-is-write-only +10368 0x11/imm32/alloc-id:fake +10369 _Primitive-increment-ecx/imm32/next +10370 _Primitive-increment-ecx: # (payload primitive) +10371 0x11/imm32/alloc-id:fake:payload +10372 # var/ecx <- increment => 41/increment-ecx +10373 0x11/imm32/alloc-id:fake +10374 _string-increment/imm32/name +10375 0/imm32/no-inouts +10376 0/imm32/no-inouts +10377 0x11/imm32/alloc-id:fake +10378 Single-int-var-in-ecx/imm32/outputs +10379 0x11/imm32/alloc-id:fake +10380 _string_41_increment_ecx/imm32/subx-name +10381 0/imm32/no-rm32 +10382 0/imm32/no-r32 +10383 0/imm32/no-imm32 +10384 0/imm32/no-disp32 +10385 0/imm32/output-is-write-only +10386 0x11/imm32/alloc-id:fake +10387 _Primitive-increment-edx/imm32/next +10388 _Primitive-increment-edx: # (payload primitive) +10389 0x11/imm32/alloc-id:fake:payload +10390 # var/edx <- increment => 42/increment-edx +10391 0x11/imm32/alloc-id:fake +10392 _string-increment/imm32/name +10393 0/imm32/no-inouts +10394 0/imm32/no-inouts +10395 0x11/imm32/alloc-id:fake +10396 Single-int-var-in-edx/imm32/outputs +10397 0x11/imm32/alloc-id:fake +10398 _string_42_increment_edx/imm32/subx-name +10399 0/imm32/no-rm32 +10400 0/imm32/no-r32 +10401 0/imm32/no-imm32 +10402 0/imm32/no-disp32 +10403 0/imm32/output-is-write-only +10404 0x11/imm32/alloc-id:fake +10405 _Primitive-increment-ebx/imm32/next +10406 _Primitive-increment-ebx: # (payload primitive) +10407 0x11/imm32/alloc-id:fake:payload +10408 # var/ebx <- increment => 43/increment-ebx +10409 0x11/imm32/alloc-id:fake +10410 _string-increment/imm32/name +10411 0/imm32/no-inouts +10412 0/imm32/no-inouts +10413 0x11/imm32/alloc-id:fake +10414 Single-int-var-in-ebx/imm32/outputs +10415 0x11/imm32/alloc-id:fake +10416 _string_43_increment_ebx/imm32/subx-name +10417 0/imm32/no-rm32 +10418 0/imm32/no-r32 +10419 0/imm32/no-imm32 +10420 0/imm32/no-disp32 +10421 0/imm32/output-is-write-only 10422 0x11/imm32/alloc-id:fake -10423 Single-int-var-in-eax/imm32/outputs -10424 0x11/imm32/alloc-id:fake -10425 _string_25_and_with_eax/imm32/subx-name -10426 0/imm32/no-rm32 -10427 0/imm32/no-r32 -10428 1/imm32/imm32-is-first-inout -10429 0/imm32/no-disp32 -10430 0/imm32/output-is-write-only +10423 _Primitive-increment-esi/imm32/next +10424 _Primitive-increment-esi: # (payload primitive) +10425 0x11/imm32/alloc-id:fake:payload +10426 # var/esi <- increment => 46/increment-esi +10427 0x11/imm32/alloc-id:fake +10428 _string-increment/imm32/name +10429 0/imm32/no-inouts +10430 0/imm32/no-inouts 10431 0x11/imm32/alloc-id:fake -10432 _Primitive-and-reg-with-reg/imm32/next -10433 _Primitive-and-reg-with-reg: # (payload primitive) -10434 0x11/imm32/alloc-id:fake:payload -10435 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 -10436 0x11/imm32/alloc-id:fake -10437 _string-and/imm32/name -10438 0x11/imm32/alloc-id:fake -10439 Single-int-var-in-some-register/imm32/inouts +10432 Single-int-var-in-esi/imm32/outputs +10433 0x11/imm32/alloc-id:fake +10434 _string_46_increment_esi/imm32/subx-name +10435 0/imm32/no-rm32 +10436 0/imm32/no-r32 +10437 0/imm32/no-imm32 +10438 0/imm32/no-disp32 +10439 0/imm32/output-is-write-only 10440 0x11/imm32/alloc-id:fake -10441 Single-int-var-in-some-register/imm32/outputs -10442 0x11/imm32/alloc-id:fake -10443 _string_21_and_with/imm32/subx-name -10444 3/imm32/rm32-is-first-output -10445 1/imm32/r32-is-first-inout -10446 0/imm32/no-imm32 -10447 0/imm32/no-disp32 -10448 0/imm32/output-is-write-only +10441 _Primitive-increment-edi/imm32/next +10442 _Primitive-increment-edi: # (payload primitive) +10443 0x11/imm32/alloc-id:fake:payload +10444 # var/edi <- increment => 47/increment-edi +10445 0x11/imm32/alloc-id:fake +10446 _string-increment/imm32/name +10447 0/imm32/no-inouts +10448 0/imm32/no-inouts 10449 0x11/imm32/alloc-id:fake -10450 _Primitive-and-reg-with-mem/imm32/next -10451 _Primitive-and-reg-with-mem: # (payload primitive) -10452 0x11/imm32/alloc-id:fake:payload -10453 # and-with var1 var2/reg => 21/and-with var1 var2/r32 -10454 0x11/imm32/alloc-id:fake -10455 _string-and-with/imm32/name -10456 0x11/imm32/alloc-id:fake -10457 Two-args-int-stack-int-reg/imm32/inouts -10458 0/imm32/no-outputs -10459 0/imm32/no-outputs -10460 0x11/imm32/alloc-id:fake -10461 _string_21_and_with/imm32/subx-name -10462 1/imm32/rm32-is-first-inout -10463 2/imm32/r32-is-second-inout -10464 0/imm32/no-imm32 -10465 0/imm32/no-disp32 -10466 0/imm32/output-is-write-only +10450 Single-int-var-in-edi/imm32/outputs +10451 0x11/imm32/alloc-id:fake +10452 _string_47_increment_edi/imm32/subx-name +10453 0/imm32/no-rm32 +10454 0/imm32/no-r32 +10455 0/imm32/no-imm32 +10456 0/imm32/no-disp32 +10457 0/imm32/output-is-write-only +10458 0x11/imm32/alloc-id:fake +10459 _Primitive-decrement-eax/imm32/next +10460 _Primitive-decrement-eax: # (payload primitive) +10461 0x11/imm32/alloc-id:fake:payload +10462 # var/eax <- decrement => 48/decrement-eax +10463 0x11/imm32/alloc-id:fake +10464 _string-decrement/imm32/name +10465 0/imm32/no-inouts +10466 0/imm32/no-inouts 10467 0x11/imm32/alloc-id:fake -10468 _Primitive-and-mem-with-reg/imm32/next -10469 _Primitive-and-mem-with-reg: # (payload primitive) -10470 0x11/imm32/alloc-id:fake:payload -10471 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 -10472 0x11/imm32/alloc-id:fake -10473 _string-and/imm32/name -10474 0x11/imm32/alloc-id:fake -10475 Single-int-var-in-mem/imm32/inouts +10468 Single-int-var-in-eax/imm32/outputs +10469 0x11/imm32/alloc-id:fake +10470 _string_48_decrement_eax/imm32/subx-name +10471 0/imm32/no-rm32 +10472 0/imm32/no-r32 +10473 0/imm32/no-imm32 +10474 0/imm32/no-disp32 +10475 0/imm32/output-is-write-only 10476 0x11/imm32/alloc-id:fake -10477 Single-int-var-in-some-register/imm32/outputs -10478 0x11/imm32/alloc-id:fake -10479 _string_23_and/imm32/subx-name -10480 1/imm32/rm32-is-first-inout -10481 3/imm32/r32-is-first-output -10482 0/imm32/no-imm32 -10483 0/imm32/no-disp32 -10484 0/imm32/output-is-write-only +10477 _Primitive-decrement-ecx/imm32/next +10478 _Primitive-decrement-ecx: # (payload primitive) +10479 0x11/imm32/alloc-id:fake:payload +10480 # var/ecx <- decrement => 49/decrement-ecx +10481 0x11/imm32/alloc-id:fake +10482 _string-decrement/imm32/name +10483 0/imm32/no-inouts +10484 0/imm32/no-inouts 10485 0x11/imm32/alloc-id:fake -10486 _Primitive-and-lit-with-reg/imm32/next -10487 _Primitive-and-lit-with-reg: # (payload primitive) -10488 0x11/imm32/alloc-id:fake:payload -10489 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 -10490 0x11/imm32/alloc-id:fake -10491 _string-and/imm32/name -10492 0x11/imm32/alloc-id:fake -10493 Single-lit-var/imm32/inouts +10486 Single-int-var-in-ecx/imm32/outputs +10487 0x11/imm32/alloc-id:fake +10488 _string_49_decrement_ecx/imm32/subx-name +10489 0/imm32/no-rm32 +10490 0/imm32/no-r32 +10491 0/imm32/no-imm32 +10492 0/imm32/no-disp32 +10493 0/imm32/output-is-write-only 10494 0x11/imm32/alloc-id:fake -10495 Single-int-var-in-some-register/imm32/outputs -10496 0x11/imm32/alloc-id:fake -10497 _string_81_subop_and/imm32/subx-name -10498 3/imm32/rm32-is-first-output -10499 0/imm32/no-r32 -10500 1/imm32/imm32-is-first-inout -10501 0/imm32/no-disp32 -10502 0/imm32/output-is-write-only +10495 _Primitive-decrement-edx/imm32/next +10496 _Primitive-decrement-edx: # (payload primitive) +10497 0x11/imm32/alloc-id:fake:payload +10498 # var/edx <- decrement => 4a/decrement-edx +10499 0x11/imm32/alloc-id:fake +10500 _string-decrement/imm32/name +10501 0/imm32/no-inouts +10502 0/imm32/no-inouts 10503 0x11/imm32/alloc-id:fake -10504 _Primitive-and-lit-with-mem/imm32/next -10505 _Primitive-and-lit-with-mem: # (payload primitive) -10506 0x11/imm32/alloc-id:fake:payload -10507 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 -10508 0x11/imm32/alloc-id:fake -10509 _string-and-with/imm32/name -10510 0x11/imm32/alloc-id:fake -10511 Int-var-and-literal/imm32/inouts -10512 0/imm32/no-outputs -10513 0/imm32/no-outputs -10514 0x11/imm32/alloc-id:fake -10515 _string_81_subop_and/imm32/subx-name -10516 1/imm32/rm32-is-first-inout -10517 0/imm32/no-r32 -10518 2/imm32/imm32-is-first-inout -10519 0/imm32/no-disp32 -10520 0/imm32/output-is-write-only +10504 Single-int-var-in-edx/imm32/outputs +10505 0x11/imm32/alloc-id:fake +10506 _string_4a_decrement_edx/imm32/subx-name +10507 0/imm32/no-rm32 +10508 0/imm32/no-r32 +10509 0/imm32/no-imm32 +10510 0/imm32/no-disp32 +10511 0/imm32/output-is-write-only +10512 0x11/imm32/alloc-id:fake +10513 _Primitive-decrement-ebx/imm32/next +10514 _Primitive-decrement-ebx: # (payload primitive) +10515 0x11/imm32/alloc-id:fake:payload +10516 # var/ebx <- decrement => 4b/decrement-ebx +10517 0x11/imm32/alloc-id:fake +10518 _string-decrement/imm32/name +10519 0/imm32/no-inouts +10520 0/imm32/no-inouts 10521 0x11/imm32/alloc-id:fake -10522 _Primitive-or-with-eax/imm32/next -10523 # - or -10524 _Primitive-or-with-eax: # (payload primitive) -10525 0x11/imm32/alloc-id:fake:payload -10526 # var/eax <- or lit => 0d/or-with-eax lit/imm32 -10527 0x11/imm32/alloc-id:fake -10528 _string-or/imm32/name -10529 0x11/imm32/alloc-id:fake -10530 Single-lit-var/imm32/inouts -10531 0x11/imm32/alloc-id:fake -10532 Single-int-var-in-eax/imm32/outputs -10533 0x11/imm32/alloc-id:fake -10534 _string_0d_or_with_eax/imm32/subx-name -10535 0/imm32/no-rm32 -10536 0/imm32/no-r32 -10537 1/imm32/imm32-is-first-inout -10538 0/imm32/no-disp32 -10539 0/imm32/output-is-write-only -10540 0x11/imm32/alloc-id:fake -10541 _Primitive-or-reg-with-reg/imm32/next -10542 _Primitive-or-reg-with-reg: # (payload primitive) -10543 0x11/imm32/alloc-id:fake:payload -10544 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 -10545 0x11/imm32/alloc-id:fake -10546 _string-or/imm32/name -10547 0x11/imm32/alloc-id:fake -10548 Single-int-var-in-some-register/imm32/inouts -10549 0x11/imm32/alloc-id:fake -10550 Single-int-var-in-some-register/imm32/outputs -10551 0x11/imm32/alloc-id:fake -10552 _string_09_or_with/imm32/subx-name -10553 3/imm32/rm32-is-first-output -10554 1/imm32/r32-is-first-inout -10555 0/imm32/no-imm32 -10556 0/imm32/no-disp32 -10557 0/imm32/output-is-write-only -10558 0x11/imm32/alloc-id:fake -10559 _Primitive-or-reg-with-mem/imm32/next -10560 _Primitive-or-reg-with-mem: # (payload primitive) -10561 0x11/imm32/alloc-id:fake:payload -10562 # or-with var1 var2/reg => 09/or-with var1 var2/r32 -10563 0x11/imm32/alloc-id:fake -10564 _string-or-with/imm32/name -10565 0x11/imm32/alloc-id:fake -10566 Two-args-int-stack-int-reg/imm32/inouts -10567 0/imm32/no-outputs -10568 0/imm32/no-outputs -10569 0x11/imm32/alloc-id:fake -10570 _string_09_or_with/imm32/subx-name -10571 1/imm32/rm32-is-first-inout -10572 2/imm32/r32-is-second-inout -10573 0/imm32/no-imm32 -10574 0/imm32/no-disp32 -10575 0/imm32/output-is-write-only -10576 0x11/imm32/alloc-id:fake -10577 _Primitive-or-mem-with-reg/imm32/next -10578 _Primitive-or-mem-with-reg: # (payload primitive) -10579 0x11/imm32/alloc-id:fake:payload -10580 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 -10581 0x11/imm32/alloc-id:fake -10582 _string-or/imm32/name -10583 0x11/imm32/alloc-id:fake -10584 Single-int-var-in-mem/imm32/inouts -10585 0x11/imm32/alloc-id:fake -10586 Single-int-var-in-some-register/imm32/outputs -10587 0x11/imm32/alloc-id:fake -10588 _string_0b_or/imm32/subx-name -10589 1/imm32/rm32-is-first-inout -10590 3/imm32/r32-is-first-output -10591 0/imm32/no-imm32 -10592 0/imm32/no-disp32 -10593 0/imm32/output-is-write-only -10594 0x11/imm32/alloc-id:fake -10595 _Primitive-or-lit-with-reg/imm32/next -10596 _Primitive-or-lit-with-reg: # (payload primitive) -10597 0x11/imm32/alloc-id:fake:payload -10598 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 -10599 0x11/imm32/alloc-id:fake -10600 _string-or/imm32/name -10601 0x11/imm32/alloc-id:fake -10602 Single-lit-var/imm32/inouts -10603 0x11/imm32/alloc-id:fake -10604 Single-int-var-in-some-register/imm32/outputs -10605 0x11/imm32/alloc-id:fake -10606 _string_81_subop_or/imm32/subx-name -10607 3/imm32/rm32-is-first-output -10608 0/imm32/no-r32 -10609 1/imm32/imm32-is-first-inout -10610 0/imm32/no-disp32 -10611 0/imm32/output-is-write-only -10612 0x11/imm32/alloc-id:fake -10613 _Primitive-or-lit-with-mem/imm32/next -10614 _Primitive-or-lit-with-mem: # (payload primitive) -10615 0x11/imm32/alloc-id:fake:payload -10616 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 -10617 0x11/imm32/alloc-id:fake -10618 _string-or-with/imm32/name -10619 0x11/imm32/alloc-id:fake -10620 Int-var-and-literal/imm32/inouts -10621 0/imm32/no-outputs -10622 0/imm32/no-outputs -10623 0x11/imm32/alloc-id:fake -10624 _string_81_subop_or/imm32/subx-name -10625 1/imm32/rm32-is-first-inout -10626 0/imm32/no-r32 -10627 2/imm32/imm32-is-second-inout -10628 0/imm32/no-disp32 -10629 0/imm32/output-is-write-only -10630 0x11/imm32/alloc-id:fake -10631 _Primitive-xor-with-eax/imm32/next -10632 # - xor -10633 _Primitive-xor-with-eax: # (payload primitive) -10634 0x11/imm32/alloc-id:fake:payload -10635 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 -10636 0x11/imm32/alloc-id:fake -10637 _string-xor/imm32/name +10522 Single-int-var-in-ebx/imm32/outputs +10523 0x11/imm32/alloc-id:fake +10524 _string_4b_decrement_ebx/imm32/subx-name +10525 0/imm32/no-rm32 +10526 0/imm32/no-r32 +10527 0/imm32/no-imm32 +10528 0/imm32/no-disp32 +10529 0/imm32/output-is-write-only +10530 0x11/imm32/alloc-id:fake +10531 _Primitive-decrement-esi/imm32/next +10532 _Primitive-decrement-esi: # (payload primitive) +10533 0x11/imm32/alloc-id:fake:payload +10534 # var/esi <- decrement => 4e/decrement-esi +10535 0x11/imm32/alloc-id:fake +10536 _string-decrement/imm32/name +10537 0/imm32/no-inouts +10538 0/imm32/no-inouts +10539 0x11/imm32/alloc-id:fake +10540 Single-int-var-in-esi/imm32/outputs +10541 0x11/imm32/alloc-id:fake +10542 _string_4e_decrement_esi/imm32/subx-name +10543 0/imm32/no-rm32 +10544 0/imm32/no-r32 +10545 0/imm32/no-imm32 +10546 0/imm32/no-disp32 +10547 0/imm32/output-is-write-only +10548 0x11/imm32/alloc-id:fake +10549 _Primitive-decrement-edi/imm32/next +10550 _Primitive-decrement-edi: # (payload primitive) +10551 0x11/imm32/alloc-id:fake:payload +10552 # var/edi <- decrement => 4f/decrement-edi +10553 0x11/imm32/alloc-id:fake +10554 _string-decrement/imm32/name +10555 0/imm32/no-inouts +10556 0/imm32/no-inouts +10557 0x11/imm32/alloc-id:fake +10558 Single-int-var-in-edi/imm32/outputs +10559 0x11/imm32/alloc-id:fake +10560 _string_4f_decrement_edi/imm32/subx-name +10561 0/imm32/no-rm32 +10562 0/imm32/no-r32 +10563 0/imm32/no-imm32 +10564 0/imm32/no-disp32 +10565 0/imm32/output-is-write-only +10566 0x11/imm32/alloc-id:fake +10567 _Primitive-increment-mem/imm32/next +10568 _Primitive-increment-mem: # (payload primitive) +10569 0x11/imm32/alloc-id:fake:payload +10570 # increment var => ff 0/subop/increment *(ebp+__) +10571 0x11/imm32/alloc-id:fake +10572 _string-increment/imm32/name +10573 0x11/imm32/alloc-id:fake +10574 Single-int-var-in-mem/imm32/inouts +10575 0/imm32/no-outputs +10576 0/imm32/no-outputs +10577 0x11/imm32/alloc-id:fake +10578 _string_ff_subop_increment/imm32/subx-name +10579 1/imm32/rm32-is-first-inout +10580 0/imm32/no-r32 +10581 0/imm32/no-imm32 +10582 0/imm32/no-disp32 +10583 0/imm32/output-is-write-only +10584 0x11/imm32/alloc-id:fake +10585 _Primitive-increment-reg/imm32/next +10586 _Primitive-increment-reg: # (payload primitive) +10587 0x11/imm32/alloc-id:fake:payload +10588 # var/reg <- increment => ff 0/subop/increment %__ +10589 0x11/imm32/alloc-id:fake +10590 _string-increment/imm32/name +10591 0/imm32/no-inouts +10592 0/imm32/no-inouts +10593 0x11/imm32/alloc-id:fake +10594 Single-int-var-in-some-register/imm32/outputs +10595 0x11/imm32/alloc-id:fake +10596 _string_ff_subop_increment/imm32/subx-name +10597 3/imm32/rm32-is-first-output +10598 0/imm32/no-r32 +10599 0/imm32/no-imm32 +10600 0/imm32/no-disp32 +10601 0/imm32/output-is-write-only +10602 0x11/imm32/alloc-id:fake +10603 _Primitive-decrement-mem/imm32/next +10604 _Primitive-decrement-mem: # (payload primitive) +10605 0x11/imm32/alloc-id:fake:payload +10606 # decrement var => ff 1/subop/decrement *(ebp+__) +10607 0x11/imm32/alloc-id:fake +10608 _string-decrement/imm32/name +10609 0x11/imm32/alloc-id:fake +10610 Single-int-var-in-mem/imm32/inouts +10611 0/imm32/no-outputs +10612 0/imm32/no-outputs +10613 0x11/imm32/alloc-id:fake +10614 _string_ff_subop_decrement/imm32/subx-name +10615 1/imm32/rm32-is-first-inout +10616 0/imm32/no-r32 +10617 0/imm32/no-imm32 +10618 0/imm32/no-disp32 +10619 0/imm32/output-is-write-only +10620 0x11/imm32/alloc-id:fake +10621 _Primitive-decrement-reg/imm32/next +10622 _Primitive-decrement-reg: # (payload primitive) +10623 0x11/imm32/alloc-id:fake:payload +10624 # var/reg <- decrement => ff 1/subop/decrement %__ +10625 0x11/imm32/alloc-id:fake +10626 _string-decrement/imm32/name +10627 0/imm32/no-inouts +10628 0/imm32/no-inouts +10629 0x11/imm32/alloc-id:fake +10630 Single-int-var-in-some-register/imm32/outputs +10631 0x11/imm32/alloc-id:fake +10632 _string_ff_subop_decrement/imm32/subx-name +10633 3/imm32/rm32-is-first-output +10634 0/imm32/no-r32 +10635 0/imm32/no-imm32 +10636 0/imm32/no-disp32 +10637 0/imm32/output-is-write-only 10638 0x11/imm32/alloc-id:fake -10639 Single-lit-var/imm32/inouts -10640 0x11/imm32/alloc-id:fake -10641 Single-int-var-in-eax/imm32/outputs -10642 0x11/imm32/alloc-id:fake -10643 _string_35_xor_with_eax/imm32/subx-name -10644 0/imm32/no-rm32 -10645 0/imm32/no-r32 -10646 1/imm32/imm32-is-first-inout -10647 0/imm32/no-disp32 -10648 0/imm32/output-is-write-only -10649 0x11/imm32/alloc-id:fake -10650 _Primitive-xor-reg-with-reg/imm32/next -10651 _Primitive-xor-reg-with-reg: # (payload primitive) -10652 0x11/imm32/alloc-id:fake:payload -10653 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 -10654 0x11/imm32/alloc-id:fake -10655 _string-xor/imm32/name -10656 0x11/imm32/alloc-id:fake -10657 Single-int-var-in-some-register/imm32/inouts -10658 0x11/imm32/alloc-id:fake -10659 Single-int-var-in-some-register/imm32/outputs -10660 0x11/imm32/alloc-id:fake -10661 _string_31_xor_with/imm32/subx-name -10662 3/imm32/rm32-is-first-output -10663 1/imm32/r32-is-first-inout -10664 0/imm32/no-imm32 -10665 0/imm32/no-disp32 -10666 0/imm32/output-is-write-only -10667 0x11/imm32/alloc-id:fake -10668 _Primitive-xor-reg-with-mem/imm32/next -10669 _Primitive-xor-reg-with-mem: # (payload primitive) -10670 0x11/imm32/alloc-id:fake:payload -10671 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 -10672 0x11/imm32/alloc-id:fake -10673 _string-xor-with/imm32/name -10674 0x11/imm32/alloc-id:fake -10675 Two-args-int-stack-int-reg/imm32/inouts -10676 0/imm32/no-outputs -10677 0/imm32/no-outputs -10678 0x11/imm32/alloc-id:fake -10679 _string_31_xor_with/imm32/subx-name -10680 1/imm32/rm32-is-first-inout -10681 2/imm32/r32-is-second-inout -10682 0/imm32/no-imm32 -10683 0/imm32/no-disp32 -10684 0/imm32/output-is-write-only -10685 0x11/imm32/alloc-id:fake -10686 _Primitive-xor-mem-with-reg/imm32/next -10687 _Primitive-xor-mem-with-reg: # (payload primitive) -10688 0x11/imm32/alloc-id:fake:payload -10689 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 -10690 0x11/imm32/alloc-id:fake -10691 _string-xor/imm32/name -10692 0x11/imm32/alloc-id:fake -10693 Single-int-var-in-mem/imm32/inouts -10694 0x11/imm32/alloc-id:fake -10695 Single-int-var-in-some-register/imm32/outputs -10696 0x11/imm32/alloc-id:fake -10697 _string_33_xor/imm32/subx-name -10698 1/imm32/rm32-is-first-inout -10699 3/imm32/r32-is-first-output -10700 0/imm32/no-imm32 -10701 0/imm32/no-disp32 -10702 0/imm32/output-is-write-only -10703 0x11/imm32/alloc-id:fake -10704 _Primitive-xor-lit-with-reg/imm32/next -10705 _Primitive-xor-lit-with-reg: # (payload primitive) -10706 0x11/imm32/alloc-id:fake:payload -10707 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 -10708 0x11/imm32/alloc-id:fake -10709 _string-xor/imm32/name -10710 0x11/imm32/alloc-id:fake -10711 Single-lit-var/imm32/inouts -10712 0x11/imm32/alloc-id:fake -10713 Single-int-var-in-some-register/imm32/outputs -10714 0x11/imm32/alloc-id:fake -10715 _string_81_subop_xor/imm32/subx-name -10716 3/imm32/rm32-is-first-output -10717 0/imm32/no-r32 -10718 1/imm32/imm32-is-first-inout -10719 0/imm32/no-disp32 -10720 0/imm32/output-is-write-only -10721 0x11/imm32/alloc-id:fake -10722 _Primitive-xor-lit-with-mem/imm32/next -10723 _Primitive-xor-lit-with-mem: # (payload primitive) -10724 0x11/imm32/alloc-id:fake:payload -10725 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 -10726 0x11/imm32/alloc-id:fake -10727 _string-xor-with/imm32/name -10728 0x11/imm32/alloc-id:fake -10729 Int-var-and-literal/imm32/inouts -10730 0/imm32/no-outputs -10731 0/imm32/no-outputs -10732 0x11/imm32/alloc-id:fake -10733 _string_81_subop_xor/imm32/subx-name -10734 1/imm32/rm32-is-first-inout -10735 0/imm32/no-r32 -10736 2/imm32/imm32-is-first-inout -10737 0/imm32/no-disp32 -10738 0/imm32/output-is-write-only -10739 0x11/imm32/alloc-id:fake -10740 _Primitive-copy-to-eax/imm32/next -10741 # - copy -10742 _Primitive-copy-to-eax: # (payload primitive) -10743 0x11/imm32/alloc-id:fake:payload -10744 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 -10745 0x11/imm32/alloc-id:fake -10746 _string-copy/imm32/name +10639 _Primitive-add-to-eax/imm32/next +10640 # - add +10641 _Primitive-add-to-eax: # (payload primitive) +10642 0x11/imm32/alloc-id:fake:payload +10643 # var/eax <- add lit => 05/add-to-eax lit/imm32 +10644 0x11/imm32/alloc-id:fake +10645 _string-add/imm32/name +10646 0x11/imm32/alloc-id:fake +10647 Single-lit-var/imm32/inouts +10648 0x11/imm32/alloc-id:fake +10649 Single-int-var-in-eax/imm32/outputs +10650 0x11/imm32/alloc-id:fake +10651 _string_05_add_to_eax/imm32/subx-name +10652 0/imm32/no-rm32 +10653 0/imm32/no-r32 +10654 1/imm32/imm32-is-first-inout +10655 0/imm32/no-disp32 +10656 0/imm32/output-is-write-only +10657 0x11/imm32/alloc-id:fake +10658 _Primitive-add-reg-to-reg/imm32/next +10659 _Primitive-add-reg-to-reg: # (payload primitive) +10660 0x11/imm32/alloc-id:fake:payload +10661 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 +10662 0x11/imm32/alloc-id:fake +10663 _string-add/imm32/name +10664 0x11/imm32/alloc-id:fake +10665 Single-int-var-in-some-register/imm32/inouts +10666 0x11/imm32/alloc-id:fake +10667 Single-int-var-in-some-register/imm32/outputs +10668 0x11/imm32/alloc-id:fake +10669 _string_01_add_to/imm32/subx-name +10670 3/imm32/rm32-is-first-output +10671 1/imm32/r32-is-first-inout +10672 0/imm32/no-imm32 +10673 0/imm32/no-disp32 +10674 0/imm32/output-is-write-only +10675 0x11/imm32/alloc-id:fake +10676 _Primitive-add-reg-to-mem/imm32/next +10677 _Primitive-add-reg-to-mem: # (payload primitive) +10678 0x11/imm32/alloc-id:fake:payload +10679 # add-to var1 var2/reg => 01/add-to var1 var2/r32 +10680 0x11/imm32/alloc-id:fake +10681 _string-add-to/imm32/name +10682 0x11/imm32/alloc-id:fake +10683 Two-args-int-stack-int-reg/imm32/inouts +10684 0/imm32/no-outputs +10685 0/imm32/no-outputs +10686 0x11/imm32/alloc-id:fake +10687 _string_01_add_to/imm32/subx-name +10688 1/imm32/rm32-is-first-inout +10689 2/imm32/r32-is-second-inout +10690 0/imm32/no-imm32 +10691 0/imm32/no-disp32 +10692 0/imm32/output-is-write-only +10693 0x11/imm32/alloc-id:fake +10694 _Primitive-add-mem-to-reg/imm32/next +10695 _Primitive-add-mem-to-reg: # (payload primitive) +10696 0x11/imm32/alloc-id:fake:payload +10697 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 +10698 0x11/imm32/alloc-id:fake +10699 _string-add/imm32/name +10700 0x11/imm32/alloc-id:fake +10701 Single-int-var-in-mem/imm32/inouts +10702 0x11/imm32/alloc-id:fake +10703 Single-int-var-in-some-register/imm32/outputs +10704 0x11/imm32/alloc-id:fake +10705 _string_03_add/imm32/subx-name +10706 1/imm32/rm32-is-first-inout +10707 3/imm32/r32-is-first-output +10708 0/imm32/no-imm32 +10709 0/imm32/no-disp32 +10710 0/imm32/output-is-write-only +10711 0x11/imm32/alloc-id:fake +10712 _Primitive-add-lit-to-reg/imm32/next +10713 _Primitive-add-lit-to-reg: # (payload primitive) +10714 0x11/imm32/alloc-id:fake:payload +10715 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 +10716 0x11/imm32/alloc-id:fake +10717 _string-add/imm32/name +10718 0x11/imm32/alloc-id:fake +10719 Single-lit-var/imm32/inouts +10720 0x11/imm32/alloc-id:fake +10721 Single-int-var-in-some-register/imm32/outputs +10722 0x11/imm32/alloc-id:fake +10723 _string_81_subop_add/imm32/subx-name +10724 3/imm32/rm32-is-first-output +10725 0/imm32/no-r32 +10726 1/imm32/imm32-is-first-inout +10727 0/imm32/no-disp32 +10728 0/imm32/output-is-write-only +10729 0x11/imm32/alloc-id:fake +10730 _Primitive-add-lit-to-mem/imm32/next +10731 _Primitive-add-lit-to-mem: # (payload primitive) +10732 0x11/imm32/alloc-id:fake:payload +10733 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 +10734 0x11/imm32/alloc-id:fake +10735 _string-add-to/imm32/name +10736 0x11/imm32/alloc-id:fake +10737 Int-var-and-literal/imm32/inouts +10738 0/imm32/no-outputs +10739 0/imm32/no-outputs +10740 0x11/imm32/alloc-id:fake +10741 _string_81_subop_add/imm32/subx-name +10742 1/imm32/rm32-is-first-inout +10743 0/imm32/no-r32 +10744 2/imm32/imm32-is-second-inout +10745 0/imm32/no-disp32 +10746 0/imm32/output-is-write-only 10747 0x11/imm32/alloc-id:fake -10748 Single-lit-var/imm32/inouts -10749 0x11/imm32/alloc-id:fake -10750 Single-int-var-in-eax/imm32/outputs -10751 0x11/imm32/alloc-id:fake -10752 _string_b8_copy_to_eax/imm32/subx-name -10753 0/imm32/no-rm32 -10754 0/imm32/no-r32 -10755 1/imm32/imm32-is-first-inout -10756 0/imm32/no-disp32 -10757 1/imm32/output-is-write-only -10758 0x11/imm32/alloc-id:fake -10759 _Primitive-copy-to-ecx/imm32/next -10760 _Primitive-copy-to-ecx: # (payload primitive) -10761 0x11/imm32/alloc-id:fake:payload -10762 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 -10763 0x11/imm32/alloc-id:fake -10764 _string-copy/imm32/name -10765 0x11/imm32/alloc-id:fake -10766 Single-lit-var/imm32/inouts -10767 0x11/imm32/alloc-id:fake -10768 Single-int-var-in-ecx/imm32/outputs -10769 0x11/imm32/alloc-id:fake -10770 _string_b9_copy_to_ecx/imm32/subx-name -10771 0/imm32/no-rm32 -10772 0/imm32/no-r32 -10773 1/imm32/imm32-is-first-inout -10774 0/imm32/no-disp32 -10775 1/imm32/output-is-write-only -10776 0x11/imm32/alloc-id:fake -10777 _Primitive-copy-to-edx/imm32/next -10778 _Primitive-copy-to-edx: # (payload primitive) -10779 0x11/imm32/alloc-id:fake:payload -10780 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 -10781 0x11/imm32/alloc-id:fake -10782 _string-copy/imm32/name -10783 0x11/imm32/alloc-id:fake -10784 Single-lit-var/imm32/inouts -10785 0x11/imm32/alloc-id:fake -10786 Single-int-var-in-edx/imm32/outputs -10787 0x11/imm32/alloc-id:fake -10788 _string_ba_copy_to_edx/imm32/subx-name -10789 0/imm32/no-rm32 -10790 0/imm32/no-r32 -10791 1/imm32/imm32-is-first-inout -10792 0/imm32/no-disp32 -10793 1/imm32/output-is-write-only -10794 0x11/imm32/alloc-id:fake -10795 _Primitive-copy-to-ebx/imm32/next -10796 _Primitive-copy-to-ebx: # (payload primitive) -10797 0x11/imm32/alloc-id:fake:payload -10798 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 -10799 0x11/imm32/alloc-id:fake -10800 _string-copy/imm32/name -10801 0x11/imm32/alloc-id:fake -10802 Single-lit-var/imm32/inouts -10803 0x11/imm32/alloc-id:fake -10804 Single-int-var-in-ebx/imm32/outputs -10805 0x11/imm32/alloc-id:fake -10806 _string_bb_copy_to_ebx/imm32/subx-name -10807 0/imm32/no-rm32 -10808 0/imm32/no-r32 -10809 1/imm32/imm32-is-first-inout -10810 0/imm32/no-disp32 -10811 1/imm32/output-is-write-only -10812 0x11/imm32/alloc-id:fake -10813 _Primitive-copy-to-esi/imm32/next -10814 _Primitive-copy-to-esi: # (payload primitive) -10815 0x11/imm32/alloc-id:fake:payload -10816 # var/esi <- copy lit => be/copy-to-esi lit/imm32 -10817 0x11/imm32/alloc-id:fake -10818 _string-copy/imm32/name -10819 0x11/imm32/alloc-id:fake -10820 Single-lit-var/imm32/inouts -10821 0x11/imm32/alloc-id:fake -10822 Single-int-var-in-esi/imm32/outputs -10823 0x11/imm32/alloc-id:fake -10824 _string_be_copy_to_esi/imm32/subx-name -10825 0/imm32/no-rm32 -10826 0/imm32/no-r32 -10827 1/imm32/imm32-is-first-inout -10828 0/imm32/no-disp32 -10829 1/imm32/output-is-write-only -10830 0x11/imm32/alloc-id:fake -10831 _Primitive-copy-to-edi/imm32/next -10832 _Primitive-copy-to-edi: # (payload primitive) -10833 0x11/imm32/alloc-id:fake:payload -10834 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 -10835 0x11/imm32/alloc-id:fake -10836 _string-copy/imm32/name -10837 0x11/imm32/alloc-id:fake -10838 Single-lit-var/imm32/inouts -10839 0x11/imm32/alloc-id:fake -10840 Single-int-var-in-edi/imm32/outputs -10841 0x11/imm32/alloc-id:fake -10842 _string_bf_copy_to_edi/imm32/subx-name -10843 0/imm32/no-rm32 -10844 0/imm32/no-r32 -10845 1/imm32/imm32-is-first-inout -10846 0/imm32/no-disp32 -10847 1/imm32/output-is-write-only -10848 0x11/imm32/alloc-id:fake -10849 _Primitive-copy-reg-to-reg/imm32/next -10850 _Primitive-copy-reg-to-reg: # (payload primitive) -10851 0x11/imm32/alloc-id:fake:payload -10852 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 -10853 0x11/imm32/alloc-id:fake -10854 _string-copy/imm32/name -10855 0x11/imm32/alloc-id:fake -10856 Single-int-var-in-some-register/imm32/inouts -10857 0x11/imm32/alloc-id:fake -10858 Single-int-var-in-some-register/imm32/outputs -10859 0x11/imm32/alloc-id:fake -10860 _string_89_<-/imm32/subx-name -10861 3/imm32/rm32-is-first-output -10862 1/imm32/r32-is-first-inout -10863 0/imm32/no-imm32 -10864 0/imm32/no-disp32 -10865 1/imm32/output-is-write-only +10748 _Primitive-subtract-from-eax/imm32/next +10749 # - subtract +10750 _Primitive-subtract-from-eax: # (payload primitive) +10751 0x11/imm32/alloc-id:fake:payload +10752 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 +10753 0x11/imm32/alloc-id:fake +10754 _string-subtract/imm32/name +10755 0x11/imm32/alloc-id:fake +10756 Single-lit-var/imm32/inouts +10757 0x11/imm32/alloc-id:fake +10758 Single-int-var-in-eax/imm32/outputs +10759 0x11/imm32/alloc-id:fake +10760 _string_2d_subtract_from_eax/imm32/subx-name +10761 0/imm32/no-rm32 +10762 0/imm32/no-r32 +10763 1/imm32/imm32-is-first-inout +10764 0/imm32/no-disp32 +10765 0/imm32/output-is-write-only +10766 0x11/imm32/alloc-id:fake +10767 _Primitive-subtract-reg-from-reg/imm32/next +10768 _Primitive-subtract-reg-from-reg: # (payload primitive) +10769 0x11/imm32/alloc-id:fake:payload +10770 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 +10771 0x11/imm32/alloc-id:fake +10772 _string-subtract/imm32/name +10773 0x11/imm32/alloc-id:fake +10774 Single-int-var-in-some-register/imm32/inouts +10775 0x11/imm32/alloc-id:fake +10776 Single-int-var-in-some-register/imm32/outputs +10777 0x11/imm32/alloc-id:fake +10778 _string_29_subtract_from/imm32/subx-name +10779 3/imm32/rm32-is-first-output +10780 1/imm32/r32-is-first-inout +10781 0/imm32/no-imm32 +10782 0/imm32/no-disp32 +10783 0/imm32/output-is-write-only +10784 0x11/imm32/alloc-id:fake +10785 _Primitive-subtract-reg-from-mem/imm32/next +10786 _Primitive-subtract-reg-from-mem: # (payload primitive) +10787 0x11/imm32/alloc-id:fake:payload +10788 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 +10789 0x11/imm32/alloc-id:fake +10790 _string-subtract-from/imm32/name +10791 0x11/imm32/alloc-id:fake +10792 Two-args-int-stack-int-reg/imm32/inouts +10793 0/imm32/no-outputs +10794 0/imm32/no-outputs +10795 0x11/imm32/alloc-id:fake +10796 _string_29_subtract_from/imm32/subx-name +10797 1/imm32/rm32-is-first-inout +10798 2/imm32/r32-is-second-inout +10799 0/imm32/no-imm32 +10800 0/imm32/no-disp32 +10801 0/imm32/output-is-write-only +10802 0x11/imm32/alloc-id:fake +10803 _Primitive-subtract-mem-from-reg/imm32/next +10804 _Primitive-subtract-mem-from-reg: # (payload primitive) +10805 0x11/imm32/alloc-id:fake:payload +10806 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 +10807 0x11/imm32/alloc-id:fake +10808 _string-subtract/imm32/name +10809 0x11/imm32/alloc-id:fake +10810 Single-int-var-in-mem/imm32/inouts +10811 0x11/imm32/alloc-id:fake +10812 Single-int-var-in-some-register/imm32/outputs +10813 0x11/imm32/alloc-id:fake +10814 _string_2b_subtract/imm32/subx-name +10815 1/imm32/rm32-is-first-inout +10816 3/imm32/r32-is-first-output +10817 0/imm32/no-imm32 +10818 0/imm32/no-disp32 +10819 0/imm32/output-is-write-only +10820 0x11/imm32/alloc-id:fake +10821 _Primitive-subtract-lit-from-reg/imm32/next +10822 _Primitive-subtract-lit-from-reg: # (payload primitive) +10823 0x11/imm32/alloc-id:fake:payload +10824 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 +10825 0x11/imm32/alloc-id:fake +10826 _string-subtract/imm32/name +10827 0x11/imm32/alloc-id:fake +10828 Single-lit-var/imm32/inouts +10829 0x11/imm32/alloc-id:fake +10830 Single-int-var-in-some-register/imm32/outputs +10831 0x11/imm32/alloc-id:fake +10832 _string_81_subop_subtract/imm32/subx-name +10833 3/imm32/rm32-is-first-output +10834 0/imm32/no-r32 +10835 1/imm32/imm32-is-first-inout +10836 0/imm32/no-disp32 +10837 0/imm32/output-is-write-only +10838 0x11/imm32/alloc-id:fake +10839 _Primitive-subtract-lit-from-mem/imm32/next +10840 _Primitive-subtract-lit-from-mem: # (payload primitive) +10841 0x11/imm32/alloc-id:fake:payload +10842 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 +10843 0x11/imm32/alloc-id:fake +10844 _string-subtract-from/imm32/name +10845 0x11/imm32/alloc-id:fake +10846 Int-var-and-literal/imm32/inouts +10847 0/imm32/no-outputs +10848 0/imm32/no-outputs +10849 0x11/imm32/alloc-id:fake +10850 _string_81_subop_subtract/imm32/subx-name +10851 1/imm32/rm32-is-first-inout +10852 0/imm32/no-r32 +10853 2/imm32/imm32-is-first-inout +10854 0/imm32/no-disp32 +10855 0/imm32/output-is-write-only +10856 0x11/imm32/alloc-id:fake +10857 _Primitive-and-with-eax/imm32/next +10858 # - and +10859 _Primitive-and-with-eax: # (payload primitive) +10860 0x11/imm32/alloc-id:fake:payload +10861 # var/eax <- and lit => 25/and-with-eax lit/imm32 +10862 0x11/imm32/alloc-id:fake +10863 _string-and/imm32/name +10864 0x11/imm32/alloc-id:fake +10865 Single-lit-var/imm32/inouts 10866 0x11/imm32/alloc-id:fake -10867 _Primitive-copy-reg-to-mem/imm32/next -10868 _Primitive-copy-reg-to-mem: # (payload primitive) -10869 0x11/imm32/alloc-id:fake:payload -10870 # copy-to var1 var2/reg => 89/<- var1 var2/r32 -10871 0x11/imm32/alloc-id:fake -10872 _string-copy-to/imm32/name -10873 0x11/imm32/alloc-id:fake -10874 Two-args-int-stack-int-reg/imm32/inouts -10875 0/imm32/no-outputs -10876 0/imm32/no-outputs -10877 0x11/imm32/alloc-id:fake -10878 _string_89_<-/imm32/subx-name -10879 1/imm32/rm32-is-first-inout -10880 2/imm32/r32-is-second-inout -10881 0/imm32/no-imm32 -10882 0/imm32/no-disp32 -10883 1/imm32/output-is-write-only +10867 Single-int-var-in-eax/imm32/outputs +10868 0x11/imm32/alloc-id:fake +10869 _string_25_and_with_eax/imm32/subx-name +10870 0/imm32/no-rm32 +10871 0/imm32/no-r32 +10872 1/imm32/imm32-is-first-inout +10873 0/imm32/no-disp32 +10874 0/imm32/output-is-write-only +10875 0x11/imm32/alloc-id:fake +10876 _Primitive-and-reg-with-reg/imm32/next +10877 _Primitive-and-reg-with-reg: # (payload primitive) +10878 0x11/imm32/alloc-id:fake:payload +10879 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 +10880 0x11/imm32/alloc-id:fake +10881 _string-and/imm32/name +10882 0x11/imm32/alloc-id:fake +10883 Single-int-var-in-some-register/imm32/inouts 10884 0x11/imm32/alloc-id:fake -10885 _Primitive-copy-mem-to-reg/imm32/next -10886 _Primitive-copy-mem-to-reg: # (payload primitive) -10887 0x11/imm32/alloc-id:fake:payload -10888 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 -10889 0x11/imm32/alloc-id:fake -10890 _string-copy/imm32/name -10891 0x11/imm32/alloc-id:fake -10892 Single-int-var-in-mem/imm32/inouts +10885 Single-int-var-in-some-register/imm32/outputs +10886 0x11/imm32/alloc-id:fake +10887 _string_21_and_with/imm32/subx-name +10888 3/imm32/rm32-is-first-output +10889 1/imm32/r32-is-first-inout +10890 0/imm32/no-imm32 +10891 0/imm32/no-disp32 +10892 0/imm32/output-is-write-only 10893 0x11/imm32/alloc-id:fake -10894 Single-int-var-in-some-register/imm32/outputs -10895 0x11/imm32/alloc-id:fake -10896 _string_8b_->/imm32/subx-name -10897 1/imm32/rm32-is-first-inout -10898 3/imm32/r32-is-first-output -10899 0/imm32/no-imm32 -10900 0/imm32/no-disp32 -10901 1/imm32/output-is-write-only -10902 0x11/imm32/alloc-id:fake -10903 _Primitive-copy-lit-to-reg/imm32/next -10904 _Primitive-copy-lit-to-reg: # (payload primitive) -10905 0x11/imm32/alloc-id:fake:payload -10906 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 -10907 0x11/imm32/alloc-id:fake -10908 _string-copy/imm32/name -10909 0x11/imm32/alloc-id:fake -10910 Single-lit-var/imm32/inouts +10894 _Primitive-and-reg-with-mem/imm32/next +10895 _Primitive-and-reg-with-mem: # (payload primitive) +10896 0x11/imm32/alloc-id:fake:payload +10897 # and-with var1 var2/reg => 21/and-with var1 var2/r32 +10898 0x11/imm32/alloc-id:fake +10899 _string-and-with/imm32/name +10900 0x11/imm32/alloc-id:fake +10901 Two-args-int-stack-int-reg/imm32/inouts +10902 0/imm32/no-outputs +10903 0/imm32/no-outputs +10904 0x11/imm32/alloc-id:fake +10905 _string_21_and_with/imm32/subx-name +10906 1/imm32/rm32-is-first-inout +10907 2/imm32/r32-is-second-inout +10908 0/imm32/no-imm32 +10909 0/imm32/no-disp32 +10910 0/imm32/output-is-write-only 10911 0x11/imm32/alloc-id:fake -10912 Single-int-var-in-some-register/imm32/outputs -10913 0x11/imm32/alloc-id:fake -10914 _string_c7_subop_copy/imm32/subx-name -10915 3/imm32/rm32-is-first-output -10916 0/imm32/no-r32 -10917 1/imm32/imm32-is-first-inout -10918 0/imm32/no-disp32 -10919 1/imm32/output-is-write-only +10912 _Primitive-and-mem-with-reg/imm32/next +10913 _Primitive-and-mem-with-reg: # (payload primitive) +10914 0x11/imm32/alloc-id:fake:payload +10915 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 +10916 0x11/imm32/alloc-id:fake +10917 _string-and/imm32/name +10918 0x11/imm32/alloc-id:fake +10919 Single-int-var-in-mem/imm32/inouts 10920 0x11/imm32/alloc-id:fake -10921 _Primitive-copy-lit-to-mem/imm32/next -10922 _Primitive-copy-lit-to-mem: # (payload primitive) -10923 0x11/imm32/alloc-id:fake:payload -10924 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 -10925 0x11/imm32/alloc-id:fake -10926 _string-copy-to/imm32/name -10927 0x11/imm32/alloc-id:fake -10928 Int-var-and-literal/imm32/inouts -10929 0/imm32/no-outputs -10930 0/imm32/no-outputs -10931 0x11/imm32/alloc-id:fake -10932 _string_c7_subop_copy/imm32/subx-name -10933 1/imm32/rm32-is-first-inout -10934 0/imm32/no-r32 -10935 2/imm32/imm32-is-first-inout -10936 0/imm32/no-disp32 -10937 1/imm32/output-is-write-only +10921 Single-int-var-in-some-register/imm32/outputs +10922 0x11/imm32/alloc-id:fake +10923 _string_23_and/imm32/subx-name +10924 1/imm32/rm32-is-first-inout +10925 3/imm32/r32-is-first-output +10926 0/imm32/no-imm32 +10927 0/imm32/no-disp32 +10928 0/imm32/output-is-write-only +10929 0x11/imm32/alloc-id:fake +10930 _Primitive-and-lit-with-reg/imm32/next +10931 _Primitive-and-lit-with-reg: # (payload primitive) +10932 0x11/imm32/alloc-id:fake:payload +10933 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 +10934 0x11/imm32/alloc-id:fake +10935 _string-and/imm32/name +10936 0x11/imm32/alloc-id:fake +10937 Single-lit-var/imm32/inouts 10938 0x11/imm32/alloc-id:fake -10939 _Primitive-address/imm32/next -10940 # - address -10941 _Primitive-address: # (payload primitive) -10942 0x11/imm32/alloc-id:fake:payload -10943 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 -10944 0x11/imm32/alloc-id:fake -10945 _string-address/imm32/name -10946 0x11/imm32/alloc-id:fake -10947 Single-int-var-in-mem/imm32/inouts -10948 0x11/imm32/alloc-id:fake -10949 Single-addr-var-in-some-register/imm32/outputs -10950 0x11/imm32/alloc-id:fake -10951 _string_8d_copy_address/imm32/subx-name -10952 1/imm32/rm32-is-first-inout -10953 3/imm32/r32-is-first-output -10954 0/imm32/no-imm32 -10955 0/imm32/no-disp32 -10956 1/imm32/output-is-write-only -10957 0x11/imm32/alloc-id:fake -10958 _Primitive-compare-mem-with-reg/imm32/next -10959 # - compare -10960 _Primitive-compare-mem-with-reg: # (payload primitive) -10961 0x11/imm32/alloc-id:fake:payload -10962 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 -10963 0x11/imm32/alloc-id:fake -10964 _string-compare/imm32/name +10939 Single-int-var-in-some-register/imm32/outputs +10940 0x11/imm32/alloc-id:fake +10941 _string_81_subop_and/imm32/subx-name +10942 3/imm32/rm32-is-first-output +10943 0/imm32/no-r32 +10944 1/imm32/imm32-is-first-inout +10945 0/imm32/no-disp32 +10946 0/imm32/output-is-write-only +10947 0x11/imm32/alloc-id:fake +10948 _Primitive-and-lit-with-mem/imm32/next +10949 _Primitive-and-lit-with-mem: # (payload primitive) +10950 0x11/imm32/alloc-id:fake:payload +10951 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 +10952 0x11/imm32/alloc-id:fake +10953 _string-and-with/imm32/name +10954 0x11/imm32/alloc-id:fake +10955 Int-var-and-literal/imm32/inouts +10956 0/imm32/no-outputs +10957 0/imm32/no-outputs +10958 0x11/imm32/alloc-id:fake +10959 _string_81_subop_and/imm32/subx-name +10960 1/imm32/rm32-is-first-inout +10961 0/imm32/no-r32 +10962 2/imm32/imm32-is-first-inout +10963 0/imm32/no-disp32 +10964 0/imm32/output-is-write-only 10965 0x11/imm32/alloc-id:fake -10966 Two-args-int-stack-int-reg/imm32/inouts -10967 0/imm32/no-outputs -10968 0/imm32/no-outputs -10969 0x11/imm32/alloc-id:fake -10970 _string_39_compare->/imm32/subx-name -10971 1/imm32/rm32-is-first-inout -10972 2/imm32/r32-is-second-inout -10973 0/imm32/no-imm32 -10974 0/imm32/no-disp32 -10975 0/imm32/output-is-write-only -10976 0x11/imm32/alloc-id:fake -10977 _Primitive-compare-reg-with-mem/imm32/next -10978 _Primitive-compare-reg-with-mem: # (payload primitive) -10979 0x11/imm32/alloc-id:fake:payload -10980 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 -10981 0x11/imm32/alloc-id:fake -10982 _string-compare/imm32/name -10983 0x11/imm32/alloc-id:fake -10984 Two-args-int-reg-int-stack/imm32/inouts -10985 0/imm32/no-outputs -10986 0/imm32/no-outputs -10987 0x11/imm32/alloc-id:fake -10988 _string_3b_compare<-/imm32/subx-name -10989 2/imm32/rm32-is-second-inout -10990 1/imm32/r32-is-first-inout -10991 0/imm32/no-imm32 -10992 0/imm32/no-disp32 -10993 0/imm32/output-is-write-only -10994 0x11/imm32/alloc-id:fake -10995 _Primitive-compare-eax-with-literal/imm32/next -10996 _Primitive-compare-eax-with-literal: # (payload primitive) -10997 0x11/imm32/alloc-id:fake:payload -10998 # compare var1/eax n => 3d/compare-eax-with n/imm32 -10999 0x11/imm32/alloc-id:fake -11000 _string-compare/imm32/name -11001 0x11/imm32/alloc-id:fake -11002 Two-args-int-eax-int-literal/imm32/inouts -11003 0/imm32/no-outputs -11004 0/imm32/no-outputs -11005 0x11/imm32/alloc-id:fake -11006 _string_3d_compare_eax_with/imm32/subx-name -11007 0/imm32/no-rm32 -11008 0/imm32/no-r32 -11009 2/imm32/imm32-is-second-inout -11010 0/imm32/no-disp32 -11011 0/imm32/output-is-write-only -11012 0x11/imm32/alloc-id:fake -11013 _Primitive-compare-reg-with-literal/imm32/next -11014 _Primitive-compare-reg-with-literal: # (payload primitive) -11015 0x11/imm32/alloc-id:fake:payload -11016 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 -11017 0x11/imm32/alloc-id:fake -11018 _string-compare/imm32/name -11019 0x11/imm32/alloc-id:fake -11020 Int-var-in-register-and-literal/imm32/inouts -11021 0/imm32/no-outputs -11022 0/imm32/no-outputs -11023 0x11/imm32/alloc-id:fake -11024 _string_81_subop_compare/imm32/subx-name -11025 1/imm32/rm32-is-first-inout -11026 0/imm32/no-r32 -11027 2/imm32/imm32-is-second-inout -11028 0/imm32/no-disp32 -11029 0/imm32/output-is-write-only -11030 0x11/imm32/alloc-id:fake -11031 _Primitive-compare-mem-with-literal/imm32/next -11032 _Primitive-compare-mem-with-literal: # (payload primitive) -11033 0x11/imm32/alloc-id:fake:payload -11034 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 -11035 0x11/imm32/alloc-id:fake -11036 _string-compare/imm32/name -11037 0x11/imm32/alloc-id:fake -11038 Int-var-and-literal/imm32/inouts -11039 0/imm32/no-outputs -11040 0/imm32/no-outputs -11041 0x11/imm32/alloc-id:fake -11042 _string_81_subop_compare/imm32/subx-name -11043 1/imm32/rm32-is-first-inout -11044 0/imm32/no-r32 -11045 2/imm32/imm32-is-second-inout -11046 0/imm32/no-disp32 -11047 0/imm32/output-is-write-only -11048 0x11/imm32/alloc-id:fake -11049 _Primitive-multiply-reg-by-mem/imm32/next -11050 # - multiply -11051 _Primitive-multiply-reg-by-mem: # (payload primitive) -11052 0x11/imm32/alloc-id:fake:payload -11053 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -11054 0x11/imm32/alloc-id:fake -11055 _string-multiply/imm32/name +10966 _Primitive-or-with-eax/imm32/next +10967 # - or +10968 _Primitive-or-with-eax: # (payload primitive) +10969 0x11/imm32/alloc-id:fake:payload +10970 # var/eax <- or lit => 0d/or-with-eax lit/imm32 +10971 0x11/imm32/alloc-id:fake +10972 _string-or/imm32/name +10973 0x11/imm32/alloc-id:fake +10974 Single-lit-var/imm32/inouts +10975 0x11/imm32/alloc-id:fake +10976 Single-int-var-in-eax/imm32/outputs +10977 0x11/imm32/alloc-id:fake +10978 _string_0d_or_with_eax/imm32/subx-name +10979 0/imm32/no-rm32 +10980 0/imm32/no-r32 +10981 1/imm32/imm32-is-first-inout +10982 0/imm32/no-disp32 +10983 0/imm32/output-is-write-only +10984 0x11/imm32/alloc-id:fake +10985 _Primitive-or-reg-with-reg/imm32/next +10986 _Primitive-or-reg-with-reg: # (payload primitive) +10987 0x11/imm32/alloc-id:fake:payload +10988 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 +10989 0x11/imm32/alloc-id:fake +10990 _string-or/imm32/name +10991 0x11/imm32/alloc-id:fake +10992 Single-int-var-in-some-register/imm32/inouts +10993 0x11/imm32/alloc-id:fake +10994 Single-int-var-in-some-register/imm32/outputs +10995 0x11/imm32/alloc-id:fake +10996 _string_09_or_with/imm32/subx-name +10997 3/imm32/rm32-is-first-output +10998 1/imm32/r32-is-first-inout +10999 0/imm32/no-imm32 +11000 0/imm32/no-disp32 +11001 0/imm32/output-is-write-only +11002 0x11/imm32/alloc-id:fake +11003 _Primitive-or-reg-with-mem/imm32/next +11004 _Primitive-or-reg-with-mem: # (payload primitive) +11005 0x11/imm32/alloc-id:fake:payload +11006 # or-with var1 var2/reg => 09/or-with var1 var2/r32 +11007 0x11/imm32/alloc-id:fake +11008 _string-or-with/imm32/name +11009 0x11/imm32/alloc-id:fake +11010 Two-args-int-stack-int-reg/imm32/inouts +11011 0/imm32/no-outputs +11012 0/imm32/no-outputs +11013 0x11/imm32/alloc-id:fake +11014 _string_09_or_with/imm32/subx-name +11015 1/imm32/rm32-is-first-inout +11016 2/imm32/r32-is-second-inout +11017 0/imm32/no-imm32 +11018 0/imm32/no-disp32 +11019 0/imm32/output-is-write-only +11020 0x11/imm32/alloc-id:fake +11021 _Primitive-or-mem-with-reg/imm32/next +11022 _Primitive-or-mem-with-reg: # (payload primitive) +11023 0x11/imm32/alloc-id:fake:payload +11024 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 +11025 0x11/imm32/alloc-id:fake +11026 _string-or/imm32/name +11027 0x11/imm32/alloc-id:fake +11028 Single-int-var-in-mem/imm32/inouts +11029 0x11/imm32/alloc-id:fake +11030 Single-int-var-in-some-register/imm32/outputs +11031 0x11/imm32/alloc-id:fake +11032 _string_0b_or/imm32/subx-name +11033 1/imm32/rm32-is-first-inout +11034 3/imm32/r32-is-first-output +11035 0/imm32/no-imm32 +11036 0/imm32/no-disp32 +11037 0/imm32/output-is-write-only +11038 0x11/imm32/alloc-id:fake +11039 _Primitive-or-lit-with-reg/imm32/next +11040 _Primitive-or-lit-with-reg: # (payload primitive) +11041 0x11/imm32/alloc-id:fake:payload +11042 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 +11043 0x11/imm32/alloc-id:fake +11044 _string-or/imm32/name +11045 0x11/imm32/alloc-id:fake +11046 Single-lit-var/imm32/inouts +11047 0x11/imm32/alloc-id:fake +11048 Single-int-var-in-some-register/imm32/outputs +11049 0x11/imm32/alloc-id:fake +11050 _string_81_subop_or/imm32/subx-name +11051 3/imm32/rm32-is-first-output +11052 0/imm32/no-r32 +11053 1/imm32/imm32-is-first-inout +11054 0/imm32/no-disp32 +11055 0/imm32/output-is-write-only 11056 0x11/imm32/alloc-id:fake -11057 Single-int-var-in-mem/imm32/inouts -11058 0x11/imm32/alloc-id:fake -11059 Single-int-var-in-some-register/imm32/outputs -11060 0x11/imm32/alloc-id:fake -11061 _string_0f_af_multiply/imm32/subx-name -11062 1/imm32/rm32-is-first-inout -11063 3/imm32/r32-is-first-output -11064 0/imm32/no-imm32 -11065 0/imm32/no-disp32 -11066 0/imm32/output-is-write-only +11057 _Primitive-or-lit-with-mem/imm32/next +11058 _Primitive-or-lit-with-mem: # (payload primitive) +11059 0x11/imm32/alloc-id:fake:payload +11060 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 +11061 0x11/imm32/alloc-id:fake +11062 _string-or-with/imm32/name +11063 0x11/imm32/alloc-id:fake +11064 Int-var-and-literal/imm32/inouts +11065 0/imm32/no-outputs +11066 0/imm32/no-outputs 11067 0x11/imm32/alloc-id:fake -11068 _Primitive-break-if-addr</imm32/next -11069 # - branches -11070 _Primitive-break-if-addr<: # (payload primitive) -11071 0x11/imm32/alloc-id:fake:payload -11072 0x11/imm32/alloc-id:fake -11073 _string-break-if-addr</imm32/name -11074 0/imm32/no-inouts -11075 0/imm32/no-inouts -11076 0/imm32/no-outputs -11077 0/imm32/no-outputs -11078 0x11/imm32/alloc-id:fake -11079 _string_0f_82_jump_break/imm32/subx-name -11080 0/imm32/no-rm32 -11081 0/imm32/no-r32 -11082 0/imm32/no-imm32 -11083 0/imm32/no-disp32 -11084 0/imm32/no-output -11085 0x11/imm32/alloc-id:fake -11086 _Primitive-break-if-addr>=/imm32/next -11087 _Primitive-break-if-addr>=: # (payload primitive) -11088 0x11/imm32/alloc-id:fake:payload -11089 0x11/imm32/alloc-id:fake -11090 _string-break-if-addr>=/imm32/name -11091 0/imm32/no-inouts -11092 0/imm32/no-inouts -11093 0/imm32/no-outputs -11094 0/imm32/no-outputs -11095 0x11/imm32/alloc-id:fake -11096 _string_0f_83_jump_break/imm32/subx-name -11097 0/imm32/no-rm32 -11098 0/imm32/no-r32 -11099 0/imm32/no-imm32 -11100 0/imm32/no-disp32 -11101 0/imm32/no-output +11068 _string_81_subop_or/imm32/subx-name +11069 1/imm32/rm32-is-first-inout +11070 0/imm32/no-r32 +11071 2/imm32/imm32-is-second-inout +11072 0/imm32/no-disp32 +11073 0/imm32/output-is-write-only +11074 0x11/imm32/alloc-id:fake +11075 _Primitive-xor-with-eax/imm32/next +11076 # - xor +11077 _Primitive-xor-with-eax: # (payload primitive) +11078 0x11/imm32/alloc-id:fake:payload +11079 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 +11080 0x11/imm32/alloc-id:fake +11081 _string-xor/imm32/name +11082 0x11/imm32/alloc-id:fake +11083 Single-lit-var/imm32/inouts +11084 0x11/imm32/alloc-id:fake +11085 Single-int-var-in-eax/imm32/outputs +11086 0x11/imm32/alloc-id:fake +11087 _string_35_xor_with_eax/imm32/subx-name +11088 0/imm32/no-rm32 +11089 0/imm32/no-r32 +11090 1/imm32/imm32-is-first-inout +11091 0/imm32/no-disp32 +11092 0/imm32/output-is-write-only +11093 0x11/imm32/alloc-id:fake +11094 _Primitive-xor-reg-with-reg/imm32/next +11095 _Primitive-xor-reg-with-reg: # (payload primitive) +11096 0x11/imm32/alloc-id:fake:payload +11097 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 +11098 0x11/imm32/alloc-id:fake +11099 _string-xor/imm32/name +11100 0x11/imm32/alloc-id:fake +11101 Single-int-var-in-some-register/imm32/inouts 11102 0x11/imm32/alloc-id:fake -11103 _Primitive-break-if-=/imm32/next -11104 _Primitive-break-if-=: # (payload primitive) -11105 0x11/imm32/alloc-id:fake:payload -11106 0x11/imm32/alloc-id:fake -11107 _string-break-if-=/imm32/name -11108 0/imm32/no-inouts -11109 0/imm32/no-inouts -11110 0/imm32/no-outputs -11111 0/imm32/no-outputs -11112 0x11/imm32/alloc-id:fake -11113 _string_0f_84_jump_break/imm32/subx-name -11114 0/imm32/no-rm32 -11115 0/imm32/no-r32 -11116 0/imm32/no-imm32 -11117 0/imm32/no-disp32 -11118 0/imm32/no-output -11119 0x11/imm32/alloc-id:fake -11120 _Primitive-break-if-!=/imm32/next -11121 _Primitive-break-if-!=: # (payload primitive) -11122 0x11/imm32/alloc-id:fake:payload -11123 0x11/imm32/alloc-id:fake -11124 _string-break-if-!=/imm32/name -11125 0/imm32/no-inouts -11126 0/imm32/no-inouts -11127 0/imm32/no-outputs -11128 0/imm32/no-outputs +11103 Single-int-var-in-some-register/imm32/outputs +11104 0x11/imm32/alloc-id:fake +11105 _string_31_xor_with/imm32/subx-name +11106 3/imm32/rm32-is-first-output +11107 1/imm32/r32-is-first-inout +11108 0/imm32/no-imm32 +11109 0/imm32/no-disp32 +11110 0/imm32/output-is-write-only +11111 0x11/imm32/alloc-id:fake +11112 _Primitive-xor-reg-with-mem/imm32/next +11113 _Primitive-xor-reg-with-mem: # (payload primitive) +11114 0x11/imm32/alloc-id:fake:payload +11115 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 +11116 0x11/imm32/alloc-id:fake +11117 _string-xor-with/imm32/name +11118 0x11/imm32/alloc-id:fake +11119 Two-args-int-stack-int-reg/imm32/inouts +11120 0/imm32/no-outputs +11121 0/imm32/no-outputs +11122 0x11/imm32/alloc-id:fake +11123 _string_31_xor_with/imm32/subx-name +11124 1/imm32/rm32-is-first-inout +11125 2/imm32/r32-is-second-inout +11126 0/imm32/no-imm32 +11127 0/imm32/no-disp32 +11128 0/imm32/output-is-write-only 11129 0x11/imm32/alloc-id:fake -11130 _string_0f_85_jump_break/imm32/subx-name -11131 0/imm32/no-rm32 -11132 0/imm32/no-r32 -11133 0/imm32/no-imm32 -11134 0/imm32/no-disp32 -11135 0/imm32/no-output +11130 _Primitive-xor-mem-with-reg/imm32/next +11131 _Primitive-xor-mem-with-reg: # (payload primitive) +11132 0x11/imm32/alloc-id:fake:payload +11133 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 +11134 0x11/imm32/alloc-id:fake +11135 _string-xor/imm32/name 11136 0x11/imm32/alloc-id:fake -11137 _Primitive-break-if-addr<=/imm32/next -11138 _Primitive-break-if-addr<=: # (payload primitive) -11139 0x11/imm32/alloc-id:fake:payload +11137 Single-int-var-in-mem/imm32/inouts +11138 0x11/imm32/alloc-id:fake +11139 Single-int-var-in-some-register/imm32/outputs 11140 0x11/imm32/alloc-id:fake -11141 _string-break-if-addr<=/imm32/name -11142 0/imm32/no-inouts -11143 0/imm32/no-inouts -11144 0/imm32/no-outputs -11145 0/imm32/no-outputs -11146 0x11/imm32/alloc-id:fake -11147 _string_0f_86_jump_break/imm32/subx-name -11148 0/imm32/no-rm32 -11149 0/imm32/no-r32 -11150 0/imm32/no-imm32 -11151 0/imm32/no-disp32 -11152 0/imm32/no-output -11153 0x11/imm32/alloc-id:fake -11154 _Primitive-break-if-addr>/imm32/next -11155 _Primitive-break-if-addr>: # (payload primitive) -11156 0x11/imm32/alloc-id:fake:payload -11157 0x11/imm32/alloc-id:fake -11158 _string-break-if-addr>/imm32/name -11159 0/imm32/no-inouts -11160 0/imm32/no-inouts -11161 0/imm32/no-outputs -11162 0/imm32/no-outputs -11163 0x11/imm32/alloc-id:fake -11164 _string_0f_87_jump_break/imm32/subx-name -11165 0/imm32/no-rm32 -11166 0/imm32/no-r32 -11167 0/imm32/no-imm32 -11168 0/imm32/no-disp32 -11169 0/imm32/no-output +11141 _string_33_xor/imm32/subx-name +11142 1/imm32/rm32-is-first-inout +11143 3/imm32/r32-is-first-output +11144 0/imm32/no-imm32 +11145 0/imm32/no-disp32 +11146 0/imm32/output-is-write-only +11147 0x11/imm32/alloc-id:fake +11148 _Primitive-xor-lit-with-reg/imm32/next +11149 _Primitive-xor-lit-with-reg: # (payload primitive) +11150 0x11/imm32/alloc-id:fake:payload +11151 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 +11152 0x11/imm32/alloc-id:fake +11153 _string-xor/imm32/name +11154 0x11/imm32/alloc-id:fake +11155 Single-lit-var/imm32/inouts +11156 0x11/imm32/alloc-id:fake +11157 Single-int-var-in-some-register/imm32/outputs +11158 0x11/imm32/alloc-id:fake +11159 _string_81_subop_xor/imm32/subx-name +11160 3/imm32/rm32-is-first-output +11161 0/imm32/no-r32 +11162 1/imm32/imm32-is-first-inout +11163 0/imm32/no-disp32 +11164 0/imm32/output-is-write-only +11165 0x11/imm32/alloc-id:fake +11166 _Primitive-xor-lit-with-mem/imm32/next +11167 _Primitive-xor-lit-with-mem: # (payload primitive) +11168 0x11/imm32/alloc-id:fake:payload +11169 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 11170 0x11/imm32/alloc-id:fake -11171 _Primitive-break-if-</imm32/next -11172 _Primitive-break-if-<: # (payload primitive) -11173 0x11/imm32/alloc-id:fake:payload -11174 0x11/imm32/alloc-id:fake -11175 _string-break-if-</imm32/name -11176 0/imm32/no-inouts -11177 0/imm32/no-inouts -11178 0/imm32/no-outputs -11179 0/imm32/no-outputs -11180 0x11/imm32/alloc-id:fake -11181 _string_0f_8c_jump_break/imm32/subx-name -11182 0/imm32/no-rm32 -11183 0/imm32/no-r32 -11184 0/imm32/no-imm32 -11185 0/imm32/no-disp32 -11186 0/imm32/no-output -11187 0x11/imm32/alloc-id:fake -11188 _Primitive-break-if->=/imm32/next -11189 _Primitive-break-if->=: # (payload primitive) -11190 0x11/imm32/alloc-id:fake:payload +11171 _string-xor-with/imm32/name +11172 0x11/imm32/alloc-id:fake +11173 Int-var-and-literal/imm32/inouts +11174 0/imm32/no-outputs +11175 0/imm32/no-outputs +11176 0x11/imm32/alloc-id:fake +11177 _string_81_subop_xor/imm32/subx-name +11178 1/imm32/rm32-is-first-inout +11179 0/imm32/no-r32 +11180 2/imm32/imm32-is-first-inout +11181 0/imm32/no-disp32 +11182 0/imm32/output-is-write-only +11183 0x11/imm32/alloc-id:fake +11184 _Primitive-copy-to-eax/imm32/next +11185 # - copy +11186 _Primitive-copy-to-eax: # (payload primitive) +11187 0x11/imm32/alloc-id:fake:payload +11188 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 +11189 0x11/imm32/alloc-id:fake +11190 _string-copy/imm32/name 11191 0x11/imm32/alloc-id:fake -11192 _string-break-if->=/imm32/name -11193 0/imm32/no-inouts -11194 0/imm32/no-inouts -11195 0/imm32/no-outputs -11196 0/imm32/no-outputs -11197 0x11/imm32/alloc-id:fake -11198 _string_0f_8d_jump_break/imm32/subx-name -11199 0/imm32/no-rm32 -11200 0/imm32/no-r32 -11201 0/imm32/no-imm32 -11202 0/imm32/no-disp32 -11203 0/imm32/no-output -11204 0x11/imm32/alloc-id:fake -11205 _Primitive-break-if-<=/imm32/next -11206 _Primitive-break-if-<=: # (payload primitive) -11207 0x11/imm32/alloc-id:fake:payload -11208 0x11/imm32/alloc-id:fake -11209 _string-break-if-<=/imm32/name -11210 0/imm32/no-inouts -11211 0/imm32/no-inouts -11212 0/imm32/no-outputs -11213 0/imm32/no-outputs -11214 0x11/imm32/alloc-id:fake -11215 _string_0f_8e_jump_break/imm32/subx-name -11216 0/imm32/no-rm32 -11217 0/imm32/no-r32 -11218 0/imm32/no-imm32 -11219 0/imm32/no-disp32 -11220 0/imm32/no-output -11221 0x11/imm32/alloc-id:fake -11222 _Primitive-break-if->/imm32/next -11223 _Primitive-break-if->: # (payload primitive) -11224 0x11/imm32/alloc-id:fake:payload +11192 Single-lit-var/imm32/inouts +11193 0x11/imm32/alloc-id:fake +11194 Single-int-var-in-eax/imm32/outputs +11195 0x11/imm32/alloc-id:fake +11196 _string_b8_copy_to_eax/imm32/subx-name +11197 0/imm32/no-rm32 +11198 0/imm32/no-r32 +11199 1/imm32/imm32-is-first-inout +11200 0/imm32/no-disp32 +11201 1/imm32/output-is-write-only +11202 0x11/imm32/alloc-id:fake +11203 _Primitive-copy-to-ecx/imm32/next +11204 _Primitive-copy-to-ecx: # (payload primitive) +11205 0x11/imm32/alloc-id:fake:payload +11206 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 +11207 0x11/imm32/alloc-id:fake +11208 _string-copy/imm32/name +11209 0x11/imm32/alloc-id:fake +11210 Single-lit-var/imm32/inouts +11211 0x11/imm32/alloc-id:fake +11212 Single-int-var-in-ecx/imm32/outputs +11213 0x11/imm32/alloc-id:fake +11214 _string_b9_copy_to_ecx/imm32/subx-name +11215 0/imm32/no-rm32 +11216 0/imm32/no-r32 +11217 1/imm32/imm32-is-first-inout +11218 0/imm32/no-disp32 +11219 1/imm32/output-is-write-only +11220 0x11/imm32/alloc-id:fake +11221 _Primitive-copy-to-edx/imm32/next +11222 _Primitive-copy-to-edx: # (payload primitive) +11223 0x11/imm32/alloc-id:fake:payload +11224 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 11225 0x11/imm32/alloc-id:fake -11226 _string-break-if->/imm32/name -11227 0/imm32/no-inouts -11228 0/imm32/no-inouts -11229 0/imm32/no-outputs -11230 0/imm32/no-outputs +11226 _string-copy/imm32/name +11227 0x11/imm32/alloc-id:fake +11228 Single-lit-var/imm32/inouts +11229 0x11/imm32/alloc-id:fake +11230 Single-int-var-in-edx/imm32/outputs 11231 0x11/imm32/alloc-id:fake -11232 _string_0f_8f_jump_break/imm32/subx-name +11232 _string_ba_copy_to_edx/imm32/subx-name 11233 0/imm32/no-rm32 11234 0/imm32/no-r32 -11235 0/imm32/no-imm32 +11235 1/imm32/imm32-is-first-inout 11236 0/imm32/no-disp32 -11237 0/imm32/no-output +11237 1/imm32/output-is-write-only 11238 0x11/imm32/alloc-id:fake -11239 _Primitive-break/imm32/next -11240 _Primitive-break: # (payload primitive) +11239 _Primitive-copy-to-ebx/imm32/next +11240 _Primitive-copy-to-ebx: # (payload primitive) 11241 0x11/imm32/alloc-id:fake:payload -11242 0x11/imm32/alloc-id:fake -11243 _string-break/imm32/name -11244 0/imm32/no-inouts -11245 0/imm32/no-inouts -11246 0/imm32/no-outputs -11247 0/imm32/no-outputs -11248 0x11/imm32/alloc-id:fake -11249 _string_e9_jump_break/imm32/subx-name -11250 0/imm32/no-rm32 -11251 0/imm32/no-r32 -11252 0/imm32/no-imm32 -11253 0/imm32/no-disp32 -11254 0/imm32/no-output -11255 0x11/imm32/alloc-id:fake -11256 _Primitive-loop-if-addr</imm32/next -11257 _Primitive-loop-if-addr<: # (payload primitive) -11258 0x11/imm32/alloc-id:fake:payload -11259 0x11/imm32/alloc-id:fake -11260 _string-loop-if-addr</imm32/name -11261 0/imm32/no-inouts -11262 0/imm32/no-inouts -11263 0/imm32/no-outputs -11264 0/imm32/no-outputs +11242 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 +11243 0x11/imm32/alloc-id:fake +11244 _string-copy/imm32/name +11245 0x11/imm32/alloc-id:fake +11246 Single-lit-var/imm32/inouts +11247 0x11/imm32/alloc-id:fake +11248 Single-int-var-in-ebx/imm32/outputs +11249 0x11/imm32/alloc-id:fake +11250 _string_bb_copy_to_ebx/imm32/subx-name +11251 0/imm32/no-rm32 +11252 0/imm32/no-r32 +11253 1/imm32/imm32-is-first-inout +11254 0/imm32/no-disp32 +11255 1/imm32/output-is-write-only +11256 0x11/imm32/alloc-id:fake +11257 _Primitive-copy-to-esi/imm32/next +11258 _Primitive-copy-to-esi: # (payload primitive) +11259 0x11/imm32/alloc-id:fake:payload +11260 # var/esi <- copy lit => be/copy-to-esi lit/imm32 +11261 0x11/imm32/alloc-id:fake +11262 _string-copy/imm32/name +11263 0x11/imm32/alloc-id:fake +11264 Single-lit-var/imm32/inouts 11265 0x11/imm32/alloc-id:fake -11266 _string_0f_82_jump_loop/imm32/subx-name -11267 0/imm32/no-rm32 -11268 0/imm32/no-r32 -11269 0/imm32/no-imm32 -11270 0/imm32/no-disp32 -11271 0/imm32/no-output -11272 0x11/imm32/alloc-id:fake -11273 _Primitive-loop-if-addr>=/imm32/next -11274 _Primitive-loop-if-addr>=: # (payload primitive) -11275 0x11/imm32/alloc-id:fake:payload -11276 0x11/imm32/alloc-id:fake -11277 _string-loop-if-addr>=/imm32/name -11278 0/imm32/no-inouts -11279 0/imm32/no-inouts -11280 0/imm32/no-outputs -11281 0/imm32/no-outputs -11282 0x11/imm32/alloc-id:fake -11283 _string_0f_83_jump_loop/imm32/subx-name -11284 0/imm32/no-rm32 -11285 0/imm32/no-r32 -11286 0/imm32/no-imm32 -11287 0/imm32/no-disp32 -11288 0/imm32/no-output -11289 0x11/imm32/alloc-id:fake -11290 _Primitive-loop-if-=/imm32/next -11291 _Primitive-loop-if-=: # (payload primitive) -11292 0x11/imm32/alloc-id:fake:payload -11293 0x11/imm32/alloc-id:fake -11294 _string-loop-if-=/imm32/name -11295 0/imm32/no-inouts -11296 0/imm32/no-inouts -11297 0/imm32/no-outputs -11298 0/imm32/no-outputs +11266 Single-int-var-in-esi/imm32/outputs +11267 0x11/imm32/alloc-id:fake +11268 _string_be_copy_to_esi/imm32/subx-name +11269 0/imm32/no-rm32 +11270 0/imm32/no-r32 +11271 1/imm32/imm32-is-first-inout +11272 0/imm32/no-disp32 +11273 1/imm32/output-is-write-only +11274 0x11/imm32/alloc-id:fake +11275 _Primitive-copy-to-edi/imm32/next +11276 _Primitive-copy-to-edi: # (payload primitive) +11277 0x11/imm32/alloc-id:fake:payload +11278 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 +11279 0x11/imm32/alloc-id:fake +11280 _string-copy/imm32/name +11281 0x11/imm32/alloc-id:fake +11282 Single-lit-var/imm32/inouts +11283 0x11/imm32/alloc-id:fake +11284 Single-int-var-in-edi/imm32/outputs +11285 0x11/imm32/alloc-id:fake +11286 _string_bf_copy_to_edi/imm32/subx-name +11287 0/imm32/no-rm32 +11288 0/imm32/no-r32 +11289 1/imm32/imm32-is-first-inout +11290 0/imm32/no-disp32 +11291 1/imm32/output-is-write-only +11292 0x11/imm32/alloc-id:fake +11293 _Primitive-copy-reg-to-reg/imm32/next +11294 _Primitive-copy-reg-to-reg: # (payload primitive) +11295 0x11/imm32/alloc-id:fake:payload +11296 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 +11297 0x11/imm32/alloc-id:fake +11298 _string-copy/imm32/name 11299 0x11/imm32/alloc-id:fake -11300 _string_0f_84_jump_loop/imm32/subx-name -11301 0/imm32/no-rm32 -11302 0/imm32/no-r32 -11303 0/imm32/no-imm32 -11304 0/imm32/no-disp32 -11305 0/imm32/no-output -11306 0x11/imm32/alloc-id:fake -11307 _Primitive-loop-if-!=/imm32/next -11308 _Primitive-loop-if-!=: # (payload primitive) -11309 0x11/imm32/alloc-id:fake:payload +11300 Single-int-var-in-some-register/imm32/inouts +11301 0x11/imm32/alloc-id:fake +11302 Single-int-var-in-some-register/imm32/outputs +11303 0x11/imm32/alloc-id:fake +11304 _string_89_<-/imm32/subx-name +11305 3/imm32/rm32-is-first-output +11306 1/imm32/r32-is-first-inout +11307 0/imm32/no-imm32 +11308 0/imm32/no-disp32 +11309 1/imm32/output-is-write-only 11310 0x11/imm32/alloc-id:fake -11311 _string-loop-if-!=/imm32/name -11312 0/imm32/no-inouts -11313 0/imm32/no-inouts -11314 0/imm32/no-outputs -11315 0/imm32/no-outputs -11316 0x11/imm32/alloc-id:fake -11317 _string_0f_85_jump_loop/imm32/subx-name -11318 0/imm32/no-rm32 -11319 0/imm32/no-r32 -11320 0/imm32/no-imm32 -11321 0/imm32/no-disp32 -11322 0/imm32/no-output -11323 0x11/imm32/alloc-id:fake -11324 _Primitive-loop-if-addr<=/imm32/next -11325 _Primitive-loop-if-addr<=: # (payload primitive) -11326 0x11/imm32/alloc-id:fake:payload -11327 0x11/imm32/alloc-id:fake -11328 _string-loop-if-addr<=/imm32/name -11329 0/imm32/no-inouts -11330 0/imm32/no-inouts -11331 0/imm32/no-outputs -11332 0/imm32/no-outputs +11311 _Primitive-copy-reg-to-mem/imm32/next +11312 _Primitive-copy-reg-to-mem: # (payload primitive) +11313 0x11/imm32/alloc-id:fake:payload +11314 # copy-to var1 var2/reg => 89/<- var1 var2/r32 +11315 0x11/imm32/alloc-id:fake +11316 _string-copy-to/imm32/name +11317 0x11/imm32/alloc-id:fake +11318 Two-args-int-stack-int-reg/imm32/inouts +11319 0/imm32/no-outputs +11320 0/imm32/no-outputs +11321 0x11/imm32/alloc-id:fake +11322 _string_89_<-/imm32/subx-name +11323 1/imm32/rm32-is-first-inout +11324 2/imm32/r32-is-second-inout +11325 0/imm32/no-imm32 +11326 0/imm32/no-disp32 +11327 1/imm32/output-is-write-only +11328 0x11/imm32/alloc-id:fake +11329 _Primitive-copy-mem-to-reg/imm32/next +11330 _Primitive-copy-mem-to-reg: # (payload primitive) +11331 0x11/imm32/alloc-id:fake:payload +11332 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 11333 0x11/imm32/alloc-id:fake -11334 _string_0f_86_jump_loop/imm32/subx-name -11335 0/imm32/no-rm32 -11336 0/imm32/no-r32 -11337 0/imm32/no-imm32 -11338 0/imm32/no-disp32 -11339 0/imm32/no-output -11340 0x11/imm32/alloc-id:fake -11341 _Primitive-loop-if-addr>/imm32/next -11342 _Primitive-loop-if-addr>: # (payload primitive) -11343 0x11/imm32/alloc-id:fake:payload -11344 0x11/imm32/alloc-id:fake -11345 _string-loop-if-addr>/imm32/name -11346 0/imm32/no-inouts -11347 0/imm32/no-inouts -11348 0/imm32/no-outputs -11349 0/imm32/no-outputs -11350 0x11/imm32/alloc-id:fake -11351 _string_0f_87_jump_loop/imm32/subx-name -11352 0/imm32/no-rm32 -11353 0/imm32/no-r32 -11354 0/imm32/no-imm32 -11355 0/imm32/no-disp32 -11356 0/imm32/no-output +11334 _string-copy/imm32/name +11335 0x11/imm32/alloc-id:fake +11336 Single-int-var-in-mem/imm32/inouts +11337 0x11/imm32/alloc-id:fake +11338 Single-int-var-in-some-register/imm32/outputs +11339 0x11/imm32/alloc-id:fake +11340 _string_8b_->/imm32/subx-name +11341 1/imm32/rm32-is-first-inout +11342 3/imm32/r32-is-first-output +11343 0/imm32/no-imm32 +11344 0/imm32/no-disp32 +11345 1/imm32/output-is-write-only +11346 0x11/imm32/alloc-id:fake +11347 _Primitive-copy-lit-to-reg/imm32/next +11348 _Primitive-copy-lit-to-reg: # (payload primitive) +11349 0x11/imm32/alloc-id:fake:payload +11350 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 +11351 0x11/imm32/alloc-id:fake +11352 _string-copy/imm32/name +11353 0x11/imm32/alloc-id:fake +11354 Single-lit-var/imm32/inouts +11355 0x11/imm32/alloc-id:fake +11356 Single-int-var-in-some-register/imm32/outputs 11357 0x11/imm32/alloc-id:fake -11358 _Primitive-loop-if-</imm32/next -11359 _Primitive-loop-if-<: # (payload primitive) -11360 0x11/imm32/alloc-id:fake:payload -11361 0x11/imm32/alloc-id:fake -11362 _string-loop-if-</imm32/name -11363 0/imm32/no-inouts -11364 0/imm32/no-inouts -11365 0/imm32/no-outputs -11366 0/imm32/no-outputs -11367 0x11/imm32/alloc-id:fake -11368 _string_0f_8c_jump_loop/imm32/subx-name -11369 0/imm32/no-rm32 -11370 0/imm32/no-r32 -11371 0/imm32/no-imm32 -11372 0/imm32/no-disp32 -11373 0/imm32/no-output -11374 0x11/imm32/alloc-id:fake -11375 _Primitive-loop-if->=/imm32/next -11376 _Primitive-loop-if->=: # (payload primitive) -11377 0x11/imm32/alloc-id:fake:payload -11378 0x11/imm32/alloc-id:fake -11379 _string-loop-if->=/imm32/name -11380 0/imm32/no-inouts -11381 0/imm32/no-inouts -11382 0/imm32/no-outputs -11383 0/imm32/no-outputs -11384 0x11/imm32/alloc-id:fake -11385 _string_0f_8d_jump_loop/imm32/subx-name -11386 0/imm32/no-rm32 -11387 0/imm32/no-r32 -11388 0/imm32/no-imm32 -11389 0/imm32/no-disp32 -11390 0/imm32/no-output -11391 0x11/imm32/alloc-id:fake -11392 _Primitive-loop-if-<=/imm32/next -11393 _Primitive-loop-if-<=: # (payload primitive) -11394 0x11/imm32/alloc-id:fake:payload -11395 0x11/imm32/alloc-id:fake -11396 _string-loop-if-<=/imm32/name -11397 0/imm32/no-inouts -11398 0/imm32/no-inouts -11399 0/imm32/no-outputs -11400 0/imm32/no-outputs +11358 _string_c7_subop_copy/imm32/subx-name +11359 3/imm32/rm32-is-first-output +11360 0/imm32/no-r32 +11361 1/imm32/imm32-is-first-inout +11362 0/imm32/no-disp32 +11363 1/imm32/output-is-write-only +11364 0x11/imm32/alloc-id:fake +11365 _Primitive-copy-lit-to-mem/imm32/next +11366 _Primitive-copy-lit-to-mem: # (payload primitive) +11367 0x11/imm32/alloc-id:fake:payload +11368 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 +11369 0x11/imm32/alloc-id:fake +11370 _string-copy-to/imm32/name +11371 0x11/imm32/alloc-id:fake +11372 Int-var-and-literal/imm32/inouts +11373 0/imm32/no-outputs +11374 0/imm32/no-outputs +11375 0x11/imm32/alloc-id:fake +11376 _string_c7_subop_copy/imm32/subx-name +11377 1/imm32/rm32-is-first-inout +11378 0/imm32/no-r32 +11379 2/imm32/imm32-is-first-inout +11380 0/imm32/no-disp32 +11381 1/imm32/output-is-write-only +11382 0x11/imm32/alloc-id:fake +11383 _Primitive-address/imm32/next +11384 # - address +11385 _Primitive-address: # (payload primitive) +11386 0x11/imm32/alloc-id:fake:payload +11387 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 +11388 0x11/imm32/alloc-id:fake +11389 _string-address/imm32/name +11390 0x11/imm32/alloc-id:fake +11391 Single-int-var-in-mem/imm32/inouts +11392 0x11/imm32/alloc-id:fake +11393 Single-addr-var-in-some-register/imm32/outputs +11394 0x11/imm32/alloc-id:fake +11395 _string_8d_copy_address/imm32/subx-name +11396 1/imm32/rm32-is-first-inout +11397 3/imm32/r32-is-first-output +11398 0/imm32/no-imm32 +11399 0/imm32/no-disp32 +11400 1/imm32/output-is-write-only 11401 0x11/imm32/alloc-id:fake -11402 _string_0f_8e_jump_loop/imm32/subx-name -11403 0/imm32/no-rm32 -11404 0/imm32/no-r32 -11405 0/imm32/no-imm32 -11406 0/imm32/no-disp32 -11407 0/imm32/no-output -11408 0x11/imm32/alloc-id:fake -11409 _Primitive-loop-if->/imm32/next -11410 _Primitive-loop-if->: # (payload primitive) -11411 0x11/imm32/alloc-id:fake:payload -11412 0x11/imm32/alloc-id:fake -11413 _string-loop-if->/imm32/name -11414 0/imm32/no-inouts -11415 0/imm32/no-inouts -11416 0/imm32/no-outputs -11417 0/imm32/no-outputs -11418 0x11/imm32/alloc-id:fake -11419 _string_0f_8f_jump_loop/imm32/subx-name -11420 0/imm32/no-rm32 -11421 0/imm32/no-r32 -11422 0/imm32/no-imm32 -11423 0/imm32/no-disp32 -11424 0/imm32/no-output +11402 _Primitive-compare-mem-with-reg/imm32/next +11403 # - compare +11404 _Primitive-compare-mem-with-reg: # (payload primitive) +11405 0x11/imm32/alloc-id:fake:payload +11406 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 +11407 0x11/imm32/alloc-id:fake +11408 _string-compare/imm32/name +11409 0x11/imm32/alloc-id:fake +11410 Two-args-int-stack-int-reg/imm32/inouts +11411 0/imm32/no-outputs +11412 0/imm32/no-outputs +11413 0x11/imm32/alloc-id:fake +11414 _string_39_compare->/imm32/subx-name +11415 1/imm32/rm32-is-first-inout +11416 2/imm32/r32-is-second-inout +11417 0/imm32/no-imm32 +11418 0/imm32/no-disp32 +11419 0/imm32/output-is-write-only +11420 0x11/imm32/alloc-id:fake +11421 _Primitive-compare-reg-with-mem/imm32/next +11422 _Primitive-compare-reg-with-mem: # (payload primitive) +11423 0x11/imm32/alloc-id:fake:payload +11424 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 11425 0x11/imm32/alloc-id:fake -11426 _Primitive-loop/imm32/next # we probably don't need an unconditional break -11427 _Primitive-loop: # (payload primitive) -11428 0x11/imm32/alloc-id:fake:payload -11429 0x11/imm32/alloc-id:fake -11430 _string-loop/imm32/name -11431 0/imm32/no-inouts -11432 0/imm32/no-inouts -11433 0/imm32/no-outputs -11434 0/imm32/no-outputs -11435 0x11/imm32/alloc-id:fake -11436 _string_e9_jump_loop/imm32/subx-name -11437 0/imm32/no-rm32 -11438 0/imm32/no-r32 -11439 0/imm32/no-imm32 -11440 0/imm32/no-disp32 -11441 0/imm32/no-output -11442 0x11/imm32/alloc-id:fake -11443 _Primitive-break-if-addr<-named/imm32/next -11444 # - branches to named blocks -11445 _Primitive-break-if-addr<-named: # (payload primitive) -11446 0x11/imm32/alloc-id:fake:payload -11447 0x11/imm32/alloc-id:fake -11448 _string-break-if-addr</imm32/name +11426 _string-compare/imm32/name +11427 0x11/imm32/alloc-id:fake +11428 Two-args-int-reg-int-stack/imm32/inouts +11429 0/imm32/no-outputs +11430 0/imm32/no-outputs +11431 0x11/imm32/alloc-id:fake +11432 _string_3b_compare<-/imm32/subx-name +11433 2/imm32/rm32-is-second-inout +11434 1/imm32/r32-is-first-inout +11435 0/imm32/no-imm32 +11436 0/imm32/no-disp32 +11437 0/imm32/output-is-write-only +11438 0x11/imm32/alloc-id:fake +11439 _Primitive-compare-eax-with-literal/imm32/next +11440 _Primitive-compare-eax-with-literal: # (payload primitive) +11441 0x11/imm32/alloc-id:fake:payload +11442 # compare var1/eax n => 3d/compare-eax-with n/imm32 +11443 0x11/imm32/alloc-id:fake +11444 _string-compare/imm32/name +11445 0x11/imm32/alloc-id:fake +11446 Two-args-int-eax-int-literal/imm32/inouts +11447 0/imm32/no-outputs +11448 0/imm32/no-outputs 11449 0x11/imm32/alloc-id:fake -11450 Single-lit-var/imm32/inouts -11451 0/imm32/no-outputs -11452 0/imm32/no-outputs -11453 0x11/imm32/alloc-id:fake -11454 _string_0f_82_jump_label/imm32/subx-name -11455 0/imm32/no-rm32 -11456 0/imm32/no-r32 -11457 0/imm32/no-imm32 -11458 1/imm32/disp32-is-first-inout -11459 0/imm32/no-output -11460 0x11/imm32/alloc-id:fake -11461 _Primitive-break-if-addr>=-named/imm32/next -11462 _Primitive-break-if-addr>=-named: # (payload primitive) -11463 0x11/imm32/alloc-id:fake:payload -11464 0x11/imm32/alloc-id:fake -11465 _string-break-if-addr>=/imm32/name -11466 0x11/imm32/alloc-id:fake -11467 Single-lit-var/imm32/inouts -11468 0/imm32/no-outputs -11469 0/imm32/no-outputs -11470 0x11/imm32/alloc-id:fake -11471 _string_0f_83_jump_label/imm32/subx-name -11472 0/imm32/no-rm32 -11473 0/imm32/no-r32 -11474 0/imm32/no-imm32 -11475 1/imm32/disp32-is-first-inout -11476 0/imm32/no-output -11477 0x11/imm32/alloc-id:fake -11478 _Primitive-break-if-=-named/imm32/next -11479 _Primitive-break-if-=-named: # (payload primitive) -11480 0x11/imm32/alloc-id:fake:payload +11450 _string_3d_compare_eax_with/imm32/subx-name +11451 0/imm32/no-rm32 +11452 0/imm32/no-r32 +11453 2/imm32/imm32-is-second-inout +11454 0/imm32/no-disp32 +11455 0/imm32/output-is-write-only +11456 0x11/imm32/alloc-id:fake +11457 _Primitive-compare-reg-with-literal/imm32/next +11458 _Primitive-compare-reg-with-literal: # (payload primitive) +11459 0x11/imm32/alloc-id:fake:payload +11460 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 +11461 0x11/imm32/alloc-id:fake +11462 _string-compare/imm32/name +11463 0x11/imm32/alloc-id:fake +11464 Int-var-in-register-and-literal/imm32/inouts +11465 0/imm32/no-outputs +11466 0/imm32/no-outputs +11467 0x11/imm32/alloc-id:fake +11468 _string_81_subop_compare/imm32/subx-name +11469 1/imm32/rm32-is-first-inout +11470 0/imm32/no-r32 +11471 2/imm32/imm32-is-second-inout +11472 0/imm32/no-disp32 +11473 0/imm32/output-is-write-only +11474 0x11/imm32/alloc-id:fake +11475 _Primitive-compare-mem-with-literal/imm32/next +11476 _Primitive-compare-mem-with-literal: # (payload primitive) +11477 0x11/imm32/alloc-id:fake:payload +11478 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 +11479 0x11/imm32/alloc-id:fake +11480 _string-compare/imm32/name 11481 0x11/imm32/alloc-id:fake -11482 _string-break-if-=/imm32/name -11483 0x11/imm32/alloc-id:fake -11484 Single-lit-var/imm32/inouts -11485 0/imm32/no-outputs -11486 0/imm32/no-outputs -11487 0x11/imm32/alloc-id:fake -11488 _string_0f_84_jump_label/imm32/subx-name -11489 0/imm32/no-rm32 -11490 0/imm32/no-r32 -11491 0/imm32/no-imm32 -11492 1/imm32/disp32-is-first-inout -11493 0/imm32/no-output -11494 0x11/imm32/alloc-id:fake -11495 _Primitive-break-if-!=-named/imm32/next -11496 _Primitive-break-if-!=-named: # (payload primitive) -11497 0x11/imm32/alloc-id:fake:payload +11482 Int-var-and-literal/imm32/inouts +11483 0/imm32/no-outputs +11484 0/imm32/no-outputs +11485 0x11/imm32/alloc-id:fake +11486 _string_81_subop_compare/imm32/subx-name +11487 1/imm32/rm32-is-first-inout +11488 0/imm32/no-r32 +11489 2/imm32/imm32-is-second-inout +11490 0/imm32/no-disp32 +11491 0/imm32/output-is-write-only +11492 0x11/imm32/alloc-id:fake +11493 _Primitive-multiply-reg-by-mem/imm32/next +11494 # - multiply +11495 _Primitive-multiply-reg-by-mem: # (payload primitive) +11496 0x11/imm32/alloc-id:fake:payload +11497 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 11498 0x11/imm32/alloc-id:fake -11499 _string-break-if-!=/imm32/name +11499 _string-multiply/imm32/name 11500 0x11/imm32/alloc-id:fake -11501 Single-lit-var/imm32/inouts -11502 0/imm32/no-outputs -11503 0/imm32/no-outputs +11501 Single-int-var-in-mem/imm32/inouts +11502 0x11/imm32/alloc-id:fake +11503 Single-int-var-in-some-register/imm32/outputs 11504 0x11/imm32/alloc-id:fake -11505 _string_0f_85_jump_label/imm32/subx-name -11506 0/imm32/no-rm32 -11507 0/imm32/no-r32 +11505 _string_0f_af_multiply/imm32/subx-name +11506 1/imm32/rm32-is-first-inout +11507 3/imm32/r32-is-first-output 11508 0/imm32/no-imm32 -11509 1/imm32/disp32-is-first-inout -11510 0/imm32/no-output +11509 0/imm32/no-disp32 +11510 0/imm32/output-is-write-only 11511 0x11/imm32/alloc-id:fake -11512 _Primitive-break-if-addr<=-named/imm32/next -11513 _Primitive-break-if-addr<=-named: # (payload primitive) -11514 0x11/imm32/alloc-id:fake:payload -11515 0x11/imm32/alloc-id:fake -11516 _string-break-if-addr<=/imm32/name -11517 0x11/imm32/alloc-id:fake -11518 Single-lit-var/imm32/inouts -11519 0/imm32/no-outputs +11512 _Primitive-break-if-addr</imm32/next +11513 # - branches +11514 _Primitive-break-if-addr<: # (payload primitive) +11515 0x11/imm32/alloc-id:fake:payload +11516 0x11/imm32/alloc-id:fake +11517 _string-break-if-addr</imm32/name +11518 0/imm32/no-inouts +11519 0/imm32/no-inouts 11520 0/imm32/no-outputs -11521 0x11/imm32/alloc-id:fake -11522 _string_0f_86_jump_label/imm32/subx-name -11523 0/imm32/no-rm32 -11524 0/imm32/no-r32 -11525 0/imm32/no-imm32 -11526 1/imm32/disp32-is-first-inout -11527 0/imm32/no-output -11528 0x11/imm32/alloc-id:fake -11529 _Primitive-break-if-addr>-named/imm32/next -11530 _Primitive-break-if-addr>-named: # (payload primitive) -11531 0x11/imm32/alloc-id:fake:payload -11532 0x11/imm32/alloc-id:fake -11533 _string-break-if-addr>/imm32/name -11534 0x11/imm32/alloc-id:fake -11535 Single-lit-var/imm32/inouts -11536 0/imm32/no-outputs +11521 0/imm32/no-outputs +11522 0x11/imm32/alloc-id:fake +11523 _string_0f_82_jump_break/imm32/subx-name +11524 0/imm32/no-rm32 +11525 0/imm32/no-r32 +11526 0/imm32/no-imm32 +11527 0/imm32/no-disp32 +11528 0/imm32/no-output +11529 0x11/imm32/alloc-id:fake +11530 _Primitive-break-if-addr>=/imm32/next +11531 _Primitive-break-if-addr>=: # (payload primitive) +11532 0x11/imm32/alloc-id:fake:payload +11533 0x11/imm32/alloc-id:fake +11534 _string-break-if-addr>=/imm32/name +11535 0/imm32/no-inouts +11536 0/imm32/no-inouts 11537 0/imm32/no-outputs -11538 0x11/imm32/alloc-id:fake -11539 _string_0f_87_jump_label/imm32/subx-name -11540 0/imm32/no-rm32 -11541 0/imm32/no-r32 -11542 0/imm32/no-imm32 -11543 1/imm32/disp32-is-first-inout -11544 0/imm32/no-output -11545 0x11/imm32/alloc-id:fake -11546 _Primitive-break-if-<-named/imm32/next -11547 _Primitive-break-if-<-named: # (payload primitive) -11548 0x11/imm32/alloc-id:fake:payload -11549 0x11/imm32/alloc-id:fake -11550 _string-break-if-</imm32/name -11551 0x11/imm32/alloc-id:fake -11552 Single-lit-var/imm32/inouts -11553 0/imm32/no-outputs +11538 0/imm32/no-outputs +11539 0x11/imm32/alloc-id:fake +11540 _string_0f_83_jump_break/imm32/subx-name +11541 0/imm32/no-rm32 +11542 0/imm32/no-r32 +11543 0/imm32/no-imm32 +11544 0/imm32/no-disp32 +11545 0/imm32/no-output +11546 0x11/imm32/alloc-id:fake +11547 _Primitive-break-if-=/imm32/next +11548 _Primitive-break-if-=: # (payload primitive) +11549 0x11/imm32/alloc-id:fake:payload +11550 0x11/imm32/alloc-id:fake +11551 _string-break-if-=/imm32/name +11552 0/imm32/no-inouts +11553 0/imm32/no-inouts 11554 0/imm32/no-outputs -11555 0x11/imm32/alloc-id:fake -11556 _string_0f_8c_jump_label/imm32/subx-name -11557 0/imm32/no-rm32 -11558 0/imm32/no-r32 -11559 0/imm32/no-imm32 -11560 1/imm32/disp32-is-first-inout -11561 0/imm32/no-output -11562 0x11/imm32/alloc-id:fake -11563 _Primitive-break-if->=-named/imm32/next -11564 _Primitive-break-if->=-named: # (payload primitive) -11565 0x11/imm32/alloc-id:fake:payload -11566 0x11/imm32/alloc-id:fake -11567 _string-break-if->=/imm32/name -11568 0x11/imm32/alloc-id:fake -11569 Single-lit-var/imm32/inouts -11570 0/imm32/no-outputs +11555 0/imm32/no-outputs +11556 0x11/imm32/alloc-id:fake +11557 _string_0f_84_jump_break/imm32/subx-name +11558 0/imm32/no-rm32 +11559 0/imm32/no-r32 +11560 0/imm32/no-imm32 +11561 0/imm32/no-disp32 +11562 0/imm32/no-output +11563 0x11/imm32/alloc-id:fake +11564 _Primitive-break-if-!=/imm32/next +11565 _Primitive-break-if-!=: # (payload primitive) +11566 0x11/imm32/alloc-id:fake:payload +11567 0x11/imm32/alloc-id:fake +11568 _string-break-if-!=/imm32/name +11569 0/imm32/no-inouts +11570 0/imm32/no-inouts 11571 0/imm32/no-outputs -11572 0x11/imm32/alloc-id:fake -11573 _string_0f_8d_jump_label/imm32/subx-name -11574 0/imm32/no-rm32 -11575 0/imm32/no-r32 -11576 0/imm32/no-imm32 -11577 1/imm32/disp32-is-first-inout -11578 0/imm32/no-output -11579 0x11/imm32/alloc-id:fake -11580 _Primitive-break-if-<=-named/imm32/next -11581 _Primitive-break-if-<=-named: # (payload primitive) -11582 0x11/imm32/alloc-id:fake:payload -11583 0x11/imm32/alloc-id:fake -11584 _string-break-if-<=/imm32/name -11585 0x11/imm32/alloc-id:fake -11586 Single-lit-var/imm32/inouts -11587 0/imm32/no-outputs +11572 0/imm32/no-outputs +11573 0x11/imm32/alloc-id:fake +11574 _string_0f_85_jump_break/imm32/subx-name +11575 0/imm32/no-rm32 +11576 0/imm32/no-r32 +11577 0/imm32/no-imm32 +11578 0/imm32/no-disp32 +11579 0/imm32/no-output +11580 0x11/imm32/alloc-id:fake +11581 _Primitive-break-if-addr<=/imm32/next +11582 _Primitive-break-if-addr<=: # (payload primitive) +11583 0x11/imm32/alloc-id:fake:payload +11584 0x11/imm32/alloc-id:fake +11585 _string-break-if-addr<=/imm32/name +11586 0/imm32/no-inouts +11587 0/imm32/no-inouts 11588 0/imm32/no-outputs -11589 0x11/imm32/alloc-id:fake -11590 _string_0f_8e_jump_label/imm32/subx-name -11591 0/imm32/no-rm32 -11592 0/imm32/no-r32 -11593 0/imm32/no-imm32 -11594 1/imm32/disp32-is-first-inout -11595 0/imm32/no-output -11596 0x11/imm32/alloc-id:fake -11597 _Primitive-break-if->-named/imm32/next -11598 _Primitive-break-if->-named: # (payload primitive) -11599 0x11/imm32/alloc-id:fake:payload -11600 0x11/imm32/alloc-id:fake -11601 _string-break-if->/imm32/name -11602 0x11/imm32/alloc-id:fake -11603 Single-lit-var/imm32/inouts -11604 0/imm32/no-outputs +11589 0/imm32/no-outputs +11590 0x11/imm32/alloc-id:fake +11591 _string_0f_86_jump_break/imm32/subx-name +11592 0/imm32/no-rm32 +11593 0/imm32/no-r32 +11594 0/imm32/no-imm32 +11595 0/imm32/no-disp32 +11596 0/imm32/no-output +11597 0x11/imm32/alloc-id:fake +11598 _Primitive-break-if-addr>/imm32/next +11599 _Primitive-break-if-addr>: # (payload primitive) +11600 0x11/imm32/alloc-id:fake:payload +11601 0x11/imm32/alloc-id:fake +11602 _string-break-if-addr>/imm32/name +11603 0/imm32/no-inouts +11604 0/imm32/no-inouts 11605 0/imm32/no-outputs -11606 0x11/imm32/alloc-id:fake -11607 _string_0f_8f_jump_label/imm32/subx-name -11608 0/imm32/no-rm32 -11609 0/imm32/no-r32 -11610 0/imm32/no-imm32 -11611 1/imm32/disp32-is-first-inout -11612 0/imm32/no-output -11613 0x11/imm32/alloc-id:fake -11614 _Primitive-break-named/imm32/next -11615 _Primitive-break-named: # (payload primitive) -11616 0x11/imm32/alloc-id:fake:payload -11617 0x11/imm32/alloc-id:fake -11618 _string-break/imm32/name -11619 0x11/imm32/alloc-id:fake -11620 Single-lit-var/imm32/inouts -11621 0/imm32/no-outputs +11606 0/imm32/no-outputs +11607 0x11/imm32/alloc-id:fake +11608 _string_0f_87_jump_break/imm32/subx-name +11609 0/imm32/no-rm32 +11610 0/imm32/no-r32 +11611 0/imm32/no-imm32 +11612 0/imm32/no-disp32 +11613 0/imm32/no-output +11614 0x11/imm32/alloc-id:fake +11615 _Primitive-break-if-</imm32/next +11616 _Primitive-break-if-<: # (payload primitive) +11617 0x11/imm32/alloc-id:fake:payload +11618 0x11/imm32/alloc-id:fake +11619 _string-break-if-</imm32/name +11620 0/imm32/no-inouts +11621 0/imm32/no-inouts 11622 0/imm32/no-outputs -11623 0x11/imm32/alloc-id:fake -11624 _string_e9_jump_label/imm32/subx-name -11625 0/imm32/no-rm32 -11626 0/imm32/no-r32 -11627 0/imm32/no-imm32 -11628 1/imm32/disp32-is-first-inout -11629 0/imm32/no-output -11630 0x11/imm32/alloc-id:fake -11631 _Primitive-loop-if-addr<-named/imm32/next -11632 _Primitive-loop-if-addr<-named: # (payload primitive) -11633 0x11/imm32/alloc-id:fake:payload -11634 0x11/imm32/alloc-id:fake -11635 _string-loop-if-addr</imm32/name -11636 0x11/imm32/alloc-id:fake -11637 Single-lit-var/imm32/inouts -11638 0/imm32/no-outputs +11623 0/imm32/no-outputs +11624 0x11/imm32/alloc-id:fake +11625 _string_0f_8c_jump_break/imm32/subx-name +11626 0/imm32/no-rm32 +11627 0/imm32/no-r32 +11628 0/imm32/no-imm32 +11629 0/imm32/no-disp32 +11630 0/imm32/no-output +11631 0x11/imm32/alloc-id:fake +11632 _Primitive-break-if->=/imm32/next +11633 _Primitive-break-if->=: # (payload primitive) +11634 0x11/imm32/alloc-id:fake:payload +11635 0x11/imm32/alloc-id:fake +11636 _string-break-if->=/imm32/name +11637 0/imm32/no-inouts +11638 0/imm32/no-inouts 11639 0/imm32/no-outputs -11640 0x11/imm32/alloc-id:fake -11641 _string_0f_82_jump_label/imm32/subx-name -11642 0/imm32/no-rm32 -11643 0/imm32/no-r32 -11644 0/imm32/no-imm32 -11645 1/imm32/disp32-is-first-inout -11646 0/imm32/no-output -11647 0x11/imm32/alloc-id:fake -11648 _Primitive-loop-if-addr>=-named/imm32/next -11649 _Primitive-loop-if-addr>=-named: # (payload primitive) -11650 0x11/imm32/alloc-id:fake:payload -11651 0x11/imm32/alloc-id:fake -11652 _string-loop-if-addr>=/imm32/name -11653 0x11/imm32/alloc-id:fake -11654 Single-lit-var/imm32/inouts -11655 0/imm32/no-outputs +11640 0/imm32/no-outputs +11641 0x11/imm32/alloc-id:fake +11642 _string_0f_8d_jump_break/imm32/subx-name +11643 0/imm32/no-rm32 +11644 0/imm32/no-r32 +11645 0/imm32/no-imm32 +11646 0/imm32/no-disp32 +11647 0/imm32/no-output +11648 0x11/imm32/alloc-id:fake +11649 _Primitive-break-if-<=/imm32/next +11650 _Primitive-break-if-<=: # (payload primitive) +11651 0x11/imm32/alloc-id:fake:payload +11652 0x11/imm32/alloc-id:fake +11653 _string-break-if-<=/imm32/name +11654 0/imm32/no-inouts +11655 0/imm32/no-inouts 11656 0/imm32/no-outputs -11657 0x11/imm32/alloc-id:fake -11658 _string_0f_83_jump_label/imm32/subx-name -11659 0/imm32/no-rm32 -11660 0/imm32/no-r32 -11661 0/imm32/no-imm32 -11662 1/imm32/disp32-is-first-inout -11663 0/imm32/no-output -11664 0x11/imm32/alloc-id:fake -11665 _Primitive-loop-if-=-named/imm32/next -11666 _Primitive-loop-if-=-named: # (payload primitive) -11667 0x11/imm32/alloc-id:fake:payload -11668 0x11/imm32/alloc-id:fake -11669 _string-loop-if-=/imm32/name -11670 0x11/imm32/alloc-id:fake -11671 Single-lit-var/imm32/inouts -11672 0/imm32/no-outputs +11657 0/imm32/no-outputs +11658 0x11/imm32/alloc-id:fake +11659 _string_0f_8e_jump_break/imm32/subx-name +11660 0/imm32/no-rm32 +11661 0/imm32/no-r32 +11662 0/imm32/no-imm32 +11663 0/imm32/no-disp32 +11664 0/imm32/no-output +11665 0x11/imm32/alloc-id:fake +11666 _Primitive-break-if->/imm32/next +11667 _Primitive-break-if->: # (payload primitive) +11668 0x11/imm32/alloc-id:fake:payload +11669 0x11/imm32/alloc-id:fake +11670 _string-break-if->/imm32/name +11671 0/imm32/no-inouts +11672 0/imm32/no-inouts 11673 0/imm32/no-outputs -11674 0x11/imm32/alloc-id:fake -11675 _string_0f_84_jump_label/imm32/subx-name -11676 0/imm32/no-rm32 -11677 0/imm32/no-r32 -11678 0/imm32/no-imm32 -11679 1/imm32/disp32-is-first-inout -11680 0/imm32/no-output -11681 0x11/imm32/alloc-id:fake -11682 _Primitive-loop-if-!=-named/imm32/next -11683 _Primitive-loop-if-!=-named: # (payload primitive) -11684 0x11/imm32/alloc-id:fake:payload -11685 0x11/imm32/alloc-id:fake -11686 _string-loop-if-!=/imm32/name -11687 0x11/imm32/alloc-id:fake -11688 Single-lit-var/imm32/inouts -11689 0/imm32/no-outputs +11674 0/imm32/no-outputs +11675 0x11/imm32/alloc-id:fake +11676 _string_0f_8f_jump_break/imm32/subx-name +11677 0/imm32/no-rm32 +11678 0/imm32/no-r32 +11679 0/imm32/no-imm32 +11680 0/imm32/no-disp32 +11681 0/imm32/no-output +11682 0x11/imm32/alloc-id:fake +11683 _Primitive-break/imm32/next +11684 _Primitive-break: # (payload primitive) +11685 0x11/imm32/alloc-id:fake:payload +11686 0x11/imm32/alloc-id:fake +11687 _string-break/imm32/name +11688 0/imm32/no-inouts +11689 0/imm32/no-inouts 11690 0/imm32/no-outputs -11691 0x11/imm32/alloc-id:fake -11692 _string_0f_85_jump_label/imm32/subx-name -11693 0/imm32/no-rm32 -11694 0/imm32/no-r32 -11695 0/imm32/no-imm32 -11696 1/imm32/disp32-is-first-inout -11697 0/imm32/no-output -11698 0x11/imm32/alloc-id:fake -11699 _Primitive-loop-if-addr<=-named/imm32/next -11700 _Primitive-loop-if-addr<=-named: # (payload primitive) -11701 0x11/imm32/alloc-id:fake:payload -11702 0x11/imm32/alloc-id:fake -11703 _string-loop-if-addr<=/imm32/name -11704 0x11/imm32/alloc-id:fake -11705 Single-lit-var/imm32/inouts -11706 0/imm32/no-outputs +11691 0/imm32/no-outputs +11692 0x11/imm32/alloc-id:fake +11693 _string_e9_jump_break/imm32/subx-name +11694 0/imm32/no-rm32 +11695 0/imm32/no-r32 +11696 0/imm32/no-imm32 +11697 0/imm32/no-disp32 +11698 0/imm32/no-output +11699 0x11/imm32/alloc-id:fake +11700 _Primitive-loop-if-addr</imm32/next +11701 _Primitive-loop-if-addr<: # (payload primitive) +11702 0x11/imm32/alloc-id:fake:payload +11703 0x11/imm32/alloc-id:fake +11704 _string-loop-if-addr</imm32/name +11705 0/imm32/no-inouts +11706 0/imm32/no-inouts 11707 0/imm32/no-outputs -11708 0x11/imm32/alloc-id:fake -11709 _string_0f_86_jump_label/imm32/subx-name -11710 0/imm32/no-rm32 -11711 0/imm32/no-r32 -11712 0/imm32/no-imm32 -11713 1/imm32/disp32-is-first-inout -11714 0/imm32/no-output -11715 0x11/imm32/alloc-id:fake -11716 _Primitive-loop-if-addr>-named/imm32/next -11717 _Primitive-loop-if-addr>-named: # (payload primitive) -11718 0x11/imm32/alloc-id:fake:payload -11719 0x11/imm32/alloc-id:fake -11720 _string-loop-if-addr>/imm32/name -11721 0x11/imm32/alloc-id:fake -11722 Single-lit-var/imm32/inouts -11723 0/imm32/no-outputs +11708 0/imm32/no-outputs +11709 0x11/imm32/alloc-id:fake +11710 _string_0f_82_jump_loop/imm32/subx-name +11711 0/imm32/no-rm32 +11712 0/imm32/no-r32 +11713 0/imm32/no-imm32 +11714 0/imm32/no-disp32 +11715 0/imm32/no-output +11716 0x11/imm32/alloc-id:fake +11717 _Primitive-loop-if-addr>=/imm32/next +11718 _Primitive-loop-if-addr>=: # (payload primitive) +11719 0x11/imm32/alloc-id:fake:payload +11720 0x11/imm32/alloc-id:fake +11721 _string-loop-if-addr>=/imm32/name +11722 0/imm32/no-inouts +11723 0/imm32/no-inouts 11724 0/imm32/no-outputs -11725 0x11/imm32/alloc-id:fake -11726 _string_0f_87_jump_label/imm32/subx-name -11727 0/imm32/no-rm32 -11728 0/imm32/no-r32 -11729 0/imm32/no-imm32 -11730 1/imm32/disp32-is-first-inout -11731 0/imm32/no-output -11732 0x11/imm32/alloc-id:fake -11733 _Primitive-loop-if-<-named/imm32/next -11734 _Primitive-loop-if-<-named: # (payload primitive) -11735 0x11/imm32/alloc-id:fake:payload -11736 0x11/imm32/alloc-id:fake -11737 _string-loop-if-</imm32/name -11738 0x11/imm32/alloc-id:fake -11739 Single-lit-var/imm32/inouts -11740 0/imm32/no-outputs +11725 0/imm32/no-outputs +11726 0x11/imm32/alloc-id:fake +11727 _string_0f_83_jump_loop/imm32/subx-name +11728 0/imm32/no-rm32 +11729 0/imm32/no-r32 +11730 0/imm32/no-imm32 +11731 0/imm32/no-disp32 +11732 0/imm32/no-output +11733 0x11/imm32/alloc-id:fake +11734 _Primitive-loop-if-=/imm32/next +11735 _Primitive-loop-if-=: # (payload primitive) +11736 0x11/imm32/alloc-id:fake:payload +11737 0x11/imm32/alloc-id:fake +11738 _string-loop-if-=/imm32/name +11739 0/imm32/no-inouts +11740 0/imm32/no-inouts 11741 0/imm32/no-outputs -11742 0x11/imm32/alloc-id:fake -11743 _string_0f_8c_jump_label/imm32/subx-name -11744 0/imm32/no-rm32 -11745 0/imm32/no-r32 -11746 0/imm32/no-imm32 -11747 1/imm32/disp32-is-first-inout -11748 0/imm32/no-output -11749 0x11/imm32/alloc-id:fake -11750 _Primitive-loop-if->=-named/imm32/next -11751 _Primitive-loop-if->=-named: # (payload primitive) -11752 0x11/imm32/alloc-id:fake:payload -11753 0x11/imm32/alloc-id:fake -11754 _string-loop-if->=/imm32/name -11755 0x11/imm32/alloc-id:fake -11756 Single-lit-var/imm32/inouts -11757 0/imm32/no-outputs +11742 0/imm32/no-outputs +11743 0x11/imm32/alloc-id:fake +11744 _string_0f_84_jump_loop/imm32/subx-name +11745 0/imm32/no-rm32 +11746 0/imm32/no-r32 +11747 0/imm32/no-imm32 +11748 0/imm32/no-disp32 +11749 0/imm32/no-output +11750 0x11/imm32/alloc-id:fake +11751 _Primitive-loop-if-!=/imm32/next +11752 _Primitive-loop-if-!=: # (payload primitive) +11753 0x11/imm32/alloc-id:fake:payload +11754 0x11/imm32/alloc-id:fake +11755 _string-loop-if-!=/imm32/name +11756 0/imm32/no-inouts +11757 0/imm32/no-inouts 11758 0/imm32/no-outputs -11759 0x11/imm32/alloc-id:fake -11760 _string_0f_8d_jump_label/imm32/subx-name -11761 0/imm32/no-rm32 -11762 0/imm32/no-r32 -11763 0/imm32/no-imm32 -11764 1/imm32/disp32-is-first-inout -11765 0/imm32/no-output -11766 0x11/imm32/alloc-id:fake -11767 _Primitive-loop-if-<=-named/imm32/next -11768 _Primitive-loop-if-<=-named: # (payload primitive) -11769 0x11/imm32/alloc-id:fake:payload -11770 0x11/imm32/alloc-id:fake -11771 _string-loop-if-<=/imm32/name -11772 0x11/imm32/alloc-id:fake -11773 Single-lit-var/imm32/inouts -11774 0/imm32/no-outputs +11759 0/imm32/no-outputs +11760 0x11/imm32/alloc-id:fake +11761 _string_0f_85_jump_loop/imm32/subx-name +11762 0/imm32/no-rm32 +11763 0/imm32/no-r32 +11764 0/imm32/no-imm32 +11765 0/imm32/no-disp32 +11766 0/imm32/no-output +11767 0x11/imm32/alloc-id:fake +11768 _Primitive-loop-if-addr<=/imm32/next +11769 _Primitive-loop-if-addr<=: # (payload primitive) +11770 0x11/imm32/alloc-id:fake:payload +11771 0x11/imm32/alloc-id:fake +11772 _string-loop-if-addr<=/imm32/name +11773 0/imm32/no-inouts +11774 0/imm32/no-inouts 11775 0/imm32/no-outputs -11776 0x11/imm32/alloc-id:fake -11777 _string_0f_8e_jump_label/imm32/subx-name -11778 0/imm32/no-rm32 -11779 0/imm32/no-r32 -11780 0/imm32/no-imm32 -11781 1/imm32/disp32-is-first-inout -11782 0/imm32/no-output -11783 0x11/imm32/alloc-id:fake -11784 _Primitive-loop-if->-named/imm32/next -11785 _Primitive-loop-if->-named: # (payload primitive) -11786 0x11/imm32/alloc-id:fake:payload -11787 0x11/imm32/alloc-id:fake -11788 _string-loop-if->/imm32/name -11789 0x11/imm32/alloc-id:fake -11790 Single-lit-var/imm32/inouts -11791 0/imm32/no-outputs +11776 0/imm32/no-outputs +11777 0x11/imm32/alloc-id:fake +11778 _string_0f_86_jump_loop/imm32/subx-name +11779 0/imm32/no-rm32 +11780 0/imm32/no-r32 +11781 0/imm32/no-imm32 +11782 0/imm32/no-disp32 +11783 0/imm32/no-output +11784 0x11/imm32/alloc-id:fake +11785 _Primitive-loop-if-addr>/imm32/next +11786 _Primitive-loop-if-addr>: # (payload primitive) +11787 0x11/imm32/alloc-id:fake:payload +11788 0x11/imm32/alloc-id:fake +11789 _string-loop-if-addr>/imm32/name +11790 0/imm32/no-inouts +11791 0/imm32/no-inouts 11792 0/imm32/no-outputs -11793 0x11/imm32/alloc-id:fake -11794 _string_0f_8f_jump_label/imm32/subx-name -11795 0/imm32/no-rm32 -11796 0/imm32/no-r32 -11797 0/imm32/no-imm32 -11798 1/imm32/disp32-is-first-inout -11799 0/imm32/no-output -11800 0x11/imm32/alloc-id:fake -11801 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break -11802 _Primitive-loop-named: # (payload primitive) -11803 0x11/imm32/alloc-id:fake:payload -11804 0x11/imm32/alloc-id:fake -11805 _string-loop/imm32/name -11806 0x11/imm32/alloc-id:fake -11807 Single-lit-var/imm32/inouts -11808 0/imm32/no-outputs +11793 0/imm32/no-outputs +11794 0x11/imm32/alloc-id:fake +11795 _string_0f_87_jump_loop/imm32/subx-name +11796 0/imm32/no-rm32 +11797 0/imm32/no-r32 +11798 0/imm32/no-imm32 +11799 0/imm32/no-disp32 +11800 0/imm32/no-output +11801 0x11/imm32/alloc-id:fake +11802 _Primitive-loop-if-</imm32/next +11803 _Primitive-loop-if-<: # (payload primitive) +11804 0x11/imm32/alloc-id:fake:payload +11805 0x11/imm32/alloc-id:fake +11806 _string-loop-if-</imm32/name +11807 0/imm32/no-inouts +11808 0/imm32/no-inouts 11809 0/imm32/no-outputs -11810 0x11/imm32/alloc-id:fake -11811 _string_e9_jump_label/imm32/subx-name -11812 0/imm32/no-rm32 -11813 0/imm32/no-r32 -11814 0/imm32/no-imm32 -11815 1/imm32/disp32-is-first-inout -11816 0/imm32/no-output -11817 0/imm32/next -11818 0/imm32/next -11819 -11820 # string literals for Mu instructions -11821 _string-add: # (payload array byte) -11822 0x11/imm32/alloc-id:fake:payload -11823 # "add" -11824 0x3/imm32/size -11825 0x61/a 0x64/d 0x64/d -11826 _string-address: # (payload array byte) -11827 0x11/imm32/alloc-id:fake:payload -11828 # "address" -11829 0x7/imm32/size -11830 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s -11831 _string-add-to: # (payload array byte) -11832 0x11/imm32/alloc-id:fake:payload -11833 # "add-to" -11834 0x6/imm32/size -11835 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -11836 _string-and: # (payload array byte) -11837 0x11/imm32/alloc-id:fake:payload -11838 # "and" -11839 0x3/imm32/size -11840 0x61/a 0x6e/n 0x64/d -11841 _string-and-with: # (payload array byte) -11842 0x11/imm32/alloc-id:fake:payload -11843 # "and-with" -11844 0x8/imm32/size -11845 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -11846 _string-break: # (payload array byte) -11847 0x11/imm32/alloc-id:fake:payload -11848 # "break" -11849 0x5/imm32/size -11850 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k -11851 _string-break-if-<: # (payload array byte) -11852 0x11/imm32/alloc-id:fake:payload -11853 # "break-if-<" -11854 0xa/imm32/size -11855 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -11856 _string-break-if-<=: # (payload array byte) -11857 0x11/imm32/alloc-id:fake:payload -11858 # "break-if-<=" -11859 0xb/imm32/size -11860 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -11861 _string-break-if-=: # (payload array byte) -11862 0x11/imm32/alloc-id:fake:payload -11863 # "break-if-=" -11864 0xa/imm32/size -11865 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -11866 _string-break-if->: # (payload array byte) -11867 0x11/imm32/alloc-id:fake:payload -11868 # "break-if->" -11869 0xa/imm32/size -11870 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -11871 _string-break-if->=: # (payload array byte) +11810 0/imm32/no-outputs +11811 0x11/imm32/alloc-id:fake +11812 _string_0f_8c_jump_loop/imm32/subx-name +11813 0/imm32/no-rm32 +11814 0/imm32/no-r32 +11815 0/imm32/no-imm32 +11816 0/imm32/no-disp32 +11817 0/imm32/no-output +11818 0x11/imm32/alloc-id:fake +11819 _Primitive-loop-if->=/imm32/next +11820 _Primitive-loop-if->=: # (payload primitive) +11821 0x11/imm32/alloc-id:fake:payload +11822 0x11/imm32/alloc-id:fake +11823 _string-loop-if->=/imm32/name +11824 0/imm32/no-inouts +11825 0/imm32/no-inouts +11826 0/imm32/no-outputs +11827 0/imm32/no-outputs +11828 0x11/imm32/alloc-id:fake +11829 _string_0f_8d_jump_loop/imm32/subx-name +11830 0/imm32/no-rm32 +11831 0/imm32/no-r32 +11832 0/imm32/no-imm32 +11833 0/imm32/no-disp32 +11834 0/imm32/no-output +11835 0x11/imm32/alloc-id:fake +11836 _Primitive-loop-if-<=/imm32/next +11837 _Primitive-loop-if-<=: # (payload primitive) +11838 0x11/imm32/alloc-id:fake:payload +11839 0x11/imm32/alloc-id:fake +11840 _string-loop-if-<=/imm32/name +11841 0/imm32/no-inouts +11842 0/imm32/no-inouts +11843 0/imm32/no-outputs +11844 0/imm32/no-outputs +11845 0x11/imm32/alloc-id:fake +11846 _string_0f_8e_jump_loop/imm32/subx-name +11847 0/imm32/no-rm32 +11848 0/imm32/no-r32 +11849 0/imm32/no-imm32 +11850 0/imm32/no-disp32 +11851 0/imm32/no-output +11852 0x11/imm32/alloc-id:fake +11853 _Primitive-loop-if->/imm32/next +11854 _Primitive-loop-if->: # (payload primitive) +11855 0x11/imm32/alloc-id:fake:payload +11856 0x11/imm32/alloc-id:fake +11857 _string-loop-if->/imm32/name +11858 0/imm32/no-inouts +11859 0/imm32/no-inouts +11860 0/imm32/no-outputs +11861 0/imm32/no-outputs +11862 0x11/imm32/alloc-id:fake +11863 _string_0f_8f_jump_loop/imm32/subx-name +11864 0/imm32/no-rm32 +11865 0/imm32/no-r32 +11866 0/imm32/no-imm32 +11867 0/imm32/no-disp32 +11868 0/imm32/no-output +11869 0x11/imm32/alloc-id:fake +11870 _Primitive-loop/imm32/next # we probably don't need an unconditional break +11871 _Primitive-loop: # (payload primitive) 11872 0x11/imm32/alloc-id:fake:payload -11873 # "break-if->=" -11874 0xb/imm32/size -11875 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -11876 _string-break-if-!=: # (payload array byte) -11877 0x11/imm32/alloc-id:fake:payload -11878 # "break-if-!=" -11879 0xb/imm32/size -11880 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -11881 _string-break-if-addr<: # (payload array byte) -11882 0x11/imm32/alloc-id:fake:payload -11883 # "break-if-addr<" -11884 0xe/imm32/size -11885 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -11886 _string-break-if-addr<=: # (payload array byte) -11887 0x11/imm32/alloc-id:fake:payload -11888 # "break-if-addr<=" -11889 0xf/imm32/size -11890 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -11891 _string-break-if-addr>: # (payload array byte) -11892 0x11/imm32/alloc-id:fake:payload -11893 # "break-if-addr>" -11894 0xe/imm32/size -11895 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -11896 _string-break-if-addr>=: # (payload array byte) -11897 0x11/imm32/alloc-id:fake:payload -11898 # "break-if-addr>=" -11899 0xf/imm32/size -11900 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -11901 _string-compare: # (payload array byte) -11902 0x11/imm32/alloc-id:fake:payload -11903 # "compare" -11904 0x7/imm32/size -11905 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -11906 _string-copy: # (payload array byte) +11873 0x11/imm32/alloc-id:fake +11874 _string-loop/imm32/name +11875 0/imm32/no-inouts +11876 0/imm32/no-inouts +11877 0/imm32/no-outputs +11878 0/imm32/no-outputs +11879 0x11/imm32/alloc-id:fake +11880 _string_e9_jump_loop/imm32/subx-name +11881 0/imm32/no-rm32 +11882 0/imm32/no-r32 +11883 0/imm32/no-imm32 +11884 0/imm32/no-disp32 +11885 0/imm32/no-output +11886 0x11/imm32/alloc-id:fake +11887 _Primitive-break-if-addr<-named/imm32/next +11888 # - branches to named blocks +11889 _Primitive-break-if-addr<-named: # (payload primitive) +11890 0x11/imm32/alloc-id:fake:payload +11891 0x11/imm32/alloc-id:fake +11892 _string-break-if-addr</imm32/name +11893 0x11/imm32/alloc-id:fake +11894 Single-lit-var/imm32/inouts +11895 0/imm32/no-outputs +11896 0/imm32/no-outputs +11897 0x11/imm32/alloc-id:fake +11898 _string_0f_82_jump_label/imm32/subx-name +11899 0/imm32/no-rm32 +11900 0/imm32/no-r32 +11901 0/imm32/no-imm32 +11902 1/imm32/disp32-is-first-inout +11903 0/imm32/no-output +11904 0x11/imm32/alloc-id:fake +11905 _Primitive-break-if-addr>=-named/imm32/next +11906 _Primitive-break-if-addr>=-named: # (payload primitive) 11907 0x11/imm32/alloc-id:fake:payload -11908 # "copy" -11909 0x4/imm32/size -11910 0x63/c 0x6f/o 0x70/p 0x79/y -11911 _string-copy-to: # (payload array byte) -11912 0x11/imm32/alloc-id:fake:payload -11913 # "copy-to" -11914 0x7/imm32/size -11915 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o -11916 _string-decrement: # (payload array byte) -11917 0x11/imm32/alloc-id:fake:payload -11918 # "decrement" -11919 0x9/imm32/size -11920 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -11921 _string-increment: # (payload array byte) -11922 0x11/imm32/alloc-id:fake:payload -11923 # "increment" -11924 0x9/imm32/size -11925 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -11926 _string-loop: # (payload array byte) -11927 0x11/imm32/alloc-id:fake:payload -11928 # "loop" -11929 0x4/imm32/size -11930 0x6c/l 0x6f/o 0x6f/o 0x70/p -11931 _string-loop-if-<: # (payload array byte) -11932 0x11/imm32/alloc-id:fake:payload -11933 # "loop-if-<" -11934 0x9/imm32/size -11935 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -11936 _string-loop-if-<=: # (payload array byte) -11937 0x11/imm32/alloc-id:fake:payload -11938 # "loop-if-<=" -11939 0xa/imm32/size -11940 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -11941 _string-loop-if-=: # (payload array byte) -11942 0x11/imm32/alloc-id:fake:payload -11943 # "loop-if-=" -11944 0x9/imm32/size -11945 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -11946 _string-loop-if->: # (payload array byte) -11947 0x11/imm32/alloc-id:fake:payload -11948 # "loop-if->" -11949 0x9/imm32/size -11950 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -11951 _string-loop-if->=: # (payload array byte) -11952 0x11/imm32/alloc-id:fake:payload -11953 # "loop-if->=" -11954 0xa/imm32/size -11955 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -11956 _string-loop-if-!=: # (payload array byte) -11957 0x11/imm32/alloc-id:fake:payload -11958 # "loop-if-!=" -11959 0xa/imm32/size -11960 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -11961 _string-loop-if-addr<: # (payload array byte) -11962 0x11/imm32/alloc-id:fake:payload -11963 # "loop-if-addr<" -11964 0xd/imm32/size -11965 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -11966 _string-loop-if-addr<=: # (payload array byte) -11967 0x11/imm32/alloc-id:fake:payload -11968 # "loop-if-addr<=" -11969 0xe/imm32/size -11970 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -11971 _string-loop-if-addr>: # (payload array byte) -11972 0x11/imm32/alloc-id:fake:payload -11973 # "loop-if-addr>" -11974 0xd/imm32/size -11975 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -11976 _string-loop-if-addr>=: # (payload array byte) -11977 0x11/imm32/alloc-id:fake:payload -11978 # "loop-if-addr>=" -11979 0xe/imm32/size -11980 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -11981 _string-multiply: # (payload array byte) -11982 0x11/imm32/alloc-id:fake:payload -11983 # "multiply" -11984 0x8/imm32/size -11985 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -11986 _string-or: # (payload array byte) -11987 0x11/imm32/alloc-id:fake:payload -11988 # "or" -11989 0x2/imm32/size -11990 0x6f/o 0x72/r -11991 _string-or-with: # (payload array byte) +11908 0x11/imm32/alloc-id:fake +11909 _string-break-if-addr>=/imm32/name +11910 0x11/imm32/alloc-id:fake +11911 Single-lit-var/imm32/inouts +11912 0/imm32/no-outputs +11913 0/imm32/no-outputs +11914 0x11/imm32/alloc-id:fake +11915 _string_0f_83_jump_label/imm32/subx-name +11916 0/imm32/no-rm32 +11917 0/imm32/no-r32 +11918 0/imm32/no-imm32 +11919 1/imm32/disp32-is-first-inout +11920 0/imm32/no-output +11921 0x11/imm32/alloc-id:fake +11922 _Primitive-break-if-=-named/imm32/next +11923 _Primitive-break-if-=-named: # (payload primitive) +11924 0x11/imm32/alloc-id:fake:payload +11925 0x11/imm32/alloc-id:fake +11926 _string-break-if-=/imm32/name +11927 0x11/imm32/alloc-id:fake +11928 Single-lit-var/imm32/inouts +11929 0/imm32/no-outputs +11930 0/imm32/no-outputs +11931 0x11/imm32/alloc-id:fake +11932 _string_0f_84_jump_label/imm32/subx-name +11933 0/imm32/no-rm32 +11934 0/imm32/no-r32 +11935 0/imm32/no-imm32 +11936 1/imm32/disp32-is-first-inout +11937 0/imm32/no-output +11938 0x11/imm32/alloc-id:fake +11939 _Primitive-break-if-!=-named/imm32/next +11940 _Primitive-break-if-!=-named: # (payload primitive) +11941 0x11/imm32/alloc-id:fake:payload +11942 0x11/imm32/alloc-id:fake +11943 _string-break-if-!=/imm32/name +11944 0x11/imm32/alloc-id:fake +11945 Single-lit-var/imm32/inouts +11946 0/imm32/no-outputs +11947 0/imm32/no-outputs +11948 0x11/imm32/alloc-id:fake +11949 _string_0f_85_jump_label/imm32/subx-name +11950 0/imm32/no-rm32 +11951 0/imm32/no-r32 +11952 0/imm32/no-imm32 +11953 1/imm32/disp32-is-first-inout +11954 0/imm32/no-output +11955 0x11/imm32/alloc-id:fake +11956 _Primitive-break-if-addr<=-named/imm32/next +11957 _Primitive-break-if-addr<=-named: # (payload primitive) +11958 0x11/imm32/alloc-id:fake:payload +11959 0x11/imm32/alloc-id:fake +11960 _string-break-if-addr<=/imm32/name +11961 0x11/imm32/alloc-id:fake +11962 Single-lit-var/imm32/inouts +11963 0/imm32/no-outputs +11964 0/imm32/no-outputs +11965 0x11/imm32/alloc-id:fake +11966 _string_0f_86_jump_label/imm32/subx-name +11967 0/imm32/no-rm32 +11968 0/imm32/no-r32 +11969 0/imm32/no-imm32 +11970 1/imm32/disp32-is-first-inout +11971 0/imm32/no-output +11972 0x11/imm32/alloc-id:fake +11973 _Primitive-break-if-addr>-named/imm32/next +11974 _Primitive-break-if-addr>-named: # (payload primitive) +11975 0x11/imm32/alloc-id:fake:payload +11976 0x11/imm32/alloc-id:fake +11977 _string-break-if-addr>/imm32/name +11978 0x11/imm32/alloc-id:fake +11979 Single-lit-var/imm32/inouts +11980 0/imm32/no-outputs +11981 0/imm32/no-outputs +11982 0x11/imm32/alloc-id:fake +11983 _string_0f_87_jump_label/imm32/subx-name +11984 0/imm32/no-rm32 +11985 0/imm32/no-r32 +11986 0/imm32/no-imm32 +11987 1/imm32/disp32-is-first-inout +11988 0/imm32/no-output +11989 0x11/imm32/alloc-id:fake +11990 _Primitive-break-if-<-named/imm32/next +11991 _Primitive-break-if-<-named: # (payload primitive) 11992 0x11/imm32/alloc-id:fake:payload -11993 # "or-with" -11994 0x7/imm32/size -11995 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -11996 _string-subtract: # (payload array byte) -11997 0x11/imm32/alloc-id:fake:payload -11998 # "subtract" -11999 0x8/imm32/size -12000 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -12001 _string-subtract-from: # (payload array byte) -12002 0x11/imm32/alloc-id:fake:payload -12003 # "subtract-from" -12004 0xd/imm32/size -12005 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m -12006 _string-xor: # (payload array byte) -12007 0x11/imm32/alloc-id:fake:payload -12008 # "xor" -12009 0x3/imm32/size -12010 0x78/x 0x6f/o 0x72/r -12011 _string-xor-with: # (payload array byte) -12012 0x11/imm32/alloc-id:fake:payload -12013 # "xor-with" -12014 0x8/imm32/size -12015 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -12016 -12017 # string literals for SubX instructions -12018 _string_01_add_to: # (payload array byte) -12019 0x11/imm32/alloc-id:fake:payload -12020 # "01/add-to" -12021 0x9/imm32/size -12022 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -12023 _string_03_add: # (payload array byte) -12024 0x11/imm32/alloc-id:fake:payload -12025 # "03/add" -12026 0x6/imm32/size -12027 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d -12028 _string_05_add_to_eax: # (payload array byte) -12029 0x11/imm32/alloc-id:fake:payload -12030 # "05/add-to-eax" -12031 0xd/imm32/size -12032 0x30/0 0x35/5 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x -12033 _string_09_or_with: # (payload array byte) -12034 0x11/imm32/alloc-id:fake:payload -12035 # "09/or-with" -12036 0xa/imm32/size -12037 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -12038 _string_0b_or: # (payload array byte) -12039 0x11/imm32/alloc-id:fake:payload -12040 # "0b/or" -12041 0x5/imm32/size -12042 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r -12043 _string_0d_or_with_eax: # (payload array byte) -12044 0x11/imm32/alloc-id:fake:payload -12045 # "0d/or-with-eax" -12046 0xe/imm32/size -12047 0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -12048 _string_0f_82_jump_label: # (payload array byte) -12049 0x11/imm32/alloc-id:fake:payload -12050 # "0f 82/jump-if-addr<" -12051 0x13/imm32/size -12052 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -12053 _string_0f_82_jump_break: # (payload array byte) -12054 0x11/imm32/alloc-id:fake:payload -12055 # "0f 82/jump-if-addr< break/disp32" -12056 0x20/imm32/size -12057 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12058 _string_0f_82_jump_loop: # (payload array byte) -12059 0x11/imm32/alloc-id:fake:payload -12060 # "0f 82/jump-if-addr< loop/disp32" -12061 0x1f/imm32/size -12062 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12063 _string_0f_83_jump_label: # (payload array byte) -12064 0x11/imm32/alloc-id:fake:payload -12065 # "0f 83/jump-if-addr>=" -12066 0x14/imm32/size -12067 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -12068 _string_0f_83_jump_break: # (payload array byte) -12069 0x11/imm32/alloc-id:fake:payload -12070 # "0f 83/jump-if-addr>= break/disp32" -12071 0x21/imm32/size -12072 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12073 _string_0f_83_jump_loop: # (payload array byte) -12074 0x11/imm32/alloc-id:fake:payload -12075 # "0f 83/jump-if-addr>= loop/disp32" -12076 0x20/imm32/size -12077 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12078 _string_0f_84_jump_label: # (payload array byte) -12079 0x11/imm32/alloc-id:fake:payload -12080 # "0f 84/jump-if-=" -12081 0xf/imm32/size -12082 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -12083 _string_0f_84_jump_break: # (payload array byte) -12084 0x11/imm32/alloc-id:fake:payload -12085 # "0f 84/jump-if-= break/disp32" -12086 0x1c/imm32/size -12087 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12088 _string_0f_84_jump_loop: # (payload array byte) -12089 0x11/imm32/alloc-id:fake:payload -12090 # "0f 84/jump-if-= loop/disp32" -12091 0x1b/imm32/size -12092 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12093 _string_0f_85_jump_label: # (payload array byte) +11993 0x11/imm32/alloc-id:fake +11994 _string-break-if-</imm32/name +11995 0x11/imm32/alloc-id:fake +11996 Single-lit-var/imm32/inouts +11997 0/imm32/no-outputs +11998 0/imm32/no-outputs +11999 0x11/imm32/alloc-id:fake +12000 _string_0f_8c_jump_label/imm32/subx-name +12001 0/imm32/no-rm32 +12002 0/imm32/no-r32 +12003 0/imm32/no-imm32 +12004 1/imm32/disp32-is-first-inout +12005 0/imm32/no-output +12006 0x11/imm32/alloc-id:fake +12007 _Primitive-break-if->=-named/imm32/next +12008 _Primitive-break-if->=-named: # (payload primitive) +12009 0x11/imm32/alloc-id:fake:payload +12010 0x11/imm32/alloc-id:fake +12011 _string-break-if->=/imm32/name +12012 0x11/imm32/alloc-id:fake +12013 Single-lit-var/imm32/inouts +12014 0/imm32/no-outputs +12015 0/imm32/no-outputs +12016 0x11/imm32/alloc-id:fake +12017 _string_0f_8d_jump_label/imm32/subx-name +12018 0/imm32/no-rm32 +12019 0/imm32/no-r32 +12020 0/imm32/no-imm32 +12021 1/imm32/disp32-is-first-inout +12022 0/imm32/no-output +12023 0x11/imm32/alloc-id:fake +12024 _Primitive-break-if-<=-named/imm32/next +12025 _Primitive-break-if-<=-named: # (payload primitive) +12026 0x11/imm32/alloc-id:fake:payload +12027 0x11/imm32/alloc-id:fake +12028 _string-break-if-<=/imm32/name +12029 0x11/imm32/alloc-id:fake +12030 Single-lit-var/imm32/inouts +12031 0/imm32/no-outputs +12032 0/imm32/no-outputs +12033 0x11/imm32/alloc-id:fake +12034 _string_0f_8e_jump_label/imm32/subx-name +12035 0/imm32/no-rm32 +12036 0/imm32/no-r32 +12037 0/imm32/no-imm32 +12038 1/imm32/disp32-is-first-inout +12039 0/imm32/no-output +12040 0x11/imm32/alloc-id:fake +12041 _Primitive-break-if->-named/imm32/next +12042 _Primitive-break-if->-named: # (payload primitive) +12043 0x11/imm32/alloc-id:fake:payload +12044 0x11/imm32/alloc-id:fake +12045 _string-break-if->/imm32/name +12046 0x11/imm32/alloc-id:fake +12047 Single-lit-var/imm32/inouts +12048 0/imm32/no-outputs +12049 0/imm32/no-outputs +12050 0x11/imm32/alloc-id:fake +12051 _string_0f_8f_jump_label/imm32/subx-name +12052 0/imm32/no-rm32 +12053 0/imm32/no-r32 +12054 0/imm32/no-imm32 +12055 1/imm32/disp32-is-first-inout +12056 0/imm32/no-output +12057 0x11/imm32/alloc-id:fake +12058 _Primitive-break-named/imm32/next +12059 _Primitive-break-named: # (payload primitive) +12060 0x11/imm32/alloc-id:fake:payload +12061 0x11/imm32/alloc-id:fake +12062 _string-break/imm32/name +12063 0x11/imm32/alloc-id:fake +12064 Single-lit-var/imm32/inouts +12065 0/imm32/no-outputs +12066 0/imm32/no-outputs +12067 0x11/imm32/alloc-id:fake +12068 _string_e9_jump_label/imm32/subx-name +12069 0/imm32/no-rm32 +12070 0/imm32/no-r32 +12071 0/imm32/no-imm32 +12072 1/imm32/disp32-is-first-inout +12073 0/imm32/no-output +12074 0x11/imm32/alloc-id:fake +12075 _Primitive-loop-if-addr<-named/imm32/next +12076 _Primitive-loop-if-addr<-named: # (payload primitive) +12077 0x11/imm32/alloc-id:fake:payload +12078 0x11/imm32/alloc-id:fake +12079 _string-loop-if-addr</imm32/name +12080 0x11/imm32/alloc-id:fake +12081 Single-lit-var/imm32/inouts +12082 0/imm32/no-outputs +12083 0/imm32/no-outputs +12084 0x11/imm32/alloc-id:fake +12085 _string_0f_82_jump_label/imm32/subx-name +12086 0/imm32/no-rm32 +12087 0/imm32/no-r32 +12088 0/imm32/no-imm32 +12089 1/imm32/disp32-is-first-inout +12090 0/imm32/no-output +12091 0x11/imm32/alloc-id:fake +12092 _Primitive-loop-if-addr>=-named/imm32/next +12093 _Primitive-loop-if-addr>=-named: # (payload primitive) 12094 0x11/imm32/alloc-id:fake:payload -12095 # "0f 85/jump-if-!=" -12096 0x10/imm32/size -12097 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -12098 _string_0f_85_jump_break: # (payload array byte) -12099 0x11/imm32/alloc-id:fake:payload -12100 # "0f 85/jump-if-!= break/disp32" -12101 0x1d/imm32/size -12102 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12103 _string_0f_85_jump_loop: # (payload array byte) -12104 0x11/imm32/alloc-id:fake:payload -12105 # "0f 85/jump-if-!= loop/disp32" -12106 0x1c/imm32/size -12107 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12108 _string_0f_86_jump_label: # (payload array byte) -12109 0x11/imm32/alloc-id:fake:payload -12110 # "0f 86/jump-if-addr<=" -12111 0x14/imm32/size -12112 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -12113 _string_0f_86_jump_break: # (payload array byte) -12114 0x11/imm32/alloc-id:fake:payload -12115 # "0f 86/jump-if-addr<= break/disp32" -12116 0x21/imm32/size -12117 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12118 _string_0f_86_jump_loop: # (payload array byte) -12119 0x11/imm32/alloc-id:fake:payload -12120 # "0f 86/jump-if-addr<= loop/disp32" -12121 0x20/imm32/size -12122 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12123 _string_0f_87_jump_label: # (payload array byte) -12124 0x11/imm32/alloc-id:fake:payload -12125 # "0f 87/jump-if-addr>" -12126 0x13/imm32/size -12127 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -12128 _string_0f_87_jump_break: # (payload array byte) -12129 0x11/imm32/alloc-id:fake:payload -12130 # "0f 87/jump-if-addr> break/disp32" -12131 0x20/imm32/size -12132 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12133 _string_0f_87_jump_loop: # (payload array byte) -12134 0x11/imm32/alloc-id:fake:payload -12135 # "0f 87/jump-if-addr> loop/disp32" -12136 0x1f/imm32/size -12137 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12138 _string_0f_8c_jump_label: # (payload array byte) -12139 0x11/imm32/alloc-id:fake:payload -12140 # "0f 8c/jump-if-<" -12141 0xf/imm32/size -12142 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -12143 _string_0f_8c_jump_break: # (payload array byte) -12144 0x11/imm32/alloc-id:fake:payload -12145 # "0f 8c/jump-if-< break/disp32" -12146 0x1c/imm32/size -12147 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12148 _string_0f_8c_jump_loop: # (payload array byte) -12149 0x11/imm32/alloc-id:fake:payload -12150 # "0f 8c/jump-if-< loop/disp32" -12151 0x1b/imm32/size -12152 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12153 _string_0f_8d_jump_label: # (payload array byte) -12154 0x11/imm32/alloc-id:fake:payload -12155 # "0f 8d/jump-if->=" -12156 0x10/imm32/size -12157 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -12158 _string_0f_8d_jump_break: # (payload array byte) -12159 0x11/imm32/alloc-id:fake:payload -12160 # "0f 8d/jump-if->= break/disp32" -12161 0x1d/imm32/size -12162 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12163 _string_0f_8d_jump_loop: # (payload array byte) -12164 0x11/imm32/alloc-id:fake:payload -12165 # "0f 8d/jump-if->= loop/disp32" -12166 0x1c/imm32/size -12167 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12168 _string_0f_8e_jump_label: # (payload array byte) -12169 0x11/imm32/alloc-id:fake:payload -12170 # "0f 8e/jump-if-<=" -12171 0x10/imm32/size -12172 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -12173 _string_0f_8e_jump_break: # (payload array byte) -12174 0x11/imm32/alloc-id:fake:payload -12175 # "0f 8e/jump-if-<= break/disp32" -12176 0x1d/imm32/size -12177 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12178 _string_0f_8e_jump_loop: # (payload array byte) +12095 0x11/imm32/alloc-id:fake +12096 _string-loop-if-addr>=/imm32/name +12097 0x11/imm32/alloc-id:fake +12098 Single-lit-var/imm32/inouts +12099 0/imm32/no-outputs +12100 0/imm32/no-outputs +12101 0x11/imm32/alloc-id:fake +12102 _string_0f_83_jump_label/imm32/subx-name +12103 0/imm32/no-rm32 +12104 0/imm32/no-r32 +12105 0/imm32/no-imm32 +12106 1/imm32/disp32-is-first-inout +12107 0/imm32/no-output +12108 0x11/imm32/alloc-id:fake +12109 _Primitive-loop-if-=-named/imm32/next +12110 _Primitive-loop-if-=-named: # (payload primitive) +12111 0x11/imm32/alloc-id:fake:payload +12112 0x11/imm32/alloc-id:fake +12113 _string-loop-if-=/imm32/name +12114 0x11/imm32/alloc-id:fake +12115 Single-lit-var/imm32/inouts +12116 0/imm32/no-outputs +12117 0/imm32/no-outputs +12118 0x11/imm32/alloc-id:fake +12119 _string_0f_84_jump_label/imm32/subx-name +12120 0/imm32/no-rm32 +12121 0/imm32/no-r32 +12122 0/imm32/no-imm32 +12123 1/imm32/disp32-is-first-inout +12124 0/imm32/no-output +12125 0x11/imm32/alloc-id:fake +12126 _Primitive-loop-if-!=-named/imm32/next +12127 _Primitive-loop-if-!=-named: # (payload primitive) +12128 0x11/imm32/alloc-id:fake:payload +12129 0x11/imm32/alloc-id:fake +12130 _string-loop-if-!=/imm32/name +12131 0x11/imm32/alloc-id:fake +12132 Single-lit-var/imm32/inouts +12133 0/imm32/no-outputs +12134 0/imm32/no-outputs +12135 0x11/imm32/alloc-id:fake +12136 _string_0f_85_jump_label/imm32/subx-name +12137 0/imm32/no-rm32 +12138 0/imm32/no-r32 +12139 0/imm32/no-imm32 +12140 1/imm32/disp32-is-first-inout +12141 0/imm32/no-output +12142 0x11/imm32/alloc-id:fake +12143 _Primitive-loop-if-addr<=-named/imm32/next +12144 _Primitive-loop-if-addr<=-named: # (payload primitive) +12145 0x11/imm32/alloc-id:fake:payload +12146 0x11/imm32/alloc-id:fake +12147 _string-loop-if-addr<=/imm32/name +12148 0x11/imm32/alloc-id:fake +12149 Single-lit-var/imm32/inouts +12150 0/imm32/no-outputs +12151 0/imm32/no-outputs +12152 0x11/imm32/alloc-id:fake +12153 _string_0f_86_jump_label/imm32/subx-name +12154 0/imm32/no-rm32 +12155 0/imm32/no-r32 +12156 0/imm32/no-imm32 +12157 1/imm32/disp32-is-first-inout +12158 0/imm32/no-output +12159 0x11/imm32/alloc-id:fake +12160 _Primitive-loop-if-addr>-named/imm32/next +12161 _Primitive-loop-if-addr>-named: # (payload primitive) +12162 0x11/imm32/alloc-id:fake:payload +12163 0x11/imm32/alloc-id:fake +12164 _string-loop-if-addr>/imm32/name +12165 0x11/imm32/alloc-id:fake +12166 Single-lit-var/imm32/inouts +12167 0/imm32/no-outputs +12168 0/imm32/no-outputs +12169 0x11/imm32/alloc-id:fake +12170 _string_0f_87_jump_label/imm32/subx-name +12171 0/imm32/no-rm32 +12172 0/imm32/no-r32 +12173 0/imm32/no-imm32 +12174 1/imm32/disp32-is-first-inout +12175 0/imm32/no-output +12176 0x11/imm32/alloc-id:fake +12177 _Primitive-loop-if-<-named/imm32/next +12178 _Primitive-loop-if-<-named: # (payload primitive) 12179 0x11/imm32/alloc-id:fake:payload -12180 # "0f 8e/jump-if-<= loop/disp32" -12181 0x1c/imm32/size -12182 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12183 _string_0f_8f_jump_label: # (payload array byte) -12184 0x11/imm32/alloc-id:fake:payload -12185 # "0f 8f/jump-if->" -12186 0xf/imm32/size -12187 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -12188 _string_0f_8f_jump_break: # (payload array byte) -12189 0x11/imm32/alloc-id:fake:payload -12190 # "0f 8f/jump-if-> break/disp32" -12191 0x1c/imm32/size -12192 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12193 _string_0f_8f_jump_loop: # (payload array byte) -12194 0x11/imm32/alloc-id:fake:payload -12195 # "0f 8f/jump-if-> loop/disp32" -12196 0x1b/imm32/size -12197 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12198 _string_0f_af_multiply: # (payload array byte) -12199 0x11/imm32/alloc-id:fake:payload -12200 # "0f af/multiply" -12201 0xe/imm32/size -12202 0x30/0 0x66/f 0x20/space 0x61/a 0x66/f 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -12203 _string_21_and_with: # (payload array byte) -12204 0x11/imm32/alloc-id:fake:payload -12205 # "21/and-with" -12206 0xb/imm32/size -12207 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -12208 _string_23_and: # (payload array byte) -12209 0x11/imm32/alloc-id:fake:payload -12210 # "23/and" -12211 0x6/imm32/size -12212 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d -12213 _string_25_and_with_eax: # (payload array byte) -12214 0x11/imm32/alloc-id:fake:payload -12215 # "25/and-with-eax" -12216 0xf/imm32/size -12217 0x32/2 0x35/5 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -12218 _string_29_subtract_from: # (payload array byte) -12219 0x11/imm32/alloc-id:fake:payload -12220 # "29/subtract-from" -12221 0x10/imm32/size -12222 0x32/2 0x39/9 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m -12223 _string_2b_subtract: # (payload array byte) -12224 0x11/imm32/alloc-id:fake:payload -12225 # "2b/subtract" -12226 0xb/imm32/size -12227 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -12228 _string_2d_subtract_from_eax: # (payload array byte) -12229 0x11/imm32/alloc-id:fake:payload -12230 # "2d/subtract-from-eax" -12231 0x14/imm32/size -12232 0x32/2 0x64/d 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m 0x2d/dash 0x65/e 0x61/a 0x78/x -12233 _string_31_xor_with: # (payload array byte) -12234 0x11/imm32/alloc-id:fake:payload -12235 # "31/xor-with" -12236 0xb/imm32/size -12237 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -12238 _string_33_xor: # (payload array byte) -12239 0x11/imm32/alloc-id:fake:payload -12240 # "33/xor" -12241 0x6/imm32/size -12242 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r -12243 _string_35_xor_with_eax: # (payload array byte) -12244 0x11/imm32/alloc-id:fake:payload -12245 # "35/xor-with-eax" -12246 0xf/imm32/size -12247 0x33/3 0x35/5 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -12248 _string_39_compare->: # (payload array byte) -12249 0x11/imm32/alloc-id:fake:payload -12250 # "39/compare->" -12251 0xc/imm32/size -12252 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> -12253 _string_3b_compare<-: # (payload array byte) -12254 0x11/imm32/alloc-id:fake:payload -12255 # "3b/compare<-" -12256 0xc/imm32/size -12257 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash -12258 _string_3d_compare_eax_with: # (payload array byte) -12259 0x11/imm32/alloc-id:fake:payload -12260 # "3d/compare-eax-with" -12261 0x13/imm32/size -12262 0x33/3 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x65/e 0x61/a 0x78/x 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -12263 _string_40_increment_eax: # (payload array byte) -12264 0x11/imm32/alloc-id:fake:payload -12265 # "40/increment-eax" -12266 0x10/imm32/size -12267 0x34/4 0x30/0 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x -12268 _string_41_increment_ecx: # (payload array byte) -12269 0x11/imm32/alloc-id:fake:payload -12270 # "41/increment-ecx" -12271 0x10/imm32/size -12272 0x34/4 0x31/1 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x -12273 _string_42_increment_edx: # (payload array byte) -12274 0x11/imm32/alloc-id:fake:payload -12275 # "42/increment-edx" -12276 0x10/imm32/size -12277 0x34/4 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x -12278 _string_43_increment_ebx: # (payload array byte) -12279 0x11/imm32/alloc-id:fake:payload -12280 # "43/increment-ebx" -12281 0x10/imm32/size -12282 0x34/4 0x33/3 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x -12283 _string_46_increment_esi: # (payload array byte) -12284 0x11/imm32/alloc-id:fake:payload -12285 # "46/increment-esi" -12286 0x10/imm32/size -12287 0x34/4 0x36/6 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i -12288 _string_47_increment_edi: # (payload array byte) -12289 0x11/imm32/alloc-id:fake:payload -12290 # "47/increment-edi" -12291 0x10/imm32/size -12292 0x34/4 0x37/7 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i -12293 _string_48_decrement_eax: # (payload array byte) -12294 0x11/imm32/alloc-id:fake:payload -12295 # "48/decrement-eax" -12296 0x10/imm32/size -12297 0x34/4 0x38/8 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x -12298 _string_49_decrement_ecx: # (payload array byte) -12299 0x11/imm32/alloc-id:fake:payload -12300 # "49/decrement-ecx" -12301 0x10/imm32/size -12302 0x34/4 0x39/9 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x -12303 _string_4a_decrement_edx: # (payload array byte) -12304 0x11/imm32/alloc-id:fake:payload -12305 # "4a/decrement-edx" -12306 0x10/imm32/size -12307 0x34/4 0x61/a 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x -12308 _string_4b_decrement_ebx: # (payload array byte) -12309 0x11/imm32/alloc-id:fake:payload -12310 # "4b/decrement-ebx" -12311 0x10/imm32/size -12312 0x34/4 0x62/b 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x -12313 _string_4e_decrement_esi: # (payload array byte) -12314 0x11/imm32/alloc-id:fake:payload -12315 # "4e/decrement-esi" -12316 0x10/imm32/size -12317 0x34/4 0x65/e 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i -12318 _string_4f_decrement_edi: # (payload array byte) -12319 0x11/imm32/alloc-id:fake:payload -12320 # "4f/decrement-edi" -12321 0x10/imm32/size -12322 0x34/4 0x66/f 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i -12323 _string_81_subop_add: # (payload array byte) -12324 0x11/imm32/alloc-id:fake:payload -12325 # "81 0/subop/add" -12326 0xe/imm32/size -12327 0x38/8 0x31/1 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x64/d 0x64/d -12328 _string_81_subop_or: # (payload array byte) -12329 0x11/imm32/alloc-id:fake:payload -12330 # "81 1/subop/or" -12331 0xd/imm32/size -12332 0x38/8 0x31/1 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6f/o 0x72/r -12333 _string_81_subop_and: # (payload array byte) -12334 0x11/imm32/alloc-id:fake:payload -12335 # "81 4/subop/and" -12336 0xe/imm32/size -12337 0x38/8 0x31/1 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x6e/n 0x64/d -12338 _string_81_subop_subtract: # (payload array byte) -12339 0x11/imm32/alloc-id:fake:payload -12340 # "81 5/subop/subtract" -12341 0x13/imm32/size -12342 0x38/8 0x31/1 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -12343 _string_81_subop_xor: # (payload array byte) -12344 0x11/imm32/alloc-id:fake:payload -12345 # "81 6/subop/xor" -12346 0xe/imm32/size -12347 0x38/8 0x31/1 0x20/space 0x36/6 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x78/x 0x6f/o 0x72/r -12348 _string_81_subop_compare: # (payload array byte) -12349 0x11/imm32/alloc-id:fake:payload -12350 # "81 7/subop/compare" -12351 0x12/imm32/size -12352 0x38/8 0x31/1 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -12353 _string_89_<-: # (payload array byte) -12354 0x11/imm32/alloc-id:fake:payload -12355 # "89/<-" -12356 0x5/imm32/size -12357 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash -12358 _string_8b_->: # (payload array byte) -12359 0x11/imm32/alloc-id:fake:payload -12360 # "8b/->" -12361 0x5/imm32/size -12362 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> -12363 _string_8d_copy_address: # (payload array byte) -12364 0x11/imm32/alloc-id:fake:payload -12365 # "8d/copy-address" -12366 0xf/imm32/size -12367 0x38/8 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s -12368 _string_b8_copy_to_eax: # (payload array byte) -12369 0x11/imm32/alloc-id:fake:payload -12370 # "b8/copy-to-eax" -12371 0xe/imm32/size -12372 0x62/b 0x38/8 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x -12373 _string_b9_copy_to_ecx: # (payload array byte) -12374 0x11/imm32/alloc-id:fake:payload -12375 # "b9/copy-to-ecx" -12376 0xe/imm32/size -12377 0x62/b 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x63/c 0x78/x -12378 _string_ba_copy_to_edx: # (payload array byte) -12379 0x11/imm32/alloc-id:fake:payload -12380 # "ba/copy-to-edx" -12381 0xe/imm32/size -12382 0x62/b 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x78/x -12383 _string_bb_copy_to_ebx: # (payload array byte) -12384 0x11/imm32/alloc-id:fake:payload -12385 # "bb/copy-to-ebx" -12386 0xe/imm32/size -12387 0x62/b 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x62/b 0x78/x -12388 _string_be_copy_to_esi: # (payload array byte) -12389 0x11/imm32/alloc-id:fake:payload -12390 # "be/copy-to-esi" -12391 0xe/imm32/size -12392 0x62/b 0x65/e 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x73/s 0x69/i -12393 _string_bf_copy_to_edi: # (payload array byte) -12394 0x11/imm32/alloc-id:fake:payload -12395 # "bf/copy-to-edi" -12396 0xe/imm32/size -12397 0x62/b 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x69/i -12398 _string_c7_subop_copy: # (payload array byte) -12399 0x11/imm32/alloc-id:fake:payload -12400 # "c7 0/subop/copy" -12401 0xf/imm32/size -12402 0x63/c 0x37/7 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y -12403 _string_e9_jump_label: # (payload array byte) -12404 0x11/imm32/alloc-id:fake:payload -12405 # "e9/jump" -12406 0x7/imm32/size -12407 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p -12408 _string_e9_jump_break: # (payload array byte) -12409 0x11/imm32/alloc-id:fake:payload -12410 # "e9/jump break/disp32" -12411 0x14/imm32/size -12412 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12413 _string_e9_jump_loop: # (payload array byte) -12414 0x11/imm32/alloc-id:fake:payload -12415 # "e9/jump loop/disp32" -12416 0x13/imm32/size -12417 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -12418 _string_ff_subop_increment: # (payload array byte) -12419 0x11/imm32/alloc-id:fake:payload -12420 # "ff 0/subop/increment" -12421 0x14/imm32/size -12422 0x66/f 0x66/f 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -12423 _string_ff_subop_decrement: # (payload array byte) -12424 0x11/imm32/alloc-id:fake:payload -12425 # "ff 1/subop/decrement" -12426 0x14/imm32/size -12427 0x66/f 0x66/f 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -12428 -12429 Single-int-var-in-mem: # (payload list var) -12430 0x11/imm32/alloc-id:fake:payload -12431 0x11/imm32/alloc-id:fake -12432 Int-var-in-mem/imm32 -12433 0/imm32/next -12434 0/imm32/next -12435 -12436 Int-var-in-mem: # (payload var) -12437 0x11/imm32/alloc-id:fake:payload -12438 0/imm32/name -12439 0/imm32/name -12440 0x11/imm32/alloc-id:fake -12441 Type-int/imm32 -12442 1/imm32/some-block-depth -12443 1/imm32/some-stack-offset -12444 0/imm32/no-register -12445 0/imm32/no-register -12446 -12447 Two-args-int-stack-int-reg: # (payload list var) -12448 0x11/imm32/alloc-id:fake:payload -12449 0x11/imm32/alloc-id:fake -12450 Int-var-in-mem/imm32 -12451 0x11/imm32/alloc-id:fake -12452 Single-int-var-in-some-register/imm32/next -12453 -12454 Two-args-int-reg-int-stack: # (payload list var) -12455 0x11/imm32/alloc-id:fake:payload -12456 0x11/imm32/alloc-id:fake -12457 Int-var-in-some-register/imm32 -12458 0x11/imm32/alloc-id:fake -12459 Single-int-var-in-mem/imm32/next +12180 0x11/imm32/alloc-id:fake +12181 _string-loop-if-</imm32/name +12182 0x11/imm32/alloc-id:fake +12183 Single-lit-var/imm32/inouts +12184 0/imm32/no-outputs +12185 0/imm32/no-outputs +12186 0x11/imm32/alloc-id:fake +12187 _string_0f_8c_jump_label/imm32/subx-name +12188 0/imm32/no-rm32 +12189 0/imm32/no-r32 +12190 0/imm32/no-imm32 +12191 1/imm32/disp32-is-first-inout +12192 0/imm32/no-output +12193 0x11/imm32/alloc-id:fake +12194 _Primitive-loop-if->=-named/imm32/next +12195 _Primitive-loop-if->=-named: # (payload primitive) +12196 0x11/imm32/alloc-id:fake:payload +12197 0x11/imm32/alloc-id:fake +12198 _string-loop-if->=/imm32/name +12199 0x11/imm32/alloc-id:fake +12200 Single-lit-var/imm32/inouts +12201 0/imm32/no-outputs +12202 0/imm32/no-outputs +12203 0x11/imm32/alloc-id:fake +12204 _string_0f_8d_jump_label/imm32/subx-name +12205 0/imm32/no-rm32 +12206 0/imm32/no-r32 +12207 0/imm32/no-imm32 +12208 1/imm32/disp32-is-first-inout +12209 0/imm32/no-output +12210 0x11/imm32/alloc-id:fake +12211 _Primitive-loop-if-<=-named/imm32/next +12212 _Primitive-loop-if-<=-named: # (payload primitive) +12213 0x11/imm32/alloc-id:fake:payload +12214 0x11/imm32/alloc-id:fake +12215 _string-loop-if-<=/imm32/name +12216 0x11/imm32/alloc-id:fake +12217 Single-lit-var/imm32/inouts +12218 0/imm32/no-outputs +12219 0/imm32/no-outputs +12220 0x11/imm32/alloc-id:fake +12221 _string_0f_8e_jump_label/imm32/subx-name +12222 0/imm32/no-rm32 +12223 0/imm32/no-r32 +12224 0/imm32/no-imm32 +12225 1/imm32/disp32-is-first-inout +12226 0/imm32/no-output +12227 0x11/imm32/alloc-id:fake +12228 _Primitive-loop-if->-named/imm32/next +12229 _Primitive-loop-if->-named: # (payload primitive) +12230 0x11/imm32/alloc-id:fake:payload +12231 0x11/imm32/alloc-id:fake +12232 _string-loop-if->/imm32/name +12233 0x11/imm32/alloc-id:fake +12234 Single-lit-var/imm32/inouts +12235 0/imm32/no-outputs +12236 0/imm32/no-outputs +12237 0x11/imm32/alloc-id:fake +12238 _string_0f_8f_jump_label/imm32/subx-name +12239 0/imm32/no-rm32 +12240 0/imm32/no-r32 +12241 0/imm32/no-imm32 +12242 1/imm32/disp32-is-first-inout +12243 0/imm32/no-output +12244 0x11/imm32/alloc-id:fake +12245 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break +12246 _Primitive-loop-named: # (payload primitive) +12247 0x11/imm32/alloc-id:fake:payload +12248 0x11/imm32/alloc-id:fake +12249 _string-loop/imm32/name +12250 0x11/imm32/alloc-id:fake +12251 Single-lit-var/imm32/inouts +12252 0/imm32/no-outputs +12253 0/imm32/no-outputs +12254 0x11/imm32/alloc-id:fake +12255 _string_e9_jump_label/imm32/subx-name +12256 0/imm32/no-rm32 +12257 0/imm32/no-r32 +12258 0/imm32/no-imm32 +12259 1/imm32/disp32-is-first-inout +12260 0/imm32/no-output +12261 0/imm32/next +12262 0/imm32/next +12263 +12264 # string literals for Mu instructions +12265 _string-add: # (payload array byte) +12266 0x11/imm32/alloc-id:fake:payload +12267 # "add" +12268 0x3/imm32/size +12269 0x61/a 0x64/d 0x64/d +12270 _string-address: # (payload array byte) +12271 0x11/imm32/alloc-id:fake:payload +12272 # "address" +12273 0x7/imm32/size +12274 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s +12275 _string-add-to: # (payload array byte) +12276 0x11/imm32/alloc-id:fake:payload +12277 # "add-to" +12278 0x6/imm32/size +12279 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +12280 _string-and: # (payload array byte) +12281 0x11/imm32/alloc-id:fake:payload +12282 # "and" +12283 0x3/imm32/size +12284 0x61/a 0x6e/n 0x64/d +12285 _string-and-with: # (payload array byte) +12286 0x11/imm32/alloc-id:fake:payload +12287 # "and-with" +12288 0x8/imm32/size +12289 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +12290 _string-break: # (payload array byte) +12291 0x11/imm32/alloc-id:fake:payload +12292 # "break" +12293 0x5/imm32/size +12294 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k +12295 _string-break-if-<: # (payload array byte) +12296 0x11/imm32/alloc-id:fake:payload +12297 # "break-if-<" +12298 0xa/imm32/size +12299 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +12300 _string-break-if-<=: # (payload array byte) +12301 0x11/imm32/alloc-id:fake:payload +12302 # "break-if-<=" +12303 0xb/imm32/size +12304 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +12305 _string-break-if-=: # (payload array byte) +12306 0x11/imm32/alloc-id:fake:payload +12307 # "break-if-=" +12308 0xa/imm32/size +12309 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +12310 _string-break-if->: # (payload array byte) +12311 0x11/imm32/alloc-id:fake:payload +12312 # "break-if->" +12313 0xa/imm32/size +12314 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +12315 _string-break-if->=: # (payload array byte) +12316 0x11/imm32/alloc-id:fake:payload +12317 # "break-if->=" +12318 0xb/imm32/size +12319 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +12320 _string-break-if-!=: # (payload array byte) +12321 0x11/imm32/alloc-id:fake:payload +12322 # "break-if-!=" +12323 0xb/imm32/size +12324 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +12325 _string-break-if-addr<: # (payload array byte) +12326 0x11/imm32/alloc-id:fake:payload +12327 # "break-if-addr<" +12328 0xe/imm32/size +12329 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +12330 _string-break-if-addr<=: # (payload array byte) +12331 0x11/imm32/alloc-id:fake:payload +12332 # "break-if-addr<=" +12333 0xf/imm32/size +12334 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +12335 _string-break-if-addr>: # (payload array byte) +12336 0x11/imm32/alloc-id:fake:payload +12337 # "break-if-addr>" +12338 0xe/imm32/size +12339 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +12340 _string-break-if-addr>=: # (payload array byte) +12341 0x11/imm32/alloc-id:fake:payload +12342 # "break-if-addr>=" +12343 0xf/imm32/size +12344 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +12345 _string-compare: # (payload array byte) +12346 0x11/imm32/alloc-id:fake:payload +12347 # "compare" +12348 0x7/imm32/size +12349 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +12350 _string-copy: # (payload array byte) +12351 0x11/imm32/alloc-id:fake:payload +12352 # "copy" +12353 0x4/imm32/size +12354 0x63/c 0x6f/o 0x70/p 0x79/y +12355 _string-copy-to: # (payload array byte) +12356 0x11/imm32/alloc-id:fake:payload +12357 # "copy-to" +12358 0x7/imm32/size +12359 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o +12360 _string-decrement: # (payload array byte) +12361 0x11/imm32/alloc-id:fake:payload +12362 # "decrement" +12363 0x9/imm32/size +12364 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +12365 _string-increment: # (payload array byte) +12366 0x11/imm32/alloc-id:fake:payload +12367 # "increment" +12368 0x9/imm32/size +12369 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +12370 _string-loop: # (payload array byte) +12371 0x11/imm32/alloc-id:fake:payload +12372 # "loop" +12373 0x4/imm32/size +12374 0x6c/l 0x6f/o 0x6f/o 0x70/p +12375 _string-loop-if-<: # (payload array byte) +12376 0x11/imm32/alloc-id:fake:payload +12377 # "loop-if-<" +12378 0x9/imm32/size +12379 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +12380 _string-loop-if-<=: # (payload array byte) +12381 0x11/imm32/alloc-id:fake:payload +12382 # "loop-if-<=" +12383 0xa/imm32/size +12384 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +12385 _string-loop-if-=: # (payload array byte) +12386 0x11/imm32/alloc-id:fake:payload +12387 # "loop-if-=" +12388 0x9/imm32/size +12389 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +12390 _string-loop-if->: # (payload array byte) +12391 0x11/imm32/alloc-id:fake:payload +12392 # "loop-if->" +12393 0x9/imm32/size +12394 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +12395 _string-loop-if->=: # (payload array byte) +12396 0x11/imm32/alloc-id:fake:payload +12397 # "loop-if->=" +12398 0xa/imm32/size +12399 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +12400 _string-loop-if-!=: # (payload array byte) +12401 0x11/imm32/alloc-id:fake:payload +12402 # "loop-if-!=" +12403 0xa/imm32/size +12404 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +12405 _string-loop-if-addr<: # (payload array byte) +12406 0x11/imm32/alloc-id:fake:payload +12407 # "loop-if-addr<" +12408 0xd/imm32/size +12409 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +12410 _string-loop-if-addr<=: # (payload array byte) +12411 0x11/imm32/alloc-id:fake:payload +12412 # "loop-if-addr<=" +12413 0xe/imm32/size +12414 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +12415 _string-loop-if-addr>: # (payload array byte) +12416 0x11/imm32/alloc-id:fake:payload +12417 # "loop-if-addr>" +12418 0xd/imm32/size +12419 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +12420 _string-loop-if-addr>=: # (payload array byte) +12421 0x11/imm32/alloc-id:fake:payload +12422 # "loop-if-addr>=" +12423 0xe/imm32/size +12424 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +12425 _string-multiply: # (payload array byte) +12426 0x11/imm32/alloc-id:fake:payload +12427 # "multiply" +12428 0x8/imm32/size +12429 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +12430 _string-or: # (payload array byte) +12431 0x11/imm32/alloc-id:fake:payload +12432 # "or" +12433 0x2/imm32/size +12434 0x6f/o 0x72/r +12435 _string-or-with: # (payload array byte) +12436 0x11/imm32/alloc-id:fake:payload +12437 # "or-with" +12438 0x7/imm32/size +12439 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +12440 _string-subtract: # (payload array byte) +12441 0x11/imm32/alloc-id:fake:payload +12442 # "subtract" +12443 0x8/imm32/size +12444 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +12445 _string-subtract-from: # (payload array byte) +12446 0x11/imm32/alloc-id:fake:payload +12447 # "subtract-from" +12448 0xd/imm32/size +12449 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m +12450 _string-xor: # (payload array byte) +12451 0x11/imm32/alloc-id:fake:payload +12452 # "xor" +12453 0x3/imm32/size +12454 0x78/x 0x6f/o 0x72/r +12455 _string-xor-with: # (payload array byte) +12456 0x11/imm32/alloc-id:fake:payload +12457 # "xor-with" +12458 0x8/imm32/size +12459 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 12460 -12461 Two-args-int-eax-int-literal: # (payload list var) -12462 0x11/imm32/alloc-id:fake:payload -12463 0x11/imm32/alloc-id:fake -12464 Int-var-in-eax/imm32 -12465 0x11/imm32/alloc-id:fake -12466 Single-lit-var/imm32/next -12467 -12468 Int-var-and-literal: # (payload list var) -12469 0x11/imm32/alloc-id:fake:payload -12470 0x11/imm32/alloc-id:fake -12471 Int-var-in-mem/imm32 -12472 0x11/imm32/alloc-id:fake -12473 Single-lit-var/imm32/next -12474 -12475 Int-var-in-register-and-literal: # (payload list var) -12476 0x11/imm32/alloc-id:fake:payload -12477 0x11/imm32/alloc-id:fake -12478 Int-var-in-some-register/imm32 -12479 0x11/imm32/alloc-id:fake -12480 Single-lit-var/imm32/next -12481 -12482 Single-int-var-in-some-register: # (payload list var) +12461 # string literals for SubX instructions +12462 _string_01_add_to: # (payload array byte) +12463 0x11/imm32/alloc-id:fake:payload +12464 # "01/add-to" +12465 0x9/imm32/size +12466 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +12467 _string_03_add: # (payload array byte) +12468 0x11/imm32/alloc-id:fake:payload +12469 # "03/add" +12470 0x6/imm32/size +12471 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d +12472 _string_05_add_to_eax: # (payload array byte) +12473 0x11/imm32/alloc-id:fake:payload +12474 # "05/add-to-eax" +12475 0xd/imm32/size +12476 0x30/0 0x35/5 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x +12477 _string_09_or_with: # (payload array byte) +12478 0x11/imm32/alloc-id:fake:payload +12479 # "09/or-with" +12480 0xa/imm32/size +12481 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +12482 _string_0b_or: # (payload array byte) 12483 0x11/imm32/alloc-id:fake:payload -12484 0x11/imm32/alloc-id:fake -12485 Int-var-in-some-register/imm32 -12486 0/imm32/next -12487 0/imm32/next -12488 -12489 Single-addr-var-in-some-register: # (payload list var) -12490 0x11/imm32/alloc-id:fake:payload -12491 0x11/imm32/alloc-id:fake -12492 Addr-var-in-some-register/imm32 -12493 0/imm32/next -12494 0/imm32/next -12495 -12496 Int-var-in-some-register: # (payload var) -12497 0x11/imm32/alloc-id:fake:payload -12498 0/imm32/name -12499 0/imm32/name -12500 0x11/imm32/alloc-id:fake -12501 Type-int/imm32 -12502 1/imm32/some-block-depth -12503 0/imm32/no-stack-offset -12504 0x11/imm32/alloc-id:fake -12505 Any-register/imm32 -12506 -12507 Any-register: # (payload array byte) -12508 0x11/imm32/alloc-id:fake:payload -12509 1/imm32/size -12510 # data -12511 2a/asterisk -12512 -12513 Addr-var-in-some-register: # (payload var) -12514 0x11/imm32/alloc-id:fake:payload -12515 0/imm32/name -12516 0/imm32/name -12517 0x11/imm32/alloc-id:fake -12518 Type-addr/imm32 -12519 1/imm32/some-block-depth -12520 0/imm32/no-stack-offset -12521 0x11/imm32/alloc-id:fake -12522 Any-register/imm32 -12523 -12524 Single-int-var-in-eax: # (payload list var) -12525 0x11/imm32/alloc-id:fake:payload -12526 0x11/imm32/alloc-id:fake -12527 Int-var-in-eax/imm32 -12528 0/imm32/next -12529 0/imm32/next -12530 -12531 Int-var-in-eax: -12532 0x11/imm32/alloc-id:fake:payload -12533 0/imm32/name -12534 0/imm32/name -12535 0x11/imm32/alloc-id:fake -12536 Type-int/imm32 -12537 1/imm32/some-block-depth -12538 0/imm32/no-stack-offset -12539 0x11/imm32/alloc-id:fake -12540 $Register-eax/imm32 -12541 -12542 Single-int-var-in-ecx: # (payload list var) +12484 # "0b/or" +12485 0x5/imm32/size +12486 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r +12487 _string_0d_or_with_eax: # (payload array byte) +12488 0x11/imm32/alloc-id:fake:payload +12489 # "0d/or-with-eax" +12490 0xe/imm32/size +12491 0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +12492 _string_0f_82_jump_label: # (payload array byte) +12493 0x11/imm32/alloc-id:fake:payload +12494 # "0f 82/jump-if-addr<" +12495 0x13/imm32/size +12496 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +12497 _string_0f_82_jump_break: # (payload array byte) +12498 0x11/imm32/alloc-id:fake:payload +12499 # "0f 82/jump-if-addr< break/disp32" +12500 0x20/imm32/size +12501 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12502 _string_0f_82_jump_loop: # (payload array byte) +12503 0x11/imm32/alloc-id:fake:payload +12504 # "0f 82/jump-if-addr< loop/disp32" +12505 0x1f/imm32/size +12506 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12507 _string_0f_83_jump_label: # (payload array byte) +12508 0x11/imm32/alloc-id:fake:payload +12509 # "0f 83/jump-if-addr>=" +12510 0x14/imm32/size +12511 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +12512 _string_0f_83_jump_break: # (payload array byte) +12513 0x11/imm32/alloc-id:fake:payload +12514 # "0f 83/jump-if-addr>= break/disp32" +12515 0x21/imm32/size +12516 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12517 _string_0f_83_jump_loop: # (payload array byte) +12518 0x11/imm32/alloc-id:fake:payload +12519 # "0f 83/jump-if-addr>= loop/disp32" +12520 0x20/imm32/size +12521 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12522 _string_0f_84_jump_label: # (payload array byte) +12523 0x11/imm32/alloc-id:fake:payload +12524 # "0f 84/jump-if-=" +12525 0xf/imm32/size +12526 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +12527 _string_0f_84_jump_break: # (payload array byte) +12528 0x11/imm32/alloc-id:fake:payload +12529 # "0f 84/jump-if-= break/disp32" +12530 0x1c/imm32/size +12531 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12532 _string_0f_84_jump_loop: # (payload array byte) +12533 0x11/imm32/alloc-id:fake:payload +12534 # "0f 84/jump-if-= loop/disp32" +12535 0x1b/imm32/size +12536 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12537 _string_0f_85_jump_label: # (payload array byte) +12538 0x11/imm32/alloc-id:fake:payload +12539 # "0f 85/jump-if-!=" +12540 0x10/imm32/size +12541 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +12542 _string_0f_85_jump_break: # (payload array byte) 12543 0x11/imm32/alloc-id:fake:payload -12544 0x11/imm32/alloc-id:fake -12545 Int-var-in-ecx/imm32 -12546 0/imm32/next -12547 0/imm32/next -12548 -12549 Int-var-in-ecx: -12550 0x11/imm32/alloc-id:fake:payload -12551 0/imm32/name -12552 0/imm32/name -12553 0x11/imm32/alloc-id:fake -12554 Type-int/imm32 -12555 1/imm32/some-block-depth -12556 0/imm32/no-stack-offset -12557 0x11/imm32/alloc-id:fake -12558 $Register-ecx/imm32/register -12559 -12560 Single-int-var-in-edx: # (payload list var) -12561 0x11/imm32/alloc-id:fake:payload -12562 0x11/imm32/alloc-id:fake -12563 Int-var-in-edx/imm32 -12564 0/imm32/next -12565 0/imm32/next -12566 -12567 Int-var-in-edx: # (payload list var) +12544 # "0f 85/jump-if-!= break/disp32" +12545 0x1d/imm32/size +12546 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12547 _string_0f_85_jump_loop: # (payload array byte) +12548 0x11/imm32/alloc-id:fake:payload +12549 # "0f 85/jump-if-!= loop/disp32" +12550 0x1c/imm32/size +12551 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12552 _string_0f_86_jump_label: # (payload array byte) +12553 0x11/imm32/alloc-id:fake:payload +12554 # "0f 86/jump-if-addr<=" +12555 0x14/imm32/size +12556 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +12557 _string_0f_86_jump_break: # (payload array byte) +12558 0x11/imm32/alloc-id:fake:payload +12559 # "0f 86/jump-if-addr<= break/disp32" +12560 0x21/imm32/size +12561 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12562 _string_0f_86_jump_loop: # (payload array byte) +12563 0x11/imm32/alloc-id:fake:payload +12564 # "0f 86/jump-if-addr<= loop/disp32" +12565 0x20/imm32/size +12566 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12567 _string_0f_87_jump_label: # (payload array byte) 12568 0x11/imm32/alloc-id:fake:payload -12569 0/imm32/name -12570 0/imm32/name -12571 0x11/imm32/alloc-id:fake -12572 Type-int/imm32 -12573 1/imm32/some-block-depth -12574 0/imm32/no-stack-offset -12575 0x11/imm32/alloc-id:fake -12576 $Register-edx/imm32/register -12577 -12578 Single-int-var-in-ebx: # (payload list var) -12579 0x11/imm32/alloc-id:fake:payload -12580 0x11/imm32/alloc-id:fake -12581 Int-var-in-ebx/imm32 -12582 0/imm32/next -12583 0/imm32/next -12584 -12585 Int-var-in-ebx: # (payload list var) -12586 0x11/imm32/alloc-id:fake:payload -12587 0/imm32/name -12588 0/imm32/name -12589 0x11/imm32/alloc-id:fake -12590 Type-int/imm32 -12591 1/imm32/some-block-depth -12592 0/imm32/no-stack-offset -12593 0x11/imm32/alloc-id:fake -12594 $Register-ebx/imm32/register -12595 -12596 Single-int-var-in-esi: # (payload list var) -12597 0x11/imm32/alloc-id:fake:payload -12598 0x11/imm32/alloc-id:fake -12599 Int-var-in-esi/imm32 -12600 0/imm32/next -12601 0/imm32/next -12602 -12603 Int-var-in-esi: # (payload list var) -12604 0x11/imm32/alloc-id:fake:payload -12605 0/imm32/name -12606 0/imm32/name -12607 0x11/imm32/alloc-id:fake -12608 Type-int/imm32 -12609 1/imm32/some-block-depth -12610 0/imm32/no-stack-offset -12611 0x11/imm32/alloc-id:fake -12612 $Register-esi/imm32/register -12613 -12614 Single-int-var-in-edi: # (payload list var) -12615 0x11/imm32/alloc-id:fake:payload -12616 0x11/imm32/alloc-id:fake -12617 Int-var-in-edi/imm32 -12618 0/imm32/next -12619 0/imm32/next -12620 -12621 Int-var-in-edi: # (payload list var) -12622 0x11/imm32/alloc-id:fake:payload -12623 0/imm32/name -12624 0/imm32/name -12625 0x11/imm32/alloc-id:fake -12626 Type-int/imm32 -12627 1/imm32/some-block-depth -12628 0/imm32/no-stack-offset -12629 0x11/imm32/alloc-id:fake -12630 $Register-edi/imm32/register -12631 -12632 Single-lit-var: # (payload list var) +12569 # "0f 87/jump-if-addr>" +12570 0x13/imm32/size +12571 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +12572 _string_0f_87_jump_break: # (payload array byte) +12573 0x11/imm32/alloc-id:fake:payload +12574 # "0f 87/jump-if-addr> break/disp32" +12575 0x20/imm32/size +12576 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12577 _string_0f_87_jump_loop: # (payload array byte) +12578 0x11/imm32/alloc-id:fake:payload +12579 # "0f 87/jump-if-addr> loop/disp32" +12580 0x1f/imm32/size +12581 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12582 _string_0f_8c_jump_label: # (payload array byte) +12583 0x11/imm32/alloc-id:fake:payload +12584 # "0f 8c/jump-if-<" +12585 0xf/imm32/size +12586 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +12587 _string_0f_8c_jump_break: # (payload array byte) +12588 0x11/imm32/alloc-id:fake:payload +12589 # "0f 8c/jump-if-< break/disp32" +12590 0x1c/imm32/size +12591 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12592 _string_0f_8c_jump_loop: # (payload array byte) +12593 0x11/imm32/alloc-id:fake:payload +12594 # "0f 8c/jump-if-< loop/disp32" +12595 0x1b/imm32/size +12596 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12597 _string_0f_8d_jump_label: # (payload array byte) +12598 0x11/imm32/alloc-id:fake:payload +12599 # "0f 8d/jump-if->=" +12600 0x10/imm32/size +12601 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +12602 _string_0f_8d_jump_break: # (payload array byte) +12603 0x11/imm32/alloc-id:fake:payload +12604 # "0f 8d/jump-if->= break/disp32" +12605 0x1d/imm32/size +12606 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12607 _string_0f_8d_jump_loop: # (payload array byte) +12608 0x11/imm32/alloc-id:fake:payload +12609 # "0f 8d/jump-if->= loop/disp32" +12610 0x1c/imm32/size +12611 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12612 _string_0f_8e_jump_label: # (payload array byte) +12613 0x11/imm32/alloc-id:fake:payload +12614 # "0f 8e/jump-if-<=" +12615 0x10/imm32/size +12616 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +12617 _string_0f_8e_jump_break: # (payload array byte) +12618 0x11/imm32/alloc-id:fake:payload +12619 # "0f 8e/jump-if-<= break/disp32" +12620 0x1d/imm32/size +12621 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12622 _string_0f_8e_jump_loop: # (payload array byte) +12623 0x11/imm32/alloc-id:fake:payload +12624 # "0f 8e/jump-if-<= loop/disp32" +12625 0x1c/imm32/size +12626 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12627 _string_0f_8f_jump_label: # (payload array byte) +12628 0x11/imm32/alloc-id:fake:payload +12629 # "0f 8f/jump-if->" +12630 0xf/imm32/size +12631 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +12632 _string_0f_8f_jump_break: # (payload array byte) 12633 0x11/imm32/alloc-id:fake:payload -12634 0x11/imm32/alloc-id:fake -12635 Lit-var/imm32 -12636 0/imm32/next -12637 0/imm32/next -12638 -12639 Lit-var: # (payload var) -12640 0x11/imm32/alloc-id:fake:payload -12641 0/imm32/name -12642 0/imm32/name -12643 0x11/imm32/alloc-id:fake -12644 Type-literal/imm32 -12645 1/imm32/some-block-depth -12646 0/imm32/no-stack-offset -12647 0/imm32/no-register -12648 0/imm32/no-register -12649 -12650 Type-int: # (payload tree type-id) -12651 0x11/imm32/alloc-id:fake:payload -12652 1/imm32/left-is-atom -12653 1/imm32/value:int -12654 0/imm32/left:unused -12655 0/imm32/right:null -12656 0/imm32/right:null -12657 -12658 Type-literal: # (payload tree type-id) -12659 0x11/imm32/alloc-id:fake:payload -12660 1/imm32/is-atom -12661 0/imm32/value:literal -12662 0/imm32/left:unused -12663 0/imm32/right:null -12664 0/imm32/right:null -12665 -12666 Type-addr: # (payload tree type-id) -12667 0x11/imm32/alloc-id:fake:payload -12668 1/imm32/is-atom -12669 2/imm32/value:addr -12670 0/imm32/left:unused -12671 0/imm32/right:null -12672 0/imm32/right:null -12673 -12674 == code -12675 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive) -12676 # . prologue -12677 55/push-ebp -12678 89/<- %ebp 4/r32/esp -12679 # . save registers -12680 50/push-eax -12681 51/push-ecx -12682 # ecx = primitive -12683 8b/-> *(ebp+0x10) 1/r32/ecx -12684 # emit primitive name -12685 (emit-indent *(ebp+8) *Curr-block-depth) -12686 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax -12687 (write-buffered *(ebp+8) %eax) -12688 # emit rm32 if necessary -12689 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc)) # out, Primitive-subx-rm32, stmt -12690 # emit r32 if necessary -12691 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # out, Primitive-subx-r32, stmt -12692 # emit imm32 if necessary -12693 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # out, Primitive-subx-imm32, stmt -12694 # emit disp32 if necessary -12695 (emit-subx-disp32 *(ebp+8) *(ecx+0x2c) *(ebp+0xc)) # out, Primitive-subx-disp32, stmt -12696 (write-buffered *(ebp+8) Newline) -12697 $emit-subx-primitive:end: -12698 # . restore registers -12699 59/pop-to-ecx -12700 58/pop-to-eax -12701 # . epilogue -12702 89/<- %esp 5/r32/ebp -12703 5d/pop-to-ebp -12704 c3/return -12705 -12706 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -12707 # . prologue -12708 55/push-ebp -12709 89/<- %ebp 4/r32/esp -12710 # . save registers -12711 50/push-eax -12712 # if (l == 0) return -12713 81 7/subop/compare *(ebp+0xc) 0/imm32 -12714 74/jump-if-= $emit-subx-rm32:end/disp8 -12715 # var v/eax: (addr stmt-var) -12716 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -12717 (emit-subx-var-as-rm32 *(ebp+8) %eax) -12718 $emit-subx-rm32:end: -12719 # . restore registers -12720 58/pop-to-eax -12721 # . epilogue -12722 89/<- %esp 5/r32/ebp -12723 5d/pop-to-ebp -12724 c3/return -12725 -12726 get-stmt-operand-from-arg-location: # stmt: (addr stmt), l: arg-location -> var/eax: (addr stmt-var) -12727 # . prologue -12728 55/push-ebp -12729 89/<- %ebp 4/r32/esp -12730 # . save registers -12731 51/push-ecx -12732 # eax = l -12733 8b/-> *(ebp+0xc) 0/r32/eax -12734 # ecx = stmt -12735 8b/-> *(ebp+8) 1/r32/ecx -12736 # if (l == 1) return stmt->inouts -12737 { -12738 3d/compare-eax-and 1/imm32 -12739 75/jump-if-!= break/disp8 -12740 $get-stmt-operand-from-arg-location:1: -12741 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12742 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -12743 } -12744 # if (l == 2) return stmt->inouts->next -12745 { -12746 3d/compare-eax-and 2/imm32 -12747 75/jump-if-!= break/disp8 -12748 $get-stmt-operand-from-arg-location:2: -12749 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12750 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12751 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -12752 } -12753 # if (l == 3) return stmt->outputs -12754 { -12755 3d/compare-eax-and 3/imm32 -12756 75/jump-if-!= break/disp8 -12757 $get-stmt-operand-from-arg-location:3: -12758 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12759 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -12760 } -12761 # abort -12762 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 -12763 $get-stmt-operand-from-arg-location:end: -12764 # . restore registers -12765 59/pop-to-ecx -12766 # . epilogue -12767 89/<- %esp 5/r32/ebp -12768 5d/pop-to-ebp -12769 c3/return -12770 -12771 $get-stmt-operand-from-arg-location:abort: -12772 # error("invalid arg-location " eax) -12773 (write-buffered Stderr "invalid arg-location ") -12774 (print-int32-buffered Stderr %eax) -12775 (write-buffered Stderr Newline) -12776 (flush Stderr) -12777 # . syscall(exit, 1) -12778 bb/copy-to-ebx 1/imm32 -12779 b8/copy-to-eax 1/imm32/exit -12780 cd/syscall 0x80/imm8 -12781 # never gets here -12782 -12783 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -12784 # . prologue -12785 55/push-ebp -12786 89/<- %ebp 4/r32/esp -12787 # . save registers -12788 50/push-eax -12789 51/push-ecx -12790 # if (l == 0) return -12791 81 7/subop/compare *(ebp+0xc) 0/imm32 -12792 0f 84/jump-if-= $emit-subx-r32:end/disp32 -12793 # var v/eax: (addr stmt-var) -12794 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -12795 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12796 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -12797 (maybe-get Registers %eax 0xc) # => eax: (addr register-index) -12798 (write-buffered *(ebp+8) Space) -12799 (print-int32-buffered *(ebp+8) *eax) -12800 (write-buffered *(ebp+8) "/r32") -12801 $emit-subx-r32:end: -12802 # . restore registers -12803 59/pop-to-ecx -12804 58/pop-to-eax -12805 # . epilogue -12806 89/<- %esp 5/r32/ebp -12807 5d/pop-to-ebp -12808 c3/return -12809 -12810 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -12811 # . prologue -12812 55/push-ebp -12813 89/<- %ebp 4/r32/esp -12814 # . save registers -12815 50/push-eax -12816 51/push-ecx -12817 # if (l == 0) return -12818 81 7/subop/compare *(ebp+0xc) 0/imm32 -12819 0f 84/jump-if-= $emit-subx-imm32:end/disp32 -12820 # var v/eax: (handle var) -12821 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -12822 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12823 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12824 (write-buffered *(ebp+8) Space) -12825 (write-buffered *(ebp+8) %eax) -12826 (write-buffered *(ebp+8) "/imm32") -12827 $emit-subx-imm32:end: -12828 # . restore registers -12829 59/pop-to-ecx -12830 58/pop-to-eax -12831 # . epilogue -12832 89/<- %esp 5/r32/ebp -12833 5d/pop-to-ebp -12834 c3/return -12835 -12836 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -12837 # . prologue -12838 55/push-ebp -12839 89/<- %ebp 4/r32/esp -12840 # . save registers -12841 50/push-eax -12842 51/push-ecx -12843 # if (location == 0) return -12844 81 7/subop/compare *(ebp+0xc) 0/imm32 -12845 0f 84/jump-if-= $emit-subx-disp32:end/disp32 -12846 # var v/eax: (addr stmt-var) -12847 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -12848 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12849 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12850 (write-buffered *(ebp+8) Space) -12851 (write-buffered *(ebp+8) %eax) -12852 # hack: if instruction operation starts with "break", emit ":break" -12853 # var name/ecx: (addr array byte) = lookup(stmt->operation) -12854 8b/-> *(ebp+0x10) 0/r32/eax -12855 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -12856 89/<- %ecx 0/r32/eax -12857 { -12858 (string-starts-with? %ecx "break") # => eax -12859 3d/compare-eax-and 0/imm32/false -12860 74/jump-if-= break/disp8 -12861 (write-buffered *(ebp+8) ":break") -12862 } -12863 # hack: if instruction operation starts with "loop", emit ":loop" -12864 { -12865 (string-starts-with? %ecx "loop") # => eax -12866 3d/compare-eax-and 0/imm32/false -12867 74/jump-if-= break/disp8 -12868 (write-buffered *(ebp+8) ":loop") -12869 } -12870 (write-buffered *(ebp+8) "/disp32") -12871 $emit-subx-disp32:end: -12872 # . restore registers -12873 59/pop-to-ecx -12874 58/pop-to-eax -12875 # . epilogue -12876 89/<- %esp 5/r32/ebp -12877 5d/pop-to-ebp -12878 c3/return +12634 # "0f 8f/jump-if-> break/disp32" +12635 0x1c/imm32/size +12636 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12637 _string_0f_8f_jump_loop: # (payload array byte) +12638 0x11/imm32/alloc-id:fake:payload +12639 # "0f 8f/jump-if-> loop/disp32" +12640 0x1b/imm32/size +12641 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12642 _string_0f_af_multiply: # (payload array byte) +12643 0x11/imm32/alloc-id:fake:payload +12644 # "0f af/multiply" +12645 0xe/imm32/size +12646 0x30/0 0x66/f 0x20/space 0x61/a 0x66/f 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +12647 _string_21_and_with: # (payload array byte) +12648 0x11/imm32/alloc-id:fake:payload +12649 # "21/and-with" +12650 0xb/imm32/size +12651 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +12652 _string_23_and: # (payload array byte) +12653 0x11/imm32/alloc-id:fake:payload +12654 # "23/and" +12655 0x6/imm32/size +12656 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d +12657 _string_25_and_with_eax: # (payload array byte) +12658 0x11/imm32/alloc-id:fake:payload +12659 # "25/and-with-eax" +12660 0xf/imm32/size +12661 0x32/2 0x35/5 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +12662 _string_29_subtract_from: # (payload array byte) +12663 0x11/imm32/alloc-id:fake:payload +12664 # "29/subtract-from" +12665 0x10/imm32/size +12666 0x32/2 0x39/9 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m +12667 _string_2b_subtract: # (payload array byte) +12668 0x11/imm32/alloc-id:fake:payload +12669 # "2b/subtract" +12670 0xb/imm32/size +12671 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +12672 _string_2d_subtract_from_eax: # (payload array byte) +12673 0x11/imm32/alloc-id:fake:payload +12674 # "2d/subtract-from-eax" +12675 0x14/imm32/size +12676 0x32/2 0x64/d 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m 0x2d/dash 0x65/e 0x61/a 0x78/x +12677 _string_31_xor_with: # (payload array byte) +12678 0x11/imm32/alloc-id:fake:payload +12679 # "31/xor-with" +12680 0xb/imm32/size +12681 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +12682 _string_33_xor: # (payload array byte) +12683 0x11/imm32/alloc-id:fake:payload +12684 # "33/xor" +12685 0x6/imm32/size +12686 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r +12687 _string_35_xor_with_eax: # (payload array byte) +12688 0x11/imm32/alloc-id:fake:payload +12689 # "35/xor-with-eax" +12690 0xf/imm32/size +12691 0x33/3 0x35/5 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +12692 _string_39_compare->: # (payload array byte) +12693 0x11/imm32/alloc-id:fake:payload +12694 # "39/compare->" +12695 0xc/imm32/size +12696 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> +12697 _string_3b_compare<-: # (payload array byte) +12698 0x11/imm32/alloc-id:fake:payload +12699 # "3b/compare<-" +12700 0xc/imm32/size +12701 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash +12702 _string_3d_compare_eax_with: # (payload array byte) +12703 0x11/imm32/alloc-id:fake:payload +12704 # "3d/compare-eax-with" +12705 0x13/imm32/size +12706 0x33/3 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x65/e 0x61/a 0x78/x 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +12707 _string_40_increment_eax: # (payload array byte) +12708 0x11/imm32/alloc-id:fake:payload +12709 # "40/increment-eax" +12710 0x10/imm32/size +12711 0x34/4 0x30/0 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x +12712 _string_41_increment_ecx: # (payload array byte) +12713 0x11/imm32/alloc-id:fake:payload +12714 # "41/increment-ecx" +12715 0x10/imm32/size +12716 0x34/4 0x31/1 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x +12717 _string_42_increment_edx: # (payload array byte) +12718 0x11/imm32/alloc-id:fake:payload +12719 # "42/increment-edx" +12720 0x10/imm32/size +12721 0x34/4 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x +12722 _string_43_increment_ebx: # (payload array byte) +12723 0x11/imm32/alloc-id:fake:payload +12724 # "43/increment-ebx" +12725 0x10/imm32/size +12726 0x34/4 0x33/3 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x +12727 _string_46_increment_esi: # (payload array byte) +12728 0x11/imm32/alloc-id:fake:payload +12729 # "46/increment-esi" +12730 0x10/imm32/size +12731 0x34/4 0x36/6 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i +12732 _string_47_increment_edi: # (payload array byte) +12733 0x11/imm32/alloc-id:fake:payload +12734 # "47/increment-edi" +12735 0x10/imm32/size +12736 0x34/4 0x37/7 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i +12737 _string_48_decrement_eax: # (payload array byte) +12738 0x11/imm32/alloc-id:fake:payload +12739 # "48/decrement-eax" +12740 0x10/imm32/size +12741 0x34/4 0x38/8 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x +12742 _string_49_decrement_ecx: # (payload array byte) +12743 0x11/imm32/alloc-id:fake:payload +12744 # "49/decrement-ecx" +12745 0x10/imm32/size +12746 0x34/4 0x39/9 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x +12747 _string_4a_decrement_edx: # (payload array byte) +12748 0x11/imm32/alloc-id:fake:payload +12749 # "4a/decrement-edx" +12750 0x10/imm32/size +12751 0x34/4 0x61/a 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x +12752 _string_4b_decrement_ebx: # (payload array byte) +12753 0x11/imm32/alloc-id:fake:payload +12754 # "4b/decrement-ebx" +12755 0x10/imm32/size +12756 0x34/4 0x62/b 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x +12757 _string_4e_decrement_esi: # (payload array byte) +12758 0x11/imm32/alloc-id:fake:payload +12759 # "4e/decrement-esi" +12760 0x10/imm32/size +12761 0x34/4 0x65/e 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i +12762 _string_4f_decrement_edi: # (payload array byte) +12763 0x11/imm32/alloc-id:fake:payload +12764 # "4f/decrement-edi" +12765 0x10/imm32/size +12766 0x34/4 0x66/f 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i +12767 _string_81_subop_add: # (payload array byte) +12768 0x11/imm32/alloc-id:fake:payload +12769 # "81 0/subop/add" +12770 0xe/imm32/size +12771 0x38/8 0x31/1 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x64/d 0x64/d +12772 _string_81_subop_or: # (payload array byte) +12773 0x11/imm32/alloc-id:fake:payload +12774 # "81 1/subop/or" +12775 0xd/imm32/size +12776 0x38/8 0x31/1 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6f/o 0x72/r +12777 _string_81_subop_and: # (payload array byte) +12778 0x11/imm32/alloc-id:fake:payload +12779 # "81 4/subop/and" +12780 0xe/imm32/size +12781 0x38/8 0x31/1 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x6e/n 0x64/d +12782 _string_81_subop_subtract: # (payload array byte) +12783 0x11/imm32/alloc-id:fake:payload +12784 # "81 5/subop/subtract" +12785 0x13/imm32/size +12786 0x38/8 0x31/1 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +12787 _string_81_subop_xor: # (payload array byte) +12788 0x11/imm32/alloc-id:fake:payload +12789 # "81 6/subop/xor" +12790 0xe/imm32/size +12791 0x38/8 0x31/1 0x20/space 0x36/6 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x78/x 0x6f/o 0x72/r +12792 _string_81_subop_compare: # (payload array byte) +12793 0x11/imm32/alloc-id:fake:payload +12794 # "81 7/subop/compare" +12795 0x12/imm32/size +12796 0x38/8 0x31/1 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +12797 _string_89_<-: # (payload array byte) +12798 0x11/imm32/alloc-id:fake:payload +12799 # "89/<-" +12800 0x5/imm32/size +12801 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash +12802 _string_8b_->: # (payload array byte) +12803 0x11/imm32/alloc-id:fake:payload +12804 # "8b/->" +12805 0x5/imm32/size +12806 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> +12807 _string_8d_copy_address: # (payload array byte) +12808 0x11/imm32/alloc-id:fake:payload +12809 # "8d/copy-address" +12810 0xf/imm32/size +12811 0x38/8 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s +12812 _string_b8_copy_to_eax: # (payload array byte) +12813 0x11/imm32/alloc-id:fake:payload +12814 # "b8/copy-to-eax" +12815 0xe/imm32/size +12816 0x62/b 0x38/8 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x +12817 _string_b9_copy_to_ecx: # (payload array byte) +12818 0x11/imm32/alloc-id:fake:payload +12819 # "b9/copy-to-ecx" +12820 0xe/imm32/size +12821 0x62/b 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x63/c 0x78/x +12822 _string_ba_copy_to_edx: # (payload array byte) +12823 0x11/imm32/alloc-id:fake:payload +12824 # "ba/copy-to-edx" +12825 0xe/imm32/size +12826 0x62/b 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x78/x +12827 _string_bb_copy_to_ebx: # (payload array byte) +12828 0x11/imm32/alloc-id:fake:payload +12829 # "bb/copy-to-ebx" +12830 0xe/imm32/size +12831 0x62/b 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x62/b 0x78/x +12832 _string_be_copy_to_esi: # (payload array byte) +12833 0x11/imm32/alloc-id:fake:payload +12834 # "be/copy-to-esi" +12835 0xe/imm32/size +12836 0x62/b 0x65/e 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x73/s 0x69/i +12837 _string_bf_copy_to_edi: # (payload array byte) +12838 0x11/imm32/alloc-id:fake:payload +12839 # "bf/copy-to-edi" +12840 0xe/imm32/size +12841 0x62/b 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x69/i +12842 _string_c7_subop_copy: # (payload array byte) +12843 0x11/imm32/alloc-id:fake:payload +12844 # "c7 0/subop/copy" +12845 0xf/imm32/size +12846 0x63/c 0x37/7 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y +12847 _string_e9_jump_label: # (payload array byte) +12848 0x11/imm32/alloc-id:fake:payload +12849 # "e9/jump" +12850 0x7/imm32/size +12851 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p +12852 _string_e9_jump_break: # (payload array byte) +12853 0x11/imm32/alloc-id:fake:payload +12854 # "e9/jump break/disp32" +12855 0x14/imm32/size +12856 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12857 _string_e9_jump_loop: # (payload array byte) +12858 0x11/imm32/alloc-id:fake:payload +12859 # "e9/jump loop/disp32" +12860 0x13/imm32/size +12861 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +12862 _string_ff_subop_increment: # (payload array byte) +12863 0x11/imm32/alloc-id:fake:payload +12864 # "ff 0/subop/increment" +12865 0x14/imm32/size +12866 0x66/f 0x66/f 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +12867 _string_ff_subop_decrement: # (payload array byte) +12868 0x11/imm32/alloc-id:fake:payload +12869 # "ff 1/subop/decrement" +12870 0x14/imm32/size +12871 0x66/f 0x66/f 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +12872 +12873 Single-int-var-in-mem: # (payload list var) +12874 0x11/imm32/alloc-id:fake:payload +12875 0x11/imm32/alloc-id:fake +12876 Int-var-in-mem/imm32 +12877 0/imm32/next +12878 0/imm32/next 12879 -12880 emit-call: # out: (addr buffered-file), stmt: (addr stmt) -12881 # . prologue -12882 55/push-ebp -12883 89/<- %ebp 4/r32/esp -12884 # . save registers -12885 50/push-eax -12886 51/push-ecx -12887 # -12888 (emit-indent *(ebp+8) *Curr-block-depth) -12889 (write-buffered *(ebp+8) "(") -12890 # ecx = stmt -12891 8b/-> *(ebp+0xc) 1/r32/ecx -12892 # - emit function name -12893 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -12894 (write-buffered *(ebp+8) %eax) -12895 # - emit arguments -12896 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) -12897 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12898 { -12899 # if (curr == null) break -12900 3d/compare-eax-and 0/imm32 -12901 74/jump-if-= break/disp8 -12902 # -12903 (emit-subx-call-operand *(ebp+8) %eax) -12904 # curr = lookup(curr->next) -12905 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12906 eb/jump loop/disp8 -12907 } -12908 # -12909 (write-buffered *(ebp+8) ")\n") -12910 $emit-call:end: -12911 # . restore registers -12912 59/pop-to-ecx -12913 58/pop-to-eax -12914 # . epilogue -12915 89/<- %esp 5/r32/ebp -12916 5d/pop-to-ebp -12917 c3/return +12880 Int-var-in-mem: # (payload var) +12881 0x11/imm32/alloc-id:fake:payload +12882 0/imm32/name +12883 0/imm32/name +12884 0x11/imm32/alloc-id:fake +12885 Type-int/imm32 +12886 1/imm32/some-block-depth +12887 1/imm32/some-stack-offset +12888 0/imm32/no-register +12889 0/imm32/no-register +12890 +12891 Two-args-int-stack-int-reg: # (payload list var) +12892 0x11/imm32/alloc-id:fake:payload +12893 0x11/imm32/alloc-id:fake +12894 Int-var-in-mem/imm32 +12895 0x11/imm32/alloc-id:fake +12896 Single-int-var-in-some-register/imm32/next +12897 +12898 Two-args-int-reg-int-stack: # (payload list var) +12899 0x11/imm32/alloc-id:fake:payload +12900 0x11/imm32/alloc-id:fake +12901 Int-var-in-some-register/imm32 +12902 0x11/imm32/alloc-id:fake +12903 Single-int-var-in-mem/imm32/next +12904 +12905 Two-args-int-eax-int-literal: # (payload list var) +12906 0x11/imm32/alloc-id:fake:payload +12907 0x11/imm32/alloc-id:fake +12908 Int-var-in-eax/imm32 +12909 0x11/imm32/alloc-id:fake +12910 Single-lit-var/imm32/next +12911 +12912 Int-var-and-literal: # (payload list var) +12913 0x11/imm32/alloc-id:fake:payload +12914 0x11/imm32/alloc-id:fake +12915 Int-var-in-mem/imm32 +12916 0x11/imm32/alloc-id:fake +12917 Single-lit-var/imm32/next 12918 -12919 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) -12920 # shares code with emit-subx-var-as-rm32 -12921 # . prologue -12922 55/push-ebp -12923 89/<- %ebp 4/r32/esp -12924 # . save registers -12925 50/push-eax -12926 51/push-ecx -12927 56/push-esi -12928 # ecx = s -12929 8b/-> *(ebp+0xc) 1/r32/ecx -12930 # var operand/esi: (addr var) = lookup(s->value) -12931 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -12932 89/<- %esi 0/r32/eax -12933 # if (operand->register && !s->is-deref?) emit "%__" -12934 { -12935 $emit-subx-call-operand:check-for-register-direct: -12936 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -12937 74/jump-if-= break/disp8 -12938 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -12939 75/jump-if-!= break/disp8 -12940 $emit-subx-call-operand:register-direct: -12941 (write-buffered *(ebp+8) " %") -12942 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -12943 (write-buffered *(ebp+8) %eax) -12944 e9/jump $emit-subx-call-operand:end/disp32 -12945 } -12946 # else if (operand->register && s->is-deref?) emit "*__" -12947 { -12948 $emit-subx-call-operand:check-for-register-indirect: -12949 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -12950 74/jump-if-= break/disp8 -12951 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -12952 74/jump-if-= break/disp8 -12953 $emit-subx-call-operand:register-indirect: -12954 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) -12955 e9/jump $emit-subx-call-operand:end/disp32 -12956 } -12957 # else if (operand->stack-offset) emit "*(ebp+__)" -12958 { -12959 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -12960 74/jump-if-= break/disp8 -12961 $emit-subx-call-operand:stack: -12962 (emit-subx-call-operand-stack *(ebp+8) %esi) -12963 e9/jump $emit-subx-call-operand:end/disp32 -12964 } -12965 # else if (operand->type == literal) emit "__" -12966 { -12967 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -12968 81 7/subop/compare *(eax+4) 0/imm32 # Tree-left -12969 75/jump-if-!= break/disp8 -12970 $emit-subx-call-operand:literal: -12971 (write-buffered *(ebp+8) Space) -12972 (lookup *esi *(esi+4)) # Var-name Var-name => eax -12973 (write-buffered *(ebp+8) %eax) -12974 } -12975 $emit-subx-call-operand:end: -12976 # . restore registers -12977 5e/pop-to-esi -12978 59/pop-to-ecx -12979 58/pop-to-eax -12980 # . epilogue -12981 89/<- %esp 5/r32/ebp -12982 5d/pop-to-ebp -12983 c3/return -12984 -12985 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) -12986 # . prologue -12987 55/push-ebp -12988 89/<- %ebp 4/r32/esp -12989 # . save registers -12990 50/push-eax -12991 51/push-ecx -12992 56/push-esi -12993 # esi = v -12994 8b/-> *(ebp+0xc) 6/r32/esi -12995 # var size/ecx: int = size-of-deref(v) -12996 (size-of-deref %esi) # => eax -12997 89/<- %ecx 0/r32/eax -12998 # var reg-name/esi: (addr array byte) = lookup(v->register) -12999 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -13000 89/<- %esi 0/r32/eax -13001 # TODO: assert size is a multiple of 4 -13002 # var i/eax: int = 0 -13003 b8/copy-to-eax 0/imm32 -13004 { -13005 $emit-subx-call-operand-register-indirect:loop: -13006 # if (i >= size) break -13007 39/compare %eax 1/r32/ecx -13008 7d/jump-if->= break/disp8 -13009 # emit " *(" v->register "+" i ")" -13010 (write-buffered *(ebp+8) " *(") -13011 (write-buffered *(ebp+8) %esi) -13012 (write-buffered *(ebp+8) "+") -13013 (print-int32-buffered *(ebp+8) %eax) -13014 (write-buffered *(ebp+8) ")") -13015 # i += 4 -13016 05/add-to-eax 4/imm32 -13017 # -13018 eb/jump loop/disp8 -13019 } -13020 $emit-subx-call-operand-register-indirect:end: -13021 # . restore registers -13022 5e/pop-to-esi -13023 59/pop-to-ecx -13024 58/pop-to-eax -13025 # . epilogue -13026 89/<- %esp 5/r32/ebp -13027 5d/pop-to-ebp -13028 c3/return -13029 -13030 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) -13031 # . prologue -13032 55/push-ebp -13033 89/<- %ebp 4/r32/esp -13034 # . save registers -13035 50/push-eax -13036 51/push-ecx -13037 56/push-esi -13038 # esi = v -13039 8b/-> *(ebp+0xc) 6/r32/esi -13040 # var curr/ecx: int = v->offset -13041 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset -13042 # var max/eax: int = v->offset + size-of(v) -13043 (size-of %esi) # => eax -13044 # TODO: assert size is a multiple of 4 -13045 01/add-to %eax 1/r32/ecx -13046 { -13047 $emit-subx-call-operand-stack:loop: -13048 # if (curr >= max) break -13049 39/compare %ecx 0/r32/eax -13050 7d/jump-if->= break/disp8 -13051 # emit " *(ebp+" curr ")" -13052 (write-buffered *(ebp+8) " *(ebp+") -13053 (print-int32-buffered *(ebp+8) %ecx) -13054 (write-buffered *(ebp+8) ")") -13055 # i += 4 -13056 81 0/subop/add %ecx 4/imm32 -13057 # -13058 eb/jump loop/disp8 -13059 } -13060 $emit-subx-call-operand-stack:end: -13061 # . restore registers -13062 5e/pop-to-esi -13063 59/pop-to-ecx -13064 58/pop-to-eax -13065 # . epilogue -13066 89/<- %esp 5/r32/ebp -13067 5d/pop-to-ebp -13068 c3/return -13069 -13070 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) -13071 # . prologue -13072 55/push-ebp -13073 89/<- %ebp 4/r32/esp -13074 # . save registers -13075 50/push-eax -13076 51/push-ecx -13077 56/push-esi -13078 # ecx = s -13079 8b/-> *(ebp+0xc) 1/r32/ecx -13080 # var operand/esi: (addr var) = lookup(s->value) -13081 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -13082 89/<- %esi 0/r32/eax -13083 # if (operand->register && s->is-deref?) emit "*__" -13084 { -13085 $emit-subx-var-as-rm32:check-for-register-indirect: -13086 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -13087 74/jump-if-= break/disp8 -13088 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -13089 74/jump-if-= break/disp8 -13090 $emit-subx-var-as-rm32:register-indirect: -13091 (write-buffered *(ebp+8) " *") -13092 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -13093 (write-buffered *(ebp+8) %eax) -13094 e9/jump $emit-subx-var-as-rm32:end/disp32 -13095 } -13096 # if (operand->register && !s->is-deref?) emit "%__" -13097 { -13098 $emit-subx-var-as-rm32:check-for-register-direct: -13099 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -13100 74/jump-if-= break/disp8 -13101 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -13102 75/jump-if-!= break/disp8 -13103 $emit-subx-var-as-rm32:register-direct: -13104 (write-buffered *(ebp+8) " %") -13105 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -13106 (write-buffered *(ebp+8) %eax) -13107 e9/jump $emit-subx-var-as-rm32:end/disp32 -13108 } -13109 # else if (operand->stack-offset) emit "*(ebp+__)" -13110 { -13111 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -13112 74/jump-if-= break/disp8 -13113 $emit-subx-var-as-rm32:stack: -13114 (write-buffered *(ebp+8) Space) -13115 (write-buffered *(ebp+8) "*(ebp+") -13116 (print-int32-buffered *(ebp+8) *(esi+0x14)) # Var-offset -13117 (write-buffered *(ebp+8) ")") -13118 } -13119 $emit-subx-var-as-rm32:end: -13120 # . restore registers -13121 5e/pop-to-esi -13122 59/pop-to-ecx -13123 58/pop-to-eax -13124 # . epilogue -13125 89/<- %esp 5/r32/ebp -13126 5d/pop-to-ebp -13127 c3/return -13128 -13129 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) -13130 # . prologue -13131 55/push-ebp -13132 89/<- %ebp 4/r32/esp -13133 # . save registers -13134 51/push-ecx -13135 # var curr/ecx: (addr primitive) = primitives -13136 8b/-> *(ebp+8) 1/r32/ecx -13137 { -13138 $find-matching-primitive:loop: -13139 # if (curr == null) break -13140 81 7/subop/compare %ecx 0/imm32 -13141 0f 84/jump-if-= break/disp32 -13142 # if match(curr, stmt) return curr -13143 { -13144 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax -13145 3d/compare-eax-and 0/imm32/false -13146 74/jump-if-= break/disp8 -13147 89/<- %eax 1/r32/ecx -13148 eb/jump $find-matching-primitive:end/disp8 -13149 } -13150 $find-matching-primitive:next-primitive: -13151 # curr = curr->next -13152 (lookup *(ecx+0x34) *(ecx+0x38)) # Primitive-next Primitive-next => eax -13153 89/<- %ecx 0/r32/eax -13154 # -13155 e9/jump loop/disp32 -13156 } -13157 # return null -13158 b8/copy-to-eax 0/imm32 -13159 $find-matching-primitive:end: -13160 # . restore registers -13161 59/pop-to-ecx -13162 # . epilogue -13163 89/<- %esp 5/r32/ebp -13164 5d/pop-to-ebp -13165 c3/return -13166 -13167 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean -13168 # A mu stmt matches a primitive if the name matches, all the inout vars -13169 # match, and all the output vars match. -13170 # Vars match if types match and registers match. -13171 # In addition, a stmt output matches a primitive's output if types match -13172 # and the primitive has a wildcard register. -13173 # . prologue -13174 55/push-ebp -13175 89/<- %ebp 4/r32/esp -13176 # . save registers -13177 51/push-ecx -13178 52/push-edx -13179 53/push-ebx -13180 56/push-esi -13181 57/push-edi -13182 # ecx = stmt -13183 8b/-> *(ebp+8) 1/r32/ecx -13184 # edx = primitive -13185 8b/-> *(ebp+0xc) 2/r32/edx -13186 { -13187 $mu-stmt-matches-primitive?:check-name: -13188 # if (primitive->name != stmt->operation) return false -13189 # . var esi: (addr array byte) = lookup(stmt->operation) -13190 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -13191 89/<- %esi 0/r32/eax -13192 # . var edi: (addr array byte) = lookup(primitive->name) -13193 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax -13194 89/<- %edi 0/r32/eax -13195 (string-equal? %esi %edi) # => eax -13196 3d/compare-eax-and 0/imm32/false -13197 75/jump-if-!= break/disp8 -13198 b8/copy-to-eax 0/imm32 -13199 e9/jump $mu-stmt-matches-primitive?:end/disp32 -13200 } -13201 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) -13202 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -13203 89/<- %esi 0/r32/eax -13204 # var curr2/edi: (addr list var) = lookup(primitive->inouts) -13205 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax -13206 89/<- %edi 0/r32/eax -13207 { -13208 $mu-stmt-matches-primitive?:inouts-loop: -13209 # if (curr == 0 && curr2 == 0) move on to check outputs -13210 { -13211 $mu-stmt-matches-primitive?:check-both-inouts-null: -13212 81 7/subop/compare %esi 0/imm32 -13213 75/jump-if-!= break/disp8 -13214 $mu-stmt-matches-primitive?:stmt-inout-null: -13215 81 7/subop/compare %edi 0/imm32 -13216 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 -13217 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: -13218 # return false -13219 b8/copy-to-eax 0/imm32/false -13220 e9/jump $mu-stmt-matches-primitive?:end/disp32 -13221 } -13222 # if (curr2 == 0) return false -13223 { -13224 $mu-stmt-matches-primitive?:check-prim-inout-null: -13225 81 7/subop/compare %edi 0/imm32 -13226 75/jump-if-!= break/disp8 -13227 $mu-stmt-matches-primitive?:prim-inout-null: -13228 b8/copy-to-eax 0/imm32/false -13229 e9/jump $mu-stmt-matches-primitive?:end/disp32 -13230 } -13231 # if (curr != curr2) return false -13232 { -13233 $mu-stmt-matches-primitive?:check-inouts-match: -13234 (lookup *edi *(edi+4)) # List-value List-value => eax -13235 (operand-matches-primitive? %esi %eax) # => eax -13236 3d/compare-eax-and 0/imm32/false -13237 75/jump-if-!= break/disp8 -13238 $mu-stmt-matches-primitive?:inouts-match: -13239 b8/copy-to-eax 0/imm32/false -13240 e9/jump $mu-stmt-matches-primitive?:end/disp32 -13241 } -13242 $mu-stmt-matches-primitive?:next-inout: -13243 # curr = lookup(curr->next) -13244 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -13245 89/<- %esi 0/r32/eax -13246 # curr2 = lookup(curr2->next) -13247 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -13248 89/<- %edi 0/r32/eax -13249 # -13250 e9/jump loop/disp32 -13251 } -13252 $mu-stmt-matches-primitive?:check-outputs: -13253 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) -13254 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -13255 89/<- %esi 0/r32/eax -13256 # var curr2/edi: (addr list var) = lookup(primitive->outputs) -13257 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax -13258 89/<- %edi 0/r32/eax -13259 { -13260 $mu-stmt-matches-primitive?:outputs-loop: -13261 # if (curr == 0) return (curr2 == 0) -13262 { -13263 $mu-stmt-matches-primitive?:check-both-outputs-null: -13264 81 7/subop/compare %esi 0/imm32 -13265 75/jump-if-!= break/disp8 -13266 { -13267 $mu-stmt-matches-primitive?:stmt-output-null: -13268 81 7/subop/compare %edi 0/imm32 -13269 75/jump-if-!= break/disp8 -13270 $mu-stmt-matches-primitive?:both-outputs-null: -13271 # return true -13272 b8/copy-to-eax 1/imm32 -13273 e9/jump $mu-stmt-matches-primitive?:end/disp32 -13274 } -13275 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: -13276 # return false -13277 b8/copy-to-eax 0/imm32 -13278 e9/jump $mu-stmt-matches-primitive?:end/disp32 -13279 } -13280 # if (curr2 == 0) return false -13281 { -13282 $mu-stmt-matches-primitive?:check-prim-output-null: -13283 81 7/subop/compare %edi 0/imm32 -13284 75/jump-if-!= break/disp8 -13285 $mu-stmt-matches-primitive?:prim-output-is-null: -13286 b8/copy-to-eax 0/imm32 -13287 e9/jump $mu-stmt-matches-primitive?:end/disp32 -13288 } -13289 # if (curr != curr2) return false -13290 { -13291 $mu-stmt-matches-primitive?:check-outputs-match: -13292 (lookup *edi *(edi+4)) # List-value List-value => eax -13293 (operand-matches-primitive? %esi %eax) # => eax -13294 3d/compare-eax-and 0/imm32/false -13295 75/jump-if-!= break/disp8 -13296 $mu-stmt-matches-primitive?:outputs-match: -13297 b8/copy-to-eax 0/imm32 -13298 e9/jump $mu-stmt-matches-primitive?:end/disp32 -13299 } -13300 $mu-stmt-matches-primitive?:next-output: -13301 # curr = lookup(curr->next) -13302 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -13303 89/<- %esi 0/r32/eax -13304 # curr2 = lookup(curr2->next) -13305 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -13306 89/<- %edi 0/r32/eax -13307 # -13308 e9/jump loop/disp32 -13309 } -13310 $mu-stmt-matches-primitive?:return-true: -13311 b8/copy-to-eax 1/imm32 -13312 $mu-stmt-matches-primitive?:end: -13313 # . restore registers -13314 5f/pop-to-edi -13315 5e/pop-to-esi -13316 5b/pop-to-ebx -13317 5a/pop-to-edx -13318 59/pop-to-ecx +12919 Int-var-in-register-and-literal: # (payload list var) +12920 0x11/imm32/alloc-id:fake:payload +12921 0x11/imm32/alloc-id:fake +12922 Int-var-in-some-register/imm32 +12923 0x11/imm32/alloc-id:fake +12924 Single-lit-var/imm32/next +12925 +12926 Single-int-var-in-some-register: # (payload list var) +12927 0x11/imm32/alloc-id:fake:payload +12928 0x11/imm32/alloc-id:fake +12929 Int-var-in-some-register/imm32 +12930 0/imm32/next +12931 0/imm32/next +12932 +12933 Single-addr-var-in-some-register: # (payload list var) +12934 0x11/imm32/alloc-id:fake:payload +12935 0x11/imm32/alloc-id:fake +12936 Addr-var-in-some-register/imm32 +12937 0/imm32/next +12938 0/imm32/next +12939 +12940 Int-var-in-some-register: # (payload var) +12941 0x11/imm32/alloc-id:fake:payload +12942 0/imm32/name +12943 0/imm32/name +12944 0x11/imm32/alloc-id:fake +12945 Type-int/imm32 +12946 1/imm32/some-block-depth +12947 0/imm32/no-stack-offset +12948 0x11/imm32/alloc-id:fake +12949 Any-register/imm32 +12950 +12951 Any-register: # (payload array byte) +12952 0x11/imm32/alloc-id:fake:payload +12953 1/imm32/size +12954 # data +12955 2a/asterisk +12956 +12957 Addr-var-in-some-register: # (payload var) +12958 0x11/imm32/alloc-id:fake:payload +12959 0/imm32/name +12960 0/imm32/name +12961 0x11/imm32/alloc-id:fake +12962 Type-addr/imm32 +12963 1/imm32/some-block-depth +12964 0/imm32/no-stack-offset +12965 0x11/imm32/alloc-id:fake +12966 Any-register/imm32 +12967 +12968 Single-int-var-in-eax: # (payload list var) +12969 0x11/imm32/alloc-id:fake:payload +12970 0x11/imm32/alloc-id:fake +12971 Int-var-in-eax/imm32 +12972 0/imm32/next +12973 0/imm32/next +12974 +12975 Int-var-in-eax: +12976 0x11/imm32/alloc-id:fake:payload +12977 0/imm32/name +12978 0/imm32/name +12979 0x11/imm32/alloc-id:fake +12980 Type-int/imm32 +12981 1/imm32/some-block-depth +12982 0/imm32/no-stack-offset +12983 0x11/imm32/alloc-id:fake +12984 $Register-eax/imm32 +12985 +12986 Single-int-var-in-ecx: # (payload list var) +12987 0x11/imm32/alloc-id:fake:payload +12988 0x11/imm32/alloc-id:fake +12989 Int-var-in-ecx/imm32 +12990 0/imm32/next +12991 0/imm32/next +12992 +12993 Int-var-in-ecx: +12994 0x11/imm32/alloc-id:fake:payload +12995 0/imm32/name +12996 0/imm32/name +12997 0x11/imm32/alloc-id:fake +12998 Type-int/imm32 +12999 1/imm32/some-block-depth +13000 0/imm32/no-stack-offset +13001 0x11/imm32/alloc-id:fake +13002 $Register-ecx/imm32/register +13003 +13004 Single-int-var-in-edx: # (payload list var) +13005 0x11/imm32/alloc-id:fake:payload +13006 0x11/imm32/alloc-id:fake +13007 Int-var-in-edx/imm32 +13008 0/imm32/next +13009 0/imm32/next +13010 +13011 Int-var-in-edx: # (payload list var) +13012 0x11/imm32/alloc-id:fake:payload +13013 0/imm32/name +13014 0/imm32/name +13015 0x11/imm32/alloc-id:fake +13016 Type-int/imm32 +13017 1/imm32/some-block-depth +13018 0/imm32/no-stack-offset +13019 0x11/imm32/alloc-id:fake +13020 $Register-edx/imm32/register +13021 +13022 Single-int-var-in-ebx: # (payload list var) +13023 0x11/imm32/alloc-id:fake:payload +13024 0x11/imm32/alloc-id:fake +13025 Int-var-in-ebx/imm32 +13026 0/imm32/next +13027 0/imm32/next +13028 +13029 Int-var-in-ebx: # (payload list var) +13030 0x11/imm32/alloc-id:fake:payload +13031 0/imm32/name +13032 0/imm32/name +13033 0x11/imm32/alloc-id:fake +13034 Type-int/imm32 +13035 1/imm32/some-block-depth +13036 0/imm32/no-stack-offset +13037 0x11/imm32/alloc-id:fake +13038 $Register-ebx/imm32/register +13039 +13040 Single-int-var-in-esi: # (payload list var) +13041 0x11/imm32/alloc-id:fake:payload +13042 0x11/imm32/alloc-id:fake +13043 Int-var-in-esi/imm32 +13044 0/imm32/next +13045 0/imm32/next +13046 +13047 Int-var-in-esi: # (payload list var) +13048 0x11/imm32/alloc-id:fake:payload +13049 0/imm32/name +13050 0/imm32/name +13051 0x11/imm32/alloc-id:fake +13052 Type-int/imm32 +13053 1/imm32/some-block-depth +13054 0/imm32/no-stack-offset +13055 0x11/imm32/alloc-id:fake +13056 $Register-esi/imm32/register +13057 +13058 Single-int-var-in-edi: # (payload list var) +13059 0x11/imm32/alloc-id:fake:payload +13060 0x11/imm32/alloc-id:fake +13061 Int-var-in-edi/imm32 +13062 0/imm32/next +13063 0/imm32/next +13064 +13065 Int-var-in-edi: # (payload list var) +13066 0x11/imm32/alloc-id:fake:payload +13067 0/imm32/name +13068 0/imm32/name +13069 0x11/imm32/alloc-id:fake +13070 Type-int/imm32 +13071 1/imm32/some-block-depth +13072 0/imm32/no-stack-offset +13073 0x11/imm32/alloc-id:fake +13074 $Register-edi/imm32/register +13075 +13076 Single-lit-var: # (payload list var) +13077 0x11/imm32/alloc-id:fake:payload +13078 0x11/imm32/alloc-id:fake +13079 Lit-var/imm32 +13080 0/imm32/next +13081 0/imm32/next +13082 +13083 Lit-var: # (payload var) +13084 0x11/imm32/alloc-id:fake:payload +13085 0/imm32/name +13086 0/imm32/name +13087 0x11/imm32/alloc-id:fake +13088 Type-literal/imm32 +13089 1/imm32/some-block-depth +13090 0/imm32/no-stack-offset +13091 0/imm32/no-register +13092 0/imm32/no-register +13093 +13094 Type-int: # (payload tree type-id) +13095 0x11/imm32/alloc-id:fake:payload +13096 1/imm32/left-is-atom +13097 1/imm32/value:int +13098 0/imm32/left:unused +13099 0/imm32/right:null +13100 0/imm32/right:null +13101 +13102 Type-literal: # (payload tree type-id) +13103 0x11/imm32/alloc-id:fake:payload +13104 1/imm32/is-atom +13105 0/imm32/value:literal +13106 0/imm32/left:unused +13107 0/imm32/right:null +13108 0/imm32/right:null +13109 +13110 Type-addr: # (payload tree type-id) +13111 0x11/imm32/alloc-id:fake:payload +13112 1/imm32/is-atom +13113 2/imm32/value:addr +13114 0/imm32/left:unused +13115 0/imm32/right:null +13116 0/imm32/right:null +13117 +13118 == code +13119 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive) +13120 # . prologue +13121 55/push-ebp +13122 89/<- %ebp 4/r32/esp +13123 # . save registers +13124 50/push-eax +13125 51/push-ecx +13126 # ecx = primitive +13127 8b/-> *(ebp+0x10) 1/r32/ecx +13128 # emit primitive name +13129 (emit-indent *(ebp+8) *Curr-block-depth) +13130 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax +13131 (write-buffered *(ebp+8) %eax) +13132 # emit rm32 if necessary +13133 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc)) # out, Primitive-subx-rm32, stmt +13134 # emit r32 if necessary +13135 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # out, Primitive-subx-r32, stmt +13136 # emit imm32 if necessary +13137 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # out, Primitive-subx-imm32, stmt +13138 # emit disp32 if necessary +13139 (emit-subx-disp32 *(ebp+8) *(ecx+0x2c) *(ebp+0xc)) # out, Primitive-subx-disp32, stmt +13140 (write-buffered *(ebp+8) Newline) +13141 $emit-subx-primitive:end: +13142 # . restore registers +13143 59/pop-to-ecx +13144 58/pop-to-eax +13145 # . epilogue +13146 89/<- %esp 5/r32/ebp +13147 5d/pop-to-ebp +13148 c3/return +13149 +13150 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +13151 # . prologue +13152 55/push-ebp +13153 89/<- %ebp 4/r32/esp +13154 # . save registers +13155 50/push-eax +13156 # if (l == 0) return +13157 81 7/subop/compare *(ebp+0xc) 0/imm32 +13158 74/jump-if-= $emit-subx-rm32:end/disp8 +13159 # var v/eax: (addr stmt-var) +13160 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +13161 (emit-subx-var-as-rm32 *(ebp+8) %eax) +13162 $emit-subx-rm32:end: +13163 # . restore registers +13164 58/pop-to-eax +13165 # . epilogue +13166 89/<- %esp 5/r32/ebp +13167 5d/pop-to-ebp +13168 c3/return +13169 +13170 get-stmt-operand-from-arg-location: # stmt: (addr stmt), l: arg-location -> var/eax: (addr stmt-var) +13171 # . prologue +13172 55/push-ebp +13173 89/<- %ebp 4/r32/esp +13174 # . save registers +13175 51/push-ecx +13176 # eax = l +13177 8b/-> *(ebp+0xc) 0/r32/eax +13178 # ecx = stmt +13179 8b/-> *(ebp+8) 1/r32/ecx +13180 # if (l == 1) return stmt->inouts +13181 { +13182 3d/compare-eax-and 1/imm32 +13183 75/jump-if-!= break/disp8 +13184 $get-stmt-operand-from-arg-location:1: +13185 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13186 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +13187 } +13188 # if (l == 2) return stmt->inouts->next +13189 { +13190 3d/compare-eax-and 2/imm32 +13191 75/jump-if-!= break/disp8 +13192 $get-stmt-operand-from-arg-location:2: +13193 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13194 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13195 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +13196 } +13197 # if (l == 3) return stmt->outputs +13198 { +13199 3d/compare-eax-and 3/imm32 +13200 75/jump-if-!= break/disp8 +13201 $get-stmt-operand-from-arg-location:3: +13202 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13203 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +13204 } +13205 # abort +13206 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 +13207 $get-stmt-operand-from-arg-location:end: +13208 # . restore registers +13209 59/pop-to-ecx +13210 # . epilogue +13211 89/<- %esp 5/r32/ebp +13212 5d/pop-to-ebp +13213 c3/return +13214 +13215 $get-stmt-operand-from-arg-location:abort: +13216 # error("invalid arg-location " eax) +13217 (write-buffered Stderr "invalid arg-location ") +13218 (print-int32-buffered Stderr %eax) +13219 (write-buffered Stderr Newline) +13220 (flush Stderr) +13221 # . syscall(exit, 1) +13222 bb/copy-to-ebx 1/imm32 +13223 b8/copy-to-eax 1/imm32/exit +13224 cd/syscall 0x80/imm8 +13225 # never gets here +13226 +13227 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +13228 # . prologue +13229 55/push-ebp +13230 89/<- %ebp 4/r32/esp +13231 # . save registers +13232 50/push-eax +13233 51/push-ecx +13234 # if (l == 0) return +13235 81 7/subop/compare *(ebp+0xc) 0/imm32 +13236 0f 84/jump-if-= $emit-subx-r32:end/disp32 +13237 # var v/eax: (addr stmt-var) +13238 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +13239 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13240 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13241 (maybe-get Registers %eax 0xc) # => eax: (addr register-index) +13242 (write-buffered *(ebp+8) Space) +13243 (print-int32-buffered *(ebp+8) *eax) +13244 (write-buffered *(ebp+8) "/r32") +13245 $emit-subx-r32:end: +13246 # . restore registers +13247 59/pop-to-ecx +13248 58/pop-to-eax +13249 # . epilogue +13250 89/<- %esp 5/r32/ebp +13251 5d/pop-to-ebp +13252 c3/return +13253 +13254 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +13255 # . prologue +13256 55/push-ebp +13257 89/<- %ebp 4/r32/esp +13258 # . save registers +13259 50/push-eax +13260 51/push-ecx +13261 # if (l == 0) return +13262 81 7/subop/compare *(ebp+0xc) 0/imm32 +13263 0f 84/jump-if-= $emit-subx-imm32:end/disp32 +13264 # var v/eax: (handle var) +13265 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +13266 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13267 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13268 (write-buffered *(ebp+8) Space) +13269 (write-buffered *(ebp+8) %eax) +13270 (write-buffered *(ebp+8) "/imm32") +13271 $emit-subx-imm32:end: +13272 # . restore registers +13273 59/pop-to-ecx +13274 58/pop-to-eax +13275 # . epilogue +13276 89/<- %esp 5/r32/ebp +13277 5d/pop-to-ebp +13278 c3/return +13279 +13280 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +13281 # . prologue +13282 55/push-ebp +13283 89/<- %ebp 4/r32/esp +13284 # . save registers +13285 50/push-eax +13286 51/push-ecx +13287 # if (location == 0) return +13288 81 7/subop/compare *(ebp+0xc) 0/imm32 +13289 0f 84/jump-if-= $emit-subx-disp32:end/disp32 +13290 # var v/eax: (addr stmt-var) +13291 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +13292 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13293 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13294 (write-buffered *(ebp+8) Space) +13295 (write-buffered *(ebp+8) %eax) +13296 # hack: if instruction operation starts with "break", emit ":break" +13297 # var name/ecx: (addr array byte) = lookup(stmt->operation) +13298 8b/-> *(ebp+0x10) 0/r32/eax +13299 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +13300 89/<- %ecx 0/r32/eax +13301 { +13302 (string-starts-with? %ecx "break") # => eax +13303 3d/compare-eax-and 0/imm32/false +13304 74/jump-if-= break/disp8 +13305 (write-buffered *(ebp+8) ":break") +13306 } +13307 # hack: if instruction operation starts with "loop", emit ":loop" +13308 { +13309 (string-starts-with? %ecx "loop") # => eax +13310 3d/compare-eax-and 0/imm32/false +13311 74/jump-if-= break/disp8 +13312 (write-buffered *(ebp+8) ":loop") +13313 } +13314 (write-buffered *(ebp+8) "/disp32") +13315 $emit-subx-disp32:end: +13316 # . restore registers +13317 59/pop-to-ecx +13318 58/pop-to-eax 13319 # . epilogue 13320 89/<- %esp 5/r32/ebp 13321 5d/pop-to-ebp 13322 c3/return 13323 -13324 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean +13324 emit-call: # out: (addr buffered-file), stmt: (addr stmt) 13325 # . prologue 13326 55/push-ebp 13327 89/<- %ebp 4/r32/esp 13328 # . save registers -13329 51/push-ecx -13330 52/push-edx -13331 53/push-ebx -13332 56/push-esi -13333 57/push-edi -13334 # ecx = s -13335 8b/-> *(ebp+8) 1/r32/ecx -13336 # var var/esi: (addr var) = lookup(s->value) -13337 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -13338 89/<- %esi 0/r32/eax -13339 # edi = prim-var -13340 8b/-> *(ebp+0xc) 7/r32/edi -13341 $operand-matches-primitive?:check-type: -13342 # if (var->type != prim-var->type) return false -13343 # . var vtype/ebx: (addr tree type-id) = lookup(var->type) -13344 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -13345 89/<- %ebx 0/r32/eax -13346 # . var ptype/eax: (addr tree type-id) = lookup(prim-var->type) -13347 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -13348 (subx-type-equal? %ebx %eax) # => eax -13349 3d/compare-eax-and 0/imm32/false -13350 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 -13351 { -13352 $operand-matches-primitive?:check-register: -13353 # if prim-var is in memory and var is in register but dereference, match -13354 { -13355 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -13356 0f 85/jump-if-!= break/disp32 -13357 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -13358 74/jump-if-= break/disp8 -13359 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -13360 74/jump-if-= break/disp8 -13361 $operand-matches-primitive?:var-deref-match: -13362 e9/jump $operand-matches-primitive?:return-true/disp32 -13363 } -13364 # if prim-var is in register and var is in register but dereference, no match -13365 { -13366 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -13367 0f 84/jump-if-= break/disp32 -13368 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -13369 0f 84/jump-if-= break/disp32 -13370 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -13371 74/jump-if-= break/disp8 -13372 $operand-matches-primitive?:var-deref-no-match: -13373 e9/jump $operand-matches-primitive?:return-false/disp32 -13374 } -13375 # return false if var->register doesn't match prim-var->register -13376 { -13377 # if register addresses are equal, it's a match -13378 # var vreg/ebx: (addr array byte) = lookup(var->register) -13379 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -13380 89/<- %ebx 0/r32/eax -13381 # var preg/ecx: (addr array byte) = lookup(prim-var->register) -13382 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -13383 89/<- %ecx 0/r32/eax -13384 # if (vreg == preg) break -13385 39/compare %ecx 3/r32/ebx -13386 74/jump-if-= break/disp8 -13387 $operand-matches-primitive?:var-register-no-match: -13388 # if either address is 0, return false -13389 81 7/subop/compare %ebx 0/imm32 -13390 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -13391 81 7/subop/compare %ecx 0/imm32 -13392 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -13393 # if prim-var->register is wildcard, it's a match -13394 (string-equal? %ecx "*") # Any-register => eax -13395 3d/compare-eax-and 0/imm32/false -13396 75/jump-if-!= break/disp8 -13397 $operand-matches-primitive?:wildcard-no-match: -13398 # if string contents aren't equal, return false -13399 (string-equal? %ecx %ebx) # => eax -13400 3d/compare-eax-and 0/imm32/false -13401 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -13402 } -13403 } -13404 $operand-matches-primitive?:return-true: -13405 b8/copy-to-eax 1/imm32/true -13406 eb/jump $operand-matches-primitive?:end/disp8 -13407 $operand-matches-primitive?:return-false: -13408 b8/copy-to-eax 0/imm32/false -13409 $operand-matches-primitive?:end: -13410 # . restore registers -13411 5f/pop-to-edi -13412 5e/pop-to-esi -13413 5b/pop-to-ebx -13414 5a/pop-to-edx -13415 59/pop-to-ecx -13416 # . epilogue -13417 89/<- %esp 5/r32/ebp -13418 5d/pop-to-ebp -13419 c3/return -13420 -13421 subx-type-equal?: # a: (addr tree type-id), b: (addr tree type-id) -> result/eax: boolean -13422 # . prologue -13423 55/push-ebp -13424 89/<- %ebp 4/r32/esp -13425 # . save registers -13426 51/push-ecx -13427 # var alit/ecx: boolean = is-literal-type?(a) -13428 (is-simple-mu-type? *(ebp+8) 0) # => eax -13429 89/<- %ecx 0/r32/eax -13430 # var blit/eax: boolean = is-literal-type?(b) -13431 (is-simple-mu-type? *(ebp+0xc) 0) # => eax -13432 # return alit == blit -13433 39/compare %eax 1/r32/ecx -13434 0f 94/set-byte-if-= %al -13435 81 4/subop/and %eax 0xff/imm32 -13436 $subx-type-equal?:end: -13437 # . restore registers -13438 59/pop-to-ecx -13439 # . epilogue -13440 89/<- %esp 5/r32/ebp -13441 5d/pop-to-ebp -13442 c3/return -13443 -13444 is-simple-mu-type?: # a: (addr tree type-id), n: type-id -> result/eax: boolean -13445 # . prologue -13446 55/push-ebp -13447 89/<- %ebp 4/r32/esp -13448 # . save registers -13449 51/push-ecx -13450 # ecx = n -13451 8b/-> *(ebp+0xc) 1/r32/ecx -13452 # return (a->value == n) -13453 8b/-> *(ebp+8) 0/r32/eax -13454 39/compare *(eax+4) 1/r32/ecx # Tree-value -13455 0f 94/set-byte-if-= %al -13456 81 4/subop/and %eax 0xff/imm32 -13457 $is-simple-mu-type?:end: -13458 # . restore registers -13459 59/pop-to-ecx -13460 # . epilogue -13461 89/<- %esp 5/r32/ebp -13462 5d/pop-to-ebp -13463 c3/return -13464 -13465 test-emit-subx-stmt-primitive: -13466 # Primitive operation on a variable on the stack. -13467 # increment foo -13468 # => -13469 # ff 0/subop/increment *(ebp-8) -13470 # -13471 # There's a variable on the var stack as follows: -13472 # name: 'foo' -13473 # type: int -13474 # stack-offset: -8 -13475 # -13476 # There's a primitive with this info: -13477 # name: 'increment' -13478 # inouts: int/mem -13479 # value: 'ff 0/subop/increment' -13480 # -13481 # . prologue -13482 55/push-ebp -13483 89/<- %ebp 4/r32/esp -13484 # setup -13485 (clear-stream _test-output-stream) -13486 (clear-stream $_test-output-buffered-file->buffer) -13487 # simulate allocated payloads starting with an initial fake alloc-id (0x11) -13488 $test-emit-subx-stmt-primitive:initialize-type: -13489 # var type/ecx: (payload tree type-id) = int -13490 68/push 0/imm32/right:null -13491 68/push 0/imm32/right:null -13492 68/push 0/imm32/left:unused -13493 68/push 1/imm32/value:int -13494 68/push 1/imm32/is-atom?:true -13495 68/push 0x11/imm32/alloc-id:fake:payload -13496 89/<- %ecx 4/r32/esp -13497 $test-emit-subx-stmt-primitive:initialize-var: -13498 # var var-foo/ecx: (payload var) = var(type) -13499 68/push 0/imm32/no-register -13500 68/push 0/imm32/no-register -13501 68/push -8/imm32/stack-offset -13502 68/push 1/imm32/block-depth -13503 51/push-ecx/type -13504 68/push 0x11/imm32/alloc-id:fake -13505 68/push 0/imm32/name -13506 68/push 0/imm32/name -13507 68/push 0x11/imm32/alloc-id:fake:payload -13508 89/<- %ecx 4/r32/esp -13509 $test-emit-subx-stmt-primitive:initialize-var-name: -13510 # var-foo->name = "foo" -13511 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -13512 (copy-array Heap "foo" %eax) -13513 $test-emit-subx-stmt-primitive:initialize-stmt-var: -13514 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -13515 68/push 0/imm32/is-deref:false -13516 68/push 0/imm32/next -13517 68/push 0/imm32/next -13518 51/push-ecx/var-foo -13519 68/push 0x11/imm32/alloc-id:fake -13520 68/push 0x11/imm32/alloc-id:fake:payload -13521 89/<- %ebx 4/r32/esp -13522 $test-emit-subx-stmt-primitive:initialize-stmt: -13523 # var stmt/esi: (addr statement) -13524 68/push 0/imm32/no-outputs -13525 68/push 0/imm32/no-outputs -13526 53/push-ebx/inouts -13527 68/push 0x11/imm32/alloc-id:fake -13528 68/push 0/imm32/operation -13529 68/push 0/imm32/operation -13530 68/push 1/imm32/tag -13531 89/<- %esi 4/r32/esp -13532 $test-emit-subx-stmt-primitive:initialize-stmt-operation: -13533 # stmt->operation = "increment" -13534 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -13535 (copy-array Heap "increment" %eax) -13536 $test-emit-subx-stmt-primitive:initialize-primitive: -13537 # var primitives/ebx: (addr primitive) -13538 68/push 0/imm32/next -13539 68/push 0/imm32/next -13540 68/push 0/imm32/output-is-write-only -13541 68/push 0/imm32/no-disp32 -13542 68/push 0/imm32/no-imm32 -13543 68/push 0/imm32/no-r32 -13544 68/push 1/imm32/rm32-is-first-inout -13545 68/push 0/imm32/subx-name -13546 68/push 0/imm32/subx-name -13547 68/push 0/imm32/no-outputs -13548 68/push 0/imm32/no-outputs -13549 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -13550 68/push 0x11/imm32/alloc-id:fake -13551 68/push 0/imm32/name -13552 68/push 0/imm32/name -13553 89/<- %ebx 4/r32/esp -13554 $test-emit-subx-stmt-primitive:initialize-primitive-name: -13555 # primitives->name = "increment" -13556 (copy-array Heap "increment" %ebx) # Primitive-name -13557 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: -13558 # primitives->subx-name = "ff 0/subop/increment" -13559 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -13560 (copy-array Heap "ff 0/subop/increment" %eax) -13561 # convert -13562 c7 0/subop/copy *Curr-block-depth 0/imm32 -13563 (emit-subx-stmt _test-output-buffered-file %esi %ebx) -13564 (flush _test-output-buffered-file) -13565 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -13571 # check output -13572 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") -13573 # . epilogue -13574 89/<- %esp 5/r32/ebp -13575 5d/pop-to-ebp -13576 c3/return -13577 -13578 test-emit-subx-stmt-primitive-register: -13579 # Primitive operation on a variable in a register. -13580 # foo <- increment -13581 # => -13582 # ff 0/subop/increment %eax # sub-optimal, but should suffice -13583 # -13584 # There's a variable on the var stack as follows: -13585 # name: 'foo' -13586 # type: int -13587 # register: 'eax' -13588 # -13589 # There's a primitive with this info: -13590 # name: 'increment' -13591 # out: int/reg -13592 # value: 'ff 0/subop/increment' -13593 # -13594 # . prologue -13595 55/push-ebp -13596 89/<- %ebp 4/r32/esp -13597 # setup -13598 (clear-stream _test-output-stream) -13599 (clear-stream $_test-output-buffered-file->buffer) -13600 $test-emit-subx-stmt-primitive-register:initialize-type: -13601 # var type/ecx: (payload tree type-id) = int -13602 68/push 0/imm32/right:null -13603 68/push 0/imm32/right:null -13604 68/push 0/imm32/left:unused -13605 68/push 1/imm32/value:int -13606 68/push 1/imm32/is-atom?:true -13607 68/push 0x11/imm32/alloc-id:fake:payload -13608 89/<- %ecx 4/r32/esp -13609 $test-emit-subx-stmt-primitive-register:initialize-var: -13610 # var var-foo/ecx: (payload var) -13611 68/push 0/imm32/register -13612 68/push 0/imm32/register -13613 68/push 0/imm32/no-stack-offset -13614 68/push 1/imm32/block-depth -13615 51/push-ecx -13616 68/push 0x11/imm32/alloc-id:fake -13617 68/push 0/imm32/name -13618 68/push 0/imm32/name -13619 68/push 0x11/imm32/alloc-id:fake:payload -13620 89/<- %ecx 4/r32/esp -13621 $test-emit-subx-stmt-primitive-register:initialize-var-name: -13622 # var-foo->name = "foo" -13623 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -13624 (copy-array Heap "foo" %eax) -13625 $test-emit-subx-stmt-primitive-register:initialize-var-register: -13626 # var-foo->register = "eax" -13627 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -13628 (copy-array Heap "eax" %eax) -13629 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: -13630 # var operand/ebx: (payload stmt-var) -13631 68/push 0/imm32/is-deref:false -13632 68/push 0/imm32/next -13633 68/push 0/imm32/next -13634 51/push-ecx/var-foo -13635 68/push 0x11/imm32/alloc-id:fake -13636 68/push 0x11/imm32/alloc-id:fake:payload -13637 89/<- %ebx 4/r32/esp -13638 $test-emit-subx-stmt-primitive-register:initialize-stmt: -13639 # var stmt/esi: (addr statement) -13640 53/push-ebx/outputs -13641 68/push 0x11/imm32/alloc-id:fake -13642 68/push 0/imm32/no-inouts -13643 68/push 0/imm32/no-inouts -13644 68/push 0/imm32/operation -13645 68/push 0/imm32/operation -13646 68/push 1/imm32 -13647 89/<- %esi 4/r32/esp -13648 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: -13649 # stmt->operation = "increment" -13650 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -13651 (copy-array Heap "increment" %eax) -13652 $test-emit-subx-stmt-primitive-register:initialize-formal-var: -13653 # var formal-var/ebx: (payload var) -13654 68/push 0/imm32/register -13655 68/push 0/imm32/register -13656 68/push 0/imm32/no-stack-offset -13657 68/push 1/imm32/block-depth -13658 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -13659 68/push 0x11/imm32/alloc-id:fake -13660 68/push 0/imm32/name -13661 68/push 0/imm32/name -13662 68/push 0x11/imm32/alloc-id:fake:payload -13663 89/<- %ebx 4/r32/esp -13664 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: -13665 # formal-var->name = "dummy" -13666 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -13667 (copy-array Heap "dummy" %eax) -13668 $test-emit-subx-stmt-primitive-register:initialize-formal-register: -13669 # formal-var->register = "*" -13670 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -13671 (copy-array Heap "*" %eax) # Any-register -13672 $test-emit-subx-stmt-primitive-register:initialize-var-list: -13673 # var formal-outputs/ebx: (payload list var) -13674 68/push 0/imm32/next -13675 68/push 0/imm32/next -13676 53/push-ebx/formal-var -13677 68/push 0x11/imm32/alloc-id:fake -13678 68/push 0x11/imm32/alloc-id:fake:payload -13679 89/<- %ebx 4/r32/esp -13680 $test-emit-subx-stmt-primitive-register:initialize-primitive: -13681 # var primitives/ebx: (addr primitive) -13682 68/push 0/imm32/next -13683 68/push 0/imm32/next -13684 68/push 0/imm32/output-is-write-only -13685 68/push 0/imm32/no-disp32 -13686 68/push 0/imm32/no-imm32 -13687 68/push 0/imm32/no-r32 -13688 68/push 3/imm32/rm32-is-first-output -13689 68/push 0/imm32/subx-name -13690 68/push 0/imm32/subx-name -13691 53/push-ebx/outputs -13692 68/push 0x11/imm32/alloc-id:fake -13693 68/push 0/imm32/no-inouts -13694 68/push 0/imm32/no-inouts -13695 68/push 0/imm32/name -13696 68/push 0/imm32/name -13697 89/<- %ebx 4/r32/esp -13698 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: -13699 # primitives->name = "increment" -13700 (copy-array Heap "increment" %ebx) # Primitive-name -13701 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: -13702 # primitives->subx-name = "ff 0/subop/increment" -13703 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -13704 (copy-array Heap "ff 0/subop/increment" %eax) -13705 # convert -13706 c7 0/subop/copy *Curr-block-depth 0/imm32 -13707 (emit-subx-stmt _test-output-buffered-file %esi %ebx) -13708 (flush _test-output-buffered-file) -13709 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -13715 # check output -13716 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") -13717 # . epilogue -13718 89/<- %esp 5/r32/ebp -13719 5d/pop-to-ebp -13720 c3/return -13721 -13722 test-emit-subx-stmt-select-primitive: -13723 # Select the right primitive between overloads. -13724 # foo <- increment -13725 # => -13726 # ff 0/subop/increment %eax # sub-optimal, but should suffice -13727 # -13728 # There's a variable on the var stack as follows: -13729 # name: 'foo' -13730 # type: int -13731 # register: 'eax' -13732 # -13733 # There's two primitives, as follows: -13734 # - name: 'increment' -13735 # out: int/reg -13736 # value: 'ff 0/subop/increment' -13737 # - name: 'increment' -13738 # inout: int/mem -13739 # value: 'ff 0/subop/increment' -13740 # -13741 # . prologue -13742 55/push-ebp -13743 89/<- %ebp 4/r32/esp -13744 # setup -13745 (clear-stream _test-output-stream) -13746 (clear-stream $_test-output-buffered-file->buffer) -13747 $test-emit-subx-stmt-select-primitive:initialize-type: -13748 # var type/ecx: (payload tree type-id) = int -13749 68/push 0/imm32/right:null -13750 68/push 0/imm32/right:null -13751 68/push 0/imm32/left:unused -13752 68/push 1/imm32/value:int -13753 68/push 1/imm32/is-atom?:true -13754 68/push 0x11/imm32/alloc-id:fake:payload -13755 89/<- %ecx 4/r32/esp -13756 $test-emit-subx-stmt-select-primitive:initialize-var: -13757 # var var-foo/ecx: (payload var) -13758 68/push 0/imm32/register -13759 68/push 0/imm32/register -13760 68/push 0/imm32/no-stack-offset -13761 68/push 1/imm32/block-depth -13762 51/push-ecx -13763 68/push 0x11/imm32/alloc-id:fake -13764 68/push 0/imm32/name -13765 68/push 0/imm32/name -13766 68/push 0x11/imm32/alloc-id:fake:payload -13767 89/<- %ecx 4/r32/esp -13768 $test-emit-subx-stmt-select-primitive:initialize-var-name: -13769 # var-foo->name = "foo" -13770 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -13771 (copy-array Heap "foo" %eax) -13772 $test-emit-subx-stmt-select-primitive:initialize-var-register: -13773 # var-foo->register = "eax" -13774 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -13775 (copy-array Heap "eax" %eax) -13776 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: -13777 # var operand/ebx: (payload stmt-var) -13778 68/push 0/imm32/is-deref:false -13779 68/push 0/imm32/next -13780 68/push 0/imm32/next -13781 51/push-ecx/var-foo -13782 68/push 0x11/imm32/alloc-id:fake -13783 68/push 0x11/imm32/alloc-id:fake:payload -13784 89/<- %ebx 4/r32/esp -13785 $test-emit-subx-stmt-select-primitive:initialize-stmt: -13786 # var stmt/esi: (addr statement) -13787 53/push-ebx/outputs -13788 68/push 0x11/imm32/alloc-id:fake -13789 68/push 0/imm32/no-inouts -13790 68/push 0/imm32/no-inouts -13791 68/push 0/imm32/operation -13792 68/push 0/imm32/operation -13793 68/push 1/imm32 -13794 89/<- %esi 4/r32/esp -13795 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: -13796 # stmt->operation = "increment" -13797 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -13798 (copy-array Heap "increment" %eax) -13799 $test-emit-subx-stmt-select-primitive:initialize-formal-var: -13800 # var formal-var/ebx: (payload var) -13801 68/push 0/imm32/register -13802 68/push 0/imm32/register -13803 68/push 0/imm32/no-stack-offset -13804 68/push 1/imm32/block-depth -13805 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -13806 68/push 0x11/imm32/alloc-id:fake -13807 68/push 0/imm32/name -13808 68/push 0/imm32/name -13809 68/push 0x11/imm32/alloc-id:fake:payload -13810 89/<- %ebx 4/r32/esp -13811 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: -13812 # formal-var->name = "dummy" -13813 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -13814 (copy-array Heap "dummy" %eax) -13815 $test-emit-subx-stmt-select-primitive:initialize-formal-register: -13816 # formal-var->register = "*" -13817 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -13818 (copy-array Heap "*" %eax) # Any-register -13819 $test-emit-subx-stmt-select-primitive:initialize-var-list: -13820 # var formal-outputs/ebx: (payload list var) -13821 68/push 0/imm32/next -13822 68/push 0/imm32/next -13823 53/push-ebx/formal-var -13824 68/push 0x11/imm32/alloc-id:fake -13825 68/push 0x11/imm32/alloc-id:fake:payload -13826 89/<- %ebx 4/r32/esp -13827 $test-emit-subx-stmt-select-primitive:initialize-primitive2: -13828 # var primitive2/edi: (payload primitive) -13829 68/push 0/imm32/next -13830 68/push 0/imm32/next -13831 68/push 0/imm32/output-is-write-only -13832 68/push 0/imm32/no-disp32 -13833 68/push 0/imm32/no-imm32 -13834 68/push 0/imm32/no-r32 -13835 68/push 3/imm32/rm32-is-first-output -13836 68/push 0/imm32/subx-name -13837 68/push 0/imm32/subx-name -13838 53/push-ebx/outputs -13839 68/push 0x11/imm32/alloc-id:fake -13840 68/push 0/imm32/no-inouts -13841 68/push 0/imm32/no-inouts -13842 68/push 0/imm32/name -13843 68/push 0/imm32/name -13844 68/push 0x11/imm32/alloc-id:fake:payload -13845 89/<- %edi 4/r32/esp -13846 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: -13847 # primitives->name = "increment" -13848 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -13849 (copy-array Heap "increment" %eax) -13850 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: -13851 # primitives->subx-name = "ff 0/subop/increment" -13852 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -13853 (copy-array Heap "ff 0/subop/increment" %eax) -13854 $test-emit-subx-stmt-select-primitive:initialize-primitive: -13855 # var primitives/ebx: (addr primitive) -13856 57/push-edi -13857 68/push 0x11/imm32/alloc-id:fake -13858 68/push 0/imm32/output-is-write-only -13859 68/push 0/imm32/no-disp32 -13860 68/push 0/imm32/no-imm32 -13861 68/push 0/imm32/no-r32 -13862 68/push 1/imm32/rm32-is-first-inout -13863 68/push 0/imm32/subx-name -13864 68/push 0/imm32/subx-name -13865 68/push 0/imm32/no-outputs -13866 68/push 0/imm32/no-outputs -13867 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -13868 68/push 0x11/imm32/alloc-id:fake -13869 68/push 0/imm32/name -13870 68/push 0/imm32/name -13871 89/<- %ebx 4/r32/esp -13872 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: -13873 # primitives->name = "increment" -13874 (copy-array Heap "increment" %ebx) # Primitive-name -13875 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: -13876 # primitives->subx-name = "ff 0/subop/increment" -13877 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -13878 (copy-array Heap "ff 0/subop/increment" %eax) -13879 # convert -13880 c7 0/subop/copy *Curr-block-depth 0/imm32 -13881 (emit-subx-stmt _test-output-buffered-file %esi %ebx) -13882 (flush _test-output-buffered-file) -13883 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -13889 # check output -13890 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") -13891 # . epilogue -13892 89/<- %esp 5/r32/ebp -13893 5d/pop-to-ebp -13894 c3/return -13895 -13896 test-emit-subx-stmt-select-primitive-2: -13897 # Select the right primitive between overloads. -13898 # increment foo -13899 # => -13900 # ff 0/subop/increment %eax # sub-optimal, but should suffice -13901 # -13902 # There's a variable on the var stack as follows: -13903 # name: 'foo' -13904 # type: int -13905 # register: 'eax' -13906 # -13907 # There's two primitives, as follows: -13908 # - name: 'increment' -13909 # out: int/reg -13910 # value: 'ff 0/subop/increment' -13911 # - name: 'increment' -13912 # inout: int/mem -13913 # value: 'ff 0/subop/increment' +13329 50/push-eax +13330 51/push-ecx +13331 # +13332 (emit-indent *(ebp+8) *Curr-block-depth) +13333 (write-buffered *(ebp+8) "(") +13334 # ecx = stmt +13335 8b/-> *(ebp+0xc) 1/r32/ecx +13336 # - emit function name +13337 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +13338 (write-buffered *(ebp+8) %eax) +13339 # - emit arguments +13340 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) +13341 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13342 { +13343 # if (curr == null) break +13344 3d/compare-eax-and 0/imm32 +13345 74/jump-if-= break/disp8 +13346 # +13347 (emit-subx-call-operand *(ebp+8) %eax) +13348 # curr = lookup(curr->next) +13349 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13350 eb/jump loop/disp8 +13351 } +13352 # +13353 (write-buffered *(ebp+8) ")\n") +13354 $emit-call:end: +13355 # . restore registers +13356 59/pop-to-ecx +13357 58/pop-to-eax +13358 # . epilogue +13359 89/<- %esp 5/r32/ebp +13360 5d/pop-to-ebp +13361 c3/return +13362 +13363 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) +13364 # shares code with emit-subx-var-as-rm32 +13365 # . prologue +13366 55/push-ebp +13367 89/<- %ebp 4/r32/esp +13368 # . save registers +13369 50/push-eax +13370 51/push-ecx +13371 56/push-esi +13372 # ecx = s +13373 8b/-> *(ebp+0xc) 1/r32/ecx +13374 # var operand/esi: (addr var) = lookup(s->value) +13375 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +13376 89/<- %esi 0/r32/eax +13377 # if (operand->register && !s->is-deref?) emit "%__" +13378 { +13379 $emit-subx-call-operand:check-for-register-direct: +13380 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +13381 74/jump-if-= break/disp8 +13382 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +13383 75/jump-if-!= break/disp8 +13384 $emit-subx-call-operand:register-direct: +13385 (write-buffered *(ebp+8) " %") +13386 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +13387 (write-buffered *(ebp+8) %eax) +13388 e9/jump $emit-subx-call-operand:end/disp32 +13389 } +13390 # else if (operand->register && s->is-deref?) emit "*__" +13391 { +13392 $emit-subx-call-operand:check-for-register-indirect: +13393 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +13394 74/jump-if-= break/disp8 +13395 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +13396 74/jump-if-= break/disp8 +13397 $emit-subx-call-operand:register-indirect: +13398 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) +13399 e9/jump $emit-subx-call-operand:end/disp32 +13400 } +13401 # else if (operand->stack-offset) emit "*(ebp+__)" +13402 { +13403 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +13404 74/jump-if-= break/disp8 +13405 $emit-subx-call-operand:stack: +13406 (emit-subx-call-operand-stack *(ebp+8) %esi) +13407 e9/jump $emit-subx-call-operand:end/disp32 +13408 } +13409 # else if (operand->type == literal) emit "__" +13410 { +13411 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +13412 81 7/subop/compare *(eax+4) 0/imm32 # Tree-left +13413 75/jump-if-!= break/disp8 +13414 $emit-subx-call-operand:literal: +13415 (write-buffered *(ebp+8) Space) +13416 (lookup *esi *(esi+4)) # Var-name Var-name => eax +13417 (write-buffered *(ebp+8) %eax) +13418 } +13419 $emit-subx-call-operand:end: +13420 # . restore registers +13421 5e/pop-to-esi +13422 59/pop-to-ecx +13423 58/pop-to-eax +13424 # . epilogue +13425 89/<- %esp 5/r32/ebp +13426 5d/pop-to-ebp +13427 c3/return +13428 +13429 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) +13430 # . prologue +13431 55/push-ebp +13432 89/<- %ebp 4/r32/esp +13433 # . save registers +13434 50/push-eax +13435 51/push-ecx +13436 56/push-esi +13437 # esi = v +13438 8b/-> *(ebp+0xc) 6/r32/esi +13439 # var size/ecx: int = size-of-deref(v) +13440 (size-of-deref %esi) # => eax +13441 89/<- %ecx 0/r32/eax +13442 # var reg-name/esi: (addr array byte) = lookup(v->register) +13443 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +13444 89/<- %esi 0/r32/eax +13445 # TODO: assert size is a multiple of 4 +13446 # var i/eax: int = 0 +13447 b8/copy-to-eax 0/imm32 +13448 { +13449 $emit-subx-call-operand-register-indirect:loop: +13450 # if (i >= size) break +13451 39/compare %eax 1/r32/ecx +13452 7d/jump-if->= break/disp8 +13453 # emit " *(" v->register "+" i ")" +13454 (write-buffered *(ebp+8) " *(") +13455 (write-buffered *(ebp+8) %esi) +13456 (write-buffered *(ebp+8) "+") +13457 (print-int32-buffered *(ebp+8) %eax) +13458 (write-buffered *(ebp+8) ")") +13459 # i += 4 +13460 05/add-to-eax 4/imm32 +13461 # +13462 eb/jump loop/disp8 +13463 } +13464 $emit-subx-call-operand-register-indirect:end: +13465 # . restore registers +13466 5e/pop-to-esi +13467 59/pop-to-ecx +13468 58/pop-to-eax +13469 # . epilogue +13470 89/<- %esp 5/r32/ebp +13471 5d/pop-to-ebp +13472 c3/return +13473 +13474 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) +13475 # . prologue +13476 55/push-ebp +13477 89/<- %ebp 4/r32/esp +13478 # . save registers +13479 50/push-eax +13480 51/push-ecx +13481 56/push-esi +13482 # esi = v +13483 8b/-> *(ebp+0xc) 6/r32/esi +13484 # var curr/ecx: int = v->offset +13485 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset +13486 # var max/eax: int = v->offset + size-of(v) +13487 (size-of %esi) # => eax +13488 # TODO: assert size is a multiple of 4 +13489 01/add-to %eax 1/r32/ecx +13490 { +13491 $emit-subx-call-operand-stack:loop: +13492 # if (curr >= max) break +13493 39/compare %ecx 0/r32/eax +13494 7d/jump-if->= break/disp8 +13495 # emit " *(ebp+" curr ")" +13496 (write-buffered *(ebp+8) " *(ebp+") +13497 (print-int32-buffered *(ebp+8) %ecx) +13498 (write-buffered *(ebp+8) ")") +13499 # i += 4 +13500 81 0/subop/add %ecx 4/imm32 +13501 # +13502 eb/jump loop/disp8 +13503 } +13504 $emit-subx-call-operand-stack:end: +13505 # . restore registers +13506 5e/pop-to-esi +13507 59/pop-to-ecx +13508 58/pop-to-eax +13509 # . epilogue +13510 89/<- %esp 5/r32/ebp +13511 5d/pop-to-ebp +13512 c3/return +13513 +13514 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) +13515 # . prologue +13516 55/push-ebp +13517 89/<- %ebp 4/r32/esp +13518 # . save registers +13519 50/push-eax +13520 51/push-ecx +13521 56/push-esi +13522 # ecx = s +13523 8b/-> *(ebp+0xc) 1/r32/ecx +13524 # var operand/esi: (addr var) = lookup(s->value) +13525 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +13526 89/<- %esi 0/r32/eax +13527 # if (operand->register && s->is-deref?) emit "*__" +13528 { +13529 $emit-subx-var-as-rm32:check-for-register-indirect: +13530 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +13531 74/jump-if-= break/disp8 +13532 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +13533 74/jump-if-= break/disp8 +13534 $emit-subx-var-as-rm32:register-indirect: +13535 (write-buffered *(ebp+8) " *") +13536 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +13537 (write-buffered *(ebp+8) %eax) +13538 e9/jump $emit-subx-var-as-rm32:end/disp32 +13539 } +13540 # if (operand->register && !s->is-deref?) emit "%__" +13541 { +13542 $emit-subx-var-as-rm32:check-for-register-direct: +13543 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +13544 74/jump-if-= break/disp8 +13545 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +13546 75/jump-if-!= break/disp8 +13547 $emit-subx-var-as-rm32:register-direct: +13548 (write-buffered *(ebp+8) " %") +13549 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +13550 (write-buffered *(ebp+8) %eax) +13551 e9/jump $emit-subx-var-as-rm32:end/disp32 +13552 } +13553 # else if (operand->stack-offset) emit "*(ebp+__)" +13554 { +13555 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +13556 74/jump-if-= break/disp8 +13557 $emit-subx-var-as-rm32:stack: +13558 (write-buffered *(ebp+8) Space) +13559 (write-buffered *(ebp+8) "*(ebp+") +13560 (print-int32-buffered *(ebp+8) *(esi+0x14)) # Var-offset +13561 (write-buffered *(ebp+8) ")") +13562 } +13563 $emit-subx-var-as-rm32:end: +13564 # . restore registers +13565 5e/pop-to-esi +13566 59/pop-to-ecx +13567 58/pop-to-eax +13568 # . epilogue +13569 89/<- %esp 5/r32/ebp +13570 5d/pop-to-ebp +13571 c3/return +13572 +13573 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) +13574 # . prologue +13575 55/push-ebp +13576 89/<- %ebp 4/r32/esp +13577 # . save registers +13578 51/push-ecx +13579 # var curr/ecx: (addr primitive) = primitives +13580 8b/-> *(ebp+8) 1/r32/ecx +13581 { +13582 $find-matching-primitive:loop: +13583 # if (curr == null) break +13584 81 7/subop/compare %ecx 0/imm32 +13585 0f 84/jump-if-= break/disp32 +13586 # if match(curr, stmt) return curr +13587 { +13588 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax +13589 3d/compare-eax-and 0/imm32/false +13590 74/jump-if-= break/disp8 +13591 89/<- %eax 1/r32/ecx +13592 eb/jump $find-matching-primitive:end/disp8 +13593 } +13594 $find-matching-primitive:next-primitive: +13595 # curr = curr->next +13596 (lookup *(ecx+0x34) *(ecx+0x38)) # Primitive-next Primitive-next => eax +13597 89/<- %ecx 0/r32/eax +13598 # +13599 e9/jump loop/disp32 +13600 } +13601 # return null +13602 b8/copy-to-eax 0/imm32 +13603 $find-matching-primitive:end: +13604 # . restore registers +13605 59/pop-to-ecx +13606 # . epilogue +13607 89/<- %esp 5/r32/ebp +13608 5d/pop-to-ebp +13609 c3/return +13610 +13611 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean +13612 # A mu stmt matches a primitive if the name matches, all the inout vars +13613 # match, and all the output vars match. +13614 # Vars match if types match and registers match. +13615 # In addition, a stmt output matches a primitive's output if types match +13616 # and the primitive has a wildcard register. +13617 # . prologue +13618 55/push-ebp +13619 89/<- %ebp 4/r32/esp +13620 # . save registers +13621 51/push-ecx +13622 52/push-edx +13623 53/push-ebx +13624 56/push-esi +13625 57/push-edi +13626 # ecx = stmt +13627 8b/-> *(ebp+8) 1/r32/ecx +13628 # edx = primitive +13629 8b/-> *(ebp+0xc) 2/r32/edx +13630 { +13631 $mu-stmt-matches-primitive?:check-name: +13632 # if (primitive->name != stmt->operation) return false +13633 # . var esi: (addr array byte) = lookup(stmt->operation) +13634 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +13635 89/<- %esi 0/r32/eax +13636 # . var edi: (addr array byte) = lookup(primitive->name) +13637 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax +13638 89/<- %edi 0/r32/eax +13639 (string-equal? %esi %edi) # => eax +13640 3d/compare-eax-and 0/imm32/false +13641 75/jump-if-!= break/disp8 +13642 b8/copy-to-eax 0/imm32 +13643 e9/jump $mu-stmt-matches-primitive?:end/disp32 +13644 } +13645 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) +13646 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13647 89/<- %esi 0/r32/eax +13648 # var curr2/edi: (addr list var) = lookup(primitive->inouts) +13649 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax +13650 89/<- %edi 0/r32/eax +13651 { +13652 $mu-stmt-matches-primitive?:inouts-loop: +13653 # if (curr == 0 && curr2 == 0) move on to check outputs +13654 { +13655 $mu-stmt-matches-primitive?:check-both-inouts-null: +13656 81 7/subop/compare %esi 0/imm32 +13657 75/jump-if-!= break/disp8 +13658 $mu-stmt-matches-primitive?:stmt-inout-null: +13659 81 7/subop/compare %edi 0/imm32 +13660 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 +13661 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: +13662 # return false +13663 b8/copy-to-eax 0/imm32/false +13664 e9/jump $mu-stmt-matches-primitive?:end/disp32 +13665 } +13666 # if (curr2 == 0) return false +13667 { +13668 $mu-stmt-matches-primitive?:check-prim-inout-null: +13669 81 7/subop/compare %edi 0/imm32 +13670 75/jump-if-!= break/disp8 +13671 $mu-stmt-matches-primitive?:prim-inout-null: +13672 b8/copy-to-eax 0/imm32/false +13673 e9/jump $mu-stmt-matches-primitive?:end/disp32 +13674 } +13675 # if (curr != curr2) return false +13676 { +13677 $mu-stmt-matches-primitive?:check-inouts-match: +13678 (lookup *edi *(edi+4)) # List-value List-value => eax +13679 (operand-matches-primitive? %esi %eax) # => eax +13680 3d/compare-eax-and 0/imm32/false +13681 75/jump-if-!= break/disp8 +13682 $mu-stmt-matches-primitive?:inouts-match: +13683 b8/copy-to-eax 0/imm32/false +13684 e9/jump $mu-stmt-matches-primitive?:end/disp32 +13685 } +13686 $mu-stmt-matches-primitive?:next-inout: +13687 # curr = lookup(curr->next) +13688 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +13689 89/<- %esi 0/r32/eax +13690 # curr2 = lookup(curr2->next) +13691 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +13692 89/<- %edi 0/r32/eax +13693 # +13694 e9/jump loop/disp32 +13695 } +13696 $mu-stmt-matches-primitive?:check-outputs: +13697 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) +13698 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13699 89/<- %esi 0/r32/eax +13700 # var curr2/edi: (addr list var) = lookup(primitive->outputs) +13701 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax +13702 89/<- %edi 0/r32/eax +13703 { +13704 $mu-stmt-matches-primitive?:outputs-loop: +13705 # if (curr == 0) return (curr2 == 0) +13706 { +13707 $mu-stmt-matches-primitive?:check-both-outputs-null: +13708 81 7/subop/compare %esi 0/imm32 +13709 75/jump-if-!= break/disp8 +13710 { +13711 $mu-stmt-matches-primitive?:stmt-output-null: +13712 81 7/subop/compare %edi 0/imm32 +13713 75/jump-if-!= break/disp8 +13714 $mu-stmt-matches-primitive?:both-outputs-null: +13715 # return true +13716 b8/copy-to-eax 1/imm32 +13717 e9/jump $mu-stmt-matches-primitive?:end/disp32 +13718 } +13719 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: +13720 # return false +13721 b8/copy-to-eax 0/imm32 +13722 e9/jump $mu-stmt-matches-primitive?:end/disp32 +13723 } +13724 # if (curr2 == 0) return false +13725 { +13726 $mu-stmt-matches-primitive?:check-prim-output-null: +13727 81 7/subop/compare %edi 0/imm32 +13728 75/jump-if-!= break/disp8 +13729 $mu-stmt-matches-primitive?:prim-output-is-null: +13730 b8/copy-to-eax 0/imm32 +13731 e9/jump $mu-stmt-matches-primitive?:end/disp32 +13732 } +13733 # if (curr != curr2) return false +13734 { +13735 $mu-stmt-matches-primitive?:check-outputs-match: +13736 (lookup *edi *(edi+4)) # List-value List-value => eax +13737 (operand-matches-primitive? %esi %eax) # => eax +13738 3d/compare-eax-and 0/imm32/false +13739 75/jump-if-!= break/disp8 +13740 $mu-stmt-matches-primitive?:outputs-match: +13741 b8/copy-to-eax 0/imm32 +13742 e9/jump $mu-stmt-matches-primitive?:end/disp32 +13743 } +13744 $mu-stmt-matches-primitive?:next-output: +13745 # curr = lookup(curr->next) +13746 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +13747 89/<- %esi 0/r32/eax +13748 # curr2 = lookup(curr2->next) +13749 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +13750 89/<- %edi 0/r32/eax +13751 # +13752 e9/jump loop/disp32 +13753 } +13754 $mu-stmt-matches-primitive?:return-true: +13755 b8/copy-to-eax 1/imm32 +13756 $mu-stmt-matches-primitive?:end: +13757 # . restore registers +13758 5f/pop-to-edi +13759 5e/pop-to-esi +13760 5b/pop-to-ebx +13761 5a/pop-to-edx +13762 59/pop-to-ecx +13763 # . epilogue +13764 89/<- %esp 5/r32/ebp +13765 5d/pop-to-ebp +13766 c3/return +13767 +13768 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean +13769 # . prologue +13770 55/push-ebp +13771 89/<- %ebp 4/r32/esp +13772 # . save registers +13773 51/push-ecx +13774 52/push-edx +13775 53/push-ebx +13776 56/push-esi +13777 57/push-edi +13778 # ecx = s +13779 8b/-> *(ebp+8) 1/r32/ecx +13780 # var var/esi: (addr var) = lookup(s->value) +13781 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +13782 89/<- %esi 0/r32/eax +13783 # edi = prim-var +13784 8b/-> *(ebp+0xc) 7/r32/edi +13785 $operand-matches-primitive?:check-type: +13786 # if (var->type != prim-var->type) return false +13787 # . var vtype/ebx: (addr tree type-id) = lookup(var->type) +13788 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +13789 89/<- %ebx 0/r32/eax +13790 # . var ptype/eax: (addr tree type-id) = lookup(prim-var->type) +13791 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +13792 (subx-type-equal? %ebx %eax) # => eax +13793 3d/compare-eax-and 0/imm32/false +13794 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 +13795 { +13796 $operand-matches-primitive?:check-register: +13797 # if prim-var is in memory and var is in register but dereference, match +13798 { +13799 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +13800 0f 85/jump-if-!= break/disp32 +13801 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +13802 74/jump-if-= break/disp8 +13803 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +13804 74/jump-if-= break/disp8 +13805 $operand-matches-primitive?:var-deref-match: +13806 e9/jump $operand-matches-primitive?:return-true/disp32 +13807 } +13808 # if prim-var is in register and var is in register but dereference, no match +13809 { +13810 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +13811 0f 84/jump-if-= break/disp32 +13812 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +13813 0f 84/jump-if-= break/disp32 +13814 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +13815 74/jump-if-= break/disp8 +13816 $operand-matches-primitive?:var-deref-no-match: +13817 e9/jump $operand-matches-primitive?:return-false/disp32 +13818 } +13819 # return false if var->register doesn't match prim-var->register +13820 { +13821 # if register addresses are equal, it's a match +13822 # var vreg/ebx: (addr array byte) = lookup(var->register) +13823 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +13824 89/<- %ebx 0/r32/eax +13825 # var preg/ecx: (addr array byte) = lookup(prim-var->register) +13826 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +13827 89/<- %ecx 0/r32/eax +13828 # if (vreg == preg) break +13829 39/compare %ecx 3/r32/ebx +13830 74/jump-if-= break/disp8 +13831 $operand-matches-primitive?:var-register-no-match: +13832 # if either address is 0, return false +13833 81 7/subop/compare %ebx 0/imm32 +13834 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +13835 81 7/subop/compare %ecx 0/imm32 +13836 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +13837 # if prim-var->register is wildcard, it's a match +13838 (string-equal? %ecx "*") # Any-register => eax +13839 3d/compare-eax-and 0/imm32/false +13840 75/jump-if-!= break/disp8 +13841 $operand-matches-primitive?:wildcard-no-match: +13842 # if string contents aren't equal, return false +13843 (string-equal? %ecx %ebx) # => eax +13844 3d/compare-eax-and 0/imm32/false +13845 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +13846 } +13847 } +13848 $operand-matches-primitive?:return-true: +13849 b8/copy-to-eax 1/imm32/true +13850 eb/jump $operand-matches-primitive?:end/disp8 +13851 $operand-matches-primitive?:return-false: +13852 b8/copy-to-eax 0/imm32/false +13853 $operand-matches-primitive?:end: +13854 # . restore registers +13855 5f/pop-to-edi +13856 5e/pop-to-esi +13857 5b/pop-to-ebx +13858 5a/pop-to-edx +13859 59/pop-to-ecx +13860 # . epilogue +13861 89/<- %esp 5/r32/ebp +13862 5d/pop-to-ebp +13863 c3/return +13864 +13865 subx-type-equal?: # a: (addr tree type-id), b: (addr tree type-id) -> result/eax: boolean +13866 # . prologue +13867 55/push-ebp +13868 89/<- %ebp 4/r32/esp +13869 # . save registers +13870 51/push-ecx +13871 # var alit/ecx: boolean = is-literal-type?(a) +13872 (is-simple-mu-type? *(ebp+8) 0) # => eax +13873 89/<- %ecx 0/r32/eax +13874 # var blit/eax: boolean = is-literal-type?(b) +13875 (is-simple-mu-type? *(ebp+0xc) 0) # => eax +13876 # return alit == blit +13877 39/compare %eax 1/r32/ecx +13878 0f 94/set-byte-if-= %al +13879 81 4/subop/and %eax 0xff/imm32 +13880 $subx-type-equal?:end: +13881 # . restore registers +13882 59/pop-to-ecx +13883 # . epilogue +13884 89/<- %esp 5/r32/ebp +13885 5d/pop-to-ebp +13886 c3/return +13887 +13888 is-simple-mu-type?: # a: (addr tree type-id), n: type-id -> result/eax: boolean +13889 # . prologue +13890 55/push-ebp +13891 89/<- %ebp 4/r32/esp +13892 # . save registers +13893 51/push-ecx +13894 # ecx = n +13895 8b/-> *(ebp+0xc) 1/r32/ecx +13896 # return (a->value == n) +13897 8b/-> *(ebp+8) 0/r32/eax +13898 39/compare *(eax+4) 1/r32/ecx # Tree-value +13899 0f 94/set-byte-if-= %al +13900 81 4/subop/and %eax 0xff/imm32 +13901 $is-simple-mu-type?:end: +13902 # . restore registers +13903 59/pop-to-ecx +13904 # . epilogue +13905 89/<- %esp 5/r32/ebp +13906 5d/pop-to-ebp +13907 c3/return +13908 +13909 test-emit-subx-stmt-primitive: +13910 # Primitive operation on a variable on the stack. +13911 # increment foo +13912 # => +13913 # ff 0/subop/increment *(ebp-8) 13914 # -13915 # . prologue -13916 55/push-ebp -13917 89/<- %ebp 4/r32/esp -13918 # setup -13919 (clear-stream _test-output-stream) -13920 (clear-stream $_test-output-buffered-file->buffer) -13921 $test-emit-subx-stmt-select-primitive-2:initialize-type: -13922 # var type/ecx: (payload tree type-id) = int -13923 68/push 0/imm32/right:null -13924 68/push 0/imm32/right:null -13925 68/push 0/imm32/left:unused -13926 68/push 1/imm32/value:int -13927 68/push 1/imm32/is-atom?:true -13928 68/push 0x11/imm32/alloc-id:fake:payload -13929 89/<- %ecx 4/r32/esp -13930 $test-emit-subx-stmt-select-primitive-2:initialize-var: -13931 # var var-foo/ecx: (payload var) -13932 68/push 0/imm32/register -13933 68/push 0/imm32/register -13934 68/push 0/imm32/no-stack-offset -13935 68/push 1/imm32/block-depth -13936 51/push-ecx -13937 68/push 0x11/imm32/alloc-id:fake -13938 68/push 0/imm32/name -13939 68/push 0/imm32/name -13940 68/push 0x11/imm32/alloc-id:fake:payload -13941 89/<- %ecx 4/r32/esp -13942 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: -13943 # var-foo->name = "foo" -13944 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -13945 (copy-array Heap "foo" %eax) -13946 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: -13947 # var-foo->register = "eax" -13948 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -13949 (copy-array Heap "eax" %eax) -13950 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: -13951 # var operand/ebx: (payload stmt-var) -13952 68/push 0/imm32/is-deref:false -13953 68/push 0/imm32/next -13954 68/push 0/imm32/next -13955 51/push-ecx/var-foo -13956 68/push 0x11/imm32/alloc-id:fake -13957 68/push 0x11/imm32/alloc-id:fake:payload -13958 89/<- %ebx 4/r32/esp -13959 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: -13960 # var stmt/esi: (addr statement) -13961 68/push 0/imm32/no-outputs -13962 68/push 0/imm32/no-outputs -13963 53/push-ebx/inouts -13964 68/push 0x11/imm32/alloc-id:fake -13965 68/push 0/imm32/operation -13966 68/push 0/imm32/operation -13967 68/push 1/imm32 -13968 89/<- %esi 4/r32/esp -13969 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: -13970 # stmt->operation = "increment" -13971 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -13972 (copy-array Heap "increment" %eax) -13973 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: -13974 # var formal-var/ebx: (payload var) -13975 68/push 0/imm32/register -13976 68/push 0/imm32/register -13977 68/push 0/imm32/no-stack-offset -13978 68/push 1/imm32/block-depth -13979 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -13980 68/push 0x11/imm32/alloc-id:fake -13981 68/push 0/imm32/name -13982 68/push 0/imm32/name -13983 68/push 0x11/imm32/alloc-id:fake:payload -13984 89/<- %ebx 4/r32/esp -13985 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: -13986 # formal-var->name = "dummy" -13987 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -13988 (copy-array Heap "dummy" %eax) -13989 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: -13990 # formal-var->register = "*" -13991 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -13992 (copy-array Heap "*" %eax) # Any-register -13993 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: -13994 # var formal-outputs/ebx: (payload list stmt-var) -13995 68/push 0/imm32/next -13996 68/push 0/imm32/next -13997 53/push-ebx/formal-var -13998 68/push 0x11/imm32/alloc-id:fake -13999 68/push 0x11/imm32/alloc-id:fake:payload -14000 89/<- %ebx 4/r32/esp -14001 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: -14002 # var primitive2/edi: (payload primitive) -14003 68/push 0/imm32/next -14004 68/push 0/imm32/next -14005 68/push 0/imm32/output-is-write-only -14006 68/push 0/imm32/no-disp32 -14007 68/push 0/imm32/no-imm32 -14008 68/push 0/imm32/no-r32 -14009 68/push 3/imm32/rm32-is-first-output -14010 68/push 0/imm32/subx-name -14011 68/push 0/imm32/subx-name -14012 53/push-ebx/outputs -14013 68/push 0x11/imm32/alloc-id:fake -14014 68/push 0/imm32/no-inouts -14015 68/push 0/imm32/no-inouts -14016 68/push 0/imm32/name -14017 68/push 0/imm32/name -14018 68/push 0x11/imm32/alloc-id:fake:payload -14019 89/<- %edi 4/r32/esp -14020 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: -14021 # primitives->name = "increment" -14022 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -14023 (copy-array Heap "increment" %eax) -14024 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: -14025 # primitives->subx-name = "ff 0/subop/increment" -14026 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -14027 (copy-array Heap "ff 0/subop/increment" %eax) -14028 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: -14029 # var primitives/ebx: (addr primitive) -14030 57/push-edi -14031 68/push 0x11/imm32/alloc-id:fake -14032 68/push 0/imm32/output-is-write-only -14033 68/push 0/imm32/no-disp32 -14034 68/push 0/imm32/no-imm32 -14035 68/push 0/imm32/no-r32 -14036 68/push 1/imm32/rm32-is-first-inout -14037 68/push 0/imm32/subx-name -14038 68/push 0/imm32/subx-name -14039 68/push 0/imm32/no-outputs -14040 68/push 0/imm32/no-outputs -14041 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -14042 68/push 0x11/imm32/alloc-id:fake -14043 68/push 0/imm32/name -14044 68/push 0/imm32/name -14045 89/<- %ebx 4/r32/esp -14046 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: -14047 # primitives->name = "increment" -14048 (copy-array Heap "increment" %ebx) # Primitive-name -14049 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: -14050 # primitives->subx-name = "ff 0/subop/increment" -14051 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -14052 (copy-array Heap "ff 0/subop/increment" %eax) -14053 # convert -14054 c7 0/subop/copy *Curr-block-depth 0/imm32 -14055 (emit-subx-stmt _test-output-buffered-file %esi %ebx) -14056 (flush _test-output-buffered-file) -14057 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14063 # check output -14064 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") -14065 # . epilogue -14066 89/<- %esp 5/r32/ebp -14067 5d/pop-to-ebp -14068 c3/return -14069 -14070 test-increment-register: -14071 # Select the right register between overloads. -14072 # foo <- increment -14073 # => -14074 # 50/increment-eax -14075 # -14076 # There's a variable on the var stack as follows: -14077 # name: 'foo' -14078 # type: int -14079 # register: 'eax' -14080 # -14081 # Primitives are the global definitions. -14082 # -14083 # . prologue -14084 55/push-ebp -14085 89/<- %ebp 4/r32/esp -14086 # setup -14087 (clear-stream _test-output-stream) -14088 (clear-stream $_test-output-buffered-file->buffer) -14089 $test-increment-register:initialize-type: -14090 # var type/ecx: (payload tree type-id) = int -14091 68/push 0/imm32/right:null -14092 68/push 0/imm32/right:null -14093 68/push 0/imm32/left:unused -14094 68/push 1/imm32/value:int -14095 68/push 1/imm32/is-atom?:true -14096 68/push 0x11/imm32/alloc-id:fake:payload -14097 89/<- %ecx 4/r32/esp -14098 $test-increment-register:initialize-var: -14099 # var var-foo/ecx: (payload var) -14100 68/push 0/imm32/register -14101 68/push 0/imm32/register -14102 68/push 0/imm32/no-stack-offset -14103 68/push 1/imm32/block-depth -14104 51/push-ecx -14105 68/push 0x11/imm32/alloc-id:fake -14106 68/push 0/imm32/name -14107 68/push 0/imm32/name -14108 68/push 0x11/imm32/alloc-id:fake:payload -14109 89/<- %ecx 4/r32/esp -14110 $test-increment-register:initialize-var-name: -14111 # var-foo->name = "foo" -14112 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14113 (copy-array Heap "foo" %eax) -14114 $test-increment-register:initialize-var-register: -14115 # var-foo->register = "eax" -14116 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -14117 (copy-array Heap "eax" %eax) -14118 $test-increment-register:initialize-stmt-var: -14119 # var operand/ebx: (payload stmt-var) -14120 68/push 0/imm32/is-deref:false -14121 68/push 0/imm32/next -14122 68/push 0/imm32/next -14123 51/push-ecx/var-foo -14124 68/push 0x11/imm32/alloc-id:fake -14125 68/push 0x11/imm32/alloc-id:fake:payload -14126 89/<- %ebx 4/r32/esp -14127 $test-increment-register:initialize-stmt: -14128 # var stmt/esi: (addr statement) -14129 53/push-ebx/outputs -14130 68/push 0x11/imm32/alloc-id:fake -14131 68/push 0/imm32/no-inouts -14132 68/push 0/imm32/no-inouts -14133 68/push 0/imm32/operation -14134 68/push 0/imm32/operation -14135 68/push 1/imm32 -14136 89/<- %esi 4/r32/esp -14137 $test-increment-register:initialize-stmt-operation: -14138 # stmt->operation = "increment" -14139 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -14140 (copy-array Heap "increment" %eax) -14141 # convert -14142 c7 0/subop/copy *Curr-block-depth 0/imm32 -14143 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -14144 (flush _test-output-buffered-file) -14145 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14151 # check output -14152 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") -14153 # . epilogue -14154 89/<- %esp 5/r32/ebp -14155 5d/pop-to-ebp -14156 c3/return -14157 -14158 test-add-reg-to-reg: -14159 # var1/reg <- add var2/reg -14160 # => -14161 # 01/add-to %var1 var2 -14162 # -14163 # . prologue -14164 55/push-ebp -14165 89/<- %ebp 4/r32/esp -14166 # setup -14167 (clear-stream _test-output-stream) -14168 (clear-stream $_test-output-buffered-file->buffer) -14169 $test-add-reg-to-reg:initialize-type: -14170 # var type/ecx: (payload tree type-id) = int -14171 68/push 0/imm32/right:null -14172 68/push 0/imm32/right:null -14173 68/push 0/imm32/left:unused -14174 68/push 1/imm32/value:int -14175 68/push 1/imm32/is-atom?:true -14176 68/push 0x11/imm32/alloc-id:fake:payload -14177 89/<- %ecx 4/r32/esp -14178 $test-add-reg-to-reg:initialize-var1: -14179 # var var1/ecx: (payload var) -14180 68/push 0/imm32/register -14181 68/push 0/imm32/register -14182 68/push 0/imm32/no-stack-offset -14183 68/push 1/imm32/block-depth -14184 51/push-ecx -14185 68/push 0x11/imm32/alloc-id:fake -14186 68/push 0/imm32/name -14187 68/push 0/imm32/name -14188 68/push 0x11/imm32/alloc-id:fake:payload -14189 89/<- %ecx 4/r32/esp -14190 $test-add-reg-to-reg:initialize-var1-name: -14191 # var1->name = "var1" -14192 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14193 (copy-array Heap "var1" %eax) -14194 $test-add-reg-to-reg:initialize-var1-register: -14195 # var1->register = "eax" -14196 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -14197 (copy-array Heap "eax" %eax) -14198 $test-add-reg-to-reg:initialize-var2: -14199 # var var2/edx: (payload var) -14200 68/push 0/imm32/register -14201 68/push 0/imm32/register -14202 68/push 0/imm32/no-stack-offset -14203 68/push 1/imm32/block-depth -14204 ff 6/subop/push *(ecx+0x10) -14205 68/push 0x11/imm32/alloc-id:fake -14206 68/push 0/imm32/name -14207 68/push 0/imm32/name -14208 68/push 0x11/imm32/alloc-id:fake:payload -14209 89/<- %edx 4/r32/esp -14210 $test-add-reg-to-reg:initialize-var2-name: -14211 # var2->name = "var2" -14212 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -14213 (copy-array Heap "var2" %eax) -14214 $test-add-reg-to-reg:initialize-var2-register: -14215 # var2->register = "ecx" -14216 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -14217 (copy-array Heap "ecx" %eax) -14218 $test-add-reg-to-reg:initialize-inouts: -14219 # var inouts/esi: (payload stmt-var) = [var2] -14220 68/push 0/imm32/is-deref:false -14221 68/push 0/imm32/next -14222 68/push 0/imm32/next -14223 52/push-edx/var2 -14224 68/push 0x11/imm32/alloc-id:fake -14225 68/push 0x11/imm32/alloc-id:fake:payload -14226 89/<- %esi 4/r32/esp -14227 $test-add-reg-to-reg:initialize-outputs: -14228 # var outputs/edi: (payload stmt-var) = [var1] -14229 68/push 0/imm32/is-deref:false -14230 68/push 0/imm32/next -14231 68/push 0/imm32/next -14232 51/push-ecx/var1 -14233 68/push 0x11/imm32/alloc-id:fake -14234 68/push 0x11/imm32/alloc-id:fake:payload -14235 89/<- %edi 4/r32/esp -14236 $test-add-reg-to-reg:initialize-stmt: -14237 # var stmt/esi: (addr statement) -14238 68/push 0/imm32/next -14239 68/push 0/imm32/next -14240 57/push-edi/outputs -14241 68/push 0x11/imm32/alloc-id:fake -14242 56/push-esi/inouts -14243 68/push 0x11/imm32/alloc-id:fake -14244 68/push 0/imm32/operation -14245 68/push 0/imm32/operation -14246 68/push 1/imm32/tag:stmt1 -14247 89/<- %esi 4/r32/esp -14248 $test-add-reg-to-reg:initialize-stmt-operation: -14249 # stmt->operation = "add" -14250 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -14251 (copy-array Heap "add" %eax) -14252 # convert -14253 c7 0/subop/copy *Curr-block-depth 0/imm32 -14254 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -14255 (flush _test-output-buffered-file) -14256 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14262 # check output -14263 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") -14264 # . epilogue -14265 89/<- %esp 5/r32/ebp -14266 5d/pop-to-ebp -14267 c3/return -14268 -14269 test-add-reg-to-mem: -14270 # add-to var1 var2/reg -14271 # => -14272 # 01/add-to *(ebp+__) var2 -14273 # -14274 # . prologue -14275 55/push-ebp -14276 89/<- %ebp 4/r32/esp -14277 # setup -14278 (clear-stream _test-output-stream) -14279 (clear-stream $_test-output-buffered-file->buffer) -14280 $test-add-reg-to-mem:initialize-type: -14281 # var type/ecx: (payload tree type-id) = int -14282 68/push 0/imm32/right:null -14283 68/push 0/imm32/right:null -14284 68/push 0/imm32/left:unused -14285 68/push 1/imm32/value:int -14286 68/push 1/imm32/is-atom?:true -14287 68/push 0x11/imm32/alloc-id:fake:payload -14288 89/<- %ecx 4/r32/esp -14289 $test-add-reg-to-mem:initialize-var1: -14290 # var var1/ecx: (payload var) -14291 68/push 0/imm32/register -14292 68/push 0/imm32/register -14293 68/push 8/imm32/stack-offset -14294 68/push 1/imm32/block-depth -14295 51/push-ecx -14296 68/push 0x11/imm32/alloc-id:fake -14297 68/push 0/imm32/name -14298 68/push 0/imm32/name -14299 68/push 0x11/imm32/alloc-id:fake:payload -14300 89/<- %ecx 4/r32/esp -14301 $test-add-reg-to-mem:initialize-var1-name: -14302 # var1->name = "var1" -14303 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14304 (copy-array Heap "var1" %eax) -14305 $test-add-reg-to-mem:initialize-var2: -14306 # var var2/edx: (payload var) -14307 68/push 0/imm32/register -14308 68/push 0/imm32/register -14309 68/push 0/imm32/no-stack-offset -14310 68/push 1/imm32/block-depth -14311 ff 6/subop/push *(ecx+0x10) +13915 # There's a variable on the var stack as follows: +13916 # name: 'foo' +13917 # type: int +13918 # stack-offset: -8 +13919 # +13920 # There's a primitive with this info: +13921 # name: 'increment' +13922 # inouts: int/mem +13923 # value: 'ff 0/subop/increment' +13924 # +13925 # . prologue +13926 55/push-ebp +13927 89/<- %ebp 4/r32/esp +13928 # setup +13929 (clear-stream _test-output-stream) +13930 (clear-stream $_test-output-buffered-file->buffer) +13931 # simulate allocated payloads starting with an initial fake alloc-id (0x11) +13932 $test-emit-subx-stmt-primitive:initialize-type: +13933 # var type/ecx: (payload tree type-id) = int +13934 68/push 0/imm32/right:null +13935 68/push 0/imm32/right:null +13936 68/push 0/imm32/left:unused +13937 68/push 1/imm32/value:int +13938 68/push 1/imm32/is-atom?:true +13939 68/push 0x11/imm32/alloc-id:fake:payload +13940 89/<- %ecx 4/r32/esp +13941 $test-emit-subx-stmt-primitive:initialize-var: +13942 # var var-foo/ecx: (payload var) = var(type) +13943 68/push 0/imm32/no-register +13944 68/push 0/imm32/no-register +13945 68/push -8/imm32/stack-offset +13946 68/push 1/imm32/block-depth +13947 51/push-ecx/type +13948 68/push 0x11/imm32/alloc-id:fake +13949 68/push 0/imm32/name +13950 68/push 0/imm32/name +13951 68/push 0x11/imm32/alloc-id:fake:payload +13952 89/<- %ecx 4/r32/esp +13953 $test-emit-subx-stmt-primitive:initialize-var-name: +13954 # var-foo->name = "foo" +13955 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +13956 (copy-array Heap "foo" %eax) +13957 $test-emit-subx-stmt-primitive:initialize-stmt-var: +13958 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +13959 68/push 0/imm32/is-deref:false +13960 68/push 0/imm32/next +13961 68/push 0/imm32/next +13962 51/push-ecx/var-foo +13963 68/push 0x11/imm32/alloc-id:fake +13964 68/push 0x11/imm32/alloc-id:fake:payload +13965 89/<- %ebx 4/r32/esp +13966 $test-emit-subx-stmt-primitive:initialize-stmt: +13967 # var stmt/esi: (addr statement) +13968 68/push 0/imm32/no-outputs +13969 68/push 0/imm32/no-outputs +13970 53/push-ebx/inouts +13971 68/push 0x11/imm32/alloc-id:fake +13972 68/push 0/imm32/operation +13973 68/push 0/imm32/operation +13974 68/push 1/imm32/tag +13975 89/<- %esi 4/r32/esp +13976 $test-emit-subx-stmt-primitive:initialize-stmt-operation: +13977 # stmt->operation = "increment" +13978 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +13979 (copy-array Heap "increment" %eax) +13980 $test-emit-subx-stmt-primitive:initialize-primitive: +13981 # var primitives/ebx: (addr primitive) +13982 68/push 0/imm32/next +13983 68/push 0/imm32/next +13984 68/push 0/imm32/output-is-write-only +13985 68/push 0/imm32/no-disp32 +13986 68/push 0/imm32/no-imm32 +13987 68/push 0/imm32/no-r32 +13988 68/push 1/imm32/rm32-is-first-inout +13989 68/push 0/imm32/subx-name +13990 68/push 0/imm32/subx-name +13991 68/push 0/imm32/no-outputs +13992 68/push 0/imm32/no-outputs +13993 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +13994 68/push 0x11/imm32/alloc-id:fake +13995 68/push 0/imm32/name +13996 68/push 0/imm32/name +13997 89/<- %ebx 4/r32/esp +13998 $test-emit-subx-stmt-primitive:initialize-primitive-name: +13999 # primitives->name = "increment" +14000 (copy-array Heap "increment" %ebx) # Primitive-name +14001 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: +14002 # primitives->subx-name = "ff 0/subop/increment" +14003 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +14004 (copy-array Heap "ff 0/subop/increment" %eax) +14005 # convert +14006 c7 0/subop/copy *Curr-block-depth 0/imm32 +14007 (emit-subx-stmt _test-output-buffered-file %esi %ebx) +14008 (flush _test-output-buffered-file) +14009 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +14015 # check output +14016 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") +14017 # . epilogue +14018 89/<- %esp 5/r32/ebp +14019 5d/pop-to-ebp +14020 c3/return +14021 +14022 test-emit-subx-stmt-primitive-register: +14023 # Primitive operation on a variable in a register. +14024 # foo <- increment +14025 # => +14026 # ff 0/subop/increment %eax # sub-optimal, but should suffice +14027 # +14028 # There's a variable on the var stack as follows: +14029 # name: 'foo' +14030 # type: int +14031 # register: 'eax' +14032 # +14033 # There's a primitive with this info: +14034 # name: 'increment' +14035 # out: int/reg +14036 # value: 'ff 0/subop/increment' +14037 # +14038 # . prologue +14039 55/push-ebp +14040 89/<- %ebp 4/r32/esp +14041 # setup +14042 (clear-stream _test-output-stream) +14043 (clear-stream $_test-output-buffered-file->buffer) +14044 $test-emit-subx-stmt-primitive-register:initialize-type: +14045 # var type/ecx: (payload tree type-id) = int +14046 68/push 0/imm32/right:null +14047 68/push 0/imm32/right:null +14048 68/push 0/imm32/left:unused +14049 68/push 1/imm32/value:int +14050 68/push 1/imm32/is-atom?:true +14051 68/push 0x11/imm32/alloc-id:fake:payload +14052 89/<- %ecx 4/r32/esp +14053 $test-emit-subx-stmt-primitive-register:initialize-var: +14054 # var var-foo/ecx: (payload var) +14055 68/push 0/imm32/register +14056 68/push 0/imm32/register +14057 68/push 0/imm32/no-stack-offset +14058 68/push 1/imm32/block-depth +14059 51/push-ecx +14060 68/push 0x11/imm32/alloc-id:fake +14061 68/push 0/imm32/name +14062 68/push 0/imm32/name +14063 68/push 0x11/imm32/alloc-id:fake:payload +14064 89/<- %ecx 4/r32/esp +14065 $test-emit-subx-stmt-primitive-register:initialize-var-name: +14066 # var-foo->name = "foo" +14067 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +14068 (copy-array Heap "foo" %eax) +14069 $test-emit-subx-stmt-primitive-register:initialize-var-register: +14070 # var-foo->register = "eax" +14071 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +14072 (copy-array Heap "eax" %eax) +14073 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: +14074 # var operand/ebx: (payload stmt-var) +14075 68/push 0/imm32/is-deref:false +14076 68/push 0/imm32/next +14077 68/push 0/imm32/next +14078 51/push-ecx/var-foo +14079 68/push 0x11/imm32/alloc-id:fake +14080 68/push 0x11/imm32/alloc-id:fake:payload +14081 89/<- %ebx 4/r32/esp +14082 $test-emit-subx-stmt-primitive-register:initialize-stmt: +14083 # var stmt/esi: (addr statement) +14084 53/push-ebx/outputs +14085 68/push 0x11/imm32/alloc-id:fake +14086 68/push 0/imm32/no-inouts +14087 68/push 0/imm32/no-inouts +14088 68/push 0/imm32/operation +14089 68/push 0/imm32/operation +14090 68/push 1/imm32 +14091 89/<- %esi 4/r32/esp +14092 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: +14093 # stmt->operation = "increment" +14094 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +14095 (copy-array Heap "increment" %eax) +14096 $test-emit-subx-stmt-primitive-register:initialize-formal-var: +14097 # var formal-var/ebx: (payload var) +14098 68/push 0/imm32/register +14099 68/push 0/imm32/register +14100 68/push 0/imm32/no-stack-offset +14101 68/push 1/imm32/block-depth +14102 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +14103 68/push 0x11/imm32/alloc-id:fake +14104 68/push 0/imm32/name +14105 68/push 0/imm32/name +14106 68/push 0x11/imm32/alloc-id:fake:payload +14107 89/<- %ebx 4/r32/esp +14108 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: +14109 # formal-var->name = "dummy" +14110 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +14111 (copy-array Heap "dummy" %eax) +14112 $test-emit-subx-stmt-primitive-register:initialize-formal-register: +14113 # formal-var->register = "*" +14114 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +14115 (copy-array Heap "*" %eax) # Any-register +14116 $test-emit-subx-stmt-primitive-register:initialize-var-list: +14117 # var formal-outputs/ebx: (payload list var) +14118 68/push 0/imm32/next +14119 68/push 0/imm32/next +14120 53/push-ebx/formal-var +14121 68/push 0x11/imm32/alloc-id:fake +14122 68/push 0x11/imm32/alloc-id:fake:payload +14123 89/<- %ebx 4/r32/esp +14124 $test-emit-subx-stmt-primitive-register:initialize-primitive: +14125 # var primitives/ebx: (addr primitive) +14126 68/push 0/imm32/next +14127 68/push 0/imm32/next +14128 68/push 0/imm32/output-is-write-only +14129 68/push 0/imm32/no-disp32 +14130 68/push 0/imm32/no-imm32 +14131 68/push 0/imm32/no-r32 +14132 68/push 3/imm32/rm32-is-first-output +14133 68/push 0/imm32/subx-name +14134 68/push 0/imm32/subx-name +14135 53/push-ebx/outputs +14136 68/push 0x11/imm32/alloc-id:fake +14137 68/push 0/imm32/no-inouts +14138 68/push 0/imm32/no-inouts +14139 68/push 0/imm32/name +14140 68/push 0/imm32/name +14141 89/<- %ebx 4/r32/esp +14142 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: +14143 # primitives->name = "increment" +14144 (copy-array Heap "increment" %ebx) # Primitive-name +14145 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: +14146 # primitives->subx-name = "ff 0/subop/increment" +14147 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +14148 (copy-array Heap "ff 0/subop/increment" %eax) +14149 # convert +14150 c7 0/subop/copy *Curr-block-depth 0/imm32 +14151 (emit-subx-stmt _test-output-buffered-file %esi %ebx) +14152 (flush _test-output-buffered-file) +14153 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +14159 # check output +14160 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") +14161 # . epilogue +14162 89/<- %esp 5/r32/ebp +14163 5d/pop-to-ebp +14164 c3/return +14165 +14166 test-emit-subx-stmt-select-primitive: +14167 # Select the right primitive between overloads. +14168 # foo <- increment +14169 # => +14170 # ff 0/subop/increment %eax # sub-optimal, but should suffice +14171 # +14172 # There's a variable on the var stack as follows: +14173 # name: 'foo' +14174 # type: int +14175 # register: 'eax' +14176 # +14177 # There's two primitives, as follows: +14178 # - name: 'increment' +14179 # out: int/reg +14180 # value: 'ff 0/subop/increment' +14181 # - name: 'increment' +14182 # inout: int/mem +14183 # value: 'ff 0/subop/increment' +14184 # +14185 # . prologue +14186 55/push-ebp +14187 89/<- %ebp 4/r32/esp +14188 # setup +14189 (clear-stream _test-output-stream) +14190 (clear-stream $_test-output-buffered-file->buffer) +14191 $test-emit-subx-stmt-select-primitive:initialize-type: +14192 # var type/ecx: (payload tree type-id) = int +14193 68/push 0/imm32/right:null +14194 68/push 0/imm32/right:null +14195 68/push 0/imm32/left:unused +14196 68/push 1/imm32/value:int +14197 68/push 1/imm32/is-atom?:true +14198 68/push 0x11/imm32/alloc-id:fake:payload +14199 89/<- %ecx 4/r32/esp +14200 $test-emit-subx-stmt-select-primitive:initialize-var: +14201 # var var-foo/ecx: (payload var) +14202 68/push 0/imm32/register +14203 68/push 0/imm32/register +14204 68/push 0/imm32/no-stack-offset +14205 68/push 1/imm32/block-depth +14206 51/push-ecx +14207 68/push 0x11/imm32/alloc-id:fake +14208 68/push 0/imm32/name +14209 68/push 0/imm32/name +14210 68/push 0x11/imm32/alloc-id:fake:payload +14211 89/<- %ecx 4/r32/esp +14212 $test-emit-subx-stmt-select-primitive:initialize-var-name: +14213 # var-foo->name = "foo" +14214 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +14215 (copy-array Heap "foo" %eax) +14216 $test-emit-subx-stmt-select-primitive:initialize-var-register: +14217 # var-foo->register = "eax" +14218 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +14219 (copy-array Heap "eax" %eax) +14220 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: +14221 # var operand/ebx: (payload stmt-var) +14222 68/push 0/imm32/is-deref:false +14223 68/push 0/imm32/next +14224 68/push 0/imm32/next +14225 51/push-ecx/var-foo +14226 68/push 0x11/imm32/alloc-id:fake +14227 68/push 0x11/imm32/alloc-id:fake:payload +14228 89/<- %ebx 4/r32/esp +14229 $test-emit-subx-stmt-select-primitive:initialize-stmt: +14230 # var stmt/esi: (addr statement) +14231 53/push-ebx/outputs +14232 68/push 0x11/imm32/alloc-id:fake +14233 68/push 0/imm32/no-inouts +14234 68/push 0/imm32/no-inouts +14235 68/push 0/imm32/operation +14236 68/push 0/imm32/operation +14237 68/push 1/imm32 +14238 89/<- %esi 4/r32/esp +14239 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: +14240 # stmt->operation = "increment" +14241 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +14242 (copy-array Heap "increment" %eax) +14243 $test-emit-subx-stmt-select-primitive:initialize-formal-var: +14244 # var formal-var/ebx: (payload var) +14245 68/push 0/imm32/register +14246 68/push 0/imm32/register +14247 68/push 0/imm32/no-stack-offset +14248 68/push 1/imm32/block-depth +14249 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +14250 68/push 0x11/imm32/alloc-id:fake +14251 68/push 0/imm32/name +14252 68/push 0/imm32/name +14253 68/push 0x11/imm32/alloc-id:fake:payload +14254 89/<- %ebx 4/r32/esp +14255 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: +14256 # formal-var->name = "dummy" +14257 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +14258 (copy-array Heap "dummy" %eax) +14259 $test-emit-subx-stmt-select-primitive:initialize-formal-register: +14260 # formal-var->register = "*" +14261 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +14262 (copy-array Heap "*" %eax) # Any-register +14263 $test-emit-subx-stmt-select-primitive:initialize-var-list: +14264 # var formal-outputs/ebx: (payload list var) +14265 68/push 0/imm32/next +14266 68/push 0/imm32/next +14267 53/push-ebx/formal-var +14268 68/push 0x11/imm32/alloc-id:fake +14269 68/push 0x11/imm32/alloc-id:fake:payload +14270 89/<- %ebx 4/r32/esp +14271 $test-emit-subx-stmt-select-primitive:initialize-primitive2: +14272 # var primitive2/edi: (payload primitive) +14273 68/push 0/imm32/next +14274 68/push 0/imm32/next +14275 68/push 0/imm32/output-is-write-only +14276 68/push 0/imm32/no-disp32 +14277 68/push 0/imm32/no-imm32 +14278 68/push 0/imm32/no-r32 +14279 68/push 3/imm32/rm32-is-first-output +14280 68/push 0/imm32/subx-name +14281 68/push 0/imm32/subx-name +14282 53/push-ebx/outputs +14283 68/push 0x11/imm32/alloc-id:fake +14284 68/push 0/imm32/no-inouts +14285 68/push 0/imm32/no-inouts +14286 68/push 0/imm32/name +14287 68/push 0/imm32/name +14288 68/push 0x11/imm32/alloc-id:fake:payload +14289 89/<- %edi 4/r32/esp +14290 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: +14291 # primitives->name = "increment" +14292 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +14293 (copy-array Heap "increment" %eax) +14294 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: +14295 # primitives->subx-name = "ff 0/subop/increment" +14296 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +14297 (copy-array Heap "ff 0/subop/increment" %eax) +14298 $test-emit-subx-stmt-select-primitive:initialize-primitive: +14299 # var primitives/ebx: (addr primitive) +14300 57/push-edi +14301 68/push 0x11/imm32/alloc-id:fake +14302 68/push 0/imm32/output-is-write-only +14303 68/push 0/imm32/no-disp32 +14304 68/push 0/imm32/no-imm32 +14305 68/push 0/imm32/no-r32 +14306 68/push 1/imm32/rm32-is-first-inout +14307 68/push 0/imm32/subx-name +14308 68/push 0/imm32/subx-name +14309 68/push 0/imm32/no-outputs +14310 68/push 0/imm32/no-outputs +14311 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration 14312 68/push 0x11/imm32/alloc-id:fake 14313 68/push 0/imm32/name 14314 68/push 0/imm32/name -14315 68/push 0x11/imm32/alloc-id:fake:payload -14316 89/<- %edx 4/r32/esp -14317 $test-add-reg-to-mem:initialize-var2-name: -14318 # var2->name = "var2" -14319 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -14320 (copy-array Heap "var2" %eax) -14321 $test-add-reg-to-mem:initialize-var2-register: -14322 # var2->register = "ecx" -14323 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -14324 (copy-array Heap "ecx" %eax) -14325 $test-add-reg-to-mem:initialize-inouts: -14326 # var inouts/esi: (payload stmt-var) = [var2] -14327 68/push 0/imm32/is-deref:false -14328 68/push 0/imm32/next -14329 68/push 0/imm32/next -14330 52/push-edx/var2 -14331 68/push 0x11/imm32/alloc-id:fake -14332 68/push 0x11/imm32/alloc-id:fake:payload -14333 89/<- %esi 4/r32/esp -14334 # inouts = [var1, var2] -14335 68/push 0/imm32/is-deref:false -14336 56/push-esi/next -14337 68/push 0x11/imm32/alloc-id:fake -14338 51/push-ecx/var1 -14339 68/push 0x11/imm32/alloc-id:fake -14340 68/push 0x11/imm32/alloc-id:fake:payload -14341 89/<- %esi 4/r32/esp -14342 $test-add-reg-to-mem:initialize-stmt: -14343 # var stmt/esi: (addr statement) -14344 68/push 0/imm32/next -14345 68/push 0/imm32/next -14346 68/push 0/imm32/outputs -14347 68/push 0/imm32/outputs -14348 56/push-esi/inouts -14349 68/push 0x11/imm32/alloc-id:fake -14350 68/push 0/imm32/operation -14351 68/push 0/imm32/operation -14352 68/push 1/imm32/tag:stmt1 -14353 89/<- %esi 4/r32/esp -14354 $test-add-reg-to-mem:initialize-stmt-operation: -14355 # stmt->operation = "add-to" -14356 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -14357 (copy-array Heap "add-to" %eax) -14358 # convert -14359 c7 0/subop/copy *Curr-block-depth 0/imm32 -14360 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -14361 (flush _test-output-buffered-file) -14362 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14368 # check output -14369 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") -14370 # . epilogue -14371 89/<- %esp 5/r32/ebp -14372 5d/pop-to-ebp -14373 c3/return -14374 -14375 test-add-mem-to-reg: -14376 # var1/reg <- add var2 -14377 # => -14378 # 03/add *(ebp+__) var1 -14379 # -14380 # . prologue -14381 55/push-ebp -14382 89/<- %ebp 4/r32/esp -14383 # setup -14384 (clear-stream _test-output-stream) -14385 (clear-stream $_test-output-buffered-file->buffer) -14386 $test-add-mem-to-reg:initialize-type: -14387 # var type/ecx: (payload tree type-id) = int -14388 68/push 0/imm32/right:null -14389 68/push 0/imm32/right:null -14390 68/push 0/imm32/left:unused -14391 68/push 1/imm32/value:int -14392 68/push 1/imm32/is-atom?:true -14393 68/push 0x11/imm32/alloc-id:fake:payload -14394 89/<- %ecx 4/r32/esp -14395 $test-add-mem-to-reg:initialize-var: -14396 # var var1/ecx: (payload var) -14397 68/push 0/imm32/register -14398 68/push 0/imm32/register -14399 68/push 0/imm32/no-stack-offset -14400 68/push 1/imm32/block-depth -14401 51/push-ecx -14402 68/push 0x11/imm32/alloc-id:fake -14403 68/push 0/imm32/name -14404 68/push 0/imm32/name -14405 68/push 0x11/imm32/alloc-id:fake:payload -14406 89/<- %ecx 4/r32/esp -14407 $test-add-mem-to-reg:initialize-var-name: -14408 # var1->name = "foo" -14409 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14410 (copy-array Heap "var1" %eax) -14411 $test-add-mem-to-reg:initialize-var-register: -14412 # var1->register = "eax" -14413 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -14414 (copy-array Heap "eax" %eax) -14415 $test-add-mem-to-reg:initialize-var2: -14416 # var var2/edx: (payload var) -14417 68/push 0/imm32/register -14418 68/push 0/imm32/register -14419 68/push 8/imm32/stack-offset -14420 68/push 1/imm32/block-depth -14421 ff 6/subop/push *(ecx+0x10) -14422 68/push 0x11/imm32/alloc-id:fake -14423 68/push 0/imm32/name -14424 68/push 0/imm32/name -14425 68/push 0x11/imm32/alloc-id:fake:payload -14426 89/<- %edx 4/r32/esp -14427 $test-add-mem-to-reg:initialize-var2-name: -14428 # var2->name = "var2" -14429 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -14430 (copy-array Heap "var2" %eax) -14431 $test-add-mem-to-reg:initialize-inouts: -14432 # var inouts/esi: (payload stmt-var) = [var2] -14433 68/push 0/imm32/is-deref:false -14434 68/push 0/imm32/next -14435 68/push 0/imm32/next -14436 52/push-edx/var2 -14437 68/push 0x11/imm32/alloc-id:fake -14438 68/push 0x11/imm32/alloc-id:fake:payload -14439 89/<- %esi 4/r32/esp -14440 $test-add-mem-to-reg:initialize-outputs: -14441 # var outputs/edi: (payload stmt-var) = [var1] -14442 68/push 0/imm32/is-deref:false -14443 68/push 0/imm32/next -14444 68/push 0/imm32/next -14445 51/push-ecx/var1 -14446 68/push 0x11/imm32/alloc-id:fake -14447 68/push 0x11/imm32/alloc-id:fake:payload -14448 89/<- %edi 4/r32/esp -14449 $test-add-mem-to-reg:initialize-stmt: -14450 # var stmt/esi: (addr statement) -14451 68/push 0/imm32/next -14452 68/push 0/imm32/next -14453 57/push-edi/outputs -14454 68/push 0x11/imm32/alloc-id:fake -14455 56/push-esi/inouts -14456 68/push 0x11/imm32/alloc-id:fake -14457 68/push 0/imm32/operation -14458 68/push 0/imm32/operation -14459 68/push 1/imm32/tag:stmt1 -14460 89/<- %esi 4/r32/esp -14461 $test-add-mem-to-reg:initialize-stmt-operation: -14462 # stmt->operation = "add" -14463 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -14464 (copy-array Heap "add" %eax) -14465 # convert -14466 c7 0/subop/copy *Curr-block-depth 0/imm32 -14467 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -14468 (flush _test-output-buffered-file) -14469 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14475 # check output -14476 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") -14477 # . epilogue -14478 89/<- %esp 5/r32/ebp -14479 5d/pop-to-ebp -14480 c3/return -14481 -14482 test-add-literal-to-eax: -14483 # var1/eax <- add 0x34 -14484 # => -14485 # 05/add-to-eax 0x34/imm32 -14486 # -14487 # . prologue -14488 55/push-ebp -14489 89/<- %ebp 4/r32/esp -14490 # setup -14491 (clear-stream _test-output-stream) -14492 (clear-stream $_test-output-buffered-file->buffer) -14493 $test-add-literal-to-eax:initialize-var-type: -14494 # var type/ecx: (payload tree type-id) = int -14495 68/push 0/imm32/right:null -14496 68/push 0/imm32/right:null -14497 68/push 0/imm32/left:unused -14498 68/push 1/imm32/value:int -14499 68/push 1/imm32/is-atom?:true -14500 68/push 0x11/imm32/alloc-id:fake:payload -14501 89/<- %ecx 4/r32/esp -14502 $test-add-literal-to-eax:initialize-var: -14503 # var v/ecx: (payload var) -14504 68/push 0/imm32/register -14505 68/push 0/imm32/register -14506 68/push 0/imm32/no-stack-offset -14507 68/push 1/imm32/block-depth -14508 51/push-ecx -14509 68/push 0x11/imm32/alloc-id:fake -14510 68/push 0/imm32/name -14511 68/push 0/imm32/name -14512 68/push 0x11/imm32/alloc-id:fake:payload -14513 89/<- %ecx 4/r32/esp -14514 $test-add-literal-to-eax:initialize-var-name: -14515 # v->name = "v" -14516 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14517 (copy-array Heap "v" %eax) -14518 $test-add-literal-to-eax:initialize-var-register: -14519 # v->register = "eax" -14520 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -14521 (copy-array Heap "eax" %eax) -14522 $test-add-literal-to-eax:initialize-literal-type: -14523 # var type/edx: (payload tree type-id) = literal -14524 68/push 0/imm32/right:null -14525 68/push 0/imm32/right:null -14526 68/push 0/imm32/left:unused -14527 68/push 0/imm32/value:literal -14528 68/push 1/imm32/is-atom?:true -14529 68/push 0x11/imm32/alloc-id:fake:payload -14530 89/<- %edx 4/r32/esp -14531 $test-add-literal-to-eax:initialize-literal: -14532 # var l/edx: (payload var) -14533 68/push 0/imm32/register -14534 68/push 0/imm32/register -14535 68/push 0/imm32/no-stack-offset -14536 68/push 1/imm32/block-depth -14537 52/push-edx -14538 68/push 0x11/imm32/alloc-id:fake -14539 68/push 0/imm32/name -14540 68/push 0/imm32/name -14541 68/push 0x11/imm32/alloc-id:fake:payload -14542 89/<- %edx 4/r32/esp -14543 $test-add-literal-to-eax:initialize-literal-value: -14544 # l->name = "0x34" -14545 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -14546 (copy-array Heap "0x34" %eax) -14547 $test-add-literal-to-eax:initialize-inouts: -14548 # var inouts/esi: (payload stmt-var) = [l] -14549 68/push 0/imm32/is-deref:false -14550 68/push 0/imm32/next -14551 68/push 0/imm32/next -14552 52/push-edx/l -14553 68/push 0x11/imm32/alloc-id:fake -14554 68/push 0x11/imm32/alloc-id:fake:payload -14555 89/<- %esi 4/r32/esp -14556 $test-add-literal-to-eax:initialize-outputs: -14557 # var outputs/edi: (payload stmt-var) = [v] -14558 68/push 0/imm32/is-deref:false -14559 68/push 0/imm32/next -14560 68/push 0/imm32/next -14561 51/push-ecx/v -14562 68/push 0x11/imm32/alloc-id:fake -14563 68/push 0x11/imm32/alloc-id:fake:payload -14564 89/<- %edi 4/r32/esp -14565 $test-add-literal-to-eax:initialize-stmt: -14566 # var stmt/esi: (addr statement) -14567 68/push 0/imm32/next -14568 68/push 0/imm32/next -14569 57/push-edi/outputs -14570 68/push 0x11/imm32/alloc-id:fake -14571 56/push-esi/inouts -14572 68/push 0x11/imm32/alloc-id:fake -14573 68/push 0/imm32/operation -14574 68/push 0/imm32/operation -14575 68/push 1/imm32/tag:stmt1 -14576 89/<- %esi 4/r32/esp -14577 $test-add-literal-to-eax:initialize-stmt-operation: -14578 # stmt->operation = "add" -14579 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -14580 (copy-array Heap "add" %eax) -14581 # convert -14582 c7 0/subop/copy *Curr-block-depth 0/imm32 -14583 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -14584 (flush _test-output-buffered-file) -14585 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14591 # check output -14592 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") -14593 # . epilogue -14594 89/<- %esp 5/r32/ebp -14595 5d/pop-to-ebp -14596 c3/return -14597 -14598 test-add-literal-to-reg: -14599 # var1/ecx <- add 0x34 -14600 # => -14601 # 81 0/subop/add %ecx 0x34/imm32 -14602 # -14603 # . prologue -14604 55/push-ebp -14605 89/<- %ebp 4/r32/esp -14606 # setup -14607 (clear-stream _test-output-stream) -14608 (clear-stream $_test-output-buffered-file->buffer) -14609 $test-add-literal-to-reg:initialize-var-type: -14610 # var type/ecx: (payload tree type-id) = int -14611 68/push 0/imm32/right:null -14612 68/push 0/imm32/right:null -14613 68/push 0/imm32/left:unused -14614 68/push 1/imm32/value:int -14615 68/push 1/imm32/is-atom?:true -14616 68/push 0x11/imm32/alloc-id:fake:payload -14617 89/<- %ecx 4/r32/esp -14618 $test-add-literal-to-reg:initialize-var: -14619 # var v/ecx: (payload var) -14620 68/push 0/imm32/register -14621 68/push 0/imm32/register -14622 68/push 0/imm32/no-stack-offset -14623 68/push 1/imm32/block-depth -14624 51/push-ecx -14625 68/push 0x11/imm32/alloc-id:fake -14626 68/push 0/imm32/name -14627 68/push 0/imm32/name -14628 68/push 0x11/imm32/alloc-id:fake:payload -14629 89/<- %ecx 4/r32/esp -14630 $test-add-literal-to-reg:initialize-var-name: -14631 # v->name = "v" -14632 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14633 (copy-array Heap "v" %eax) -14634 $test-add-literal-to-reg:initialize-var-register: -14635 # v->register = "ecx" -14636 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -14637 (copy-array Heap "ecx" %eax) -14638 $test-add-literal-to-reg:initialize-literal-type: -14639 # var type/edx: (payload tree type-id) = literal -14640 68/push 0/imm32/right:null -14641 68/push 0/imm32/right:null -14642 68/push 0/imm32/left:unused -14643 68/push 0/imm32/value:literal -14644 68/push 1/imm32/is-atom?:true -14645 68/push 0x11/imm32/alloc-id:fake:payload -14646 89/<- %edx 4/r32/esp -14647 $test-add-literal-to-reg:initialize-literal: -14648 # var l/edx: (payload var) -14649 68/push 0/imm32/register -14650 68/push 0/imm32/register -14651 68/push 0/imm32/no-stack-offset -14652 68/push 1/imm32/block-depth -14653 52/push-edx -14654 68/push 0x11/imm32/alloc-id:fake -14655 68/push 0/imm32/name -14656 68/push 0/imm32/name -14657 68/push 0x11/imm32/alloc-id:fake:payload -14658 89/<- %edx 4/r32/esp -14659 $test-add-literal-to-reg:initialize-literal-value: -14660 # l->name = "0x34" -14661 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -14662 (copy-array Heap "0x34" %eax) -14663 $test-add-literal-to-reg:initialize-inouts: -14664 # var inouts/esi: (payload stmt-var) = [l] -14665 68/push 0/imm32/is-deref:false +14315 89/<- %ebx 4/r32/esp +14316 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: +14317 # primitives->name = "increment" +14318 (copy-array Heap "increment" %ebx) # Primitive-name +14319 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: +14320 # primitives->subx-name = "ff 0/subop/increment" +14321 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +14322 (copy-array Heap "ff 0/subop/increment" %eax) +14323 # convert +14324 c7 0/subop/copy *Curr-block-depth 0/imm32 +14325 (emit-subx-stmt _test-output-buffered-file %esi %ebx) +14326 (flush _test-output-buffered-file) +14327 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +14333 # check output +14334 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") +14335 # . epilogue +14336 89/<- %esp 5/r32/ebp +14337 5d/pop-to-ebp +14338 c3/return +14339 +14340 test-emit-subx-stmt-select-primitive-2: +14341 # Select the right primitive between overloads. +14342 # increment foo +14343 # => +14344 # ff 0/subop/increment %eax # sub-optimal, but should suffice +14345 # +14346 # There's a variable on the var stack as follows: +14347 # name: 'foo' +14348 # type: int +14349 # register: 'eax' +14350 # +14351 # There's two primitives, as follows: +14352 # - name: 'increment' +14353 # out: int/reg +14354 # value: 'ff 0/subop/increment' +14355 # - name: 'increment' +14356 # inout: int/mem +14357 # value: 'ff 0/subop/increment' +14358 # +14359 # . prologue +14360 55/push-ebp +14361 89/<- %ebp 4/r32/esp +14362 # setup +14363 (clear-stream _test-output-stream) +14364 (clear-stream $_test-output-buffered-file->buffer) +14365 $test-emit-subx-stmt-select-primitive-2:initialize-type: +14366 # var type/ecx: (payload tree type-id) = int +14367 68/push 0/imm32/right:null +14368 68/push 0/imm32/right:null +14369 68/push 0/imm32/left:unused +14370 68/push 1/imm32/value:int +14371 68/push 1/imm32/is-atom?:true +14372 68/push 0x11/imm32/alloc-id:fake:payload +14373 89/<- %ecx 4/r32/esp +14374 $test-emit-subx-stmt-select-primitive-2:initialize-var: +14375 # var var-foo/ecx: (payload var) +14376 68/push 0/imm32/register +14377 68/push 0/imm32/register +14378 68/push 0/imm32/no-stack-offset +14379 68/push 1/imm32/block-depth +14380 51/push-ecx +14381 68/push 0x11/imm32/alloc-id:fake +14382 68/push 0/imm32/name +14383 68/push 0/imm32/name +14384 68/push 0x11/imm32/alloc-id:fake:payload +14385 89/<- %ecx 4/r32/esp +14386 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: +14387 # var-foo->name = "foo" +14388 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +14389 (copy-array Heap "foo" %eax) +14390 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: +14391 # var-foo->register = "eax" +14392 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +14393 (copy-array Heap "eax" %eax) +14394 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: +14395 # var operand/ebx: (payload stmt-var) +14396 68/push 0/imm32/is-deref:false +14397 68/push 0/imm32/next +14398 68/push 0/imm32/next +14399 51/push-ecx/var-foo +14400 68/push 0x11/imm32/alloc-id:fake +14401 68/push 0x11/imm32/alloc-id:fake:payload +14402 89/<- %ebx 4/r32/esp +14403 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: +14404 # var stmt/esi: (addr statement) +14405 68/push 0/imm32/no-outputs +14406 68/push 0/imm32/no-outputs +14407 53/push-ebx/inouts +14408 68/push 0x11/imm32/alloc-id:fake +14409 68/push 0/imm32/operation +14410 68/push 0/imm32/operation +14411 68/push 1/imm32 +14412 89/<- %esi 4/r32/esp +14413 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: +14414 # stmt->operation = "increment" +14415 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +14416 (copy-array Heap "increment" %eax) +14417 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: +14418 # var formal-var/ebx: (payload var) +14419 68/push 0/imm32/register +14420 68/push 0/imm32/register +14421 68/push 0/imm32/no-stack-offset +14422 68/push 1/imm32/block-depth +14423 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +14424 68/push 0x11/imm32/alloc-id:fake +14425 68/push 0/imm32/name +14426 68/push 0/imm32/name +14427 68/push 0x11/imm32/alloc-id:fake:payload +14428 89/<- %ebx 4/r32/esp +14429 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: +14430 # formal-var->name = "dummy" +14431 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +14432 (copy-array Heap "dummy" %eax) +14433 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: +14434 # formal-var->register = "*" +14435 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +14436 (copy-array Heap "*" %eax) # Any-register +14437 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: +14438 # var formal-outputs/ebx: (payload list stmt-var) +14439 68/push 0/imm32/next +14440 68/push 0/imm32/next +14441 53/push-ebx/formal-var +14442 68/push 0x11/imm32/alloc-id:fake +14443 68/push 0x11/imm32/alloc-id:fake:payload +14444 89/<- %ebx 4/r32/esp +14445 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: +14446 # var primitive2/edi: (payload primitive) +14447 68/push 0/imm32/next +14448 68/push 0/imm32/next +14449 68/push 0/imm32/output-is-write-only +14450 68/push 0/imm32/no-disp32 +14451 68/push 0/imm32/no-imm32 +14452 68/push 0/imm32/no-r32 +14453 68/push 3/imm32/rm32-is-first-output +14454 68/push 0/imm32/subx-name +14455 68/push 0/imm32/subx-name +14456 53/push-ebx/outputs +14457 68/push 0x11/imm32/alloc-id:fake +14458 68/push 0/imm32/no-inouts +14459 68/push 0/imm32/no-inouts +14460 68/push 0/imm32/name +14461 68/push 0/imm32/name +14462 68/push 0x11/imm32/alloc-id:fake:payload +14463 89/<- %edi 4/r32/esp +14464 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: +14465 # primitives->name = "increment" +14466 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +14467 (copy-array Heap "increment" %eax) +14468 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: +14469 # primitives->subx-name = "ff 0/subop/increment" +14470 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +14471 (copy-array Heap "ff 0/subop/increment" %eax) +14472 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: +14473 # var primitives/ebx: (addr primitive) +14474 57/push-edi +14475 68/push 0x11/imm32/alloc-id:fake +14476 68/push 0/imm32/output-is-write-only +14477 68/push 0/imm32/no-disp32 +14478 68/push 0/imm32/no-imm32 +14479 68/push 0/imm32/no-r32 +14480 68/push 1/imm32/rm32-is-first-inout +14481 68/push 0/imm32/subx-name +14482 68/push 0/imm32/subx-name +14483 68/push 0/imm32/no-outputs +14484 68/push 0/imm32/no-outputs +14485 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +14486 68/push 0x11/imm32/alloc-id:fake +14487 68/push 0/imm32/name +14488 68/push 0/imm32/name +14489 89/<- %ebx 4/r32/esp +14490 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: +14491 # primitives->name = "increment" +14492 (copy-array Heap "increment" %ebx) # Primitive-name +14493 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: +14494 # primitives->subx-name = "ff 0/subop/increment" +14495 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +14496 (copy-array Heap "ff 0/subop/increment" %eax) +14497 # convert +14498 c7 0/subop/copy *Curr-block-depth 0/imm32 +14499 (emit-subx-stmt _test-output-buffered-file %esi %ebx) +14500 (flush _test-output-buffered-file) +14501 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +14507 # check output +14508 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") +14509 # . epilogue +14510 89/<- %esp 5/r32/ebp +14511 5d/pop-to-ebp +14512 c3/return +14513 +14514 test-increment-register: +14515 # Select the right register between overloads. +14516 # foo <- increment +14517 # => +14518 # 50/increment-eax +14519 # +14520 # There's a variable on the var stack as follows: +14521 # name: 'foo' +14522 # type: int +14523 # register: 'eax' +14524 # +14525 # Primitives are the global definitions. +14526 # +14527 # . prologue +14528 55/push-ebp +14529 89/<- %ebp 4/r32/esp +14530 # setup +14531 (clear-stream _test-output-stream) +14532 (clear-stream $_test-output-buffered-file->buffer) +14533 $test-increment-register:initialize-type: +14534 # var type/ecx: (payload tree type-id) = int +14535 68/push 0/imm32/right:null +14536 68/push 0/imm32/right:null +14537 68/push 0/imm32/left:unused +14538 68/push 1/imm32/value:int +14539 68/push 1/imm32/is-atom?:true +14540 68/push 0x11/imm32/alloc-id:fake:payload +14541 89/<- %ecx 4/r32/esp +14542 $test-increment-register:initialize-var: +14543 # var var-foo/ecx: (payload var) +14544 68/push 0/imm32/register +14545 68/push 0/imm32/register +14546 68/push 0/imm32/no-stack-offset +14547 68/push 1/imm32/block-depth +14548 51/push-ecx +14549 68/push 0x11/imm32/alloc-id:fake +14550 68/push 0/imm32/name +14551 68/push 0/imm32/name +14552 68/push 0x11/imm32/alloc-id:fake:payload +14553 89/<- %ecx 4/r32/esp +14554 $test-increment-register:initialize-var-name: +14555 # var-foo->name = "foo" +14556 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +14557 (copy-array Heap "foo" %eax) +14558 $test-increment-register:initialize-var-register: +14559 # var-foo->register = "eax" +14560 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +14561 (copy-array Heap "eax" %eax) +14562 $test-increment-register:initialize-stmt-var: +14563 # var operand/ebx: (payload stmt-var) +14564 68/push 0/imm32/is-deref:false +14565 68/push 0/imm32/next +14566 68/push 0/imm32/next +14567 51/push-ecx/var-foo +14568 68/push 0x11/imm32/alloc-id:fake +14569 68/push 0x11/imm32/alloc-id:fake:payload +14570 89/<- %ebx 4/r32/esp +14571 $test-increment-register:initialize-stmt: +14572 # var stmt/esi: (addr statement) +14573 53/push-ebx/outputs +14574 68/push 0x11/imm32/alloc-id:fake +14575 68/push 0/imm32/no-inouts +14576 68/push 0/imm32/no-inouts +14577 68/push 0/imm32/operation +14578 68/push 0/imm32/operation +14579 68/push 1/imm32 +14580 89/<- %esi 4/r32/esp +14581 $test-increment-register:initialize-stmt-operation: +14582 # stmt->operation = "increment" +14583 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +14584 (copy-array Heap "increment" %eax) +14585 # convert +14586 c7 0/subop/copy *Curr-block-depth 0/imm32 +14587 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +14588 (flush _test-output-buffered-file) +14589 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +14595 # check output +14596 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") +14597 # . epilogue +14598 89/<- %esp 5/r32/ebp +14599 5d/pop-to-ebp +14600 c3/return +14601 +14602 test-add-reg-to-reg: +14603 # var1/reg <- add var2/reg +14604 # => +14605 # 01/add-to %var1 var2 +14606 # +14607 # . prologue +14608 55/push-ebp +14609 89/<- %ebp 4/r32/esp +14610 # setup +14611 (clear-stream _test-output-stream) +14612 (clear-stream $_test-output-buffered-file->buffer) +14613 $test-add-reg-to-reg:initialize-type: +14614 # var type/ecx: (payload tree type-id) = int +14615 68/push 0/imm32/right:null +14616 68/push 0/imm32/right:null +14617 68/push 0/imm32/left:unused +14618 68/push 1/imm32/value:int +14619 68/push 1/imm32/is-atom?:true +14620 68/push 0x11/imm32/alloc-id:fake:payload +14621 89/<- %ecx 4/r32/esp +14622 $test-add-reg-to-reg:initialize-var1: +14623 # var var1/ecx: (payload var) +14624 68/push 0/imm32/register +14625 68/push 0/imm32/register +14626 68/push 0/imm32/no-stack-offset +14627 68/push 1/imm32/block-depth +14628 51/push-ecx +14629 68/push 0x11/imm32/alloc-id:fake +14630 68/push 0/imm32/name +14631 68/push 0/imm32/name +14632 68/push 0x11/imm32/alloc-id:fake:payload +14633 89/<- %ecx 4/r32/esp +14634 $test-add-reg-to-reg:initialize-var1-name: +14635 # var1->name = "var1" +14636 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +14637 (copy-array Heap "var1" %eax) +14638 $test-add-reg-to-reg:initialize-var1-register: +14639 # var1->register = "eax" +14640 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +14641 (copy-array Heap "eax" %eax) +14642 $test-add-reg-to-reg:initialize-var2: +14643 # var var2/edx: (payload var) +14644 68/push 0/imm32/register +14645 68/push 0/imm32/register +14646 68/push 0/imm32/no-stack-offset +14647 68/push 1/imm32/block-depth +14648 ff 6/subop/push *(ecx+0x10) +14649 68/push 0x11/imm32/alloc-id:fake +14650 68/push 0/imm32/name +14651 68/push 0/imm32/name +14652 68/push 0x11/imm32/alloc-id:fake:payload +14653 89/<- %edx 4/r32/esp +14654 $test-add-reg-to-reg:initialize-var2-name: +14655 # var2->name = "var2" +14656 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +14657 (copy-array Heap "var2" %eax) +14658 $test-add-reg-to-reg:initialize-var2-register: +14659 # var2->register = "ecx" +14660 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +14661 (copy-array Heap "ecx" %eax) +14662 $test-add-reg-to-reg:initialize-inouts: +14663 # var inouts/esi: (payload stmt-var) = [var2] +14664 68/push 0/imm32/is-deref:false +14665 68/push 0/imm32/next 14666 68/push 0/imm32/next -14667 68/push 0/imm32/next -14668 52/push-edx/l -14669 68/push 0x11/imm32/alloc-id:fake -14670 68/push 0x11/imm32/alloc-id:fake:payload -14671 89/<- %esi 4/r32/esp -14672 $test-add-literal-to-reg:initialize-outputs: -14673 # var outputs/edi: (payload stmt-var) = [v] -14674 68/push 0/imm32/is-deref:false +14667 52/push-edx/var2 +14668 68/push 0x11/imm32/alloc-id:fake +14669 68/push 0x11/imm32/alloc-id:fake:payload +14670 89/<- %esi 4/r32/esp +14671 $test-add-reg-to-reg:initialize-outputs: +14672 # var outputs/edi: (payload stmt-var) = [var1] +14673 68/push 0/imm32/is-deref:false +14674 68/push 0/imm32/next 14675 68/push 0/imm32/next -14676 68/push 0/imm32/next -14677 51/push-ecx/v -14678 68/push 0x11/imm32/alloc-id:fake -14679 68/push 0x11/imm32/alloc-id:fake:payload -14680 89/<- %edi 4/r32/esp -14681 $test-add-literal-to-reg:initialize-stmt: -14682 # var stmt/esi: (addr statement) +14676 51/push-ecx/var1 +14677 68/push 0x11/imm32/alloc-id:fake +14678 68/push 0x11/imm32/alloc-id:fake:payload +14679 89/<- %edi 4/r32/esp +14680 $test-add-reg-to-reg:initialize-stmt: +14681 # var stmt/esi: (addr statement) +14682 68/push 0/imm32/next 14683 68/push 0/imm32/next -14684 68/push 0/imm32/next -14685 57/push-edi/outputs -14686 68/push 0x11/imm32/alloc-id:fake -14687 56/push-esi/inouts -14688 68/push 0x11/imm32/alloc-id:fake +14684 57/push-edi/outputs +14685 68/push 0x11/imm32/alloc-id:fake +14686 56/push-esi/inouts +14687 68/push 0x11/imm32/alloc-id:fake +14688 68/push 0/imm32/operation 14689 68/push 0/imm32/operation -14690 68/push 0/imm32/operation -14691 68/push 1/imm32/tag:stmt1 -14692 89/<- %esi 4/r32/esp -14693 $test-add-literal-to-reg:initialize-stmt-operation: -14694 # stmt->operation = "add" -14695 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -14696 (copy-array Heap "add" %eax) -14697 # convert -14698 c7 0/subop/copy *Curr-block-depth 0/imm32 -14699 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -14700 (flush _test-output-buffered-file) -14701 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14707 # check output -14708 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") -14709 # . epilogue -14710 89/<- %esp 5/r32/ebp -14711 5d/pop-to-ebp -14712 c3/return -14713 -14714 test-add-literal-to-mem: -14715 # add-to var1, 0x34 -14716 # => -14717 # 81 0/subop/add %eax 0x34/imm32 -14718 # -14719 # . prologue -14720 55/push-ebp -14721 89/<- %ebp 4/r32/esp -14722 # setup -14723 (clear-stream _test-output-stream) -14724 (clear-stream $_test-output-buffered-file->buffer) -14725 $test-add-literal-to-mem:initialize-type: -14726 # var type/ecx: (payload tree type-id) = int +14690 68/push 1/imm32/tag:stmt1 +14691 89/<- %esi 4/r32/esp +14692 $test-add-reg-to-reg:initialize-stmt-operation: +14693 # stmt->operation = "add" +14694 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +14695 (copy-array Heap "add" %eax) +14696 # convert +14697 c7 0/subop/copy *Curr-block-depth 0/imm32 +14698 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +14699 (flush _test-output-buffered-file) +14700 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +14706 # check output +14707 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") +14708 # . epilogue +14709 89/<- %esp 5/r32/ebp +14710 5d/pop-to-ebp +14711 c3/return +14712 +14713 test-add-reg-to-mem: +14714 # add-to var1 var2/reg +14715 # => +14716 # 01/add-to *(ebp+__) var2 +14717 # +14718 # . prologue +14719 55/push-ebp +14720 89/<- %ebp 4/r32/esp +14721 # setup +14722 (clear-stream _test-output-stream) +14723 (clear-stream $_test-output-buffered-file->buffer) +14724 $test-add-reg-to-mem:initialize-type: +14725 # var type/ecx: (payload tree type-id) = int +14726 68/push 0/imm32/right:null 14727 68/push 0/imm32/right:null -14728 68/push 0/imm32/right:null -14729 68/push 0/imm32/left:unused -14730 68/push 1/imm32/value:int -14731 68/push 1/imm32/is-atom?:true -14732 68/push 0x11/imm32/alloc-id:fake:payload -14733 89/<- %ecx 4/r32/esp -14734 $test-add-literal-to-mem:initialize-var1: -14735 # var var1/ecx: (payload var) +14728 68/push 0/imm32/left:unused +14729 68/push 1/imm32/value:int +14730 68/push 1/imm32/is-atom?:true +14731 68/push 0x11/imm32/alloc-id:fake:payload +14732 89/<- %ecx 4/r32/esp +14733 $test-add-reg-to-mem:initialize-var1: +14734 # var var1/ecx: (payload var) +14735 68/push 0/imm32/register 14736 68/push 0/imm32/register -14737 68/push 0/imm32/register -14738 68/push 8/imm32/stack-offset -14739 68/push 1/imm32/block-depth -14740 51/push-ecx -14741 68/push 0x11/imm32/alloc-id:fake +14737 68/push 8/imm32/stack-offset +14738 68/push 1/imm32/block-depth +14739 51/push-ecx +14740 68/push 0x11/imm32/alloc-id:fake +14741 68/push 0/imm32/name 14742 68/push 0/imm32/name -14743 68/push 0/imm32/name -14744 68/push 0x11/imm32/alloc-id:fake:payload -14745 89/<- %ecx 4/r32/esp -14746 $test-add-literal-to-mem:initialize-var1-name: -14747 # var1->name = "var1" -14748 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14749 (copy-array Heap "var1" %eax) -14750 $test-add-literal-to-mem:initialize-literal-type: -14751 # var type/edx: (payload tree type-id) = literal -14752 68/push 0/imm32/right:null -14753 68/push 0/imm32/right:null -14754 68/push 0/imm32/left:unused -14755 68/push 0/imm32/value:literal -14756 68/push 1/imm32/is-atom?:true -14757 68/push 0x11/imm32/alloc-id:fake:payload -14758 89/<- %edx 4/r32/esp -14759 $test-add-literal-to-mem:initialize-literal: -14760 # var l/edx: (payload var) -14761 68/push 0/imm32/register -14762 68/push 0/imm32/register -14763 68/push 0/imm32/no-stack-offset -14764 68/push 1/imm32/block-depth -14765 52/push-edx -14766 68/push 0x11/imm32/alloc-id:fake -14767 68/push 0/imm32/name -14768 68/push 0/imm32/name -14769 68/push 0x11/imm32/alloc-id:fake:payload -14770 89/<- %edx 4/r32/esp -14771 $test-add-literal-to-mem:initialize-literal-value: -14772 # l->name = "0x34" -14773 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -14774 (copy-array Heap "0x34" %eax) -14775 $test-add-literal-to-mem:initialize-inouts: -14776 # var inouts/esi: (payload stmt-var) = [l] -14777 68/push 0/imm32/is-deref:false -14778 68/push 0/imm32/next -14779 68/push 0/imm32/next -14780 52/push-edx/l +14743 68/push 0x11/imm32/alloc-id:fake:payload +14744 89/<- %ecx 4/r32/esp +14745 $test-add-reg-to-mem:initialize-var1-name: +14746 # var1->name = "var1" +14747 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +14748 (copy-array Heap "var1" %eax) +14749 $test-add-reg-to-mem:initialize-var2: +14750 # var var2/edx: (payload var) +14751 68/push 0/imm32/register +14752 68/push 0/imm32/register +14753 68/push 0/imm32/no-stack-offset +14754 68/push 1/imm32/block-depth +14755 ff 6/subop/push *(ecx+0x10) +14756 68/push 0x11/imm32/alloc-id:fake +14757 68/push 0/imm32/name +14758 68/push 0/imm32/name +14759 68/push 0x11/imm32/alloc-id:fake:payload +14760 89/<- %edx 4/r32/esp +14761 $test-add-reg-to-mem:initialize-var2-name: +14762 # var2->name = "var2" +14763 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +14764 (copy-array Heap "var2" %eax) +14765 $test-add-reg-to-mem:initialize-var2-register: +14766 # var2->register = "ecx" +14767 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +14768 (copy-array Heap "ecx" %eax) +14769 $test-add-reg-to-mem:initialize-inouts: +14770 # var inouts/esi: (payload stmt-var) = [var2] +14771 68/push 0/imm32/is-deref:false +14772 68/push 0/imm32/next +14773 68/push 0/imm32/next +14774 52/push-edx/var2 +14775 68/push 0x11/imm32/alloc-id:fake +14776 68/push 0x11/imm32/alloc-id:fake:payload +14777 89/<- %esi 4/r32/esp +14778 # inouts = [var1, var2] +14779 68/push 0/imm32/is-deref:false +14780 56/push-esi/next 14781 68/push 0x11/imm32/alloc-id:fake -14782 68/push 0x11/imm32/alloc-id:fake:payload -14783 89/<- %esi 4/r32/esp -14784 # var inouts = (handle stmt-var) = [var1, var2] -14785 68/push 0/imm32/is-deref:false -14786 56/push-esi/next -14787 68/push 0x11/imm32/alloc-id:fake -14788 51/push-ecx/var1 -14789 68/push 0x11/imm32/alloc-id:fake -14790 68/push 0x11/imm32/alloc-id:fake:payload -14791 89/<- %esi 4/r32/esp -14792 $test-add-literal-to-mem:initialize-stmt: -14793 # var stmt/esi: (addr statement) -14794 68/push 0/imm32/next -14795 68/push 0/imm32/next -14796 68/push 0/imm32/outputs -14797 68/push 0/imm32/outputs -14798 56/push-esi/inouts -14799 68/push 0x11/imm32/alloc-id:fake -14800 68/push 0/imm32/operation -14801 68/push 0/imm32/operation -14802 68/push 1/imm32/tag:stmt1 -14803 89/<- %esi 4/r32/esp -14804 $test-add-literal-to-mem:initialize-stmt-operation: -14805 # stmt->operation = "add-to" -14806 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -14807 (copy-array Heap "add-to" %eax) -14808 # convert -14809 c7 0/subop/copy *Curr-block-depth 0/imm32 -14810 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -14811 (flush _test-output-buffered-file) -14812 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14818 # check output -14819 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") -14820 # . epilogue -14821 89/<- %esp 5/r32/ebp -14822 5d/pop-to-ebp -14823 c3/return -14824 -14825 test-compare-mem-with-reg: -14826 # compare var1, var2/eax -14827 # => -14828 # 39/compare *(ebp+___) 0/r32/eax -14829 # -14830 # . prologue -14831 55/push-ebp -14832 89/<- %ebp 4/r32/esp -14833 # setup -14834 (clear-stream _test-output-stream) -14835 (clear-stream $_test-output-buffered-file->buffer) -14836 $test-compare-mem-with-reg:initialize-type: -14837 # var type/ecx: (payload tree type-id) = int -14838 68/push 0/imm32/right:null -14839 68/push 0/imm32/right:null -14840 68/push 0/imm32/left:unused -14841 68/push 1/imm32/value:int -14842 68/push 1/imm32/is-atom?:true -14843 68/push 0x11/imm32/alloc-id:fake:payload -14844 89/<- %ecx 4/r32/esp -14845 $test-compare-mem-with-reg:initialize-var1: -14846 # var var1/ecx: (payload var) -14847 68/push 0/imm32/register -14848 68/push 0/imm32/register -14849 68/push 8/imm32/stack-offset -14850 68/push 1/imm32/block-depth -14851 51/push-ecx -14852 68/push 0x11/imm32/alloc-id:fake -14853 68/push 0/imm32/name -14854 68/push 0/imm32/name -14855 68/push 0x11/imm32/alloc-id:fake:payload -14856 89/<- %ecx 4/r32/esp -14857 $test-compare-mem-with-reg:initialize-var1-name: -14858 # var1->name = "var1" -14859 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14860 (copy-array Heap "var1" %eax) -14861 $test-compare-mem-with-reg:initialize-var2: -14862 # var var2/edx: (payload var) -14863 68/push 0/imm32/register -14864 68/push 0/imm32/register -14865 68/push 0/imm32/no-stack-offset -14866 68/push 1/imm32/block-depth -14867 ff 6/subop/push *(ecx+0x10) -14868 68/push 0x11/imm32/alloc-id:fake -14869 68/push 0/imm32/name -14870 68/push 0/imm32/name -14871 68/push 0x11/imm32/alloc-id:fake:payload -14872 89/<- %edx 4/r32/esp -14873 $test-compare-mem-with-reg:initialize-var2-name: -14874 # var2->name = "var2" -14875 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -14876 (copy-array Heap "var2" %eax) -14877 $test-compare-mem-with-reg:initialize-var2-register: -14878 # var2->register = "eax" -14879 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -14880 (copy-array Heap "eax" %eax) -14881 $test-compare-mem-with-reg:initialize-inouts: -14882 # var inouts/esi: (payload stmt-var) = [var2] -14883 68/push 0/imm32/is-deref:false -14884 68/push 0/imm32/next -14885 68/push 0/imm32/next -14886 52/push-edx/var2 -14887 68/push 0x11/imm32/alloc-id:fake -14888 68/push 0x11/imm32/alloc-id:fake:payload -14889 89/<- %esi 4/r32/esp -14890 # inouts = [var1, var2] -14891 68/push 0/imm32/is-deref:false -14892 56/push-esi/next -14893 68/push 0x11/imm32/alloc-id:fake -14894 51/push-ecx/var1 -14895 68/push 0x11/imm32/alloc-id:fake -14896 68/push 0x11/imm32/alloc-id:fake:payload -14897 89/<- %esi 4/r32/esp -14898 $test-compare-mem-with-reg:initialize-stmt: -14899 # var stmt/esi: (addr statement) -14900 68/push 0/imm32/next -14901 68/push 0/imm32/next -14902 68/push 0/imm32/outputs -14903 68/push 0/imm32/outputs -14904 56/push-esi/inouts -14905 68/push 0x11/imm32/alloc-id:fake -14906 68/push 0/imm32/operation -14907 68/push 0/imm32/operation -14908 68/push 1/imm32/tag:stmt1 -14909 89/<- %esi 4/r32/esp -14910 $test-compare-mem-with-reg:initialize-stmt-operation: -14911 # stmt->operation = "compare" -14912 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -14913 (copy-array Heap "compare" %eax) -14914 # convert -14915 c7 0/subop/copy *Curr-block-depth 0/imm32 -14916 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -14917 (flush _test-output-buffered-file) -14918 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -14924 # check output -14925 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") -14926 # . epilogue -14927 89/<- %esp 5/r32/ebp -14928 5d/pop-to-ebp -14929 c3/return -14930 -14931 test-compare-reg-with-mem: -14932 # compare var1/eax, var2 -14933 # => -14934 # 3b/compare<- *(ebp+___) 0/r32/eax -14935 # -14936 # . prologue -14937 55/push-ebp -14938 89/<- %ebp 4/r32/esp -14939 # setup -14940 (clear-stream _test-output-stream) -14941 (clear-stream $_test-output-buffered-file->buffer) -14942 $test-compare-reg-with-mem:initialize-type: -14943 # var type/ecx: (payload tree type-id) = int -14944 68/push 0/imm32/right:null -14945 68/push 0/imm32/right:null -14946 68/push 0/imm32/left:unused -14947 68/push 1/imm32/value:int -14948 68/push 1/imm32/is-atom?:true -14949 68/push 0x11/imm32/alloc-id:fake:payload -14950 89/<- %ecx 4/r32/esp -14951 $test-compare-reg-with-mem:initialize-var1: -14952 # var var1/ecx: (payload var) -14953 68/push 0/imm32/register -14954 68/push 0/imm32/register -14955 68/push 0/imm32/no-stack-offset -14956 68/push 1/imm32/block-depth -14957 51/push-ecx -14958 68/push 0x11/imm32/alloc-id:fake -14959 68/push 0/imm32/name -14960 68/push 0/imm32/name -14961 68/push 0x11/imm32/alloc-id:fake:payload -14962 89/<- %ecx 4/r32/esp -14963 $test-compare-reg-with-mem:initialize-var1-name: -14964 # var1->name = "var1" -14965 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -14966 (copy-array Heap "var1" %eax) -14967 $test-compare-reg-with-mem:initialize-var1-register: -14968 # var1->register = "eax" -14969 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -14970 (copy-array Heap "eax" %eax) -14971 $test-compare-reg-with-mem:initialize-var2: -14972 # var var2/edx: (payload var) -14973 68/push 0/imm32/register -14974 68/push 0/imm32/register -14975 68/push 8/imm32/stack-offset -14976 68/push 1/imm32/block-depth -14977 ff 6/subop/push *(ecx+0x10) -14978 68/push 0x11/imm32/alloc-id:fake -14979 68/push 0/imm32/name -14980 68/push 0/imm32/name -14981 68/push 0x11/imm32/alloc-id:fake:payload -14982 89/<- %edx 4/r32/esp -14983 $test-compare-reg-with-mem:initialize-var2-name: -14984 # var2->name = "var2" -14985 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -14986 (copy-array Heap "var2" %eax) -14987 $test-compare-reg-with-mem:initialize-inouts: -14988 # var inouts/esi: (payload stmt-var) = [var2] -14989 68/push 0/imm32/is-deref:false -14990 68/push 0/imm32/next -14991 68/push 0/imm32/next -14992 52/push-edx/var2 -14993 68/push 0x11/imm32/alloc-id:fake -14994 68/push 0x11/imm32/alloc-id:fake:payload -14995 89/<- %esi 4/r32/esp -14996 # inouts = [var1, var2] -14997 68/push 0/imm32/is-deref:false -14998 56/push-esi/next -14999 68/push 0x11/imm32/alloc-id:fake -15000 51/push-ecx/var1 -15001 68/push 0x11/imm32/alloc-id:fake -15002 68/push 0x11/imm32/alloc-id:fake:payload -15003 89/<- %esi 4/r32/esp -15004 $test-compare-reg-with-mem:initialize-stmt: -15005 # var stmt/esi: (addr statement) -15006 68/push 0/imm32/next -15007 68/push 0/imm32/next -15008 68/push 0/imm32/outputs -15009 68/push 0/imm32/outputs -15010 56/push-esi/inouts -15011 68/push 0x11/imm32/alloc-id:fake -15012 68/push 0/imm32/operation -15013 68/push 0/imm32/operation -15014 68/push 1/imm32/tag:stmt1 -15015 89/<- %esi 4/r32/esp -15016 $test-compare-reg-with-mem:initialize-stmt-operation: -15017 # stmt->operation = "compare" -15018 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -15019 (copy-array Heap "compare" %eax) -15020 # convert -15021 c7 0/subop/copy *Curr-block-depth 0/imm32 -15022 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -15023 (flush _test-output-buffered-file) -15024 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -15030 # check output -15031 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") -15032 # . epilogue -15033 89/<- %esp 5/r32/ebp -15034 5d/pop-to-ebp -15035 c3/return -15036 -15037 test-compare-mem-with-literal: -15038 # compare var1, 0x34 -15039 # => -15040 # 81 7/subop/compare *(ebp+___) 0x34/imm32 -15041 # -15042 # . prologue -15043 55/push-ebp -15044 89/<- %ebp 4/r32/esp -15045 # setup -15046 (clear-stream _test-output-stream) -15047 (clear-stream $_test-output-buffered-file->buffer) -15048 $test-compare-mem-with-literal:initialize-type: -15049 # var type/ecx: (payload tree type-id) = int -15050 68/push 0/imm32/right:null -15051 68/push 0/imm32/right:null -15052 68/push 0/imm32/left:unused -15053 68/push 1/imm32/value:int -15054 68/push 1/imm32/is-atom?:true -15055 68/push 0x11/imm32/alloc-id:fake:payload -15056 89/<- %ecx 4/r32/esp -15057 $test-compare-mem-with-literal:initialize-var1: -15058 # var var1/ecx: (payload var) -15059 68/push 0/imm32/register -15060 68/push 0/imm32/register -15061 68/push 8/imm32/stack-offset -15062 68/push 1/imm32/block-depth -15063 51/push-ecx -15064 68/push 0x11/imm32/alloc-id:fake -15065 68/push 0/imm32/name -15066 68/push 0/imm32/name -15067 68/push 0x11/imm32/alloc-id:fake:payload -15068 89/<- %ecx 4/r32/esp -15069 $test-compare-mem-with-literal:initialize-var1-name: -15070 # var1->name = "var1" -15071 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -15072 (copy-array Heap "var1" %eax) -15073 $test-compare-mem-with-literal:initialize-literal-type: -15074 # var type/edx: (payload tree type-id) = literal -15075 68/push 0/imm32/right:null -15076 68/push 0/imm32/right:null -15077 68/push 0/imm32/left:unused -15078 68/push 0/imm32/value:literal -15079 68/push 1/imm32/is-atom?:true -15080 68/push 0x11/imm32/alloc-id:fake:payload -15081 89/<- %edx 4/r32/esp -15082 $test-compare-mem-with-literal:initialize-literal: -15083 # var l/edx: (payload var) -15084 68/push 0/imm32/register -15085 68/push 0/imm32/register -15086 68/push 0/imm32/no-stack-offset -15087 68/push 1/imm32/block-depth -15088 52/push-edx -15089 68/push 0x11/imm32/alloc-id:fake -15090 68/push 0/imm32/name -15091 68/push 0/imm32/name -15092 68/push 0x11/imm32/alloc-id:fake:payload -15093 89/<- %edx 4/r32/esp -15094 $test-compare-mem-with-literal:initialize-literal-value: -15095 # l->name = "0x34" -15096 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -15097 (copy-array Heap "0x34" %eax) -15098 $test-compare-mem-with-literal:initialize-inouts: -15099 # var inouts/esi: (payload stmt-var) = [l] -15100 68/push 0/imm32/is-deref:false -15101 68/push 0/imm32/next -15102 68/push 0/imm32/next -15103 52/push-edx/l -15104 68/push 0x11/imm32/alloc-id:fake -15105 68/push 0x11/imm32/alloc-id:fake:payload -15106 89/<- %esi 4/r32/esp -15107 # var inouts = (handle stmt-var) = [var1, var2] -15108 68/push 0/imm32/is-deref:false -15109 56/push-esi/next -15110 68/push 0x11/imm32/alloc-id:fake -15111 51/push-ecx/var1 -15112 68/push 0x11/imm32/alloc-id:fake -15113 68/push 0x11/imm32/alloc-id:fake:payload -15114 89/<- %esi 4/r32/esp -15115 $test-compare-mem-with-literal:initialize-stmt: -15116 # var stmt/esi: (addr statement) -15117 68/push 0/imm32/next -15118 68/push 0/imm32/next -15119 68/push 0/imm32/outputs -15120 68/push 0/imm32/outputs -15121 56/push-esi/inouts +14782 51/push-ecx/var1 +14783 68/push 0x11/imm32/alloc-id:fake +14784 68/push 0x11/imm32/alloc-id:fake:payload +14785 89/<- %esi 4/r32/esp +14786 $test-add-reg-to-mem:initialize-stmt: +14787 # var stmt/esi: (addr statement) +14788 68/push 0/imm32/next +14789 68/push 0/imm32/next +14790 68/push 0/imm32/outputs +14791 68/push 0/imm32/outputs +14792 56/push-esi/inouts +14793 68/push 0x11/imm32/alloc-id:fake +14794 68/push 0/imm32/operation +14795 68/push 0/imm32/operation +14796 68/push 1/imm32/tag:stmt1 +14797 89/<- %esi 4/r32/esp +14798 $test-add-reg-to-mem:initialize-stmt-operation: +14799 # stmt->operation = "add-to" +14800 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +14801 (copy-array Heap "add-to" %eax) +14802 # convert +14803 c7 0/subop/copy *Curr-block-depth 0/imm32 +14804 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +14805 (flush _test-output-buffered-file) +14806 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +14812 # check output +14813 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") +14814 # . epilogue +14815 89/<- %esp 5/r32/ebp +14816 5d/pop-to-ebp +14817 c3/return +14818 +14819 test-add-mem-to-reg: +14820 # var1/reg <- add var2 +14821 # => +14822 # 03/add *(ebp+__) var1 +14823 # +14824 # . prologue +14825 55/push-ebp +14826 89/<- %ebp 4/r32/esp +14827 # setup +14828 (clear-stream _test-output-stream) +14829 (clear-stream $_test-output-buffered-file->buffer) +14830 $test-add-mem-to-reg:initialize-type: +14831 # var type/ecx: (payload tree type-id) = int +14832 68/push 0/imm32/right:null +14833 68/push 0/imm32/right:null +14834 68/push 0/imm32/left:unused +14835 68/push 1/imm32/value:int +14836 68/push 1/imm32/is-atom?:true +14837 68/push 0x11/imm32/alloc-id:fake:payload +14838 89/<- %ecx 4/r32/esp +14839 $test-add-mem-to-reg:initialize-var: +14840 # var var1/ecx: (payload var) +14841 68/push 0/imm32/register +14842 68/push 0/imm32/register +14843 68/push 0/imm32/no-stack-offset +14844 68/push 1/imm32/block-depth +14845 51/push-ecx +14846 68/push 0x11/imm32/alloc-id:fake +14847 68/push 0/imm32/name +14848 68/push 0/imm32/name +14849 68/push 0x11/imm32/alloc-id:fake:payload +14850 89/<- %ecx 4/r32/esp +14851 $test-add-mem-to-reg:initialize-var-name: +14852 # var1->name = "foo" +14853 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +14854 (copy-array Heap "var1" %eax) +14855 $test-add-mem-to-reg:initialize-var-register: +14856 # var1->register = "eax" +14857 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +14858 (copy-array Heap "eax" %eax) +14859 $test-add-mem-to-reg:initialize-var2: +14860 # var var2/edx: (payload var) +14861 68/push 0/imm32/register +14862 68/push 0/imm32/register +14863 68/push 8/imm32/stack-offset +14864 68/push 1/imm32/block-depth +14865 ff 6/subop/push *(ecx+0x10) +14866 68/push 0x11/imm32/alloc-id:fake +14867 68/push 0/imm32/name +14868 68/push 0/imm32/name +14869 68/push 0x11/imm32/alloc-id:fake:payload +14870 89/<- %edx 4/r32/esp +14871 $test-add-mem-to-reg:initialize-var2-name: +14872 # var2->name = "var2" +14873 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +14874 (copy-array Heap "var2" %eax) +14875 $test-add-mem-to-reg:initialize-inouts: +14876 # var inouts/esi: (payload stmt-var) = [var2] +14877 68/push 0/imm32/is-deref:false +14878 68/push 0/imm32/next +14879 68/push 0/imm32/next +14880 52/push-edx/var2 +14881 68/push 0x11/imm32/alloc-id:fake +14882 68/push 0x11/imm32/alloc-id:fake:payload +14883 89/<- %esi 4/r32/esp +14884 $test-add-mem-to-reg:initialize-outputs: +14885 # var outputs/edi: (payload stmt-var) = [var1] +14886 68/push 0/imm32/is-deref:false +14887 68/push 0/imm32/next +14888 68/push 0/imm32/next +14889 51/push-ecx/var1 +14890 68/push 0x11/imm32/alloc-id:fake +14891 68/push 0x11/imm32/alloc-id:fake:payload +14892 89/<- %edi 4/r32/esp +14893 $test-add-mem-to-reg:initialize-stmt: +14894 # var stmt/esi: (addr statement) +14895 68/push 0/imm32/next +14896 68/push 0/imm32/next +14897 57/push-edi/outputs +14898 68/push 0x11/imm32/alloc-id:fake +14899 56/push-esi/inouts +14900 68/push 0x11/imm32/alloc-id:fake +14901 68/push 0/imm32/operation +14902 68/push 0/imm32/operation +14903 68/push 1/imm32/tag:stmt1 +14904 89/<- %esi 4/r32/esp +14905 $test-add-mem-to-reg:initialize-stmt-operation: +14906 # stmt->operation = "add" +14907 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +14908 (copy-array Heap "add" %eax) +14909 # convert +14910 c7 0/subop/copy *Curr-block-depth 0/imm32 +14911 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +14912 (flush _test-output-buffered-file) +14913 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +14919 # check output +14920 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") +14921 # . epilogue +14922 89/<- %esp 5/r32/ebp +14923 5d/pop-to-ebp +14924 c3/return +14925 +14926 test-add-literal-to-eax: +14927 # var1/eax <- add 0x34 +14928 # => +14929 # 05/add-to-eax 0x34/imm32 +14930 # +14931 # . prologue +14932 55/push-ebp +14933 89/<- %ebp 4/r32/esp +14934 # setup +14935 (clear-stream _test-output-stream) +14936 (clear-stream $_test-output-buffered-file->buffer) +14937 $test-add-literal-to-eax:initialize-var-type: +14938 # var type/ecx: (payload tree type-id) = int +14939 68/push 0/imm32/right:null +14940 68/push 0/imm32/right:null +14941 68/push 0/imm32/left:unused +14942 68/push 1/imm32/value:int +14943 68/push 1/imm32/is-atom?:true +14944 68/push 0x11/imm32/alloc-id:fake:payload +14945 89/<- %ecx 4/r32/esp +14946 $test-add-literal-to-eax:initialize-var: +14947 # var v/ecx: (payload var) +14948 68/push 0/imm32/register +14949 68/push 0/imm32/register +14950 68/push 0/imm32/no-stack-offset +14951 68/push 1/imm32/block-depth +14952 51/push-ecx +14953 68/push 0x11/imm32/alloc-id:fake +14954 68/push 0/imm32/name +14955 68/push 0/imm32/name +14956 68/push 0x11/imm32/alloc-id:fake:payload +14957 89/<- %ecx 4/r32/esp +14958 $test-add-literal-to-eax:initialize-var-name: +14959 # v->name = "v" +14960 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +14961 (copy-array Heap "v" %eax) +14962 $test-add-literal-to-eax:initialize-var-register: +14963 # v->register = "eax" +14964 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +14965 (copy-array Heap "eax" %eax) +14966 $test-add-literal-to-eax:initialize-literal-type: +14967 # var type/edx: (payload tree type-id) = literal +14968 68/push 0/imm32/right:null +14969 68/push 0/imm32/right:null +14970 68/push 0/imm32/left:unused +14971 68/push 0/imm32/value:literal +14972 68/push 1/imm32/is-atom?:true +14973 68/push 0x11/imm32/alloc-id:fake:payload +14974 89/<- %edx 4/r32/esp +14975 $test-add-literal-to-eax:initialize-literal: +14976 # var l/edx: (payload var) +14977 68/push 0/imm32/register +14978 68/push 0/imm32/register +14979 68/push 0/imm32/no-stack-offset +14980 68/push 1/imm32/block-depth +14981 52/push-edx +14982 68/push 0x11/imm32/alloc-id:fake +14983 68/push 0/imm32/name +14984 68/push 0/imm32/name +14985 68/push 0x11/imm32/alloc-id:fake:payload +14986 89/<- %edx 4/r32/esp +14987 $test-add-literal-to-eax:initialize-literal-value: +14988 # l->name = "0x34" +14989 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +14990 (copy-array Heap "0x34" %eax) +14991 $test-add-literal-to-eax:initialize-inouts: +14992 # var inouts/esi: (payload stmt-var) = [l] +14993 68/push 0/imm32/is-deref:false +14994 68/push 0/imm32/next +14995 68/push 0/imm32/next +14996 52/push-edx/l +14997 68/push 0x11/imm32/alloc-id:fake +14998 68/push 0x11/imm32/alloc-id:fake:payload +14999 89/<- %esi 4/r32/esp +15000 $test-add-literal-to-eax:initialize-outputs: +15001 # var outputs/edi: (payload stmt-var) = [v] +15002 68/push 0/imm32/is-deref:false +15003 68/push 0/imm32/next +15004 68/push 0/imm32/next +15005 51/push-ecx/v +15006 68/push 0x11/imm32/alloc-id:fake +15007 68/push 0x11/imm32/alloc-id:fake:payload +15008 89/<- %edi 4/r32/esp +15009 $test-add-literal-to-eax:initialize-stmt: +15010 # var stmt/esi: (addr statement) +15011 68/push 0/imm32/next +15012 68/push 0/imm32/next +15013 57/push-edi/outputs +15014 68/push 0x11/imm32/alloc-id:fake +15015 56/push-esi/inouts +15016 68/push 0x11/imm32/alloc-id:fake +15017 68/push 0/imm32/operation +15018 68/push 0/imm32/operation +15019 68/push 1/imm32/tag:stmt1 +15020 89/<- %esi 4/r32/esp +15021 $test-add-literal-to-eax:initialize-stmt-operation: +15022 # stmt->operation = "add" +15023 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15024 (copy-array Heap "add" %eax) +15025 # convert +15026 c7 0/subop/copy *Curr-block-depth 0/imm32 +15027 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +15028 (flush _test-output-buffered-file) +15029 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15035 # check output +15036 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") +15037 # . epilogue +15038 89/<- %esp 5/r32/ebp +15039 5d/pop-to-ebp +15040 c3/return +15041 +15042 test-add-literal-to-reg: +15043 # var1/ecx <- add 0x34 +15044 # => +15045 # 81 0/subop/add %ecx 0x34/imm32 +15046 # +15047 # . prologue +15048 55/push-ebp +15049 89/<- %ebp 4/r32/esp +15050 # setup +15051 (clear-stream _test-output-stream) +15052 (clear-stream $_test-output-buffered-file->buffer) +15053 $test-add-literal-to-reg:initialize-var-type: +15054 # var type/ecx: (payload tree type-id) = int +15055 68/push 0/imm32/right:null +15056 68/push 0/imm32/right:null +15057 68/push 0/imm32/left:unused +15058 68/push 1/imm32/value:int +15059 68/push 1/imm32/is-atom?:true +15060 68/push 0x11/imm32/alloc-id:fake:payload +15061 89/<- %ecx 4/r32/esp +15062 $test-add-literal-to-reg:initialize-var: +15063 # var v/ecx: (payload var) +15064 68/push 0/imm32/register +15065 68/push 0/imm32/register +15066 68/push 0/imm32/no-stack-offset +15067 68/push 1/imm32/block-depth +15068 51/push-ecx +15069 68/push 0x11/imm32/alloc-id:fake +15070 68/push 0/imm32/name +15071 68/push 0/imm32/name +15072 68/push 0x11/imm32/alloc-id:fake:payload +15073 89/<- %ecx 4/r32/esp +15074 $test-add-literal-to-reg:initialize-var-name: +15075 # v->name = "v" +15076 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15077 (copy-array Heap "v" %eax) +15078 $test-add-literal-to-reg:initialize-var-register: +15079 # v->register = "ecx" +15080 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +15081 (copy-array Heap "ecx" %eax) +15082 $test-add-literal-to-reg:initialize-literal-type: +15083 # var type/edx: (payload tree type-id) = literal +15084 68/push 0/imm32/right:null +15085 68/push 0/imm32/right:null +15086 68/push 0/imm32/left:unused +15087 68/push 0/imm32/value:literal +15088 68/push 1/imm32/is-atom?:true +15089 68/push 0x11/imm32/alloc-id:fake:payload +15090 89/<- %edx 4/r32/esp +15091 $test-add-literal-to-reg:initialize-literal: +15092 # var l/edx: (payload var) +15093 68/push 0/imm32/register +15094 68/push 0/imm32/register +15095 68/push 0/imm32/no-stack-offset +15096 68/push 1/imm32/block-depth +15097 52/push-edx +15098 68/push 0x11/imm32/alloc-id:fake +15099 68/push 0/imm32/name +15100 68/push 0/imm32/name +15101 68/push 0x11/imm32/alloc-id:fake:payload +15102 89/<- %edx 4/r32/esp +15103 $test-add-literal-to-reg:initialize-literal-value: +15104 # l->name = "0x34" +15105 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +15106 (copy-array Heap "0x34" %eax) +15107 $test-add-literal-to-reg:initialize-inouts: +15108 # var inouts/esi: (payload stmt-var) = [l] +15109 68/push 0/imm32/is-deref:false +15110 68/push 0/imm32/next +15111 68/push 0/imm32/next +15112 52/push-edx/l +15113 68/push 0x11/imm32/alloc-id:fake +15114 68/push 0x11/imm32/alloc-id:fake:payload +15115 89/<- %esi 4/r32/esp +15116 $test-add-literal-to-reg:initialize-outputs: +15117 # var outputs/edi: (payload stmt-var) = [v] +15118 68/push 0/imm32/is-deref:false +15119 68/push 0/imm32/next +15120 68/push 0/imm32/next +15121 51/push-ecx/v 15122 68/push 0x11/imm32/alloc-id:fake -15123 68/push 0/imm32/operation -15124 68/push 0/imm32/operation -15125 68/push 1/imm32/tag:stmt1 -15126 89/<- %esi 4/r32/esp -15127 $test-compare-mem-with-literal:initialize-stmt-operation: -15128 # stmt->operation = "compare" -15129 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -15130 (copy-array Heap "compare" %eax) -15131 # convert -15132 c7 0/subop/copy *Curr-block-depth 0/imm32 -15133 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -15134 (flush _test-output-buffered-file) -15135 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -15141 # check output -15142 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") -15143 # . epilogue -15144 89/<- %esp 5/r32/ebp -15145 5d/pop-to-ebp -15146 c3/return -15147 -15148 test-compare-eax-with-literal: -15149 # compare var1/eax 0x34 -15150 # => -15151 # 3d/compare-eax-with 0x34/imm32 -15152 # -15153 # . prologue -15154 55/push-ebp -15155 89/<- %ebp 4/r32/esp -15156 # setup -15157 (clear-stream _test-output-stream) -15158 (clear-stream $_test-output-buffered-file->buffer) -15159 $test-compare-eax-with-literal:initialize-type: -15160 # var type/ecx: (payload tree type-id) = int -15161 68/push 0/imm32/right:null -15162 68/push 0/imm32/right:null -15163 68/push 0/imm32/left:unused -15164 68/push 1/imm32/value:int -15165 68/push 1/imm32/is-atom?:true -15166 68/push 0x11/imm32/alloc-id:fake:payload -15167 89/<- %ecx 4/r32/esp -15168 $test-compare-eax-with-literal:initialize-var1: -15169 # var var1/ecx: (payload var) -15170 68/push 0/imm32/register -15171 68/push 0/imm32/register -15172 68/push 0/imm32/no-stack-offset -15173 68/push 1/imm32/block-depth -15174 51/push-ecx -15175 68/push 0x11/imm32/alloc-id:fake -15176 68/push 0/imm32/name -15177 68/push 0/imm32/name -15178 68/push 0x11/imm32/alloc-id:fake:payload -15179 89/<- %ecx 4/r32/esp -15180 $test-compare-eax-with-literal:initialize-var1-name: -15181 # var1->name = "var1" -15182 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -15183 (copy-array Heap "var1" %eax) -15184 $test-compare-eax-with-literal:initialize-var1-register: -15185 # v->register = "eax" -15186 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -15187 (copy-array Heap "eax" %eax) -15188 $test-compare-eax-with-literal:initialize-literal-type: -15189 # var type/edx: (payload tree type-id) = literal -15190 68/push 0/imm32/right:null -15191 68/push 0/imm32/right:null -15192 68/push 0/imm32/left:unused -15193 68/push 0/imm32/value:literal -15194 68/push 1/imm32/is-atom?:true -15195 68/push 0x11/imm32/alloc-id:fake:payload -15196 89/<- %edx 4/r32/esp -15197 $test-compare-eax-with-literal:initialize-literal: -15198 # var l/edx: (payload var) -15199 68/push 0/imm32/register -15200 68/push 0/imm32/register -15201 68/push 0/imm32/no-stack-offset -15202 68/push 1/imm32/block-depth -15203 52/push-edx -15204 68/push 0x11/imm32/alloc-id:fake -15205 68/push 0/imm32/name -15206 68/push 0/imm32/name -15207 68/push 0x11/imm32/alloc-id:fake:payload -15208 89/<- %edx 4/r32/esp -15209 $test-compare-eax-with-literal:initialize-literal-value: -15210 # l->name = "0x34" -15211 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -15212 (copy-array Heap "0x34" %eax) -15213 $test-compare-eax-with-literal:initialize-inouts: -15214 # var inouts/esi: (payload stmt-var) = [l] -15215 68/push 0/imm32/is-deref:false -15216 68/push 0/imm32/next -15217 68/push 0/imm32/next -15218 52/push-edx/l -15219 68/push 0x11/imm32/alloc-id:fake -15220 68/push 0x11/imm32/alloc-id:fake:payload -15221 89/<- %esi 4/r32/esp -15222 # var inouts = (handle stmt-var) = [var1, var2] -15223 68/push 0/imm32/is-deref:false -15224 56/push-esi/next +15123 68/push 0x11/imm32/alloc-id:fake:payload +15124 89/<- %edi 4/r32/esp +15125 $test-add-literal-to-reg:initialize-stmt: +15126 # var stmt/esi: (addr statement) +15127 68/push 0/imm32/next +15128 68/push 0/imm32/next +15129 57/push-edi/outputs +15130 68/push 0x11/imm32/alloc-id:fake +15131 56/push-esi/inouts +15132 68/push 0x11/imm32/alloc-id:fake +15133 68/push 0/imm32/operation +15134 68/push 0/imm32/operation +15135 68/push 1/imm32/tag:stmt1 +15136 89/<- %esi 4/r32/esp +15137 $test-add-literal-to-reg:initialize-stmt-operation: +15138 # stmt->operation = "add" +15139 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15140 (copy-array Heap "add" %eax) +15141 # convert +15142 c7 0/subop/copy *Curr-block-depth 0/imm32 +15143 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +15144 (flush _test-output-buffered-file) +15145 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15151 # check output +15152 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") +15153 # . epilogue +15154 89/<- %esp 5/r32/ebp +15155 5d/pop-to-ebp +15156 c3/return +15157 +15158 test-add-literal-to-mem: +15159 # add-to var1, 0x34 +15160 # => +15161 # 81 0/subop/add %eax 0x34/imm32 +15162 # +15163 # . prologue +15164 55/push-ebp +15165 89/<- %ebp 4/r32/esp +15166 # setup +15167 (clear-stream _test-output-stream) +15168 (clear-stream $_test-output-buffered-file->buffer) +15169 $test-add-literal-to-mem:initialize-type: +15170 # var type/ecx: (payload tree type-id) = int +15171 68/push 0/imm32/right:null +15172 68/push 0/imm32/right:null +15173 68/push 0/imm32/left:unused +15174 68/push 1/imm32/value:int +15175 68/push 1/imm32/is-atom?:true +15176 68/push 0x11/imm32/alloc-id:fake:payload +15177 89/<- %ecx 4/r32/esp +15178 $test-add-literal-to-mem:initialize-var1: +15179 # var var1/ecx: (payload var) +15180 68/push 0/imm32/register +15181 68/push 0/imm32/register +15182 68/push 8/imm32/stack-offset +15183 68/push 1/imm32/block-depth +15184 51/push-ecx +15185 68/push 0x11/imm32/alloc-id:fake +15186 68/push 0/imm32/name +15187 68/push 0/imm32/name +15188 68/push 0x11/imm32/alloc-id:fake:payload +15189 89/<- %ecx 4/r32/esp +15190 $test-add-literal-to-mem:initialize-var1-name: +15191 # var1->name = "var1" +15192 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15193 (copy-array Heap "var1" %eax) +15194 $test-add-literal-to-mem:initialize-literal-type: +15195 # var type/edx: (payload tree type-id) = literal +15196 68/push 0/imm32/right:null +15197 68/push 0/imm32/right:null +15198 68/push 0/imm32/left:unused +15199 68/push 0/imm32/value:literal +15200 68/push 1/imm32/is-atom?:true +15201 68/push 0x11/imm32/alloc-id:fake:payload +15202 89/<- %edx 4/r32/esp +15203 $test-add-literal-to-mem:initialize-literal: +15204 # var l/edx: (payload var) +15205 68/push 0/imm32/register +15206 68/push 0/imm32/register +15207 68/push 0/imm32/no-stack-offset +15208 68/push 1/imm32/block-depth +15209 52/push-edx +15210 68/push 0x11/imm32/alloc-id:fake +15211 68/push 0/imm32/name +15212 68/push 0/imm32/name +15213 68/push 0x11/imm32/alloc-id:fake:payload +15214 89/<- %edx 4/r32/esp +15215 $test-add-literal-to-mem:initialize-literal-value: +15216 # l->name = "0x34" +15217 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +15218 (copy-array Heap "0x34" %eax) +15219 $test-add-literal-to-mem:initialize-inouts: +15220 # var inouts/esi: (payload stmt-var) = [l] +15221 68/push 0/imm32/is-deref:false +15222 68/push 0/imm32/next +15223 68/push 0/imm32/next +15224 52/push-edx/l 15225 68/push 0x11/imm32/alloc-id:fake -15226 51/push-ecx/var1 -15227 68/push 0x11/imm32/alloc-id:fake -15228 68/push 0x11/imm32/alloc-id:fake:payload -15229 89/<- %esi 4/r32/esp -15230 $test-compare-eax-with-literal:initialize-stmt: -15231 # var stmt/esi: (addr statement) -15232 68/push 0/imm32/next -15233 68/push 0/imm32/next -15234 68/push 0/imm32/outputs -15235 68/push 0/imm32/outputs -15236 56/push-esi/inouts -15237 68/push 0x11/imm32/alloc-id:fake -15238 68/push 0/imm32/operation -15239 68/push 0/imm32/operation -15240 68/push 1/imm32/tag:stmt1 -15241 89/<- %esi 4/r32/esp -15242 $test-compare-eax-with-literal:initialize-stmt-operation: -15243 # stmt->operation = "compare" -15244 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -15245 (copy-array Heap "compare" %eax) -15246 # convert -15247 c7 0/subop/copy *Curr-block-depth 0/imm32 -15248 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -15249 (flush _test-output-buffered-file) -15250 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -15256 # check output -15257 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") -15258 # . epilogue -15259 89/<- %esp 5/r32/ebp -15260 5d/pop-to-ebp -15261 c3/return -15262 -15263 test-compare-reg-with-literal: -15264 # compare var1/ecx 0x34 -15265 # => -15266 # 81 7/subop/compare %ecx 0x34/imm32 -15267 # -15268 # . prologue -15269 55/push-ebp -15270 89/<- %ebp 4/r32/esp -15271 # setup -15272 (clear-stream _test-output-stream) -15273 (clear-stream $_test-output-buffered-file->buffer) -15274 $test-compare-reg-with-literal:initialize-type: -15275 # var type/ecx: (payload tree type-id) = int -15276 68/push 0/imm32/right:null -15277 68/push 0/imm32/right:null -15278 68/push 0/imm32/left:unused -15279 68/push 1/imm32/value:int -15280 68/push 1/imm32/is-atom?:true -15281 68/push 0x11/imm32/alloc-id:fake:payload -15282 89/<- %ecx 4/r32/esp -15283 $test-compare-reg-with-literal:initialize-var1: -15284 # var var1/ecx: (payload var) -15285 68/push 0/imm32/register -15286 68/push 0/imm32/register -15287 68/push 0/imm32/no-stack-offset -15288 68/push 1/imm32/block-depth -15289 51/push-ecx -15290 68/push 0x11/imm32/alloc-id:fake -15291 68/push 0/imm32/name -15292 68/push 0/imm32/name -15293 68/push 0x11/imm32/alloc-id:fake:payload -15294 89/<- %ecx 4/r32/esp -15295 $test-compare-reg-with-literal:initialize-var1-name: -15296 # var1->name = "var1" -15297 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -15298 (copy-array Heap "var1" %eax) -15299 $test-compare-reg-with-literal:initialize-var1-register: -15300 # v->register = "ecx" -15301 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -15302 (copy-array Heap "ecx" %eax) -15303 $test-compare-reg-with-literal:initialize-literal-type: -15304 # var type/edx: (payload tree type-id) = literal -15305 68/push 0/imm32/right:null -15306 68/push 0/imm32/right:null -15307 68/push 0/imm32/left:unused -15308 68/push 0/imm32/value:literal -15309 68/push 1/imm32/is-atom?:true -15310 68/push 0x11/imm32/alloc-id:fake:payload -15311 89/<- %edx 4/r32/esp -15312 $test-compare-reg-with-literal:initialize-literal: -15313 # var l/edx: (payload var) -15314 68/push 0/imm32/register -15315 68/push 0/imm32/register -15316 68/push 0/imm32/no-stack-offset -15317 68/push 1/imm32/block-depth -15318 52/push-edx -15319 68/push 0x11/imm32/alloc-id:fake -15320 68/push 0/imm32/name -15321 68/push 0/imm32/name -15322 68/push 0x11/imm32/alloc-id:fake:payload -15323 89/<- %edx 4/r32/esp -15324 $test-compare-reg-with-literal:initialize-literal-value: -15325 # l->name = "0x34" -15326 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -15327 (copy-array Heap "0x34" %eax) -15328 $test-compare-reg-with-literal:initialize-inouts: -15329 # var inouts/esi: (payload stmt-var) = [l] -15330 68/push 0/imm32/is-deref:false -15331 68/push 0/imm32/next -15332 68/push 0/imm32/next -15333 52/push-edx/l -15334 68/push 0x11/imm32/alloc-id:fake -15335 68/push 0x11/imm32/alloc-id:fake:payload -15336 89/<- %esi 4/r32/esp -15337 # var inouts = (handle stmt-var) = [var1, var2] -15338 68/push 0/imm32/is-deref:false -15339 56/push-esi/next -15340 68/push 0x11/imm32/alloc-id:fake -15341 51/push-ecx/var1 -15342 68/push 0x11/imm32/alloc-id:fake -15343 68/push 0x11/imm32/alloc-id:fake:payload -15344 89/<- %esi 4/r32/esp -15345 $test-compare-reg-with-literal:initialize-stmt: -15346 # var stmt/esi: (addr statement) -15347 68/push 0/imm32/next -15348 68/push 0/imm32/next -15349 68/push 0/imm32/outputs -15350 68/push 0/imm32/outputs -15351 56/push-esi/inouts -15352 68/push 0x11/imm32/alloc-id:fake -15353 68/push 0/imm32/operation -15354 68/push 0/imm32/operation -15355 68/push 1/imm32/tag:stmt1 -15356 89/<- %esi 4/r32/esp -15357 $test-compare-reg-with-literal:initialize-stmt-operation: -15358 # stmt->operation = "compare" -15359 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -15360 (copy-array Heap "compare" %eax) -15361 # convert -15362 c7 0/subop/copy *Curr-block-depth 0/imm32 -15363 (emit-subx-stmt _test-output-buffered-file %esi Primitives) -15364 (flush _test-output-buffered-file) -15365 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -15371 # check output -15372 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") -15373 # . epilogue -15374 89/<- %esp 5/r32/ebp -15375 5d/pop-to-ebp -15376 c3/return -15377 -15378 test-emit-subx-stmt-function-call: -15379 # Call a function on a variable on the stack. -15380 # f foo -15381 # => -15382 # (f *(ebp-8)) -15383 # (Changing the function name supports overloading in general, but here it -15384 # just serves to help disambiguate things.) -15385 # -15386 # There's a variable on the var stack as follows: -15387 # name: 'foo' -15388 # type: int -15389 # stack-offset: -8 -15390 # -15391 # There's nothing in primitives. -15392 # -15393 # We don't perform any checking here on the type of 'f'. -15394 # -15395 # . prologue -15396 55/push-ebp -15397 89/<- %ebp 4/r32/esp -15398 # setup -15399 (clear-stream _test-output-stream) -15400 (clear-stream $_test-output-buffered-file->buffer) -15401 $test-emit-subx-function-call:initialize-type: -15402 # var type/ecx: (payload tree type-id) = int -15403 68/push 0/imm32/right:null -15404 68/push 0/imm32/right:null -15405 68/push 0/imm32/left:unused -15406 68/push 1/imm32/value:int -15407 68/push 1/imm32/is-atom?:true -15408 68/push 0x11/imm32/alloc-id:fake:payload -15409 89/<- %ecx 4/r32/esp -15410 $test-emit-subx-function-call:initialize-var: -15411 # var var-foo/ecx: (payload var) = var(type) -15412 68/push 0/imm32/no-register -15413 68/push 0/imm32/no-register -15414 68/push -8/imm32/stack-offset -15415 68/push 1/imm32/block-depth -15416 51/push-ecx/type -15417 68/push 0x11/imm32/alloc-id:fake -15418 68/push 0/imm32/name -15419 68/push 0/imm32/name -15420 68/push 0x11/imm32/alloc-id:fake:payload -15421 89/<- %ecx 4/r32/esp -15422 $test-emit-subx-function-call:initialize-var-name: -15423 # var-foo->name = "foo" -15424 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -15425 (copy-array Heap "foo" %eax) -15426 $test-emit-subx-function-call:initialize-stmt-var: -15427 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -15428 68/push 0/imm32/is-deref:false -15429 68/push 0/imm32/next -15430 68/push 0/imm32/next -15431 51/push-ecx/var-foo -15432 68/push 0x11/imm32/alloc-id:fake -15433 68/push 0x11/imm32/alloc-id:fake:payload -15434 89/<- %ebx 4/r32/esp -15435 $test-emit-subx-function-call:initialize-stmt: -15436 # var stmt/esi: (addr statement) -15437 68/push 0/imm32/no-outputs -15438 68/push 0/imm32/no-outputs -15439 53/push-ebx/inouts -15440 68/push 0x11/imm32/alloc-id:fake -15441 68/push 0/imm32/operation -15442 68/push 0/imm32/operation -15443 68/push 1/imm32/tag -15444 89/<- %esi 4/r32/esp -15445 $test-emit-subx-function-call:initialize-stmt-operation: -15446 # stmt->operation = "f" -15447 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -15448 (copy-array Heap "f" %eax) -15449 # convert -15450 c7 0/subop/copy *Curr-block-depth 0/imm32 -15451 (emit-subx-stmt _test-output-buffered-file %esi 0) -15452 (flush _test-output-buffered-file) -15453 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -15459 # check output -15460 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") -15461 # . epilogue -15462 89/<- %esp 5/r32/ebp -15463 5d/pop-to-ebp -15464 c3/return -15465 -15466 test-emit-subx-stmt-function-call-with-literal-arg: -15467 # Call a function on a literal. -15468 # f 0x34 -15469 # => -15470 # (f2 0x34) -15471 # -15472 # . prologue -15473 55/push-ebp -15474 89/<- %ebp 4/r32/esp -15475 # setup -15476 (clear-stream _test-output-stream) -15477 (clear-stream $_test-output-buffered-file->buffer) -15478 $test-emit-subx-function-call-with-literal-arg:initialize-type: -15479 # var type/ecx: (payload tree type-id) = int -15480 68/push 0/imm32/right:null -15481 68/push 0/imm32/right:null -15482 68/push 0/imm32/left:unused -15483 68/push 0/imm32/value:literal -15484 68/push 1/imm32/is-atom?:true -15485 68/push 0x11/imm32/alloc-id:fake:payload -15486 89/<- %ecx 4/r32/esp -15487 $test-emit-subx-function-call-with-literal-arg:initialize-var: -15488 # var var-foo/ecx: (payload var) = var(lit) -15489 68/push 0/imm32/no-register -15490 68/push 0/imm32/no-register -15491 68/push 0/imm32/no-stack-offset -15492 68/push 1/imm32/block-depth -15493 51/push-ecx/type -15494 68/push 0x11/imm32/alloc-id:fake -15495 68/push 0/imm32/name -15496 68/push 0/imm32/name -15497 68/push 0x11/imm32/alloc-id:fake:payload -15498 89/<- %ecx 4/r32/esp -15499 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: -15500 # var-foo->name = "0x34" -15501 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -15502 (copy-array Heap "0x34" %eax) -15503 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: -15504 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -15505 68/push 0/imm32/is-deref:false -15506 68/push 0/imm32/next -15507 68/push 0/imm32/next -15508 51/push-ecx/var-foo -15509 68/push 0x11/imm32/alloc-id:fake -15510 68/push 0x11/imm32/alloc-id:fake:payload -15511 89/<- %ebx 4/r32/esp -15512 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: -15513 # var stmt/esi: (addr statement) -15514 68/push 0/imm32/no-outputs -15515 68/push 0/imm32/no-outputs -15516 53/push-ebx/inouts -15517 68/push 0x11/imm32/alloc-id:fake -15518 68/push 0/imm32/operation -15519 68/push 0/imm32/operation -15520 68/push 1/imm32/tag -15521 89/<- %esi 4/r32/esp -15522 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: -15523 # stmt->operation = "f" -15524 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -15525 (copy-array Heap "f" %eax) -15526 # convert -15527 c7 0/subop/copy *Curr-block-depth 0/imm32 -15528 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx) -15529 (flush _test-output-buffered-file) -15530 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -15536 # check output -15537 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") -15538 # . epilogue -15539 89/<- %esp 5/r32/ebp -15540 5d/pop-to-ebp -15541 c3/return -15542 -15543 emit-indent: # out: (addr buffered-file), n: int -15544 # . prologue -15545 55/push-ebp -15546 89/<- %ebp 4/r32/esp -15547 # . save registers -15548 50/push-eax -15549 # var i/eax: int = n -15550 8b/-> *(ebp+0xc) 0/r32/eax -15551 { -15552 # if (i <= 0) break -15553 3d/compare-eax-with 0/imm32 -15554 7e/jump-if-<= break/disp8 -15555 (write-buffered *(ebp+8) " ") -15556 48/decrement-eax -15557 eb/jump loop/disp8 -15558 } -15559 $emit-indent:end: -15560 # . restore registers -15561 58/pop-to-eax -15562 # . epilogue -15563 89/<- %esp 5/r32/ebp -15564 5d/pop-to-ebp -15565 c3/return -15566 -15567 emit-subx-prologue: # out: (addr buffered-file) -15568 # . prologue -15569 55/push-ebp -15570 89/<- %ebp 4/r32/esp -15571 # -15572 (write-buffered *(ebp+8) " # . prologue\n") -15573 (write-buffered *(ebp+8) " 55/push-ebp\n") -15574 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") -15575 $emit-subx-prologue:end: -15576 # . epilogue -15577 89/<- %esp 5/r32/ebp -15578 5d/pop-to-ebp -15579 c3/return -15580 -15581 emit-subx-epilogue: # out: (addr buffered-file) -15582 # . prologue -15583 55/push-ebp -15584 89/<- %ebp 4/r32/esp -15585 # -15586 (write-buffered *(ebp+8) " # . epilogue\n") -15587 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") -15588 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") -15589 (write-buffered *(ebp+8) " c3/return\n") -15590 $emit-subx-epilogue:end: -15591 # . epilogue -15592 89/<- %esp 5/r32/ebp -15593 5d/pop-to-ebp -15594 c3/return +15226 68/push 0x11/imm32/alloc-id:fake:payload +15227 89/<- %esi 4/r32/esp +15228 # var inouts = (handle stmt-var) = [var1, var2] +15229 68/push 0/imm32/is-deref:false +15230 56/push-esi/next +15231 68/push 0x11/imm32/alloc-id:fake +15232 51/push-ecx/var1 +15233 68/push 0x11/imm32/alloc-id:fake +15234 68/push 0x11/imm32/alloc-id:fake:payload +15235 89/<- %esi 4/r32/esp +15236 $test-add-literal-to-mem:initialize-stmt: +15237 # var stmt/esi: (addr statement) +15238 68/push 0/imm32/next +15239 68/push 0/imm32/next +15240 68/push 0/imm32/outputs +15241 68/push 0/imm32/outputs +15242 56/push-esi/inouts +15243 68/push 0x11/imm32/alloc-id:fake +15244 68/push 0/imm32/operation +15245 68/push 0/imm32/operation +15246 68/push 1/imm32/tag:stmt1 +15247 89/<- %esi 4/r32/esp +15248 $test-add-literal-to-mem:initialize-stmt-operation: +15249 # stmt->operation = "add-to" +15250 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15251 (copy-array Heap "add-to" %eax) +15252 # convert +15253 c7 0/subop/copy *Curr-block-depth 0/imm32 +15254 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +15255 (flush _test-output-buffered-file) +15256 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15262 # check output +15263 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") +15264 # . epilogue +15265 89/<- %esp 5/r32/ebp +15266 5d/pop-to-ebp +15267 c3/return +15268 +15269 test-compare-mem-with-reg: +15270 # compare var1, var2/eax +15271 # => +15272 # 39/compare *(ebp+___) 0/r32/eax +15273 # +15274 # . prologue +15275 55/push-ebp +15276 89/<- %ebp 4/r32/esp +15277 # setup +15278 (clear-stream _test-output-stream) +15279 (clear-stream $_test-output-buffered-file->buffer) +15280 $test-compare-mem-with-reg:initialize-type: +15281 # var type/ecx: (payload tree type-id) = int +15282 68/push 0/imm32/right:null +15283 68/push 0/imm32/right:null +15284 68/push 0/imm32/left:unused +15285 68/push 1/imm32/value:int +15286 68/push 1/imm32/is-atom?:true +15287 68/push 0x11/imm32/alloc-id:fake:payload +15288 89/<- %ecx 4/r32/esp +15289 $test-compare-mem-with-reg:initialize-var1: +15290 # var var1/ecx: (payload var) +15291 68/push 0/imm32/register +15292 68/push 0/imm32/register +15293 68/push 8/imm32/stack-offset +15294 68/push 1/imm32/block-depth +15295 51/push-ecx +15296 68/push 0x11/imm32/alloc-id:fake +15297 68/push 0/imm32/name +15298 68/push 0/imm32/name +15299 68/push 0x11/imm32/alloc-id:fake:payload +15300 89/<- %ecx 4/r32/esp +15301 $test-compare-mem-with-reg:initialize-var1-name: +15302 # var1->name = "var1" +15303 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15304 (copy-array Heap "var1" %eax) +15305 $test-compare-mem-with-reg:initialize-var2: +15306 # var var2/edx: (payload var) +15307 68/push 0/imm32/register +15308 68/push 0/imm32/register +15309 68/push 0/imm32/no-stack-offset +15310 68/push 1/imm32/block-depth +15311 ff 6/subop/push *(ecx+0x10) +15312 68/push 0x11/imm32/alloc-id:fake +15313 68/push 0/imm32/name +15314 68/push 0/imm32/name +15315 68/push 0x11/imm32/alloc-id:fake:payload +15316 89/<- %edx 4/r32/esp +15317 $test-compare-mem-with-reg:initialize-var2-name: +15318 # var2->name = "var2" +15319 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +15320 (copy-array Heap "var2" %eax) +15321 $test-compare-mem-with-reg:initialize-var2-register: +15322 # var2->register = "eax" +15323 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +15324 (copy-array Heap "eax" %eax) +15325 $test-compare-mem-with-reg:initialize-inouts: +15326 # var inouts/esi: (payload stmt-var) = [var2] +15327 68/push 0/imm32/is-deref:false +15328 68/push 0/imm32/next +15329 68/push 0/imm32/next +15330 52/push-edx/var2 +15331 68/push 0x11/imm32/alloc-id:fake +15332 68/push 0x11/imm32/alloc-id:fake:payload +15333 89/<- %esi 4/r32/esp +15334 # inouts = [var1, var2] +15335 68/push 0/imm32/is-deref:false +15336 56/push-esi/next +15337 68/push 0x11/imm32/alloc-id:fake +15338 51/push-ecx/var1 +15339 68/push 0x11/imm32/alloc-id:fake +15340 68/push 0x11/imm32/alloc-id:fake:payload +15341 89/<- %esi 4/r32/esp +15342 $test-compare-mem-with-reg:initialize-stmt: +15343 # var stmt/esi: (addr statement) +15344 68/push 0/imm32/next +15345 68/push 0/imm32/next +15346 68/push 0/imm32/outputs +15347 68/push 0/imm32/outputs +15348 56/push-esi/inouts +15349 68/push 0x11/imm32/alloc-id:fake +15350 68/push 0/imm32/operation +15351 68/push 0/imm32/operation +15352 68/push 1/imm32/tag:stmt1 +15353 89/<- %esi 4/r32/esp +15354 $test-compare-mem-with-reg:initialize-stmt-operation: +15355 # stmt->operation = "compare" +15356 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15357 (copy-array Heap "compare" %eax) +15358 # convert +15359 c7 0/subop/copy *Curr-block-depth 0/imm32 +15360 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +15361 (flush _test-output-buffered-file) +15362 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15368 # check output +15369 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") +15370 # . epilogue +15371 89/<- %esp 5/r32/ebp +15372 5d/pop-to-ebp +15373 c3/return +15374 +15375 test-compare-reg-with-mem: +15376 # compare var1/eax, var2 +15377 # => +15378 # 3b/compare<- *(ebp+___) 0/r32/eax +15379 # +15380 # . prologue +15381 55/push-ebp +15382 89/<- %ebp 4/r32/esp +15383 # setup +15384 (clear-stream _test-output-stream) +15385 (clear-stream $_test-output-buffered-file->buffer) +15386 $test-compare-reg-with-mem:initialize-type: +15387 # var type/ecx: (payload tree type-id) = int +15388 68/push 0/imm32/right:null +15389 68/push 0/imm32/right:null +15390 68/push 0/imm32/left:unused +15391 68/push 1/imm32/value:int +15392 68/push 1/imm32/is-atom?:true +15393 68/push 0x11/imm32/alloc-id:fake:payload +15394 89/<- %ecx 4/r32/esp +15395 $test-compare-reg-with-mem:initialize-var1: +15396 # var var1/ecx: (payload var) +15397 68/push 0/imm32/register +15398 68/push 0/imm32/register +15399 68/push 0/imm32/no-stack-offset +15400 68/push 1/imm32/block-depth +15401 51/push-ecx +15402 68/push 0x11/imm32/alloc-id:fake +15403 68/push 0/imm32/name +15404 68/push 0/imm32/name +15405 68/push 0x11/imm32/alloc-id:fake:payload +15406 89/<- %ecx 4/r32/esp +15407 $test-compare-reg-with-mem:initialize-var1-name: +15408 # var1->name = "var1" +15409 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15410 (copy-array Heap "var1" %eax) +15411 $test-compare-reg-with-mem:initialize-var1-register: +15412 # var1->register = "eax" +15413 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +15414 (copy-array Heap "eax" %eax) +15415 $test-compare-reg-with-mem:initialize-var2: +15416 # var var2/edx: (payload var) +15417 68/push 0/imm32/register +15418 68/push 0/imm32/register +15419 68/push 8/imm32/stack-offset +15420 68/push 1/imm32/block-depth +15421 ff 6/subop/push *(ecx+0x10) +15422 68/push 0x11/imm32/alloc-id:fake +15423 68/push 0/imm32/name +15424 68/push 0/imm32/name +15425 68/push 0x11/imm32/alloc-id:fake:payload +15426 89/<- %edx 4/r32/esp +15427 $test-compare-reg-with-mem:initialize-var2-name: +15428 # var2->name = "var2" +15429 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +15430 (copy-array Heap "var2" %eax) +15431 $test-compare-reg-with-mem:initialize-inouts: +15432 # var inouts/esi: (payload stmt-var) = [var2] +15433 68/push 0/imm32/is-deref:false +15434 68/push 0/imm32/next +15435 68/push 0/imm32/next +15436 52/push-edx/var2 +15437 68/push 0x11/imm32/alloc-id:fake +15438 68/push 0x11/imm32/alloc-id:fake:payload +15439 89/<- %esi 4/r32/esp +15440 # inouts = [var1, var2] +15441 68/push 0/imm32/is-deref:false +15442 56/push-esi/next +15443 68/push 0x11/imm32/alloc-id:fake +15444 51/push-ecx/var1 +15445 68/push 0x11/imm32/alloc-id:fake +15446 68/push 0x11/imm32/alloc-id:fake:payload +15447 89/<- %esi 4/r32/esp +15448 $test-compare-reg-with-mem:initialize-stmt: +15449 # var stmt/esi: (addr statement) +15450 68/push 0/imm32/next +15451 68/push 0/imm32/next +15452 68/push 0/imm32/outputs +15453 68/push 0/imm32/outputs +15454 56/push-esi/inouts +15455 68/push 0x11/imm32/alloc-id:fake +15456 68/push 0/imm32/operation +15457 68/push 0/imm32/operation +15458 68/push 1/imm32/tag:stmt1 +15459 89/<- %esi 4/r32/esp +15460 $test-compare-reg-with-mem:initialize-stmt-operation: +15461 # stmt->operation = "compare" +15462 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15463 (copy-array Heap "compare" %eax) +15464 # convert +15465 c7 0/subop/copy *Curr-block-depth 0/imm32 +15466 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +15467 (flush _test-output-buffered-file) +15468 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15474 # check output +15475 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") +15476 # . epilogue +15477 89/<- %esp 5/r32/ebp +15478 5d/pop-to-ebp +15479 c3/return +15480 +15481 test-compare-mem-with-literal: +15482 # compare var1, 0x34 +15483 # => +15484 # 81 7/subop/compare *(ebp+___) 0x34/imm32 +15485 # +15486 # . prologue +15487 55/push-ebp +15488 89/<- %ebp 4/r32/esp +15489 # setup +15490 (clear-stream _test-output-stream) +15491 (clear-stream $_test-output-buffered-file->buffer) +15492 $test-compare-mem-with-literal:initialize-type: +15493 # var type/ecx: (payload tree type-id) = int +15494 68/push 0/imm32/right:null +15495 68/push 0/imm32/right:null +15496 68/push 0/imm32/left:unused +15497 68/push 1/imm32/value:int +15498 68/push 1/imm32/is-atom?:true +15499 68/push 0x11/imm32/alloc-id:fake:payload +15500 89/<- %ecx 4/r32/esp +15501 $test-compare-mem-with-literal:initialize-var1: +15502 # var var1/ecx: (payload var) +15503 68/push 0/imm32/register +15504 68/push 0/imm32/register +15505 68/push 8/imm32/stack-offset +15506 68/push 1/imm32/block-depth +15507 51/push-ecx +15508 68/push 0x11/imm32/alloc-id:fake +15509 68/push 0/imm32/name +15510 68/push 0/imm32/name +15511 68/push 0x11/imm32/alloc-id:fake:payload +15512 89/<- %ecx 4/r32/esp +15513 $test-compare-mem-with-literal:initialize-var1-name: +15514 # var1->name = "var1" +15515 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15516 (copy-array Heap "var1" %eax) +15517 $test-compare-mem-with-literal:initialize-literal-type: +15518 # var type/edx: (payload tree type-id) = literal +15519 68/push 0/imm32/right:null +15520 68/push 0/imm32/right:null +15521 68/push 0/imm32/left:unused +15522 68/push 0/imm32/value:literal +15523 68/push 1/imm32/is-atom?:true +15524 68/push 0x11/imm32/alloc-id:fake:payload +15525 89/<- %edx 4/r32/esp +15526 $test-compare-mem-with-literal:initialize-literal: +15527 # var l/edx: (payload var) +15528 68/push 0/imm32/register +15529 68/push 0/imm32/register +15530 68/push 0/imm32/no-stack-offset +15531 68/push 1/imm32/block-depth +15532 52/push-edx +15533 68/push 0x11/imm32/alloc-id:fake +15534 68/push 0/imm32/name +15535 68/push 0/imm32/name +15536 68/push 0x11/imm32/alloc-id:fake:payload +15537 89/<- %edx 4/r32/esp +15538 $test-compare-mem-with-literal:initialize-literal-value: +15539 # l->name = "0x34" +15540 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +15541 (copy-array Heap "0x34" %eax) +15542 $test-compare-mem-with-literal:initialize-inouts: +15543 # var inouts/esi: (payload stmt-var) = [l] +15544 68/push 0/imm32/is-deref:false +15545 68/push 0/imm32/next +15546 68/push 0/imm32/next +15547 52/push-edx/l +15548 68/push 0x11/imm32/alloc-id:fake +15549 68/push 0x11/imm32/alloc-id:fake:payload +15550 89/<- %esi 4/r32/esp +15551 # var inouts = (handle stmt-var) = [var1, var2] +15552 68/push 0/imm32/is-deref:false +15553 56/push-esi/next +15554 68/push 0x11/imm32/alloc-id:fake +15555 51/push-ecx/var1 +15556 68/push 0x11/imm32/alloc-id:fake +15557 68/push 0x11/imm32/alloc-id:fake:payload +15558 89/<- %esi 4/r32/esp +15559 $test-compare-mem-with-literal:initialize-stmt: +15560 # var stmt/esi: (addr statement) +15561 68/push 0/imm32/next +15562 68/push 0/imm32/next +15563 68/push 0/imm32/outputs +15564 68/push 0/imm32/outputs +15565 56/push-esi/inouts +15566 68/push 0x11/imm32/alloc-id:fake +15567 68/push 0/imm32/operation +15568 68/push 0/imm32/operation +15569 68/push 1/imm32/tag:stmt1 +15570 89/<- %esi 4/r32/esp +15571 $test-compare-mem-with-literal:initialize-stmt-operation: +15572 # stmt->operation = "compare" +15573 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15574 (copy-array Heap "compare" %eax) +15575 # convert +15576 c7 0/subop/copy *Curr-block-depth 0/imm32 +15577 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +15578 (flush _test-output-buffered-file) +15579 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15585 # check output +15586 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") +15587 # . epilogue +15588 89/<- %esp 5/r32/ebp +15589 5d/pop-to-ebp +15590 c3/return +15591 +15592 test-compare-eax-with-literal: +15593 # compare var1/eax 0x34 +15594 # => +15595 # 3d/compare-eax-with 0x34/imm32 +15596 # +15597 # . prologue +15598 55/push-ebp +15599 89/<- %ebp 4/r32/esp +15600 # setup +15601 (clear-stream _test-output-stream) +15602 (clear-stream $_test-output-buffered-file->buffer) +15603 $test-compare-eax-with-literal:initialize-type: +15604 # var type/ecx: (payload tree type-id) = int +15605 68/push 0/imm32/right:null +15606 68/push 0/imm32/right:null +15607 68/push 0/imm32/left:unused +15608 68/push 1/imm32/value:int +15609 68/push 1/imm32/is-atom?:true +15610 68/push 0x11/imm32/alloc-id:fake:payload +15611 89/<- %ecx 4/r32/esp +15612 $test-compare-eax-with-literal:initialize-var1: +15613 # var var1/ecx: (payload var) +15614 68/push 0/imm32/register +15615 68/push 0/imm32/register +15616 68/push 0/imm32/no-stack-offset +15617 68/push 1/imm32/block-depth +15618 51/push-ecx +15619 68/push 0x11/imm32/alloc-id:fake +15620 68/push 0/imm32/name +15621 68/push 0/imm32/name +15622 68/push 0x11/imm32/alloc-id:fake:payload +15623 89/<- %ecx 4/r32/esp +15624 $test-compare-eax-with-literal:initialize-var1-name: +15625 # var1->name = "var1" +15626 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15627 (copy-array Heap "var1" %eax) +15628 $test-compare-eax-with-literal:initialize-var1-register: +15629 # v->register = "eax" +15630 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +15631 (copy-array Heap "eax" %eax) +15632 $test-compare-eax-with-literal:initialize-literal-type: +15633 # var type/edx: (payload tree type-id) = literal +15634 68/push 0/imm32/right:null +15635 68/push 0/imm32/right:null +15636 68/push 0/imm32/left:unused +15637 68/push 0/imm32/value:literal +15638 68/push 1/imm32/is-atom?:true +15639 68/push 0x11/imm32/alloc-id:fake:payload +15640 89/<- %edx 4/r32/esp +15641 $test-compare-eax-with-literal:initialize-literal: +15642 # var l/edx: (payload var) +15643 68/push 0/imm32/register +15644 68/push 0/imm32/register +15645 68/push 0/imm32/no-stack-offset +15646 68/push 1/imm32/block-depth +15647 52/push-edx +15648 68/push 0x11/imm32/alloc-id:fake +15649 68/push 0/imm32/name +15650 68/push 0/imm32/name +15651 68/push 0x11/imm32/alloc-id:fake:payload +15652 89/<- %edx 4/r32/esp +15653 $test-compare-eax-with-literal:initialize-literal-value: +15654 # l->name = "0x34" +15655 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +15656 (copy-array Heap "0x34" %eax) +15657 $test-compare-eax-with-literal:initialize-inouts: +15658 # var inouts/esi: (payload stmt-var) = [l] +15659 68/push 0/imm32/is-deref:false +15660 68/push 0/imm32/next +15661 68/push 0/imm32/next +15662 52/push-edx/l +15663 68/push 0x11/imm32/alloc-id:fake +15664 68/push 0x11/imm32/alloc-id:fake:payload +15665 89/<- %esi 4/r32/esp +15666 # var inouts = (handle stmt-var) = [var1, var2] +15667 68/push 0/imm32/is-deref:false +15668 56/push-esi/next +15669 68/push 0x11/imm32/alloc-id:fake +15670 51/push-ecx/var1 +15671 68/push 0x11/imm32/alloc-id:fake +15672 68/push 0x11/imm32/alloc-id:fake:payload +15673 89/<- %esi 4/r32/esp +15674 $test-compare-eax-with-literal:initialize-stmt: +15675 # var stmt/esi: (addr statement) +15676 68/push 0/imm32/next +15677 68/push 0/imm32/next +15678 68/push 0/imm32/outputs +15679 68/push 0/imm32/outputs +15680 56/push-esi/inouts +15681 68/push 0x11/imm32/alloc-id:fake +15682 68/push 0/imm32/operation +15683 68/push 0/imm32/operation +15684 68/push 1/imm32/tag:stmt1 +15685 89/<- %esi 4/r32/esp +15686 $test-compare-eax-with-literal:initialize-stmt-operation: +15687 # stmt->operation = "compare" +15688 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15689 (copy-array Heap "compare" %eax) +15690 # convert +15691 c7 0/subop/copy *Curr-block-depth 0/imm32 +15692 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +15693 (flush _test-output-buffered-file) +15694 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15700 # check output +15701 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") +15702 # . epilogue +15703 89/<- %esp 5/r32/ebp +15704 5d/pop-to-ebp +15705 c3/return +15706 +15707 test-compare-reg-with-literal: +15708 # compare var1/ecx 0x34 +15709 # => +15710 # 81 7/subop/compare %ecx 0x34/imm32 +15711 # +15712 # . prologue +15713 55/push-ebp +15714 89/<- %ebp 4/r32/esp +15715 # setup +15716 (clear-stream _test-output-stream) +15717 (clear-stream $_test-output-buffered-file->buffer) +15718 $test-compare-reg-with-literal:initialize-type: +15719 # var type/ecx: (payload tree type-id) = int +15720 68/push 0/imm32/right:null +15721 68/push 0/imm32/right:null +15722 68/push 0/imm32/left:unused +15723 68/push 1/imm32/value:int +15724 68/push 1/imm32/is-atom?:true +15725 68/push 0x11/imm32/alloc-id:fake:payload +15726 89/<- %ecx 4/r32/esp +15727 $test-compare-reg-with-literal:initialize-var1: +15728 # var var1/ecx: (payload var) +15729 68/push 0/imm32/register +15730 68/push 0/imm32/register +15731 68/push 0/imm32/no-stack-offset +15732 68/push 1/imm32/block-depth +15733 51/push-ecx +15734 68/push 0x11/imm32/alloc-id:fake +15735 68/push 0/imm32/name +15736 68/push 0/imm32/name +15737 68/push 0x11/imm32/alloc-id:fake:payload +15738 89/<- %ecx 4/r32/esp +15739 $test-compare-reg-with-literal:initialize-var1-name: +15740 # var1->name = "var1" +15741 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15742 (copy-array Heap "var1" %eax) +15743 $test-compare-reg-with-literal:initialize-var1-register: +15744 # v->register = "ecx" +15745 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +15746 (copy-array Heap "ecx" %eax) +15747 $test-compare-reg-with-literal:initialize-literal-type: +15748 # var type/edx: (payload tree type-id) = literal +15749 68/push 0/imm32/right:null +15750 68/push 0/imm32/right:null +15751 68/push 0/imm32/left:unused +15752 68/push 0/imm32/value:literal +15753 68/push 1/imm32/is-atom?:true +15754 68/push 0x11/imm32/alloc-id:fake:payload +15755 89/<- %edx 4/r32/esp +15756 $test-compare-reg-with-literal:initialize-literal: +15757 # var l/edx: (payload var) +15758 68/push 0/imm32/register +15759 68/push 0/imm32/register +15760 68/push 0/imm32/no-stack-offset +15761 68/push 1/imm32/block-depth +15762 52/push-edx +15763 68/push 0x11/imm32/alloc-id:fake +15764 68/push 0/imm32/name +15765 68/push 0/imm32/name +15766 68/push 0x11/imm32/alloc-id:fake:payload +15767 89/<- %edx 4/r32/esp +15768 $test-compare-reg-with-literal:initialize-literal-value: +15769 # l->name = "0x34" +15770 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +15771 (copy-array Heap "0x34" %eax) +15772 $test-compare-reg-with-literal:initialize-inouts: +15773 # var inouts/esi: (payload stmt-var) = [l] +15774 68/push 0/imm32/is-deref:false +15775 68/push 0/imm32/next +15776 68/push 0/imm32/next +15777 52/push-edx/l +15778 68/push 0x11/imm32/alloc-id:fake +15779 68/push 0x11/imm32/alloc-id:fake:payload +15780 89/<- %esi 4/r32/esp +15781 # var inouts = (handle stmt-var) = [var1, var2] +15782 68/push 0/imm32/is-deref:false +15783 56/push-esi/next +15784 68/push 0x11/imm32/alloc-id:fake +15785 51/push-ecx/var1 +15786 68/push 0x11/imm32/alloc-id:fake +15787 68/push 0x11/imm32/alloc-id:fake:payload +15788 89/<- %esi 4/r32/esp +15789 $test-compare-reg-with-literal:initialize-stmt: +15790 # var stmt/esi: (addr statement) +15791 68/push 0/imm32/next +15792 68/push 0/imm32/next +15793 68/push 0/imm32/outputs +15794 68/push 0/imm32/outputs +15795 56/push-esi/inouts +15796 68/push 0x11/imm32/alloc-id:fake +15797 68/push 0/imm32/operation +15798 68/push 0/imm32/operation +15799 68/push 1/imm32/tag:stmt1 +15800 89/<- %esi 4/r32/esp +15801 $test-compare-reg-with-literal:initialize-stmt-operation: +15802 # stmt->operation = "compare" +15803 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15804 (copy-array Heap "compare" %eax) +15805 # convert +15806 c7 0/subop/copy *Curr-block-depth 0/imm32 +15807 (emit-subx-stmt _test-output-buffered-file %esi Primitives) +15808 (flush _test-output-buffered-file) +15809 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15815 # check output +15816 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") +15817 # . epilogue +15818 89/<- %esp 5/r32/ebp +15819 5d/pop-to-ebp +15820 c3/return +15821 +15822 test-emit-subx-stmt-function-call: +15823 # Call a function on a variable on the stack. +15824 # f foo +15825 # => +15826 # (f *(ebp-8)) +15827 # (Changing the function name supports overloading in general, but here it +15828 # just serves to help disambiguate things.) +15829 # +15830 # There's a variable on the var stack as follows: +15831 # name: 'foo' +15832 # type: int +15833 # stack-offset: -8 +15834 # +15835 # There's nothing in primitives. +15836 # +15837 # We don't perform any checking here on the type of 'f'. +15838 # +15839 # . prologue +15840 55/push-ebp +15841 89/<- %ebp 4/r32/esp +15842 # setup +15843 (clear-stream _test-output-stream) +15844 (clear-stream $_test-output-buffered-file->buffer) +15845 $test-emit-subx-function-call:initialize-type: +15846 # var type/ecx: (payload tree type-id) = int +15847 68/push 0/imm32/right:null +15848 68/push 0/imm32/right:null +15849 68/push 0/imm32/left:unused +15850 68/push 1/imm32/value:int +15851 68/push 1/imm32/is-atom?:true +15852 68/push 0x11/imm32/alloc-id:fake:payload +15853 89/<- %ecx 4/r32/esp +15854 $test-emit-subx-function-call:initialize-var: +15855 # var var-foo/ecx: (payload var) = var(type) +15856 68/push 0/imm32/no-register +15857 68/push 0/imm32/no-register +15858 68/push -8/imm32/stack-offset +15859 68/push 1/imm32/block-depth +15860 51/push-ecx/type +15861 68/push 0x11/imm32/alloc-id:fake +15862 68/push 0/imm32/name +15863 68/push 0/imm32/name +15864 68/push 0x11/imm32/alloc-id:fake:payload +15865 89/<- %ecx 4/r32/esp +15866 $test-emit-subx-function-call:initialize-var-name: +15867 # var-foo->name = "foo" +15868 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15869 (copy-array Heap "foo" %eax) +15870 $test-emit-subx-function-call:initialize-stmt-var: +15871 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +15872 68/push 0/imm32/is-deref:false +15873 68/push 0/imm32/next +15874 68/push 0/imm32/next +15875 51/push-ecx/var-foo +15876 68/push 0x11/imm32/alloc-id:fake +15877 68/push 0x11/imm32/alloc-id:fake:payload +15878 89/<- %ebx 4/r32/esp +15879 $test-emit-subx-function-call:initialize-stmt: +15880 # var stmt/esi: (addr statement) +15881 68/push 0/imm32/no-outputs +15882 68/push 0/imm32/no-outputs +15883 53/push-ebx/inouts +15884 68/push 0x11/imm32/alloc-id:fake +15885 68/push 0/imm32/operation +15886 68/push 0/imm32/operation +15887 68/push 1/imm32/tag +15888 89/<- %esi 4/r32/esp +15889 $test-emit-subx-function-call:initialize-stmt-operation: +15890 # stmt->operation = "f" +15891 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15892 (copy-array Heap "f" %eax) +15893 # convert +15894 c7 0/subop/copy *Curr-block-depth 0/imm32 +15895 (emit-subx-stmt _test-output-buffered-file %esi 0) +15896 (flush _test-output-buffered-file) +15897 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15903 # check output +15904 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") +15905 # . epilogue +15906 89/<- %esp 5/r32/ebp +15907 5d/pop-to-ebp +15908 c3/return +15909 +15910 test-emit-subx-stmt-function-call-with-literal-arg: +15911 # Call a function on a literal. +15912 # f 0x34 +15913 # => +15914 # (f2 0x34) +15915 # +15916 # . prologue +15917 55/push-ebp +15918 89/<- %ebp 4/r32/esp +15919 # setup +15920 (clear-stream _test-output-stream) +15921 (clear-stream $_test-output-buffered-file->buffer) +15922 $test-emit-subx-function-call-with-literal-arg:initialize-type: +15923 # var type/ecx: (payload tree type-id) = int +15924 68/push 0/imm32/right:null +15925 68/push 0/imm32/right:null +15926 68/push 0/imm32/left:unused +15927 68/push 0/imm32/value:literal +15928 68/push 1/imm32/is-atom?:true +15929 68/push 0x11/imm32/alloc-id:fake:payload +15930 89/<- %ecx 4/r32/esp +15931 $test-emit-subx-function-call-with-literal-arg:initialize-var: +15932 # var var-foo/ecx: (payload var) = var(lit) +15933 68/push 0/imm32/no-register +15934 68/push 0/imm32/no-register +15935 68/push 0/imm32/no-stack-offset +15936 68/push 1/imm32/block-depth +15937 51/push-ecx/type +15938 68/push 0x11/imm32/alloc-id:fake +15939 68/push 0/imm32/name +15940 68/push 0/imm32/name +15941 68/push 0x11/imm32/alloc-id:fake:payload +15942 89/<- %ecx 4/r32/esp +15943 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: +15944 # var-foo->name = "0x34" +15945 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +15946 (copy-array Heap "0x34" %eax) +15947 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: +15948 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +15949 68/push 0/imm32/is-deref:false +15950 68/push 0/imm32/next +15951 68/push 0/imm32/next +15952 51/push-ecx/var-foo +15953 68/push 0x11/imm32/alloc-id:fake +15954 68/push 0x11/imm32/alloc-id:fake:payload +15955 89/<- %ebx 4/r32/esp +15956 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: +15957 # var stmt/esi: (addr statement) +15958 68/push 0/imm32/no-outputs +15959 68/push 0/imm32/no-outputs +15960 53/push-ebx/inouts +15961 68/push 0x11/imm32/alloc-id:fake +15962 68/push 0/imm32/operation +15963 68/push 0/imm32/operation +15964 68/push 1/imm32/tag +15965 89/<- %esi 4/r32/esp +15966 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: +15967 # stmt->operation = "f" +15968 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +15969 (copy-array Heap "f" %eax) +15970 # convert +15971 c7 0/subop/copy *Curr-block-depth 0/imm32 +15972 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx) +15973 (flush _test-output-buffered-file) +15974 +-- 6 lines: #? # dump _test-output-stream ---------------------------------------------------------------------------------------------------------------------------------------------------------------- +15980 # check output +15981 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") +15982 # . epilogue +15983 89/<- %esp 5/r32/ebp +15984 5d/pop-to-ebp +15985 c3/return +15986 +15987 emit-indent: # out: (addr buffered-file), n: int +15988 # . prologue +15989 55/push-ebp +15990 89/<- %ebp 4/r32/esp +15991 # . save registers +15992 50/push-eax +15993 # var i/eax: int = n +15994 8b/-> *(ebp+0xc) 0/r32/eax +15995 { +15996 # if (i <= 0) break +15997 3d/compare-eax-with 0/imm32 +15998 7e/jump-if-<= break/disp8 +15999 (write-buffered *(ebp+8) " ") +16000 48/decrement-eax +16001 eb/jump loop/disp8 +16002 } +16003 $emit-indent:end: +16004 # . restore registers +16005 58/pop-to-eax +16006 # . epilogue +16007 89/<- %esp 5/r32/ebp +16008 5d/pop-to-ebp +16009 c3/return +16010 +16011 emit-subx-prologue: # out: (addr buffered-file) +16012 # . prologue +16013 55/push-ebp +16014 89/<- %ebp 4/r32/esp +16015 # +16016 (write-buffered *(ebp+8) " # . prologue\n") +16017 (write-buffered *(ebp+8) " 55/push-ebp\n") +16018 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") +16019 $emit-subx-prologue:end: +16020 # . epilogue +16021 89/<- %esp 5/r32/ebp +16022 5d/pop-to-ebp +16023 c3/return +16024 +16025 emit-subx-epilogue: # out: (addr buffered-file) +16026 # . prologue +16027 55/push-ebp +16028 89/<- %ebp 4/r32/esp +16029 # +16030 (write-buffered *(ebp+8) " # . epilogue\n") +16031 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") +16032 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") +16033 (write-buffered *(ebp+8) " c3/return\n") +16034 $emit-subx-epilogue:end: +16035 # . epilogue +16036 89/<- %esp 5/r32/ebp +16037 5d/pop-to-ebp +16038 c3/return -- cgit 1.4.1-2-gfad0