From 2104d1a75b76dbffc0b15a96c98d94e7a16594e8 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 27 Jan 2020 00:39:46 -0800 Subject: 5925 --- html/apps/mu.subx.html | 4892 ++++++++++++++++++++++++------------------------ 1 file changed, 2467 insertions(+), 2425 deletions(-) (limited to 'html/apps/mu.subx.html') diff --git a/html/apps/mu.subx.html b/html/apps/mu.subx.html index 78d6532b..5c360a39 100644 --- a/html/apps/mu.subx.html +++ b/html/apps/mu.subx.html @@ -132,12 +132,12 @@ if ('onhashchange' in window) { 70 # The type of a local variable is either word-length (4 bytes) or starts with 'ref'. 71 # 72 # - variables definitions in a register. E.g.: - 73 # - var foo/eax : int <- add bar 1 + 73 # - var foo/eax: int <- add bar 1 74 # The initializer is mandatory and must be a valid instruction that writes 75 # a single output to the right register. In practice registers will 76 # usually be either initialized by primitives or copied from eax. - 77 # - var eax : int <- foo bar quux - 78 # var floo/ecx : int <- copy eax + 77 # - var eax: int <- foo bar quux + 78 # var floo/ecx: int <- copy eax 79 # 80 # Still todo: 81 # global variables @@ -450,7 +450,7 @@ if ('onhashchange' in window) { 388 b8/copy-to-eax 1/imm32/exit 389 cd/syscall 0x80/imm8 390 - 391 convert-mu: # in : (addr buffered-file), out : (addr buffered-file) + 391 convert-mu: # in: (addr buffered-file), out: (addr buffered-file) 392 # . prologue 393 55/push-ebp 394 89/<- %ebp 4/r32/esp @@ -979,11 +979,11 @@ if ('onhashchange' in window) { 962 # Parsing 963 ####################################################### 964 - 965 parse-mu: # in : (addr buffered-file) + 965 parse-mu: # in: (addr buffered-file) 966 # pseudocode - 967 # var curr-function : (addr (handle function)) = Program - 968 # var line : (stream byte 512) - 969 # var word-slice : slice + 967 # var curr-function: (addr (handle function)) = Program + 968 # var line: (stream byte 512) + 969 # var word-slice: slice 970 # while true # line loop 971 # clear-stream(line) 972 # read-line-buffered(in, line) @@ -994,8 +994,8 @@ if ('onhashchange' in window) { 977 # else if slice-starts-with?(word-slice, "#") # comment 978 # continue # end of line 979 # else if slice-equal(word-slice, "fn") - 980 # var new-function : (handle function) = allocate(function) - 981 # var vars : (stack (addr var) 256) + 980 # var new-function: (handle function) = allocate(function) + 981 # var vars: (stack (addr var) 256) 982 # populate-mu-function-header(in, new-function, vars) 983 # populate-mu-function-body(in, new-function, vars) 984 # assert(vars->top == 0) @@ -1013,19 +1013,19 @@ if ('onhashchange' in window) { 996 52/push-edx 997 53/push-ebx 998 57/push-edi - 999 # var line/ecx : (stream byte 512) + 999 # var line/ecx: (stream byte 512) 1000 81 5/subop/subtract %esp 0x200/imm32 1001 68/push 0x200/imm32/length 1002 68/push 0/imm32/read 1003 68/push 0/imm32/write 1004 89/<- %ecx 4/r32/esp -1005 # var word-slice/edx : slice +1005 # var word-slice/edx: slice 1006 68/push 0/imm32/end 1007 68/push 0/imm32/start 1008 89/<- %edx 4/r32/esp -1009 # var curr-function/edi : (addr (handle function)) = Program +1009 # var curr-function/edi: (addr (handle function)) = Program 1010 bf/copy-to-edi Program/imm32 -1011 # var vars/ebx : (stack (addr var) 256) +1011 # var vars/ebx: (stack (addr var) 256) 1012 81 5/subop/subtract %esp 0x400/imm32 1013 68/push 0x400/imm32/length 1014 68/push 0/imm32/top @@ -1057,7 +1057,7 @@ if ('onhashchange' in window) { 1045 (slice-equal? %edx "fn") 1046 3d/compare-eax-and 0/imm32 1047 0f 84/jump-if-= break/disp32 -1048 # var new-function/eax : (handle function) = populate-mu-function(in, new-function, vars) +1048 # var new-function/eax: (handle function) = populate-mu-function(in, new-function, vars) 1049 (allocate Heap *Function-size) # => eax 1050 (zero-out %eax *Function-size) 1051 (clear-stack %ebx) @@ -1118,17 +1118,17 @@ if ('onhashchange' in window) { 1106 # ✗ fn foo { } 1107 # ✗ fn foo { } { 1108 # ✗ fn foo x { -1109 # ✗ fn foo x : { -1110 # ✓ fn foo x : int { +1109 # ✗ fn foo x: { +1110 # ✓ fn foo x: int { 1111 # ✓ fn foo x: int { 1112 # ✓ fn foo x: int -> y/eax: int { -1113 populate-mu-function-header: # first-line : (addr stream byte), out : (handle function), vars : (addr stack (handle var)) +1113 populate-mu-function-header: # first-line: (addr stream byte), out: (handle function), vars: (addr stack (handle var)) 1114 # pseudocode: -1115 # var name : slice +1115 # var name: slice 1116 # next-word(first-line, name) 1117 # assert(name not in '{' '}' '->') 1118 # out->name = slice-to-string(name) -1119 # var next-offset : int = 8 +1119 # var next-offset: int = 8 1120 # ## inouts 1121 # while true 1122 # ## name @@ -1136,7 +1136,7 @@ if ('onhashchange' in window) { 1124 # if (name == '{') goto done 1125 # if (name == '->') break 1126 # assert(name != '}') -1127 # var v : (handle var) = parse-var-with-type(name, first-line) +1127 # var v: (handle var) = parse-var-with-type(name, first-line) 1128 # assert(v->register == null) 1129 # v->stack-offset = next-offset 1130 # next-offset += size-of(v) @@ -1147,7 +1147,7 @@ if ('onhashchange' in window) { 1135 # ## name 1136 # name = next-word(first-line) 1137 # assert(name not in '{' '}' '->') -1138 # var v : (handle var) = parse-var-with-type(name, first-line) +1138 # var v: (handle var) = parse-var-with-type(name, first-line) 1139 # assert(v->register != null) 1140 # out->outputs = append(out->outputs, v) 1141 # done: @@ -1163,7 +1163,7 @@ if ('onhashchange' in window) { 1151 57/push-edi 1152 # edi = out 1153 8b/-> *(ebp+0xc) 7/r32/edi -1154 # var word-slice/ecx : slice +1154 # var word-slice/ecx: slice 1155 68/push 0/imm32/end 1156 68/push 0/imm32/start 1157 89/<- %ecx 4/r32/esp @@ -1205,7 +1205,7 @@ if ('onhashchange' in window) { 1193 (slice-equal? %ecx "}") # => eax 1194 3d/compare-eax-and 0/imm32 1195 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -1196 # var v/ebx : (handle var) = parse-var-with-type(word-slice, first-line) +1196 # var v/ebx: (handle var) = parse-var-with-type(word-slice, first-line) 1197 (parse-var-with-type %ecx *(ebp+8)) # => eax 1198 89/<- %ebx 0/r32/eax 1199 # assert(v->register == null) @@ -1315,11 +1315,11 @@ if ('onhashchange' in window) { 1303 # setup 1304 (clear-stream _test-input-stream) 1305 (write _test-input-stream "foo n : int {\n") -1306 # result/ecx : function +1306 # var result/ecx: function 1307 2b/subtract-> *Function-size 4/r32/esp 1308 89/<- %ecx 4/r32/esp 1309 (zero-out %ecx *Function-size) -1310 # var vars/ebx : (stack (addr var) 16) +1310 # var vars/ebx: (stack (addr var) 16) 1311 81 5/subop/subtract %esp 0x10/imm32 1312 68/push 0x10/imm32/length 1313 68/push 0/imm32/top @@ -1328,9 +1328,9 @@ if ('onhashchange' in window) { 1316 (populate-mu-function-header _test-input-stream %ecx %ebx) 1317 # check result 1318 (check-strings-equal *ecx "foo" "F - test-function-header-with-arg/name") # Function-name -1319 # edx : (handle list var) = result->inouts +1319 # edx: (handle list var) = result->inouts 1320 8b/-> *(ecx+8) 2/r32/edx # Function-inouts -1321 # ebx : (handle var) = result->inouts->value +1321 # ebx: (handle var) = result->inouts->value 1322 8b/-> *edx 3/r32/ebx # List-value 1323 (check-strings-equal *ebx "n" "F - test-function-header-with-arg/inout:0") # Var-name 1324 8b/-> *(ebx+4) 3/r32/ebx # Var-type @@ -1349,11 +1349,11 @@ if ('onhashchange' in window) { 1337 # setup 1338 (clear-stream _test-input-stream) 1339 (write _test-input-stream "foo a: int, b: int c: int {\n") -1340 # result/ecx : (handle function) +1340 # result/ecx: (handle function) 1341 2b/subtract-> *Function-size 4/r32/esp 1342 89/<- %ecx 4/r32/esp 1343 (zero-out %ecx *Function-size) -1344 # var vars/ebx : (stack (addr var) 16) +1344 # var vars/ebx: (stack (addr var) 16) 1345 81 5/subop/subtract %esp 0x10/imm32 1346 68/push 0x10/imm32/length 1347 68/push 0/imm32/top @@ -1362,10 +1362,10 @@ if ('onhashchange' in window) { 1350 (populate-mu-function-header _test-input-stream %ecx %ebx) 1351 # check result 1352 (check-strings-equal *ecx "foo") # Function-name -1353 # edx : (handle list var) = result->inouts +1353 # edx: (handle list var) = result->inouts 1354 8b/-> *(ecx+8) 2/r32/edx # Function-inouts 1355 $test-function-header-with-multiple-args:inout0: -1356 # ebx : (handle var) = result->inouts->value +1356 # ebx: (handle var) = result->inouts->value 1357 8b/-> *edx 3/r32/ebx # List-value 1358 (check-strings-equal *ebx "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name 1359 8b/-> *(ebx+4) 3/r32/ebx # Var-type @@ -1401,12 +1401,12 @@ if ('onhashchange' in window) { 1389 89/<- %ebp 4/r32/esp 1390 # setup 1391 (clear-stream _test-input-stream) -1392 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx : int {\n") -1393 # result/ecx : (handle function) +1392 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") +1393 # result/ecx: (handle function) 1394 2b/subtract-> *Function-size 4/r32/esp 1395 89/<- %ecx 4/r32/esp 1396 (zero-out %ecx *Function-size) -1397 # var vars/ebx : (stack (addr var) 16) +1397 # var vars/ebx: (stack (addr var) 16) 1398 81 5/subop/subtract %esp 0x10/imm32 1399 68/push 0x10/imm32/length 1400 68/push 0/imm32/top @@ -1415,9 +1415,9 @@ if ('onhashchange' in window) { 1403 (populate-mu-function-header _test-input-stream %ecx %ebx) 1404 # check result 1405 (check-strings-equal *ecx "foo") # Function-name -1406 # edx : (handle list var) = result->inouts +1406 # edx: (handle list var) = result->inouts 1407 8b/-> *(ecx+8) 2/r32/edx # Function-inouts -1408 # ebx : (handle var) = result->inouts->value +1408 # ebx: (handle var) = result->inouts->value 1409 8b/-> *edx 3/r32/ebx # List-value 1410 (check-strings-equal *ebx "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") # Var-name 1411 8b/-> *(ebx+4) 3/r32/ebx # Var-type @@ -1439,9 +1439,9 @@ if ('onhashchange' in window) { 1427 8b/-> *(ebx+4) 3/r32/ebx # Var-type 1428 (check-ints-equal *ebx 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Tree-left 1429 (check-ints-equal *(ebx+4) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Tree-right -1430 # edx : (handle list var) = result->outputs +1430 # edx: (handle list var) = result->outputs 1431 8b/-> *(ecx+0xc) 2/r32/edx # Function-outputs -1432 # ebx : (handle var) = result->outputs->value +1432 # ebx: (handle var) = result->outputs->value 1433 8b/-> *edx 3/r32/ebx # List-value 1434 (check-strings-equal *ebx "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") # Var-name 1435 (check-strings-equal *(ebx+0x10) "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") # Var-register @@ -1463,16 +1463,16 @@ if ('onhashchange' in window) { 1451 c3/return 1452 1453 # format for variables with types -1454 # x : int +1454 # x: int 1455 # x: int 1456 # x: int, 1457 # ignores at most one trailing colon or comma 1458 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte) -> result/eax: (handle var) 1459 # pseudocode: -1460 # var v : (handle var) = allocate(Heap, Var-size) -1461 # var s : slice +1460 # var v: (handle var) = allocate(Heap, Var-size) +1461 # var s: slice 1462 # next-token-from-slice(name->start, name->end, '/', s) -1463 # var end : (addr byte) = s->end +1463 # var end: (addr byte) = s->end 1464 # if (slice-ends-with(s, ":")) 1465 # decrement s->end 1466 # if (slice-ends-with(s, ",")) @@ -1487,7 +1487,7 @@ if ('onhashchange' in window) { 1475 # if (!slice-empty?(s)) 1476 # v->register = slice-to-string(s) 1477 # ## type -1478 # var type : (handle tree type-id) = parse-type(first-line) +1478 # var type: (handle tree type-id) = parse-type(first-line) 1479 # v->type = type 1480 # return v 1481 # @@ -1500,13 +1500,13 @@ if ('onhashchange' in window) { 1488 53/push-ebx 1489 56/push-esi 1490 57/push-edi -1491 # var result/edi : (handle var) = allocate(Heap, Var-size) +1491 # var result/edi: (handle var) = allocate(Heap, Var-size) 1492 (allocate Heap *Var-size) # => eax 1493 (zero-out %eax *Var-size) 1494 89/<- %edi 0/r32/eax 1495 # esi = name 1496 8b/-> *(ebp+8) 6/r32/esi -1497 # var s/ecx : slice +1497 # var s/ecx: slice 1498 68/push 0/imm32/end 1499 68/push 0/imm32/start 1500 89/<- %ecx 4/r32/esp @@ -1846,7 +1846,7 @@ if ('onhashchange' in window) { 1834 # out->start = &in->data[in->read] 1835 8d/copy-address *(esi+ecx+0xc) 0/r32/eax 1836 89/<- *edi 0/r32/eax -1837 # var curr-byte/eax : byte = in->data[in->read] +1837 # var curr-byte/eax: byte = in->data[in->read] 1838 31/xor %eax 0/r32/eax 1839 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL 1840 { @@ -2088,7 +2088,7 @@ if ('onhashchange' in window) { 2076 8b/-> *eax 1/r32/ecx 2077 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2078 05/add-to-eax 4/imm32 -2079 # var slice/ecx : slice = {eax, ecx} +2079 # var slice/ecx: slice = {eax, ecx} 2080 51/push-ecx 2081 50/push-eax 2082 89/<- %ecx 4/r32/esp @@ -2116,7 +2116,7 @@ if ('onhashchange' in window) { 2104 8b/-> *eax 1/r32/ecx 2105 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2106 05/add-to-eax 4/imm32 -2107 # var slice/ecx : slice = {eax, ecx} +2107 # var slice/ecx: slice = {eax, ecx} 2108 51/push-ecx 2109 50/push-eax 2110 89/<- %ecx 4/r32/esp @@ -2146,7 +2146,7 @@ if ('onhashchange' in window) { 2134 8b/-> *eax 1/r32/ecx 2135 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2136 05/add-to-eax 4/imm32 -2137 # var slice/ecx : slice = {eax, ecx} +2137 # var slice/ecx: slice = {eax, ecx} 2138 51/push-ecx 2139 50/push-eax 2140 89/<- %ecx 4/r32/esp @@ -2176,7 +2176,7 @@ if ('onhashchange' in window) { 2164 8b/-> *eax 1/r32/ecx 2165 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2166 05/add-to-eax 4/imm32 -2167 # var slice/ecx : slice = {eax, ecx} +2167 # var slice/ecx: slice = {eax, ecx} 2168 51/push-ecx 2169 50/push-eax 2170 89/<- %ecx 4/r32/esp @@ -2206,7 +2206,7 @@ if ('onhashchange' in window) { 2194 8b/-> *eax 1/r32/ecx 2195 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2196 05/add-to-eax 4/imm32 -2197 # var slice/ecx : slice = {eax, ecx} +2197 # var slice/ecx: slice = {eax, ecx} 2198 51/push-ecx 2199 50/push-eax 2200 89/<- %ecx 4/r32/esp @@ -2238,7 +2238,7 @@ if ('onhashchange' in window) { 2226 # identifier starts with a letter or '$' or '_' 2227 # no constraints at the moment on later letters 2228 # all we really want to do so far is exclude '{', '}' and '->' -2229 is-identifier?: # in : (addr slice) -> result/eax : boolean +2229 is-identifier?: # in: (addr slice) -> result/eax: boolean 2230 # . prologue 2231 55/push-ebp 2232 89/<- %ebp 4/r32/esp @@ -2246,7 +2246,7 @@ if ('onhashchange' in window) { 2234 (slice-empty? *(ebp+8)) # => eax 2235 3d/compare-eax-and 0/imm32 2236 75/jump-if-!= $is-identifier?:false/disp8 -2237 # var c/eax : byte = *in->start +2237 # var c/eax: byte = *in->start 2238 8b/-> *(ebp+8) 0/r32/eax 2239 8b/-> *eax 0/r32/eax 2240 8a/copy-byte *eax 0/r32/AL @@ -2286,7 +2286,7 @@ if ('onhashchange' in window) { 2274 8b/-> *eax 1/r32/ecx 2275 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2276 05/add-to-eax 4/imm32 -2277 # var slice/ecx : slice = {eax, ecx} +2277 # var slice/ecx: slice = {eax, ecx} 2278 51/push-ecx 2279 50/push-eax 2280 89/<- %ecx 4/r32/esp @@ -2307,7 +2307,7 @@ if ('onhashchange' in window) { 2295 8b/-> *eax 1/r32/ecx 2296 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2297 05/add-to-eax 4/imm32 -2298 # var slice/ecx : slice = {eax, ecx} +2298 # var slice/ecx: slice = {eax, ecx} 2299 51/push-ecx 2300 50/push-eax 2301 89/<- %ecx 4/r32/esp @@ -2328,7 +2328,7 @@ if ('onhashchange' in window) { 2316 8b/-> *eax 1/r32/ecx 2317 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2318 05/add-to-eax 4/imm32 -2319 # var slice/ecx : slice = {eax, ecx} +2319 # var slice/ecx: slice = {eax, ecx} 2320 51/push-ecx 2321 50/push-eax 2322 89/<- %ecx 4/r32/esp @@ -2349,7 +2349,7 @@ if ('onhashchange' in window) { 2337 8b/-> *eax 1/r32/ecx 2338 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2339 05/add-to-eax 4/imm32 -2340 # var slice/ecx : slice = {eax, ecx} +2340 # var slice/ecx: slice = {eax, ecx} 2341 51/push-ecx 2342 50/push-eax 2343 89/<- %ecx 4/r32/esp @@ -2370,7 +2370,7 @@ if ('onhashchange' in window) { 2358 8b/-> *eax 1/r32/ecx 2359 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2360 05/add-to-eax 4/imm32 -2361 # var slice/ecx : slice = {eax, ecx} +2361 # var slice/ecx: slice = {eax, ecx} 2362 51/push-ecx 2363 50/push-eax 2364 89/<- %ecx 4/r32/esp @@ -2391,7 +2391,7 @@ if ('onhashchange' in window) { 2379 8b/-> *eax 1/r32/ecx 2380 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2381 05/add-to-eax 4/imm32 -2382 # var slice/ecx : slice = {eax, ecx} +2382 # var slice/ecx: slice = {eax, ecx} 2383 51/push-ecx 2384 50/push-eax 2385 89/<- %ecx 4/r32/esp @@ -2413,7 +2413,7 @@ if ('onhashchange' in window) { 2401 8b/-> *eax 1/r32/ecx 2402 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2403 05/add-to-eax 4/imm32 -2404 # var slice/ecx : slice = {eax, ecx} +2404 # var slice/ecx: slice = {eax, ecx} 2405 51/push-ecx 2406 50/push-eax 2407 89/<- %ecx 4/r32/esp @@ -2435,7 +2435,7 @@ if ('onhashchange' in window) { 2423 8b/-> *eax 1/r32/ecx 2424 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2425 05/add-to-eax 4/imm32 -2426 # var slice/ecx : slice = {eax, ecx} +2426 # var slice/ecx: slice = {eax, ecx} 2427 51/push-ecx 2428 50/push-eax 2429 89/<- %ecx 4/r32/esp @@ -2457,7 +2457,7 @@ if ('onhashchange' in window) { 2445 8b/-> *eax 1/r32/ecx 2446 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2447 05/add-to-eax 4/imm32 -2448 # var slice/ecx : slice = {eax, ecx} +2448 # var slice/ecx: slice = {eax, ecx} 2449 51/push-ecx 2450 50/push-eax 2451 89/<- %ecx 4/r32/esp @@ -2479,7 +2479,7 @@ if ('onhashchange' in window) { 2467 8b/-> *eax 1/r32/ecx 2468 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2469 05/add-to-eax 4/imm32 -2470 # var slice/ecx : slice = {eax, ecx} +2470 # var slice/ecx: slice = {eax, ecx} 2471 51/push-ecx 2472 50/push-eax 2473 89/<- %ecx 4/r32/esp @@ -2500,7 +2500,7 @@ if ('onhashchange' in window) { 2488 8b/-> *eax 1/r32/ecx 2489 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2490 05/add-to-eax 4/imm32 -2491 # var slice/ecx : slice = {eax, ecx} +2491 # var slice/ecx: slice = {eax, ecx} 2492 51/push-ecx 2493 50/push-eax 2494 89/<- %ecx 4/r32/esp @@ -2522,7 +2522,7 @@ if ('onhashchange' in window) { 2510 8b/-> *eax 1/r32/ecx 2511 8d/copy-address *(eax+ecx+4) 1/r32/ecx 2512 05/add-to-eax 4/imm32 -2513 # var slice/ecx : slice = {eax, ecx} +2513 # var slice/ecx: slice = {eax, ecx} 2514 51/push-ecx 2515 50/push-eax 2516 89/<- %ecx 4/r32/esp @@ -2534,7 +2534,7 @@ if ('onhashchange' in window) { 2522 5d/pop-to-ebp 2523 c3/return 2524 -2525 populate-mu-function-body: # in : (addr buffered-file), out : (handle function), vars : (addr stack (handle var)) +2525 populate-mu-function-body: # in: (addr buffered-file), out: (handle function), vars: (addr stack (handle var)) 2526 # . prologue 2527 55/push-ebp 2528 89/<- %ebp 4/r32/esp @@ -2546,7 +2546,7 @@ if ('onhashchange' in window) { 2534 8b/-> *(ebp+8) 6/r32/esi 2535 # edi = out 2536 8b/-> *(ebp+0xc) 7/r32/edi -2537 # var eax : (handle block) = parse-mu-block(in, vars) +2537 # var eax: (handle block) = parse-mu-block(in, vars) 2538 (parse-mu-block %esi *(ebp+0x10) %edi) # => eax 2539 # out->body = eax 2540 89/<- *(edi+0x10) 0/r32/eax # Function-body @@ -2561,10 +2561,10 @@ if ('onhashchange' in window) { 2549 c3/return 2550 2551 # parses a block, assuming that the leading '{' has already been read by the caller -2552 parse-mu-block: # in : (addr buffered-file), vars : (addr stack (handle var)), fn : (handle function) -> result/eax : (handle block) +2552 parse-mu-block: # in: (addr buffered-file), vars: (addr stack (handle var)), fn: (handle function) -> result/eax: (handle block) 2553 # pseudocode: -2554 # var line : (stream byte 512) -2555 # var word-slice : slice +2554 # var line: (stream byte 512) +2555 # var word-slice: slice 2556 # result/eax = allocate(Heap, Stmt-size) 2557 # result->tag = 0/Block 2558 # while true # line loop @@ -2601,13 +2601,13 @@ if ('onhashchange' in window) { 2589 52/push-edx 2590 53/push-ebx 2591 57/push-edi -2592 # var line/ecx : (stream byte 512) +2592 # var line/ecx: (stream byte 512) 2593 81 5/subop/subtract %esp 0x200/imm32 2594 68/push 0x200/imm32/length 2595 68/push 0/imm32/read 2596 68/push 0/imm32/write 2597 89/<- %ecx 4/r32/esp -2598 # var word-slice/edx : slice +2598 # var word-slice/edx: slice 2599 68/push 0/imm32/end 2600 68/push 0/imm32/start 2601 89/<- %edx 4/r32/esp @@ -2722,14 +2722,14 @@ if ('onhashchange' in window) { 2710 cd/syscall 0x80/imm8 2711 # never gets here 2712 -2713 check-no-tokens-left: # line : (addr stream byte) +2713 check-no-tokens-left: # line: (addr stream byte) 2714 # . prologue 2715 55/push-ebp 2716 89/<- %ebp 4/r32/esp 2717 # . save registers 2718 50/push-eax 2719 51/push-ecx -2720 # var s/ecx : slice +2720 # var s/ecx: slice 2721 68/push 0/imm32/end 2722 68/push 0/imm32/start 2723 89/<- %ecx 4/r32/esp @@ -2769,10 +2769,10 @@ if ('onhashchange' in window) { 2757 5d/pop-to-ebp 2758 c3/return 2759 -2760 parse-mu-named-block: # name : (addr slice), first-line : (addr stream byte), in : (addr buffered-file), vars : (addr stack (handle var)) -> result/eax : (handle stmt) +2760 parse-mu-named-block: # name: (addr slice), first-line: (addr stream byte), in: (addr buffered-file), vars: (addr stack (handle var)) -> result/eax: (handle stmt) 2761 # pseudocode: -2762 # var line : (stream byte 512) -2763 # var word-slice : slice +2762 # var line: (stream byte 512) +2763 # var word-slice: slice 2764 # result/eax = allocate(Heap, Stmt-size) 2765 # result->tag = 4/Named-block 2766 # result->name = name @@ -2813,7 +2813,7 @@ if ('onhashchange' in window) { 2801 5d/pop-to-ebp 2802 c3/return 2803 -2804 parse-mu-var-def: # line : (addr stream byte), vars : (addr stack (handle var)) -> result/eax : (handle stmt) +2804 parse-mu-var-def: # line: (addr stream byte), vars: (addr stack (handle var)) -> result/eax: (handle stmt) 2805 # pseudocode: 2806 # 2807 # . prologue @@ -2822,11 +2822,11 @@ if ('onhashchange' in window) { 2810 # . save registers 2811 51/push-ecx 2812 52/push-edx -2813 # var word-slice/ecx : slice +2813 # var word-slice/ecx: slice 2814 68/push 0/imm32/end 2815 68/push 0/imm32/start 2816 89/<- %ecx 4/r32/esp -2817 # var v/edx : (handle var) = parse-var-with-type(line) +2817 # var v/edx: (handle var) = parse-var-with-type(line) 2818 (next-word *(ebp+8) %ecx) 2819 (parse-var-with-type %ecx *(ebp+8)) # => eax 2820 89/<- %edx 0/r32/eax @@ -2884,7 +2884,7 @@ if ('onhashchange' in window) { 2872 # setup 2873 (clear-stream _test-input-stream) 2874 (write _test-input-stream "n: int\n") # caller has consumed the 'var' -2875 # var vars/ecx : (stack (addr var) 4) +2875 # var vars/ecx: (stack (addr var) 4) 2876 81 5/subop/subtract %esp 0x10/imm32 2877 68/push 0x10/imm32/length 2878 68/push 0/imm32/top @@ -2916,7 +2916,7 @@ if ('onhashchange' in window) { 2904 # setup 2905 (clear-stream _test-input-stream) 2906 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' -2907 # var vars/ecx : (stack (addr var) 4) +2907 # var vars/ecx: (stack (addr var) 4) 2908 81 5/subop/subtract %esp 0x10/imm32 2909 68/push 0x10/imm32/length 2910 68/push 0/imm32/top @@ -2940,16 +2940,16 @@ if ('onhashchange' in window) { 2928 5d/pop-to-ebp 2929 c3/return 2930 -2931 parse-mu-stmt: # line : (addr stream byte), vars : (addr stack (handle var)), fn : (handle function) -> result/eax : (handle stmt) +2931 parse-mu-stmt: # line: (addr stream byte), vars: (addr stack (handle var)), fn: (handle function) -> result/eax: (handle stmt) 2932 # pseudocode: -2933 # var name : slice +2933 # var name: slice 2934 # result = allocate(Heap, Stmt-size) 2935 # if stmt-has-outputs?(line) 2936 # while true 2937 # name = next-word(line) 2938 # if (name == '<-') break 2939 # assert(is-identifier?(name)) -2940 # var v : (handle var) = lookup-or-define-var(name, vars, fn) # regular stmts may define vars in fn outputs +2940 # var v: (handle var) = lookup-or-define-var(name, vars, fn) # regular stmts may define vars in fn outputs 2941 # result->outputs = append(result->outputs, v) 2942 # add-operation-and-inputs-to-stmt(result, line, vars) 2943 # @@ -2959,11 +2959,11 @@ if ('onhashchange' in window) { 2947 # . save registers 2948 51/push-ecx 2949 57/push-edi -2950 # var name/ecx : slice +2950 # var name/ecx: slice 2951 68/push 0/imm32/end 2952 68/push 0/imm32/start 2953 89/<- %ecx 4/r32/esp -2954 # result/edi : (handle stmt) +2954 # result/edi: (handle stmt) 2955 (allocate Heap *Stmt-size) # => eax 2956 (zero-out %eax *Stmt-size) 2957 89/<- %edi 0/r32/eax @@ -3022,7 +3022,7 @@ if ('onhashchange' in window) { 3010 cd/syscall 0x80/imm8 3011 # never gets here 3012 -3013 add-operation-and-inputs-to-stmt: # stmt : (handle stmt), line : (addr stream byte) +3013 add-operation-and-inputs-to-stmt: # stmt: (handle stmt), line: (addr stream byte) 3014 # pseudocode: 3015 # stmt->name = slice-to-string(next-word(line)) 3016 # while true @@ -3039,7 +3039,7 @@ if ('onhashchange' in window) { 3027 57/push-edi 3028 # edi = stmt 3029 8b/-> *(ebp+8) 7/r32/edi -3030 # var name/ecx : slice +3030 # var name/ecx: slice 3031 68/push 0/imm32/end 3032 68/push 0/imm32/start 3033 89/<- %ecx 4/r32/esp @@ -3091,13 +3091,13 @@ if ('onhashchange' in window) { 3079 cd/syscall 0x80/imm8 3080 # never gets here 3081 -3082 stmt-has-outputs?: # line : (addr stream byte) -> result/eax : boolean +3082 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean 3083 # . prologue 3084 55/push-ebp 3085 89/<- %ebp 4/r32/esp 3086 # . save registers 3087 51/push-ecx -3088 # var word-slice/ecx : slice +3088 # var word-slice/ecx: slice 3089 68/push 0/imm32/end 3090 68/push 0/imm32/start 3091 89/<- %ecx 4/r32/esp @@ -3139,7 +3139,7 @@ if ('onhashchange' in window) { 3127 3128 # if 'name' starts with a digit, create a new literal var for it 3129 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found -3130 lookup-var-or-literal: # name: (addr slice), vars : (addr stack (handle var)) -> result/eax: (handle var) +3130 lookup-var-or-literal: # name: (addr slice), vars: (addr stack (handle var)) -> result/eax: (handle var) 3131 # . prologue 3132 55/push-ebp 3133 89/<- %ebp 4/r32/esp @@ -3152,7 +3152,7 @@ if ('onhashchange' in window) { 3140 (slice-empty? %esi) # => eax 3141 3d/compare-eax-and 0/imm32 3142 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 -3143 # var ecx : byte = *name->start +3143 # var ecx: byte = *name->start 3144 8b/-> *esi 1/r32/ecx 3145 8a/copy-byte *ecx 1/r32/CL 3146 81 4/subop/and %ecx 0xff/imm32 @@ -3187,11 +3187,11 @@ if ('onhashchange' in window) { 3175 # never gets here 3176 3177 # return first 'name' from the top (back) of 'vars' and abort if not found -3178 lookup-var: # name: (addr slice), vars : (addr stack (handle var)) -> result/eax: (handle var) +3178 lookup-var: # name: (addr slice), vars: (addr stack (handle var)) -> result/eax: (handle var) 3179 # . prologue 3180 55/push-ebp 3181 89/<- %ebp 4/r32/esp -3182 # var target/eax : (handle array byte) = slice-to-string(name) +3182 # var target/eax: (handle array byte) = slice-to-string(name) 3183 (slice-to-string Heap *(ebp+8)) # => eax 3184 # 3185 (lookup-var-helper %eax *(ebp+0xc)) # => eax @@ -3216,12 +3216,12 @@ if ('onhashchange' in window) { 3204 # never gets here 3205 3206 # return first 'name' from the top (back) of 'vars', and 0/null if not found -3207 lookup-var-helper: # name: (addr array byte), vars : (addr stack (handle var)) -> result/eax: (handle var) +3207 lookup-var-helper: # name: (addr array byte), vars: (addr stack (handle var)) -> result/eax: (handle var) 3208 # pseudocode: -3209 # var curr : (addr handle var) = &vars->data[vars->top - 4] +3209 # var curr: (addr handle var) = &vars->data[vars->top - 4] 3210 # var min = vars->data 3211 # while curr >= min -3212 # var v : (handle var) = *curr +3212 # var v: (handle var) = *curr 3213 # if v->name == name 3214 # return v 3215 # return 0 @@ -3240,9 +3240,9 @@ if ('onhashchange' in window) { 3228 # if (vars->top > vars->length) abort 3229 3b/compare 0/r32/eax *(esi+4) 3230 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 -3231 # var min/edx : (addr handle var) = vars->data +3231 # var min/edx: (addr handle var) = vars->data 3232 8d/copy-address *(esi+8) 2/r32/edx -3233 # var curr/ebx : (addr handle var) = &vars->data[vars->top - 4] +3233 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 4] 3234 81 5/subop/subtract %ebx 4/imm32 3235 8d/copy-address *(esi+ebx+8) 3/r32/ebx 3236 { @@ -3250,7 +3250,7 @@ if ('onhashchange' in window) { 3238 39/compare %ebx 2/r32/edx 3239 b8/copy-to-eax 0/imm32 3240 0f 82/jump-if-addr< break/disp32 -3241 # var v/eax : (handle var) = *curr +3241 # var v/eax: (handle var) = *curr 3242 8b/-> *ebx 0/r32/eax 3243 # if (v->name == name) return v 3244 (string-equal? *eax *(ebp+8)) # Var-name @@ -3283,13 +3283,13 @@ if ('onhashchange' in window) { 3271 # never gets here 3272 3273 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found -3274 lookup-or-define-var: # name: (addr slice), vars : (addr stack (handle var)), fn : (handle function) -> result/eax: (handle var) +3274 lookup-or-define-var: # name: (addr slice), vars: (addr stack (handle var)), fn: (handle function) -> result/eax: (handle var) 3275 # . prologue 3276 55/push-ebp 3277 89/<- %ebp 4/r32/esp 3278 # . save registers 3279 51/push-ecx -3280 # var target/ecx : (handle array byte) = slice-to-string(name) +3280 # var target/ecx: (handle array byte) = slice-to-string(name) 3281 (slice-to-string Heap *(ebp+8)) # => eax 3282 89/<- %ecx 0/r32/eax 3283 # @@ -3314,20 +3314,20 @@ if ('onhashchange' in window) { 3302 5d/pop-to-ebp 3303 c3/return 3304 -3305 find-in-function-outputs: # fn : (handle function), name : (handle array byte) => result/eax : (handle var) +3305 find-in-function-outputs: # fn: (handle function), name: (handle array byte) => result/eax: (handle var) 3306 # . prologue 3307 55/push-ebp 3308 89/<- %ebp 4/r32/esp 3309 # . save registers 3310 51/push-ecx -3311 # var curr/ecx : (handle list var) = fn->outputs +3311 # var curr/ecx: (handle list var) = fn->outputs 3312 8b/-> *(ebp+8) 1/r32/ecx 3313 8b/-> *(ecx+0xc) 1/r32/ecx 3314 # while curr != null 3315 { 3316 81 7/subop/compare %ecx 0/imm32 3317 74/jump-if-= break/disp8 -3318 # var v : (handle var) = *curr +3318 # var v: (handle var) = *curr 3319 8b/-> *ecx 0/r32/eax # List-value 3320 # if (curr->name == name) return curr 3321 50/push-eax @@ -3356,13 +3356,13 @@ if ('onhashchange' in window) { 3344 # setup 3345 (clear-stream _test-input-stream) 3346 (write _test-input-stream "increment n\n") -3347 # var vars/ecx : (stack (addr var) 4) +3347 # var vars/ecx: (stack (addr var) 4) 3348 81 5/subop/subtract %esp 0x10/imm32 3349 68/push 0x10/imm32/length 3350 68/push 0/imm32/top 3351 89/<- %ecx 4/r32/esp 3352 (clear-stack %ecx) -3353 # var v/edx : var +3353 # var v/edx: var 3354 81 5/subop/subtract %esp 0x14/imm32 # Var-size 3355 89/<- %edx 4/r32/esp 3356 (zero-out %edx 0x14) @@ -3375,9 +3375,9 @@ if ('onhashchange' in window) { 3363 # check result 3364 (check-ints-equal *eax 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 3365 (check-strings-equal *(eax+4) "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation -3366 # edx : (handle list var) = result->inouts +3366 # edx: (handle list var) = result->inouts 3367 8b/-> *(eax+8) 2/r32/edx # Stmt1-inouts -3368 # ebx : (handle var) = result->inouts->value +3368 # ebx: (handle var) = result->inouts->value 3369 8b/-> *edx 3/r32/ebx # List-value 3370 (check-strings-equal *ebx "n" "F - test-parse-mu-stmt/inout:0") # Var-name 3371 # . epilogue @@ -3449,7 +3449,7 @@ if ('onhashchange' in window) { 3437 (is-hex-int? *(ebp+0xc)) # => eax 3438 3d/compare-eax-and 0/imm32 3439 0f 84/jump-if-= $new-literal-integer:abort/disp32 -3440 # var s/ecx : (addr array byte) +3440 # var s/ecx: (addr array byte) 3441 (slice-to-string Heap *(ebp+0xc)) # => eax 3442 89/<- %ecx 0/r32/eax 3443 # @@ -3564,7 +3564,7 @@ if ('onhashchange' in window) { 3552 5d/pop-to-ebp 3553 c3/return 3554 -3555 new-list: # ad: (addr allocation-descriptor), value: _type, next: (handle list _type) -> result/eax : (handle list _type) +3555 new-list: # ad: (addr allocation-descriptor), value: _type, next: (handle list _type) -> result/eax: (handle list _type) 3556 # . prologue 3557 55/push-ebp 3558 89/<- %ebp 4/r32/esp @@ -3584,7 +3584,7 @@ if ('onhashchange' in window) { 3572 5d/pop-to-ebp 3573 c3/return 3574 -3575 append-list: # ad: (addr allocation-descriptor), value: _type, list: (handle list _type) -> result/eax : (handle list _type) +3575 append-list: # ad: (addr allocation-descriptor), value: _type, list: (handle list _type) -> result/eax: (handle list _type) 3576 # . prologue 3577 55/push-ebp 3578 89/<- %ebp 4/r32/esp @@ -3653,7 +3653,7 @@ if ('onhashchange' in window) { 3641 5d/pop-to-ebp 3642 c3/return 3643 -3644 size-of: # n : (addr var) +3644 size-of: # n: (addr var) 3645 # . prologue 3646 55/push-ebp 3647 89/<- %ebp 4/r32/esp @@ -3669,7 +3669,7 @@ if ('onhashchange' in window) { 3657 # Code-generation 3658 ####################################################### 3659 -3660 emit-subx: # out : (addr buffered-file) +3660 emit-subx: # out: (addr buffered-file) 3661 # . prologue 3662 55/push-ebp 3663 89/<- %ebp 4/r32/esp @@ -3679,7 +3679,7 @@ if ('onhashchange' in window) { 3667 57/push-edi 3668 # edi = out 3669 8b/-> *(ebp+8) 7/r32/edi -3670 # var curr/ecx : (handle function) = *Program +3670 # var curr/ecx: (handle function) = *Program 3671 8b/-> *Program 1/r32/ecx 3672 { 3673 # if (curr == null) break @@ -3700,7 +3700,7 @@ if ('onhashchange' in window) { 3688 5d/pop-to-ebp 3689 c3/return 3690 -3691 emit-subx-function: # out : (addr buffered-file), f : (handle function) +3691 emit-subx-function: # out: (addr buffered-file), f: (handle function) 3692 # . prologue 3693 55/push-ebp 3694 89/<- %ebp 4/r32/esp @@ -3715,9 +3715,9 @@ if ('onhashchange' in window) { 3703 # 3704 (write-buffered %edi *ecx) 3705 (write-buffered %edi ":\n") -3706 (emit-subx-prologue %edi) +3706 (emit-subx-prologue %edi) 3707 (emit-subx-block %edi *(ecx+0x10)) # Function-body -3708 (emit-subx-epilogue %edi) +3708 (emit-subx-epilogue %edi) 3709 $emit-subx-function:end: 3710 # . restore registers 3711 5f/pop-to-edi @@ -3728,1183 +3728,1183 @@ if ('onhashchange' in window) { 3716 5d/pop-to-ebp 3717 c3/return 3718 -3719 emit-subx-block: # out : (addr buffered-file), block : (handle block) +3719 emit-subx-block: # out: (addr buffered-file), block: (handle block) 3720 # . prologue 3721 55/push-ebp 3722 89/<- %ebp 4/r32/esp -3723 # curr/esi : (handle list statement) = block->statements -3724 8b/-> *(ebp+0xc) 6/r32/esi -3725 8b/-> *(esi+4) 6/r32/esi # Block-statements -3726 # -3727 { -3728 $emit-subx-block:check-empty: -3729 81 7/subop/compare %esi 0/imm32 -3730 0f 84/jump-if-= break/disp32 -3731 (write-buffered *(ebp+8) "{\n") -3732 { -3733 $emit-subx-block:stmt: -3734 81 7/subop/compare %esi 0/imm32 -3735 74/jump-if-= break/disp8 -3736 (emit-subx-statement *(ebp+8) *esi Primitives *Program) -3737 (write-buffered *(ebp+8) Newline) -3738 8b/-> *(esi+4) 6/r32/esi # List-next -3739 eb/jump loop/disp8 -3740 } -3741 (write-buffered *(ebp+8) "}\n") -3742 } -3743 $emit-subx-block:end: -3744 # . epilogue -3745 89/<- %esp 5/r32/ebp -3746 5d/pop-to-ebp -3747 c3/return -3748 -3749 emit-subx-statement: # out : (addr buffered-file), stmt : (handle statement), primitives : (handle primitive), functions : (handle function) -3750 # . prologue -3751 55/push-ebp -3752 89/<- %ebp 4/r32/esp -3753 # . save registers -3754 50/push-eax -3755 51/push-ecx -3756 # if stmt matches a primitive, emit it -3757 { -3758 $emit-subx-statement:primitive: -3759 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => curr/eax -3760 3d/compare-eax-and 0/imm32 -3761 74/jump-if-= break/disp8 -3762 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr -3763 e9/jump $emit-subx-statement:end/disp32 -3764 } -3765 # else if stmt matches a function, emit a call to it -3766 { -3767 $emit-subx-statement:call: -3768 (find-matching-function *(ebp+0x14) *(ebp+0xc)) # functions, stmt => curr/eax -3769 3d/compare-eax-and 0/imm32 -3770 74/jump-if-= break/disp8 -3771 (emit-subx-call *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr -3772 e9/jump $emit-subx-statement:end/disp32 -3773 } -3774 # else abort -3775 e9/jump $emit-subx-statement:abort/disp32 -3776 $emit-subx-statement:end: -3777 # . restore registers -3778 59/pop-to-ecx -3779 58/pop-to-eax -3780 # . epilogue -3781 89/<- %esp 5/r32/ebp -3782 5d/pop-to-ebp -3783 c3/return -3784 -3785 $emit-subx-statement:abort: -3786 # error("couldn't translate '" stmt "'\n") -3787 (write-buffered Stderr "couldn't translate '") -3788 #? (emit-string Stderr *(ebp+0xc)) # TODO -3789 (write-buffered Stderr "'\n") -3790 (flush Stderr) -3791 # . syscall(exit, 1) -3792 bb/copy-to-ebx 1/imm32 -3793 b8/copy-to-eax 1/imm32/exit -3794 cd/syscall 0x80/imm8 -3795 # never gets here -3796 -3797 # Primitives supported -3798 # For each operation, put variants with hard-coded registers before flexible ones. -3799 == data -3800 Primitives: -3801 # - increment/decrement -3802 _Primitive-inc-eax: -3803 # var/eax <- increment => 40/increment-eax -3804 "increment"/imm32/name -3805 0/imm32/no-inouts -3806 Single-int-var-in-eax/imm32/outputs -3807 "40/increment-eax"/imm32/subx-name -3808 0/imm32/no-rm32 -3809 0/imm32/no-r32 -3810 0/imm32/no-imm32 -3811 0/imm32/output-is-write-only -3812 _Primitive-inc-ecx/imm32/next -3813 _Primitive-inc-ecx: -3814 # var/ecx <- increment => 41/increment-ecx -3815 "increment"/imm32/name -3816 0/imm32/no-inouts -3817 Single-int-var-in-ecx/imm32/outputs -3818 "41/increment-ecx"/imm32/subx-name -3819 0/imm32/no-rm32 -3820 0/imm32/no-r32 -3821 0/imm32/no-imm32 -3822 0/imm32/output-is-write-only -3823 _Primitive-inc-edx/imm32/next -3824 _Primitive-inc-edx: -3825 # var/edx <- increment => 42/increment-edx -3826 "increment"/imm32/name -3827 0/imm32/no-inouts -3828 Single-int-var-in-edx/imm32/outputs -3829 "42/increment-edx"/imm32/subx-name -3830 0/imm32/no-rm32 -3831 0/imm32/no-r32 -3832 0/imm32/no-imm32 -3833 0/imm32/output-is-write-only -3834 _Primitive-inc-ebx/imm32/next -3835 _Primitive-inc-ebx: -3836 # var/ebx <- increment => 43/increment-ebx -3837 "increment"/imm32/name -3838 0/imm32/no-inouts -3839 Single-int-var-in-ebx/imm32/outputs -3840 "43/increment-ebx"/imm32/subx-name -3841 0/imm32/no-rm32 -3842 0/imm32/no-r32 -3843 0/imm32/no-imm32 -3844 0/imm32/output-is-write-only -3845 _Primitive-inc-esi/imm32/next -3846 _Primitive-inc-esi: -3847 # var/esi <- increment => 46/increment-esi -3848 "increment"/imm32/name -3849 0/imm32/no-inouts -3850 Single-int-var-in-esi/imm32/outputs -3851 "46/increment-esi"/imm32/subx-name -3852 0/imm32/no-rm32 -3853 0/imm32/no-r32 -3854 0/imm32/no-imm32 -3855 0/imm32/output-is-write-only -3856 _Primitive-inc-edi/imm32/next -3857 _Primitive-inc-edi: -3858 # var/edi <- increment => 47/increment-edi -3859 "increment"/imm32/name -3860 0/imm32/no-inouts -3861 Single-int-var-in-edi/imm32/outputs -3862 "47/increment-edi"/imm32/subx-name -3863 0/imm32/no-rm32 -3864 0/imm32/no-r32 -3865 0/imm32/no-imm32 -3866 0/imm32/output-is-write-only -3867 _Primitive-dec-eax/imm32/next -3868 _Primitive-dec-eax: -3869 # var/eax <- decrement => 48/decrement-eax -3870 "decrement"/imm32/name -3871 0/imm32/no-inouts -3872 Single-int-var-in-eax/imm32/outputs -3873 "48/decrement-eax"/imm32/subx-name -3874 0/imm32/no-rm32 -3875 0/imm32/no-r32 -3876 0/imm32/no-imm32 -3877 0/imm32/output-is-write-only -3878 _Primitive-dec-ecx/imm32/next -3879 _Primitive-dec-ecx: -3880 # var/ecx <- decrement => 49/decrement-ecx -3881 "decrement"/imm32/name -3882 0/imm32/no-inouts -3883 Single-int-var-in-ecx/imm32/outputs -3884 "49/decrement-ecx"/imm32/subx-name -3885 0/imm32/no-rm32 -3886 0/imm32/no-r32 -3887 0/imm32/no-imm32 -3888 0/imm32/output-is-write-only -3889 _Primitive-dec-edx/imm32/next -3890 _Primitive-dec-edx: -3891 # var/edx <- decrement => 4a/decrement-edx -3892 "decrement"/imm32/name -3893 0/imm32/no-inouts -3894 Single-int-var-in-edx/imm32/outputs -3895 "4a/decrement-edx"/imm32/subx-name -3896 0/imm32/no-rm32 -3897 0/imm32/no-r32 -3898 0/imm32/no-imm32 -3899 0/imm32/output-is-write-only -3900 _Primitive-dec-ebx/imm32/next -3901 _Primitive-dec-ebx: -3902 # var/ebx <- decrement => 4b/decrement-ebx -3903 "decrement"/imm32/name -3904 0/imm32/no-inouts -3905 Single-int-var-in-ebx/imm32/outputs -3906 "4b/decrement-ebx"/imm32/subx-name -3907 0/imm32/no-rm32 -3908 0/imm32/no-r32 -3909 0/imm32/no-imm32 -3910 0/imm32/output-is-write-only -3911 _Primitive-dec-esi/imm32/next -3912 _Primitive-dec-esi: -3913 # var/esi <- decrement => 4e/decrement-esi -3914 "decrement"/imm32/name -3915 0/imm32/no-inouts -3916 Single-int-var-in-esi/imm32/outputs -3917 "4e/decrement-esi"/imm32/subx-name -3918 0/imm32/no-rm32 -3919 0/imm32/no-r32 -3920 0/imm32/no-imm32 -3921 0/imm32/output-is-write-only -3922 _Primitive-dec-edi/imm32/next -3923 _Primitive-dec-edi: -3924 # var/edi <- decrement => 4f/decrement-edi -3925 "decrement"/imm32/name -3926 0/imm32/no-inouts -3927 Single-int-var-in-edi/imm32/outputs -3928 "4f/decrement-edi"/imm32/subx-name -3929 0/imm32/no-rm32 -3930 0/imm32/no-r32 -3931 0/imm32/no-imm32 -3932 0/imm32/output-is-write-only -3933 _Primitive-inc-mem/imm32/next -3934 _Primitive-inc-mem: -3935 # increment var => ff 0/subop/increment *(ebp+__) -3936 "increment"/imm32/name -3937 Single-int-var-on-stack/imm32/inouts -3938 0/imm32/no-outputs -3939 "ff 0/subop/increment"/imm32/subx-name -3940 1/imm32/rm32-is-first-inout -3941 0/imm32/no-r32 -3942 0/imm32/no-imm32 -3943 0/imm32/output-is-write-only -3944 _Primitive-inc-reg/imm32/next -3945 _Primitive-inc-reg: -3946 # var/reg <- increment => ff 0/subop/increment %__ -3947 "increment"/imm32/name -3948 0/imm32/no-inouts -3949 Single-int-var-in-some-register/imm32/outputs -3950 "ff 0/subop/increment"/imm32/subx-name -3951 3/imm32/rm32-is-first-output -3952 0/imm32/no-r32 -3953 0/imm32/no-imm32 -3954 0/imm32/output-is-write-only -3955 _Primitive-dec-mem/imm32/next -3956 _Primitive-dec-mem: -3957 # decrement var => ff 1/subop/decrement *(ebp+__) -3958 "decrement"/imm32/name -3959 Single-int-var-on-stack/imm32/inouts -3960 0/imm32/no-outputs -3961 "ff 1/subop/decrement"/imm32/subx-name -3962 1/imm32/rm32-is-first-inout -3963 0/imm32/no-r32 -3964 0/imm32/no-imm32 -3965 0/imm32/output-is-write-only -3966 _Primitive-dec-reg/imm32/next -3967 _Primitive-dec-reg: -3968 # var/reg <- decrement => ff 1/subop/decrement %__ -3969 "decrement"/imm32/name -3970 0/imm32/no-inouts -3971 Single-int-var-in-some-register/imm32/outputs -3972 "ff 1/subop/decrement"/imm32/subx-name -3973 3/imm32/rm32-is-first-output -3974 0/imm32/no-r32 -3975 0/imm32/no-imm32 -3976 0/imm32/output-is-write-only -3977 _Primitive-add-to-eax/imm32/next -3978 # - add -3979 _Primitive-add-to-eax: -3980 # var/eax <- add lit => 05/add-to-eax lit/imm32 -3981 "add"/imm32/name -3982 Single-lit-var/imm32/inouts -3983 Single-int-var-in-eax/imm32/outputs -3984 "05/add-to-eax"/imm32/subx-name -3985 0/imm32/no-rm32 -3986 0/imm32/no-r32 -3987 1/imm32/imm32-is-first-inout -3988 0/imm32/output-is-write-only -3989 _Primitive-add-reg-to-reg/imm32/next -3990 _Primitive-add-reg-to-reg: -3991 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 -3992 "add"/imm32/name -3993 Single-int-var-in-some-register/imm32/inouts -3994 Single-int-var-in-some-register/imm32/outputs -3995 "01/add-to"/imm32/subx-name -3996 3/imm32/rm32-is-first-output -3997 1/imm32/r32-is-first-inout -3998 0/imm32/no-imm32 -3999 0/imm32/output-is-write-only -4000 _Primitive-add-reg-to-mem/imm32/next -4001 _Primitive-add-reg-to-mem: -4002 # add-to var1 var2/reg => 01/add-to var1 var2/r32 -4003 "add-to"/imm32/name -4004 Int-var-and-second-int-var-in-some-register/imm32/inouts -4005 0/imm32/outputs -4006 "01/add-to"/imm32/subx-name -4007 1/imm32/rm32-is-first-inout -4008 2/imm32/r32-is-second-inout -4009 0/imm32/no-imm32 -4010 0/imm32/output-is-write-only -4011 _Primitive-add-mem-to-reg/imm32/next -4012 _Primitive-add-mem-to-reg: -4013 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 -4014 "add"/imm32/name -4015 Single-int-var-on-stack/imm32/inouts -4016 Single-int-var-in-some-register/imm32/outputs -4017 "03/add"/imm32/subx-name -4018 1/imm32/rm32-is-first-inout -4019 3/imm32/r32-is-first-output -4020 0/imm32/no-imm32 -4021 0/imm32/output-is-write-only -4022 _Primitive-add-lit-to-reg/imm32/next -4023 _Primitive-add-lit-to-reg: -4024 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 -4025 "add"/imm32/name -4026 Single-lit-var/imm32/inouts -4027 Single-int-var-in-some-register/imm32/outputs -4028 "81 0/subop/add"/imm32/subx-name -4029 3/imm32/rm32-is-first-output -4030 0/imm32/no-r32 -4031 1/imm32/imm32-is-first-inout -4032 0/imm32/output-is-write-only -4033 _Primitive-add-lit-to-mem/imm32/next -4034 _Primitive-add-lit-to-mem: -4035 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 -4036 "add-to"/imm32/name -4037 Int-var-and-literal/imm32/inouts -4038 0/imm32/outputs -4039 "81 0/subop/add"/imm32/subx-name -4040 1/imm32/rm32-is-first-inout -4041 0/imm32/no-r32 -4042 2/imm32/imm32-is-first-inout -4043 0/imm32/output-is-write-only -4044 _Primitive-subtract-from-eax/imm32/next -4045 # - subtract -4046 _Primitive-subtract-from-eax: -4047 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 -4048 "subtract"/imm32/name -4049 Single-lit-var/imm32/inouts -4050 Single-int-var-in-eax/imm32/outputs -4051 "2d/subtract-from-eax"/imm32/subx-name -4052 0/imm32/no-rm32 -4053 0/imm32/no-r32 -4054 1/imm32/imm32-is-first-inout -4055 0/imm32/output-is-write-only -4056 _Primitive-subtract-reg-from-reg/imm32/next -4057 _Primitive-subtract-reg-from-reg: -4058 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 -4059 "subtract"/imm32/name -4060 Single-int-var-in-some-register/imm32/inouts -4061 Single-int-var-in-some-register/imm32/outputs -4062 "29/subtract-from"/imm32/subx-name -4063 3/imm32/rm32-is-first-output -4064 1/imm32/r32-is-first-inout -4065 0/imm32/no-imm32 -4066 0/imm32/output-is-write-only -4067 _Primitive-subtract-reg-from-mem/imm32/next -4068 _Primitive-subtract-reg-from-mem: -4069 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 -4070 "subtract-from"/imm32/name -4071 Int-var-and-second-int-var-in-some-register/imm32/inouts -4072 0/imm32/outputs -4073 "29/subtract-from"/imm32/subx-name -4074 1/imm32/rm32-is-first-inout -4075 2/imm32/r32-is-second-inout -4076 0/imm32/no-imm32 -4077 0/imm32/output-is-write-only -4078 _Primitive-subtract-mem-from-reg/imm32/next -4079 _Primitive-subtract-mem-from-reg: -4080 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 -4081 "subtract"/imm32/name -4082 Single-int-var-on-stack/imm32/inouts -4083 Single-int-var-in-some-register/imm32/outputs -4084 "2b/subtract"/imm32/subx-name -4085 1/imm32/rm32-is-first-inout -4086 3/imm32/r32-is-first-output -4087 0/imm32/no-imm32 -4088 0/imm32/output-is-write-only -4089 _Primitive-subtract-lit-from-reg/imm32/next -4090 _Primitive-subtract-lit-from-reg: -4091 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 -4092 "subtract"/imm32/name -4093 Single-lit-var/imm32/inouts -4094 Single-int-var-in-some-register/imm32/outputs -4095 "81 5/subop/subtract"/imm32/subx-name -4096 3/imm32/rm32-is-first-output -4097 0/imm32/no-r32 -4098 1/imm32/imm32-is-first-inout -4099 0/imm32/output-is-write-only -4100 _Primitive-subtract-lit-from-mem/imm32/next -4101 _Primitive-subtract-lit-from-mem: -4102 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 -4103 "subtract-from"/imm32/name -4104 Int-var-and-literal/imm32/inouts -4105 0/imm32/outputs -4106 "81 5/subop/subtract"/imm32/subx-name -4107 1/imm32/rm32-is-first-inout -4108 0/imm32/no-r32 -4109 2/imm32/imm32-is-first-inout -4110 0/imm32/output-is-write-only -4111 _Primitive-and-with-eax/imm32/next -4112 # - and -4113 _Primitive-and-with-eax: -4114 # var/eax <- and lit => 25/and-with-eax lit/imm32 -4115 "and"/imm32/name -4116 Single-lit-var/imm32/inouts -4117 Single-int-var-in-eax/imm32/outputs -4118 "25/and-with-eax"/imm32/subx-name -4119 0/imm32/no-rm32 -4120 0/imm32/no-r32 -4121 1/imm32/imm32-is-first-inout -4122 0/imm32/output-is-write-only -4123 _Primitive-and-reg-with-reg/imm32/next -4124 _Primitive-and-reg-with-reg: -4125 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 -4126 "and"/imm32/name -4127 Single-int-var-in-some-register/imm32/inouts -4128 Single-int-var-in-some-register/imm32/outputs -4129 "21/and-with"/imm32/subx-name -4130 3/imm32/rm32-is-first-output -4131 1/imm32/r32-is-first-inout -4132 0/imm32/no-imm32 -4133 0/imm32/output-is-write-only -4134 _Primitive-and-reg-with-mem/imm32/next -4135 _Primitive-and-reg-with-mem: -4136 # and-with var1 var2/reg => 21/and-with var1 var2/r32 -4137 "and-with"/imm32/name -4138 Int-var-and-second-int-var-in-some-register/imm32/inouts -4139 0/imm32/outputs -4140 "21/and-with"/imm32/subx-name -4141 1/imm32/rm32-is-first-inout -4142 2/imm32/r32-is-second-inout -4143 0/imm32/no-imm32 -4144 0/imm32/output-is-write-only -4145 _Primitive-and-mem-with-reg/imm32/next -4146 _Primitive-and-mem-with-reg: -4147 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 -4148 "and"/imm32/name -4149 Single-int-var-on-stack/imm32/inouts -4150 Single-int-var-in-some-register/imm32/outputs -4151 "23/and"/imm32/subx-name -4152 1/imm32/rm32-is-first-inout -4153 3/imm32/r32-is-first-output -4154 0/imm32/no-imm32 -4155 0/imm32/output-is-write-only -4156 _Primitive-and-lit-with-reg/imm32/next -4157 _Primitive-and-lit-with-reg: -4158 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 -4159 "and"/imm32/name -4160 Single-lit-var/imm32/inouts -4161 Single-int-var-in-some-register/imm32/outputs -4162 "81 4/subop/and"/imm32/subx-name -4163 3/imm32/rm32-is-first-output -4164 0/imm32/no-r32 -4165 1/imm32/imm32-is-first-inout -4166 0/imm32/output-is-write-only -4167 _Primitive-and-lit-with-mem/imm32/next -4168 _Primitive-and-lit-with-mem: -4169 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 -4170 "and-with"/imm32/name -4171 Int-var-and-literal/imm32/inouts -4172 0/imm32/outputs -4173 "81 4/subop/and"/imm32/subx-name -4174 1/imm32/rm32-is-first-inout -4175 0/imm32/no-r32 -4176 2/imm32/imm32-is-first-inout -4177 0/imm32/output-is-write-only -4178 _Primitive-or-with-eax/imm32/next -4179 # - or -4180 _Primitive-or-with-eax: -4181 # var/eax <- or lit => 0d/or-with-eax lit/imm32 -4182 "or"/imm32/name -4183 Single-lit-var/imm32/inouts -4184 Single-int-var-in-eax/imm32/outputs -4185 "0d/or-with-eax"/imm32/subx-name -4186 0/imm32/no-rm32 -4187 0/imm32/no-r32 -4188 1/imm32/imm32-is-first-inout -4189 0/imm32/output-is-write-only -4190 _Primitive-or-reg-with-reg/imm32/next -4191 _Primitive-or-reg-with-reg: -4192 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 -4193 "or"/imm32/name -4194 Single-int-var-in-some-register/imm32/inouts -4195 Single-int-var-in-some-register/imm32/outputs -4196 "09/or-with"/imm32/subx-name -4197 3/imm32/rm32-is-first-output -4198 1/imm32/r32-is-first-inout -4199 0/imm32/no-imm32 -4200 0/imm32/output-is-write-only -4201 _Primitive-or-reg-with-mem/imm32/next -4202 _Primitive-or-reg-with-mem: -4203 # or-with var1 var2/reg => 09/or-with var1 var2/r32 -4204 "or-with"/imm32/name -4205 Int-var-and-second-int-var-in-some-register/imm32/inouts -4206 0/imm32/outputs -4207 "09/or-with"/imm32/subx-name -4208 1/imm32/rm32-is-first-inout -4209 2/imm32/r32-is-second-inout -4210 0/imm32/no-imm32 -4211 0/imm32/output-is-write-only -4212 _Primitive-or-mem-with-reg/imm32/next -4213 _Primitive-or-mem-with-reg: -4214 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 -4215 "or"/imm32/name -4216 Single-int-var-on-stack/imm32/inouts -4217 Single-int-var-in-some-register/imm32/outputs -4218 "0b/or"/imm32/subx-name -4219 1/imm32/rm32-is-first-inout -4220 3/imm32/r32-is-first-output -4221 0/imm32/no-imm32 -4222 0/imm32/output-is-write-only -4223 _Primitive-or-lit-with-reg/imm32/next -4224 _Primitive-or-lit-with-reg: -4225 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 -4226 "or"/imm32/name -4227 Single-lit-var/imm32/inouts -4228 Single-int-var-in-some-register/imm32/outputs -4229 "81 4/subop/or"/imm32/subx-name -4230 3/imm32/rm32-is-first-output -4231 0/imm32/no-r32 -4232 1/imm32/imm32-is-first-inout -4233 0/imm32/output-is-write-only -4234 _Primitive-or-lit-with-mem/imm32/next -4235 _Primitive-or-lit-with-mem: -4236 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 -4237 "or-with"/imm32/name -4238 Int-var-and-literal/imm32/inouts -4239 0/imm32/outputs -4240 "81 4/subop/or"/imm32/subx-name -4241 1/imm32/rm32-is-first-inout -4242 0/imm32/no-r32 -4243 2/imm32/imm32-is-first-inout -4244 0/imm32/output-is-write-only -4245 _Primitive-xor-with-eax/imm32/next -4246 # - xor -4247 _Primitive-xor-with-eax: -4248 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 -4249 "xor"/imm32/name -4250 Single-lit-var/imm32/inouts -4251 Single-int-var-in-eax/imm32/outputs -4252 "35/xor-with-eax"/imm32/subx-name -4253 0/imm32/no-rm32 -4254 0/imm32/no-r32 -4255 1/imm32/imm32-is-first-inout -4256 0/imm32/output-is-write-only -4257 _Primitive-xor-reg-with-reg/imm32/next -4258 _Primitive-xor-reg-with-reg: -4259 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 -4260 "xor"/imm32/name -4261 Single-int-var-in-some-register/imm32/inouts -4262 Single-int-var-in-some-register/imm32/outputs -4263 "31/xor-with"/imm32/subx-name -4264 3/imm32/rm32-is-first-output -4265 1/imm32/r32-is-first-inout -4266 0/imm32/no-imm32 -4267 0/imm32/output-is-write-only -4268 _Primitive-xor-reg-with-mem/imm32/next -4269 _Primitive-xor-reg-with-mem: -4270 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 -4271 "xor-with"/imm32/name -4272 Int-var-and-second-int-var-in-some-register/imm32/inouts -4273 0/imm32/outputs -4274 "31/xor-with"/imm32/subx-name -4275 1/imm32/rm32-is-first-inout -4276 2/imm32/r32-is-second-inout -4277 0/imm32/no-imm32 -4278 0/imm32/output-is-write-only -4279 _Primitive-xor-mem-with-reg/imm32/next -4280 _Primitive-xor-mem-with-reg: -4281 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 -4282 "xor"/imm32/name -4283 Single-int-var-on-stack/imm32/inouts -4284 Single-int-var-in-some-register/imm32/outputs -4285 "33/xor"/imm32/subx-name -4286 1/imm32/rm32-is-first-inout -4287 3/imm32/r32-is-first-output -4288 0/imm32/no-imm32 -4289 0/imm32/output-is-write-only -4290 _Primitive-xor-lit-with-reg/imm32/next -4291 _Primitive-xor-lit-with-reg: -4292 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 -4293 "xor"/imm32/name -4294 Single-lit-var/imm32/inouts -4295 Single-int-var-in-some-register/imm32/outputs -4296 "81 4/subop/xor"/imm32/subx-name -4297 3/imm32/rm32-is-first-output -4298 0/imm32/no-r32 -4299 1/imm32/imm32-is-first-inout -4300 0/imm32/output-is-write-only -4301 _Primitive-xor-lit-with-mem/imm32/next -4302 _Primitive-xor-lit-with-mem: -4303 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 -4304 "xor-with"/imm32/name -4305 Int-var-and-literal/imm32/inouts -4306 0/imm32/outputs -4307 "81 4/subop/xor"/imm32/subx-name -4308 1/imm32/rm32-is-first-inout -4309 0/imm32/no-r32 -4310 2/imm32/imm32-is-first-inout -4311 0/imm32/output-is-write-only -4312 _Primitive-copy-to-eax/imm32/next -4313 # - copy -4314 _Primitive-copy-to-eax: -4315 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 -4316 "copy"/imm32/name -4317 Single-lit-var/imm32/inouts -4318 Single-int-var-in-eax/imm32/outputs -4319 "b8/copy-to-eax"/imm32/subx-name -4320 0/imm32/no-rm32 -4321 0/imm32/no-r32 -4322 1/imm32/imm32-is-first-inout -4323 1/imm32/output-is-write-only -4324 _Primitive-copy-to-ecx/imm32/next -4325 _Primitive-copy-to-ecx: -4326 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 -4327 "copy"/imm32/name -4328 Single-lit-var/imm32/inouts -4329 Single-int-var-in-ecx/imm32/outputs -4330 "b9/copy-to-ecx"/imm32/subx-name -4331 0/imm32/no-rm32 -4332 0/imm32/no-r32 -4333 1/imm32/imm32-is-first-inout -4334 1/imm32/output-is-write-only -4335 _Primitive-copy-to-edx/imm32/next -4336 _Primitive-copy-to-edx: -4337 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 -4338 "copy"/imm32/name -4339 Single-lit-var/imm32/inouts -4340 Single-int-var-in-edx/imm32/outputs -4341 "ba/copy-to-edx"/imm32/subx-name -4342 0/imm32/no-rm32 -4343 0/imm32/no-r32 -4344 1/imm32/imm32-is-first-inout -4345 1/imm32/output-is-write-only -4346 _Primitive-copy-to-ebx/imm32/next -4347 _Primitive-copy-to-ebx: -4348 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 -4349 "copy"/imm32/name -4350 Single-lit-var/imm32/inouts -4351 Single-int-var-in-ebx/imm32/outputs -4352 "bb/copy-to-ebx"/imm32/subx-name -4353 0/imm32/no-rm32 -4354 0/imm32/no-r32 -4355 1/imm32/imm32-is-first-inout -4356 1/imm32/output-is-write-only -4357 _Primitive-copy-to-esi/imm32/next -4358 _Primitive-copy-to-esi: -4359 # var/esi <- copy lit => be/copy-to-esi lit/imm32 -4360 "copy"/imm32/name -4361 Single-lit-var/imm32/inouts -4362 Single-int-var-in-esi/imm32/outputs -4363 "be/copy-to-esi"/imm32/subx-name -4364 0/imm32/no-rm32 -4365 0/imm32/no-r32 -4366 1/imm32/imm32-is-first-inout -4367 1/imm32/output-is-write-only -4368 _Primitive-copy-to-edi/imm32/next -4369 _Primitive-copy-to-edi: -4370 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 -4371 "copy"/imm32/name -4372 Single-lit-var/imm32/inouts -4373 Single-int-var-in-edi/imm32/outputs -4374 "bf/copy-to-edi"/imm32/subx-name -4375 0/imm32/no-rm32 -4376 0/imm32/no-r32 -4377 1/imm32/imm32-is-first-inout -4378 1/imm32/output-is-write-only -4379 _Primitive-copy-reg-to-reg/imm32/next -4380 _Primitive-copy-reg-to-reg: -4381 # var1/reg <- copy var2/reg => 89/copy-to var1/rm32 var2/r32 -4382 "copy"/imm32/name -4383 Single-int-var-in-some-register/imm32/inouts -4384 Single-int-var-in-some-register/imm32/outputs -4385 "89/copy-to"/imm32/subx-name -4386 3/imm32/rm32-is-first-output -4387 1/imm32/r32-is-first-inout -4388 0/imm32/no-imm32 -4389 1/imm32/output-is-write-only -4390 _Primitive-copy-reg-to-mem/imm32/next -4391 _Primitive-copy-reg-to-mem: -4392 # copy-to var1 var2/reg => 89/copy-to var1 var2/r32 -4393 "copy-to"/imm32/name -4394 Int-var-and-second-int-var-in-some-register/imm32/inouts -4395 0/imm32/outputs -4396 "89/copy-to"/imm32/subx-name -4397 1/imm32/rm32-is-first-inout -4398 2/imm32/r32-is-second-inout -4399 0/imm32/no-imm32 -4400 1/imm32/output-is-write-only -4401 _Primitive-copy-mem-to-reg/imm32/next -4402 _Primitive-copy-mem-to-reg: -4403 # var1/reg <- copy var2 => 8b/copy-from var2/rm32 var1/r32 -4404 "copy"/imm32/name -4405 Single-int-var-on-stack/imm32/inouts -4406 Single-int-var-in-some-register/imm32/outputs -4407 "8b/copy-from"/imm32/subx-name -4408 1/imm32/rm32-is-first-inout -4409 3/imm32/r32-is-first-output -4410 0/imm32/no-imm32 -4411 1/imm32/output-is-write-only -4412 _Primitive-copy-lit-to-reg/imm32/next -4413 _Primitive-copy-lit-to-reg: -4414 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 -4415 "copy"/imm32/name -4416 Single-lit-var/imm32/inouts -4417 Single-int-var-in-some-register/imm32/outputs -4418 "c7 0/subop/copy"/imm32/subx-name -4419 3/imm32/rm32-is-first-output -4420 0/imm32/no-r32 -4421 1/imm32/imm32-is-first-inout -4422 1/imm32/output-is-write-only -4423 _Primitive-copy-lit-to-mem/imm32/next -4424 _Primitive-copy-lit-to-mem: -4425 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 -4426 "copy-to"/imm32/name -4427 Int-var-and-literal/imm32/inouts -4428 0/imm32/outputs -4429 "c7 0/subop/copy"/imm32/subx-name -4430 1/imm32/rm32-is-first-inout -4431 0/imm32/no-r32 -4432 2/imm32/imm32-is-first-inout -4433 1/imm32/output-is-write-only -4434 0/imm32/next -4435 -4436 Single-int-var-on-stack: -4437 Int-var-on-stack/imm32 -4438 0/imm32/next -4439 -4440 Int-var-on-stack: -4441 "arg1"/imm32/name -4442 Type-int/imm32 -4443 1/imm32/some-block-depth -4444 1/imm32/some-stack-offset -4445 0/imm32/no-register -4446 -4447 Int-var-and-second-int-var-in-some-register: -4448 Int-var-on-stack/imm32 -4449 Single-int-var-in-some-register/imm32/next -4450 -4451 Int-var-and-literal: -4452 Int-var-on-stack/imm32 -4453 Single-lit-var/imm32/next -4454 -4455 Single-int-var-in-some-register: -4456 Int-var-in-some-register/imm32 -4457 0/imm32/next -4458 -4459 Int-var-in-some-register: -4460 "arg1"/imm32/name -4461 Type-int/imm32 -4462 1/imm32/some-block-depth -4463 0/imm32/no-stack-offset -4464 "*"/imm32/register -4465 -4466 Single-int-var-in-eax: -4467 Int-var-in-eax/imm32 -4468 0/imm32/next -4469 -4470 Int-var-in-eax: -4471 "arg1"/imm32/name -4472 Type-int/imm32 -4473 1/imm32/some-block-depth -4474 0/imm32/no-stack-offset -4475 "eax"/imm32/register -4476 -4477 Single-int-var-in-ecx: -4478 Int-var-in-ecx/imm32 -4479 0/imm32/next -4480 -4481 Int-var-in-ecx: -4482 "arg1"/imm32/name -4483 Type-int/imm32 -4484 1/imm32/some-block-depth -4485 0/imm32/no-stack-offset -4486 "ecx"/imm32/register -4487 -4488 Single-int-var-in-edx: -4489 Int-var-in-edx/imm32 -4490 0/imm32/next -4491 -4492 Int-var-in-edx: -4493 "arg1"/imm32/name -4494 Type-int/imm32 -4495 1/imm32/some-block-depth -4496 0/imm32/no-stack-offset -4497 "edx"/imm32/register -4498 -4499 Single-int-var-in-ebx: -4500 Int-var-in-ebx/imm32 -4501 0/imm32/next -4502 -4503 Int-var-in-ebx: -4504 "arg1"/imm32/name -4505 Type-int/imm32 -4506 1/imm32/some-block-depth -4507 0/imm32/no-stack-offset -4508 "ebx"/imm32/register -4509 -4510 Single-int-var-in-esi: -4511 Int-var-in-esi/imm32 -4512 0/imm32/next -4513 -4514 Int-var-in-esi: -4515 "arg1"/imm32/name -4516 Type-int/imm32 -4517 1/imm32/some-block-depth -4518 0/imm32/no-stack-offset -4519 "esi"/imm32/register -4520 -4521 Single-int-var-in-edi: -4522 Int-var-in-edi/imm32 -4523 0/imm32/next -4524 -4525 Int-var-in-edi: -4526 "arg1"/imm32/name -4527 Type-int/imm32 -4528 1/imm32/some-block-depth -4529 0/imm32/no-stack-offset -4530 "edi"/imm32/register -4531 -4532 Single-lit-var: -4533 Lit-var/imm32 -4534 0/imm32/next -4535 -4536 Lit-var: -4537 "literal"/imm32/name -4538 Type-literal/imm32 -4539 1/imm32/some-block-depth -4540 0/imm32/no-stack-offset -4541 0/imm32/no-register -4542 -4543 Type-int: -4544 1/imm32/left/int -4545 0/imm32/right/null -4546 -4547 Type-literal: -4548 0/imm32/left/literal -4549 0/imm32/right/null -4550 -4551 == code -4552 emit-subx-primitive: # out : (addr buffered-file), stmt : (handle statement), primitive : (handle function) -4553 # . prologue -4554 55/push-ebp -4555 89/<- %ebp 4/r32/esp -4556 # . save registers -4557 50/push-eax -4558 51/push-ecx -4559 # ecx = primitive -4560 8b/-> *(ebp+0x10) 1/r32/ecx -4561 # emit primitive name -4562 (write-buffered *(ebp+8) *(ecx+0xc)) # Primitive-subx-name -4563 # emit rm32 if necessary -4564 (emit-subx-rm32 *(ebp+8) *(ecx+0x10) *(ebp+0xc)) # out, Primitive-subx-rm32, stmt -4565 # emit r32 if necessary -4566 (emit-subx-r32 *(ebp+8) *(ecx+0x14) *(ebp+0xc)) # out, Primitive-subx-r32, stmt -4567 # emit imm32 if necessary -4568 (emit-subx-imm32 *(ebp+8) *(ecx+0x18) *(ebp+0xc)) # out, Primitive-subx-imm32, stmt -4569 $emit-subx-primitive:end: -4570 # . restore registers -4571 59/pop-to-ecx -4572 58/pop-to-eax -4573 # . epilogue -4574 89/<- %esp 5/r32/ebp -4575 5d/pop-to-ebp -4576 c3/return +3723 # . save registers +3724 50/push-eax +3725 56/push-esi +3726 # var stmts/esi: (handle list statement) = block->statements +3727 8b/-> *(ebp+0xc) 6/r32/esi +3728 8b/-> *(esi+4) 6/r32/esi # Block-statements +3729 # +3730 { +3731 $emit-subx-block:check-empty: +3732 81 7/subop/compare %esi 0/imm32 +3733 0f 84/jump-if-= break/disp32 +3734 (write-buffered *(ebp+8) "{\n") +3735 { +3736 $emit-subx-block:loop: +3737 81 7/subop/compare %esi 0/imm32 +3738 74/jump-if-= break/disp8 +3739 # var curr/eax = stmts->value +3740 8b/-> *esi 0/r32/eax # List-value +3741 { +3742 $emit-subx-block:check-for-block: +3743 81 7/subop/compare *eax 0/imm32/block # Stmt-tag +3744 75/jump-if-not-equal break/disp8 +3745 $emit-subx-block:block: +3746 # TODO +3747 } +3748 { +3749 $emit-subx-block:check-for-stmt: +3750 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag +3751 75/jump-if-not-equal break/disp8 +3752 $emit-subx-block:stmt: +3753 (emit-subx-statement *(ebp+8) %eax Primitives *Program) +3754 } +3755 { +3756 $emit-subx-block:check-for-vardef: +3757 81 7/subop/compare *eax 2/imm32/vardef # Stmt-tag +3758 75/jump-if-not-equal break/disp8 +3759 $emit-subx-block:vardef: +3760 # TODO +3761 } +3762 { +3763 $emit-subx-block:check-for-regvardef: +3764 81 7/subop/compare *eax 3/imm32/regvardef # Stmt-tag +3765 75/jump-if-not-equal break/disp8 +3766 $emit-subx-block:regvardef: +3767 # TODO +3768 } +3769 { +3770 $emit-subx-block:check-for-named-block: +3771 81 7/subop/compare *eax 4/imm32/named-block # Stmt-tag +3772 75/jump-if-not-equal break/disp8 +3773 $emit-subx-block:named-block: +3774 # TODO +3775 } +3776 (write-buffered *(ebp+8) Newline) +3777 8b/-> *(esi+4) 6/r32/esi # List-next +3778 eb/jump loop/disp8 +3779 } +3780 (write-buffered *(ebp+8) "}\n") +3781 } +3782 $emit-subx-block:end: +3783 # . restore registers +3784 5e/pop-to-esi +3785 58/pop-to-eax +3786 # . epilogue +3787 89/<- %esp 5/r32/ebp +3788 5d/pop-to-ebp +3789 c3/return +3790 +3791 emit-subx-statement: # out: (addr buffered-file), stmt: (handle statement), primitives: (handle primitive), functions: (handle function) +3792 # . prologue +3793 55/push-ebp +3794 89/<- %ebp 4/r32/esp +3795 # . save registers +3796 50/push-eax +3797 51/push-ecx +3798 # if stmt matches a primitive, emit it +3799 { +3800 $emit-subx-statement:primitive: +3801 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => curr/eax +3802 3d/compare-eax-and 0/imm32 +3803 74/jump-if-= break/disp8 +3804 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr +3805 e9/jump $emit-subx-statement:end/disp32 +3806 } +3807 # else if stmt matches a function, emit a call to it +3808 { +3809 $emit-subx-statement:call: +3810 (find-matching-function *(ebp+0x14) *(ebp+0xc)) # functions, stmt => curr/eax +3811 3d/compare-eax-and 0/imm32 +3812 74/jump-if-= break/disp8 +3813 (emit-subx-call *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr +3814 e9/jump $emit-subx-statement:end/disp32 +3815 } +3816 # else abort +3817 e9/jump $emit-subx-statement:abort/disp32 +3818 $emit-subx-statement:end: +3819 # . restore registers +3820 59/pop-to-ecx +3821 58/pop-to-eax +3822 # . epilogue +3823 89/<- %esp 5/r32/ebp +3824 5d/pop-to-ebp +3825 c3/return +3826 +3827 $emit-subx-statement:abort: +3828 # error("couldn't translate '" stmt "'\n") +3829 (write-buffered Stderr "couldn't translate '") +3830 #? (emit-string Stderr *(ebp+0xc)) # TODO +3831 (write-buffered Stderr "'\n") +3832 (flush Stderr) +3833 # . syscall(exit, 1) +3834 bb/copy-to-ebx 1/imm32 +3835 b8/copy-to-eax 1/imm32/exit +3836 cd/syscall 0x80/imm8 +3837 # never gets here +3838 +3839 # Primitives supported +3840 # For each operation, put variants with hard-coded registers before flexible ones. +3841 == data +3842 Primitives: +3843 # - increment/decrement +3844 _Primitive-inc-eax: +3845 # var/eax <- increment => 40/increment-eax +3846 "increment"/imm32/name +3847 0/imm32/no-inouts +3848 Single-int-var-in-eax/imm32/outputs +3849 "40/increment-eax"/imm32/subx-name +3850 0/imm32/no-rm32 +3851 0/imm32/no-r32 +3852 0/imm32/no-imm32 +3853 0/imm32/output-is-write-only +3854 _Primitive-inc-ecx/imm32/next +3855 _Primitive-inc-ecx: +3856 # var/ecx <- increment => 41/increment-ecx +3857 "increment"/imm32/name +3858 0/imm32/no-inouts +3859 Single-int-var-in-ecx/imm32/outputs +3860 "41/increment-ecx"/imm32/subx-name +3861 0/imm32/no-rm32 +3862 0/imm32/no-r32 +3863 0/imm32/no-imm32 +3864 0/imm32/output-is-write-only +3865 _Primitive-inc-edx/imm32/next +3866 _Primitive-inc-edx: +3867 # var/edx <- increment => 42/increment-edx +3868 "increment"/imm32/name +3869 0/imm32/no-inouts +3870 Single-int-var-in-edx/imm32/outputs +3871 "42/increment-edx"/imm32/subx-name +3872 0/imm32/no-rm32 +3873 0/imm32/no-r32 +3874 0/imm32/no-imm32 +3875 0/imm32/output-is-write-only +3876 _Primitive-inc-ebx/imm32/next +3877 _Primitive-inc-ebx: +3878 # var/ebx <- increment => 43/increment-ebx +3879 "increment"/imm32/name +3880 0/imm32/no-inouts +3881 Single-int-var-in-ebx/imm32/outputs +3882 "43/increment-ebx"/imm32/subx-name +3883 0/imm32/no-rm32 +3884 0/imm32/no-r32 +3885 0/imm32/no-imm32 +3886 0/imm32/output-is-write-only +3887 _Primitive-inc-esi/imm32/next +3888 _Primitive-inc-esi: +3889 # var/esi <- increment => 46/increment-esi +3890 "increment"/imm32/name +3891 0/imm32/no-inouts +3892 Single-int-var-in-esi/imm32/outputs +3893 "46/increment-esi"/imm32/subx-name +3894 0/imm32/no-rm32 +3895 0/imm32/no-r32 +3896 0/imm32/no-imm32 +3897 0/imm32/output-is-write-only +3898 _Primitive-inc-edi/imm32/next +3899 _Primitive-inc-edi: +3900 # var/edi <- increment => 47/increment-edi +3901 "increment"/imm32/name +3902 0/imm32/no-inouts +3903 Single-int-var-in-edi/imm32/outputs +3904 "47/increment-edi"/imm32/subx-name +3905 0/imm32/no-rm32 +3906 0/imm32/no-r32 +3907 0/imm32/no-imm32 +3908 0/imm32/output-is-write-only +3909 _Primitive-dec-eax/imm32/next +3910 _Primitive-dec-eax: +3911 # var/eax <- decrement => 48/decrement-eax +3912 "decrement"/imm32/name +3913 0/imm32/no-inouts +3914 Single-int-var-in-eax/imm32/outputs +3915 "48/decrement-eax"/imm32/subx-name +3916 0/imm32/no-rm32 +3917 0/imm32/no-r32 +3918 0/imm32/no-imm32 +3919 0/imm32/output-is-write-only +3920 _Primitive-dec-ecx/imm32/next +3921 _Primitive-dec-ecx: +3922 # var/ecx <- decrement => 49/decrement-ecx +3923 "decrement"/imm32/name +3924 0/imm32/no-inouts +3925 Single-int-var-in-ecx/imm32/outputs +3926 "49/decrement-ecx"/imm32/subx-name +3927 0/imm32/no-rm32 +3928 0/imm32/no-r32 +3929 0/imm32/no-imm32 +3930 0/imm32/output-is-write-only +3931 _Primitive-dec-edx/imm32/next +3932 _Primitive-dec-edx: +3933 # var/edx <- decrement => 4a/decrement-edx +3934 "decrement"/imm32/name +3935 0/imm32/no-inouts +3936 Single-int-var-in-edx/imm32/outputs +3937 "4a/decrement-edx"/imm32/subx-name +3938 0/imm32/no-rm32 +3939 0/imm32/no-r32 +3940 0/imm32/no-imm32 +3941 0/imm32/output-is-write-only +3942 _Primitive-dec-ebx/imm32/next +3943 _Primitive-dec-ebx: +3944 # var/ebx <- decrement => 4b/decrement-ebx +3945 "decrement"/imm32/name +3946 0/imm32/no-inouts +3947 Single-int-var-in-ebx/imm32/outputs +3948 "4b/decrement-ebx"/imm32/subx-name +3949 0/imm32/no-rm32 +3950 0/imm32/no-r32 +3951 0/imm32/no-imm32 +3952 0/imm32/output-is-write-only +3953 _Primitive-dec-esi/imm32/next +3954 _Primitive-dec-esi: +3955 # var/esi <- decrement => 4e/decrement-esi +3956 "decrement"/imm32/name +3957 0/imm32/no-inouts +3958 Single-int-var-in-esi/imm32/outputs +3959 "4e/decrement-esi"/imm32/subx-name +3960 0/imm32/no-rm32 +3961 0/imm32/no-r32 +3962 0/imm32/no-imm32 +3963 0/imm32/output-is-write-only +3964 _Primitive-dec-edi/imm32/next +3965 _Primitive-dec-edi: +3966 # var/edi <- decrement => 4f/decrement-edi +3967 "decrement"/imm32/name +3968 0/imm32/no-inouts +3969 Single-int-var-in-edi/imm32/outputs +3970 "4f/decrement-edi"/imm32/subx-name +3971 0/imm32/no-rm32 +3972 0/imm32/no-r32 +3973 0/imm32/no-imm32 +3974 0/imm32/output-is-write-only +3975 _Primitive-inc-mem/imm32/next +3976 _Primitive-inc-mem: +3977 # increment var => ff 0/subop/increment *(ebp+__) +3978 "increment"/imm32/name +3979 Single-int-var-on-stack/imm32/inouts +3980 0/imm32/no-outputs +3981 "ff 0/subop/increment"/imm32/subx-name +3982 1/imm32/rm32-is-first-inout +3983 0/imm32/no-r32 +3984 0/imm32/no-imm32 +3985 0/imm32/output-is-write-only +3986 _Primitive-inc-reg/imm32/next +3987 _Primitive-inc-reg: +3988 # var/reg <- increment => ff 0/subop/increment %__ +3989 "increment"/imm32/name +3990 0/imm32/no-inouts +3991 Single-int-var-in-some-register/imm32/outputs +3992 "ff 0/subop/increment"/imm32/subx-name +3993 3/imm32/rm32-is-first-output +3994 0/imm32/no-r32 +3995 0/imm32/no-imm32 +3996 0/imm32/output-is-write-only +3997 _Primitive-dec-mem/imm32/next +3998 _Primitive-dec-mem: +3999 # decrement var => ff 1/subop/decrement *(ebp+__) +4000 "decrement"/imm32/name +4001 Single-int-var-on-stack/imm32/inouts +4002 0/imm32/no-outputs +4003 "ff 1/subop/decrement"/imm32/subx-name +4004 1/imm32/rm32-is-first-inout +4005 0/imm32/no-r32 +4006 0/imm32/no-imm32 +4007 0/imm32/output-is-write-only +4008 _Primitive-dec-reg/imm32/next +4009 _Primitive-dec-reg: +4010 # var/reg <- decrement => ff 1/subop/decrement %__ +4011 "decrement"/imm32/name +4012 0/imm32/no-inouts +4013 Single-int-var-in-some-register/imm32/outputs +4014 "ff 1/subop/decrement"/imm32/subx-name +4015 3/imm32/rm32-is-first-output +4016 0/imm32/no-r32 +4017 0/imm32/no-imm32 +4018 0/imm32/output-is-write-only +4019 _Primitive-add-to-eax/imm32/next +4020 # - add +4021 _Primitive-add-to-eax: +4022 # var/eax <- add lit => 05/add-to-eax lit/imm32 +4023 "add"/imm32/name +4024 Single-lit-var/imm32/inouts +4025 Single-int-var-in-eax/imm32/outputs +4026 "05/add-to-eax"/imm32/subx-name +4027 0/imm32/no-rm32 +4028 0/imm32/no-r32 +4029 1/imm32/imm32-is-first-inout +4030 0/imm32/output-is-write-only +4031 _Primitive-add-reg-to-reg/imm32/next +4032 _Primitive-add-reg-to-reg: +4033 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 +4034 "add"/imm32/name +4035 Single-int-var-in-some-register/imm32/inouts +4036 Single-int-var-in-some-register/imm32/outputs +4037 "01/add-to"/imm32/subx-name +4038 3/imm32/rm32-is-first-output +4039 1/imm32/r32-is-first-inout +4040 0/imm32/no-imm32 +4041 0/imm32/output-is-write-only +4042 _Primitive-add-reg-to-mem/imm32/next +4043 _Primitive-add-reg-to-mem: +4044 # add-to var1 var2/reg => 01/add-to var1 var2/r32 +4045 "add-to"/imm32/name +4046 Int-var-and-second-int-var-in-some-register/imm32/inouts +4047 0/imm32/outputs +4048 "01/add-to"/imm32/subx-name +4049 1/imm32/rm32-is-first-inout +4050 2/imm32/r32-is-second-inout +4051 0/imm32/no-imm32 +4052 0/imm32/output-is-write-only +4053 _Primitive-add-mem-to-reg/imm32/next +4054 _Primitive-add-mem-to-reg: +4055 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 +4056 "add"/imm32/name +4057 Single-int-var-on-stack/imm32/inouts +4058 Single-int-var-in-some-register/imm32/outputs +4059 "03/add"/imm32/subx-name +4060 1/imm32/rm32-is-first-inout +4061 3/imm32/r32-is-first-output +4062 0/imm32/no-imm32 +4063 0/imm32/output-is-write-only +4064 _Primitive-add-lit-to-reg/imm32/next +4065 _Primitive-add-lit-to-reg: +4066 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 +4067 "add"/imm32/name +4068 Single-lit-var/imm32/inouts +4069 Single-int-var-in-some-register/imm32/outputs +4070 "81 0/subop/add"/imm32/subx-name +4071 3/imm32/rm32-is-first-output +4072 0/imm32/no-r32 +4073 1/imm32/imm32-is-first-inout +4074 0/imm32/output-is-write-only +4075 _Primitive-add-lit-to-mem/imm32/next +4076 _Primitive-add-lit-to-mem: +4077 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 +4078 "add-to"/imm32/name +4079 Int-var-and-literal/imm32/inouts +4080 0/imm32/outputs +4081 "81 0/subop/add"/imm32/subx-name +4082 1/imm32/rm32-is-first-inout +4083 0/imm32/no-r32 +4084 2/imm32/imm32-is-first-inout +4085 0/imm32/output-is-write-only +4086 _Primitive-subtract-from-eax/imm32/next +4087 # - subtract +4088 _Primitive-subtract-from-eax: +4089 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 +4090 "subtract"/imm32/name +4091 Single-lit-var/imm32/inouts +4092 Single-int-var-in-eax/imm32/outputs +4093 "2d/subtract-from-eax"/imm32/subx-name +4094 0/imm32/no-rm32 +4095 0/imm32/no-r32 +4096 1/imm32/imm32-is-first-inout +4097 0/imm32/output-is-write-only +4098 _Primitive-subtract-reg-from-reg/imm32/next +4099 _Primitive-subtract-reg-from-reg: +4100 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 +4101 "subtract"/imm32/name +4102 Single-int-var-in-some-register/imm32/inouts +4103 Single-int-var-in-some-register/imm32/outputs +4104 "29/subtract-from"/imm32/subx-name +4105 3/imm32/rm32-is-first-output +4106 1/imm32/r32-is-first-inout +4107 0/imm32/no-imm32 +4108 0/imm32/output-is-write-only +4109 _Primitive-subtract-reg-from-mem/imm32/next +4110 _Primitive-subtract-reg-from-mem: +4111 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 +4112 "subtract-from"/imm32/name +4113 Int-var-and-second-int-var-in-some-register/imm32/inouts +4114 0/imm32/outputs +4115 "29/subtract-from"/imm32/subx-name +4116 1/imm32/rm32-is-first-inout +4117 2/imm32/r32-is-second-inout +4118 0/imm32/no-imm32 +4119 0/imm32/output-is-write-only +4120 _Primitive-subtract-mem-from-reg/imm32/next +4121 _Primitive-subtract-mem-from-reg: +4122 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 +4123 "subtract"/imm32/name +4124 Single-int-var-on-stack/imm32/inouts +4125 Single-int-var-in-some-register/imm32/outputs +4126 "2b/subtract"/imm32/subx-name +4127 1/imm32/rm32-is-first-inout +4128 3/imm32/r32-is-first-output +4129 0/imm32/no-imm32 +4130 0/imm32/output-is-write-only +4131 _Primitive-subtract-lit-from-reg/imm32/next +4132 _Primitive-subtract-lit-from-reg: +4133 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 +4134 "subtract"/imm32/name +4135 Single-lit-var/imm32/inouts +4136 Single-int-var-in-some-register/imm32/outputs +4137 "81 5/subop/subtract"/imm32/subx-name +4138 3/imm32/rm32-is-first-output +4139 0/imm32/no-r32 +4140 1/imm32/imm32-is-first-inout +4141 0/imm32/output-is-write-only +4142 _Primitive-subtract-lit-from-mem/imm32/next +4143 _Primitive-subtract-lit-from-mem: +4144 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 +4145 "subtract-from"/imm32/name +4146 Int-var-and-literal/imm32/inouts +4147 0/imm32/outputs +4148 "81 5/subop/subtract"/imm32/subx-name +4149 1/imm32/rm32-is-first-inout +4150 0/imm32/no-r32 +4151 2/imm32/imm32-is-first-inout +4152 0/imm32/output-is-write-only +4153 _Primitive-and-with-eax/imm32/next +4154 # - and +4155 _Primitive-and-with-eax: +4156 # var/eax <- and lit => 25/and-with-eax lit/imm32 +4157 "and"/imm32/name +4158 Single-lit-var/imm32/inouts +4159 Single-int-var-in-eax/imm32/outputs +4160 "25/and-with-eax"/imm32/subx-name +4161 0/imm32/no-rm32 +4162 0/imm32/no-r32 +4163 1/imm32/imm32-is-first-inout +4164 0/imm32/output-is-write-only +4165 _Primitive-and-reg-with-reg/imm32/next +4166 _Primitive-and-reg-with-reg: +4167 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 +4168 "and"/imm32/name +4169 Single-int-var-in-some-register/imm32/inouts +4170 Single-int-var-in-some-register/imm32/outputs +4171 "21/and-with"/imm32/subx-name +4172 3/imm32/rm32-is-first-output +4173 1/imm32/r32-is-first-inout +4174 0/imm32/no-imm32 +4175 0/imm32/output-is-write-only +4176 _Primitive-and-reg-with-mem/imm32/next +4177 _Primitive-and-reg-with-mem: +4178 # and-with var1 var2/reg => 21/and-with var1 var2/r32 +4179 "and-with"/imm32/name +4180 Int-var-and-second-int-var-in-some-register/imm32/inouts +4181 0/imm32/outputs +4182 "21/and-with"/imm32/subx-name +4183 1/imm32/rm32-is-first-inout +4184 2/imm32/r32-is-second-inout +4185 0/imm32/no-imm32 +4186 0/imm32/output-is-write-only +4187 _Primitive-and-mem-with-reg/imm32/next +4188 _Primitive-and-mem-with-reg: +4189 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 +4190 "and"/imm32/name +4191 Single-int-var-on-stack/imm32/inouts +4192 Single-int-var-in-some-register/imm32/outputs +4193 "23/and"/imm32/subx-name +4194 1/imm32/rm32-is-first-inout +4195 3/imm32/r32-is-first-output +4196 0/imm32/no-imm32 +4197 0/imm32/output-is-write-only +4198 _Primitive-and-lit-with-reg/imm32/next +4199 _Primitive-and-lit-with-reg: +4200 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 +4201 "and"/imm32/name +4202 Single-lit-var/imm32/inouts +4203 Single-int-var-in-some-register/imm32/outputs +4204 "81 4/subop/and"/imm32/subx-name +4205 3/imm32/rm32-is-first-output +4206 0/imm32/no-r32 +4207 1/imm32/imm32-is-first-inout +4208 0/imm32/output-is-write-only +4209 _Primitive-and-lit-with-mem/imm32/next +4210 _Primitive-and-lit-with-mem: +4211 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 +4212 "and-with"/imm32/name +4213 Int-var-and-literal/imm32/inouts +4214 0/imm32/outputs +4215 "81 4/subop/and"/imm32/subx-name +4216 1/imm32/rm32-is-first-inout +4217 0/imm32/no-r32 +4218 2/imm32/imm32-is-first-inout +4219 0/imm32/output-is-write-only +4220 _Primitive-or-with-eax/imm32/next +4221 # - or +4222 _Primitive-or-with-eax: +4223 # var/eax <- or lit => 0d/or-with-eax lit/imm32 +4224 "or"/imm32/name +4225 Single-lit-var/imm32/inouts +4226 Single-int-var-in-eax/imm32/outputs +4227 "0d/or-with-eax"/imm32/subx-name +4228 0/imm32/no-rm32 +4229 0/imm32/no-r32 +4230 1/imm32/imm32-is-first-inout +4231 0/imm32/output-is-write-only +4232 _Primitive-or-reg-with-reg/imm32/next +4233 _Primitive-or-reg-with-reg: +4234 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 +4235 "or"/imm32/name +4236 Single-int-var-in-some-register/imm32/inouts +4237 Single-int-var-in-some-register/imm32/outputs +4238 "09/or-with"/imm32/subx-name +4239 3/imm32/rm32-is-first-output +4240 1/imm32/r32-is-first-inout +4241 0/imm32/no-imm32 +4242 0/imm32/output-is-write-only +4243 _Primitive-or-reg-with-mem/imm32/next +4244 _Primitive-or-reg-with-mem: +4245 # or-with var1 var2/reg => 09/or-with var1 var2/r32 +4246 "or-with"/imm32/name +4247 Int-var-and-second-int-var-in-some-register/imm32/inouts +4248 0/imm32/outputs +4249 "09/or-with"/imm32/subx-name +4250 1/imm32/rm32-is-first-inout +4251 2/imm32/r32-is-second-inout +4252 0/imm32/no-imm32 +4253 0/imm32/output-is-write-only +4254 _Primitive-or-mem-with-reg/imm32/next +4255 _Primitive-or-mem-with-reg: +4256 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 +4257 "or"/imm32/name +4258 Single-int-var-on-stack/imm32/inouts +4259 Single-int-var-in-some-register/imm32/outputs +4260 "0b/or"/imm32/subx-name +4261 1/imm32/rm32-is-first-inout +4262 3/imm32/r32-is-first-output +4263 0/imm32/no-imm32 +4264 0/imm32/output-is-write-only +4265 _Primitive-or-lit-with-reg/imm32/next +4266 _Primitive-or-lit-with-reg: +4267 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 +4268 "or"/imm32/name +4269 Single-lit-var/imm32/inouts +4270 Single-int-var-in-some-register/imm32/outputs +4271 "81 4/subop/or"/imm32/subx-name +4272 3/imm32/rm32-is-first-output +4273 0/imm32/no-r32 +4274 1/imm32/imm32-is-first-inout +4275 0/imm32/output-is-write-only +4276 _Primitive-or-lit-with-mem/imm32/next +4277 _Primitive-or-lit-with-mem: +4278 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 +4279 "or-with"/imm32/name +4280 Int-var-and-literal/imm32/inouts +4281 0/imm32/outputs +4282 "81 4/subop/or"/imm32/subx-name +4283 1/imm32/rm32-is-first-inout +4284 0/imm32/no-r32 +4285 2/imm32/imm32-is-first-inout +4286 0/imm32/output-is-write-only +4287 _Primitive-xor-with-eax/imm32/next +4288 # - xor +4289 _Primitive-xor-with-eax: +4290 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 +4291 "xor"/imm32/name +4292 Single-lit-var/imm32/inouts +4293 Single-int-var-in-eax/imm32/outputs +4294 "35/xor-with-eax"/imm32/subx-name +4295 0/imm32/no-rm32 +4296 0/imm32/no-r32 +4297 1/imm32/imm32-is-first-inout +4298 0/imm32/output-is-write-only +4299 _Primitive-xor-reg-with-reg/imm32/next +4300 _Primitive-xor-reg-with-reg: +4301 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 +4302 "xor"/imm32/name +4303 Single-int-var-in-some-register/imm32/inouts +4304 Single-int-var-in-some-register/imm32/outputs +4305 "31/xor-with"/imm32/subx-name +4306 3/imm32/rm32-is-first-output +4307 1/imm32/r32-is-first-inout +4308 0/imm32/no-imm32 +4309 0/imm32/output-is-write-only +4310 _Primitive-xor-reg-with-mem/imm32/next +4311 _Primitive-xor-reg-with-mem: +4312 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 +4313 "xor-with"/imm32/name +4314 Int-var-and-second-int-var-in-some-register/imm32/inouts +4315 0/imm32/outputs +4316 "31/xor-with"/imm32/subx-name +4317 1/imm32/rm32-is-first-inout +4318 2/imm32/r32-is-second-inout +4319 0/imm32/no-imm32 +4320 0/imm32/output-is-write-only +4321 _Primitive-xor-mem-with-reg/imm32/next +4322 _Primitive-xor-mem-with-reg: +4323 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 +4324 "xor"/imm32/name +4325 Single-int-var-on-stack/imm32/inouts +4326 Single-int-var-in-some-register/imm32/outputs +4327 "33/xor"/imm32/subx-name +4328 1/imm32/rm32-is-first-inout +4329 3/imm32/r32-is-first-output +4330 0/imm32/no-imm32 +4331 0/imm32/output-is-write-only +4332 _Primitive-xor-lit-with-reg/imm32/next +4333 _Primitive-xor-lit-with-reg: +4334 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 +4335 "xor"/imm32/name +4336 Single-lit-var/imm32/inouts +4337 Single-int-var-in-some-register/imm32/outputs +4338 "81 4/subop/xor"/imm32/subx-name +4339 3/imm32/rm32-is-first-output +4340 0/imm32/no-r32 +4341 1/imm32/imm32-is-first-inout +4342 0/imm32/output-is-write-only +4343 _Primitive-xor-lit-with-mem/imm32/next +4344 _Primitive-xor-lit-with-mem: +4345 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 +4346 "xor-with"/imm32/name +4347 Int-var-and-literal/imm32/inouts +4348 0/imm32/outputs +4349 "81 4/subop/xor"/imm32/subx-name +4350 1/imm32/rm32-is-first-inout +4351 0/imm32/no-r32 +4352 2/imm32/imm32-is-first-inout +4353 0/imm32/output-is-write-only +4354 _Primitive-copy-to-eax/imm32/next +4355 # - copy +4356 _Primitive-copy-to-eax: +4357 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 +4358 "copy"/imm32/name +4359 Single-lit-var/imm32/inouts +4360 Single-int-var-in-eax/imm32/outputs +4361 "b8/copy-to-eax"/imm32/subx-name +4362 0/imm32/no-rm32 +4363 0/imm32/no-r32 +4364 1/imm32/imm32-is-first-inout +4365 1/imm32/output-is-write-only +4366 _Primitive-copy-to-ecx/imm32/next +4367 _Primitive-copy-to-ecx: +4368 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 +4369 "copy"/imm32/name +4370 Single-lit-var/imm32/inouts +4371 Single-int-var-in-ecx/imm32/outputs +4372 "b9/copy-to-ecx"/imm32/subx-name +4373 0/imm32/no-rm32 +4374 0/imm32/no-r32 +4375 1/imm32/imm32-is-first-inout +4376 1/imm32/output-is-write-only +4377 _Primitive-copy-to-edx/imm32/next +4378 _Primitive-copy-to-edx: +4379 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 +4380 "copy"/imm32/name +4381 Single-lit-var/imm32/inouts +4382 Single-int-var-in-edx/imm32/outputs +4383 "ba/copy-to-edx"/imm32/subx-name +4384 0/imm32/no-rm32 +4385 0/imm32/no-r32 +4386 1/imm32/imm32-is-first-inout +4387 1/imm32/output-is-write-only +4388 _Primitive-copy-to-ebx/imm32/next +4389 _Primitive-copy-to-ebx: +4390 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 +4391 "copy"/imm32/name +4392 Single-lit-var/imm32/inouts +4393 Single-int-var-in-ebx/imm32/outputs +4394 "bb/copy-to-ebx"/imm32/subx-name +4395 0/imm32/no-rm32 +4396 0/imm32/no-r32 +4397 1/imm32/imm32-is-first-inout +4398 1/imm32/output-is-write-only +4399 _Primitive-copy-to-esi/imm32/next +4400 _Primitive-copy-to-esi: +4401 # var/esi <- copy lit => be/copy-to-esi lit/imm32 +4402 "copy"/imm32/name +4403 Single-lit-var/imm32/inouts +4404 Single-int-var-in-esi/imm32/outputs +4405 "be/copy-to-esi"/imm32/subx-name +4406 0/imm32/no-rm32 +4407 0/imm32/no-r32 +4408 1/imm32/imm32-is-first-inout +4409 1/imm32/output-is-write-only +4410 _Primitive-copy-to-edi/imm32/next +4411 _Primitive-copy-to-edi: +4412 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 +4413 "copy"/imm32/name +4414 Single-lit-var/imm32/inouts +4415 Single-int-var-in-edi/imm32/outputs +4416 "bf/copy-to-edi"/imm32/subx-name +4417 0/imm32/no-rm32 +4418 0/imm32/no-r32 +4419 1/imm32/imm32-is-first-inout +4420 1/imm32/output-is-write-only +4421 _Primitive-copy-reg-to-reg/imm32/next +4422 _Primitive-copy-reg-to-reg: +4423 # var1/reg <- copy var2/reg => 89/copy-to var1/rm32 var2/r32 +4424 "copy"/imm32/name +4425 Single-int-var-in-some-register/imm32/inouts +4426 Single-int-var-in-some-register/imm32/outputs +4427 "89/copy-to"/imm32/subx-name +4428 3/imm32/rm32-is-first-output +4429 1/imm32/r32-is-first-inout +4430 0/imm32/no-imm32 +4431 1/imm32/output-is-write-only +4432 _Primitive-copy-reg-to-mem/imm32/next +4433 _Primitive-copy-reg-to-mem: +4434 # copy-to var1 var2/reg => 89/copy-to var1 var2/r32 +4435 "copy-to"/imm32/name +4436 Int-var-and-second-int-var-in-some-register/imm32/inouts +4437 0/imm32/outputs +4438 "89/copy-to"/imm32/subx-name +4439 1/imm32/rm32-is-first-inout +4440 2/imm32/r32-is-second-inout +4441 0/imm32/no-imm32 +4442 1/imm32/output-is-write-only +4443 _Primitive-copy-mem-to-reg/imm32/next +4444 _Primitive-copy-mem-to-reg: +4445 # var1/reg <- copy var2 => 8b/copy-from var2/rm32 var1/r32 +4446 "copy"/imm32/name +4447 Single-int-var-on-stack/imm32/inouts +4448 Single-int-var-in-some-register/imm32/outputs +4449 "8b/copy-from"/imm32/subx-name +4450 1/imm32/rm32-is-first-inout +4451 3/imm32/r32-is-first-output +4452 0/imm32/no-imm32 +4453 1/imm32/output-is-write-only +4454 _Primitive-copy-lit-to-reg/imm32/next +4455 _Primitive-copy-lit-to-reg: +4456 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 +4457 "copy"/imm32/name +4458 Single-lit-var/imm32/inouts +4459 Single-int-var-in-some-register/imm32/outputs +4460 "c7 0/subop/copy"/imm32/subx-name +4461 3/imm32/rm32-is-first-output +4462 0/imm32/no-r32 +4463 1/imm32/imm32-is-first-inout +4464 1/imm32/output-is-write-only +4465 _Primitive-copy-lit-to-mem/imm32/next +4466 _Primitive-copy-lit-to-mem: +4467 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 +4468 "copy-to"/imm32/name +4469 Int-var-and-literal/imm32/inouts +4470 0/imm32/outputs +4471 "c7 0/subop/copy"/imm32/subx-name +4472 1/imm32/rm32-is-first-inout +4473 0/imm32/no-r32 +4474 2/imm32/imm32-is-first-inout +4475 1/imm32/output-is-write-only +4476 0/imm32/next +4477 +4478 Single-int-var-on-stack: +4479 Int-var-on-stack/imm32 +4480 0/imm32/next +4481 +4482 Int-var-on-stack: +4483 "arg1"/imm32/name +4484 Type-int/imm32 +4485 1/imm32/some-block-depth +4486 1/imm32/some-stack-offset +4487 0/imm32/no-register +4488 +4489 Int-var-and-second-int-var-in-some-register: +4490 Int-var-on-stack/imm32 +4491 Single-int-var-in-some-register/imm32/next +4492 +4493 Int-var-and-literal: +4494 Int-var-on-stack/imm32 +4495 Single-lit-var/imm32/next +4496 +4497 Single-int-var-in-some-register: +4498 Int-var-in-some-register/imm32 +4499 0/imm32/next +4500 +4501 Int-var-in-some-register: +4502 "arg1"/imm32/name +4503 Type-int/imm32 +4504 1/imm32/some-block-depth +4505 0/imm32/no-stack-offset +4506 "*"/imm32/register +4507 +4508 Single-int-var-in-eax: +4509 Int-var-in-eax/imm32 +4510 0/imm32/next +4511 +4512 Int-var-in-eax: +4513 "arg1"/imm32/name +4514 Type-int/imm32 +4515 1/imm32/some-block-depth +4516 0/imm32/no-stack-offset +4517 "eax"/imm32/register +4518 +4519 Single-int-var-in-ecx: +4520 Int-var-in-ecx/imm32 +4521 0/imm32/next +4522 +4523 Int-var-in-ecx: +4524 "arg1"/imm32/name +4525 Type-int/imm32 +4526 1/imm32/some-block-depth +4527 0/imm32/no-stack-offset +4528 "ecx"/imm32/register +4529 +4530 Single-int-var-in-edx: +4531 Int-var-in-edx/imm32 +4532 0/imm32/next +4533 +4534 Int-var-in-edx: +4535 "arg1"/imm32/name +4536 Type-int/imm32 +4537 1/imm32/some-block-depth +4538 0/imm32/no-stack-offset +4539 "edx"/imm32/register +4540 +4541 Single-int-var-in-ebx: +4542 Int-var-in-ebx/imm32 +4543 0/imm32/next +4544 +4545 Int-var-in-ebx: +4546 "arg1"/imm32/name +4547 Type-int/imm32 +4548 1/imm32/some-block-depth +4549 0/imm32/no-stack-offset +4550 "ebx"/imm32/register +4551 +4552 Single-int-var-in-esi: +4553 Int-var-in-esi/imm32 +4554 0/imm32/next +4555 +4556 Int-var-in-esi: +4557 "arg1"/imm32/name +4558 Type-int/imm32 +4559 1/imm32/some-block-depth +4560 0/imm32/no-stack-offset +4561 "esi"/imm32/register +4562 +4563 Single-int-var-in-edi: +4564 Int-var-in-edi/imm32 +4565 0/imm32/next +4566 +4567 Int-var-in-edi: +4568 "arg1"/imm32/name +4569 Type-int/imm32 +4570 1/imm32/some-block-depth +4571 0/imm32/no-stack-offset +4572 "edi"/imm32/register +4573 +4574 Single-lit-var: +4575 Lit-var/imm32 +4576 0/imm32/next 4577 -4578 emit-subx-rm32: # out : (addr buffered-file), l : arg-location, stmt : (handle statement) -4579 # . prologue -4580 55/push-ebp -4581 89/<- %ebp 4/r32/esp -4582 # . save registers -4583 50/push-eax -4584 # if (l == 0) return -4585 81 7/subop/compare *(ebp+0xc) 0/imm32 -4586 74/jump-if-= $emit-subx-rm32:end/disp8 -4587 # -4588 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax -4589 (emit-subx-var-as-rm32 *(ebp+8) %eax) # out, var -4590 $emit-subx-rm32:end: -4591 # . restore registers -4592 58/pop-to-eax -4593 # . epilogue -4594 89/<- %esp 5/r32/ebp -4595 5d/pop-to-ebp -4596 c3/return -4597 -4598 get-stmt-operand-from-arg-location: # stmt : (handle statement), l : arg-location -> var/eax : (handle variable) -4599 # . prologue -4600 55/push-ebp -4601 89/<- %ebp 4/r32/esp -4602 # . save registers -4603 51/push-ecx -4604 # eax = l -4605 8b/-> *(ebp+0xc) 0/r32/eax -4606 # ecx = stmt -4607 8b/-> *(ebp+8) 1/r32/ecx -4608 # if (l == 1) return stmt->inouts->var -4609 { -4610 3d/compare-eax-and 1/imm32 -4611 75/jump-if-!= break/disp8 -4612 $get-stmt-operand-from-arg-location:1: -4613 8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts -4614 8b/-> *eax 0/r32/eax # Operand-var -4615 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -4616 } -4617 # if (l == 2) return stmt->inouts->next->var -4618 { -4619 3d/compare-eax-and 2/imm32 -4620 75/jump-if-!= break/disp8 -4621 $get-stmt-operand-from-arg-location:2: -4622 8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts -4623 8b/-> *(eax+4) 0/r32/eax # Operand-next -4624 8b/-> *eax 0/r32/eax # Operand-var -4625 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -4626 } -4627 # if (l == 3) return stmt->outputs -4628 { -4629 3d/compare-eax-and 3/imm32 -4630 75/jump-if-!= break/disp8 -4631 $get-stmt-operand-from-arg-location:3: -4632 8b/-> *(ecx+0xc) 0/r32/eax # Stmt1-outputs -4633 8b/-> *eax 0/r32/eax # Operand-var -4634 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -4635 } -4636 # abort -4637 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 -4638 $get-stmt-operand-from-arg-location:end: -4639 # . restore registers -4640 59/pop-to-ecx -4641 # . epilogue -4642 89/<- %esp 5/r32/ebp -4643 5d/pop-to-ebp -4644 c3/return -4645 -4646 $get-stmt-operand-from-arg-location:abort: -4647 # error("invalid arg-location " eax) -4648 (write-buffered Stderr "invalid arg-location ") -4649 (print-int32-buffered Stderr %eax) -4650 (write-buffered Stderr "\n") -4651 (flush Stderr) -4652 # . syscall(exit, 1) -4653 bb/copy-to-ebx 1/imm32 -4654 b8/copy-to-eax 1/imm32/exit -4655 cd/syscall 0x80/imm8 -4656 # never gets here -4657 -4658 emit-subx-r32: # out : (addr buffered-file), l : arg-location, stmt : (handle statement) -4659 # . prologue -4660 55/push-ebp -4661 89/<- %ebp 4/r32/esp -4662 # . save registers -4663 50/push-eax -4664 51/push-ecx -4665 # if (location == 0) return -4666 81 7/subop/compare *(ebp+0xc) 0/imm32 -4667 0f 84/jump-if-= $emit-subx-r32:end/disp32 -4668 # -4669 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax -4670 (maybe-get Registers *(eax+0x10) 8) # Var-register => eax : (addr register-index) -4671 (write-buffered *(ebp+8) Space) -4672 (print-int32-buffered *(ebp+8) *eax) -4673 (write-buffered *(ebp+8) "/r32") -4674 $emit-subx-r32:end: -4675 # . restore registers -4676 59/pop-to-ecx -4677 58/pop-to-eax -4678 # . epilogue -4679 89/<- %esp 5/r32/ebp -4680 5d/pop-to-ebp -4681 c3/return -4682 -4683 emit-subx-imm32: # out : (addr buffered-file), l : arg-location, stmt : (handle statement) -4684 # . prologue -4685 55/push-ebp -4686 89/<- %ebp 4/r32/esp -4687 # . save registers -4688 50/push-eax -4689 51/push-ecx -4690 # if (location == 0) return -4691 81 7/subop/compare *(ebp+0xc) 0/imm32 -4692 74/jump-if-= $emit-subx-imm32:end/disp8 -4693 # -4694 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax -4695 (write-buffered *(ebp+8) Space) -4696 (write-buffered *(ebp+8) *eax) # Var-name -4697 (write-buffered *(ebp+8) "/imm32") -4698 $emit-subx-imm32:end: -4699 # . restore registers -4700 59/pop-to-ecx -4701 58/pop-to-eax -4702 # . epilogue -4703 89/<- %esp 5/r32/ebp -4704 5d/pop-to-ebp -4705 c3/return -4706 -4707 emit-subx-call: # out : (addr buffered-file), stmt : (handle statement), callee : (handle function) -4708 # . prologue -4709 55/push-ebp -4710 89/<- %ebp 4/r32/esp -4711 # . save registers -4712 50/push-eax -4713 51/push-ecx -4714 # -4715 (write-buffered *(ebp+8) "(") -4716 # - emit function name -4717 8b/-> *(ebp+0x10) 1/r32/ecx -4718 (write-buffered *(ebp+8) *(ecx+4)) # Function-subx-name -4719 # - emit arguments -4720 # var curr/ecx : (handle list var) = stmt->inouts -4721 8b/-> *(ebp+0xc) 1/r32/ecx -4722 8b/-> *(ecx+8) 1/r32/ecx # Stmt1-inouts -4723 { -4724 # if (curr == null) break -4725 81 7/subop/compare %ecx 0/imm32 -4726 74/jump-if-= break/disp8 -4727 # -4728 (emit-subx-call-operand *(ebp+8) *ecx) -4729 # curr = curr->next -4730 8b/-> *(ecx+4) 1/r32/ecx -4731 eb/jump loop/disp8 -4732 } -4733 # -4734 (write-buffered *(ebp+8) ")") -4735 $emit-subx-call:end: -4736 # . restore registers -4737 59/pop-to-ecx -4738 58/pop-to-eax -4739 # . epilogue -4740 89/<- %esp 5/r32/ebp -4741 5d/pop-to-ebp -4742 c3/return -4743 -4744 emit-subx-call-operand: # out : (addr buffered-file), operand : (handle variable) -4745 # . prologue -4746 55/push-ebp -4747 89/<- %ebp 4/r32/esp -4748 # . save registers -4749 50/push-eax -4750 # eax = operand -4751 8b/-> *(ebp+0xc) 0/r32/eax -4752 # if (operand->register) emit "%__" -4753 { -4754 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register -4755 74/jump-if-= break/disp8 -4756 $emit-subx-call-operand:register: -4757 (write-buffered *(ebp+8) " %") -4758 (write-buffered *(ebp+8) *(eax+0x10)) # Var-register -4759 e9/jump $emit-subx-call-operand:end/disp32 -4760 } -4761 # else if (operand->stack-offset) emit "*(ebp+__)" -4762 { -4763 81 7/subop/compare *(eax+0xc) 0/imm32 # Var-stack-offset -4764 74/jump-if-= break/disp8 -4765 $emit-subx-call-operand:stack: -4766 (write-buffered *(ebp+8) Space) -4767 (write-buffered *(ebp+8) "*(ebp+") -4768 8b/-> *(ebp+0xc) 0/r32/eax -4769 (print-int32-buffered *(ebp+8) *(eax+0xc)) # Var-stack-offset -4770 (write-buffered *(ebp+8) ")") -4771 e9/jump $emit-subx-call-operand:end/disp32 -4772 } -4773 # else if (operand->type == literal) emit "__" -4774 { -4775 50/push-eax -4776 8b/-> *(eax+4) 0/r32/eax # Var-type -4777 81 7/subop/compare *eax 0/imm32 # Tree-left -4778 58/pop-to-eax -4779 75/jump-if-!= break/disp8 -4780 $emit-subx-call-operand:literal: -4781 (write-buffered *(ebp+8) Space) -4782 (write-buffered *(ebp+8) *eax) -4783 } -4784 $emit-subx-call-operand:end: -4785 # . restore registers -4786 58/pop-to-eax -4787 # . epilogue -4788 89/<- %esp 5/r32/ebp -4789 5d/pop-to-ebp -4790 c3/return -4791 -4792 emit-subx-var-as-rm32: # out : (addr buffered-file), operand : (handle variable) -4793 # . prologue -4794 55/push-ebp -4795 89/<- %ebp 4/r32/esp -4796 # . save registers -4797 50/push-eax -4798 # eax = operand -4799 8b/-> *(ebp+0xc) 0/r32/eax -4800 # if (operand->register) emit "%__" -4801 { -4802 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register -4803 74/jump-if-= break/disp8 -4804 $emit-subx-var-as-rm32:register: -4805 (write-buffered *(ebp+8) " %") -4806 (write-buffered *(ebp+8) *(eax+0x10)) # Var-register -4807 } -4808 # else if (operand->stack-offset) emit "*(ebp+__)" -4809 { -4810 81 7/subop/compare *(eax+0xc) 0/imm32 # Var-stack-offset -4811 74/jump-if-= break/disp8 -4812 $emit-subx-var-as-rm32:stack: -4813 (write-buffered *(ebp+8) Space) -4814 (write-buffered *(ebp+8) "*(ebp+") -4815 8b/-> *(ebp+0xc) 0/r32/eax -4816 (print-int32-buffered *(ebp+8) *(eax+0xc)) # Var-stack-offset -4817 (write-buffered *(ebp+8) ")") -4818 } -4819 $emit-subx-var-as-rm32:end: -4820 # . restore registers -4821 58/pop-to-eax -4822 # . epilogue -4823 89/<- %esp 5/r32/ebp -4824 5d/pop-to-ebp -4825 c3/return -4826 -4827 find-matching-function: # functions : (addr function), stmt : (handle statement) -> result/eax : (handle function) -4828 # . prologue -4829 55/push-ebp -4830 89/<- %ebp 4/r32/esp -4831 # . save registers -4832 51/push-ecx -4833 # var curr/ecx : (handle function) = functions -4834 8b/-> *(ebp+8) 1/r32/ecx -4835 { -4836 # if (curr == null) break -4837 81 7/subop/compare %ecx 0/imm32 -4838 74/jump-if-= break/disp8 -4839 # if match(stmt, curr) return curr -4840 { -4841 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax -4842 3d/compare-eax-and 0/imm32 -4843 74/jump-if-= break/disp8 -4844 89/<- %eax 1/r32/ecx -4845 eb/jump $find-matching-function:end/disp8 -4846 } -4847 # curr = curr->next -4848 8b/-> *(ecx+0x14) 1/r32/ecx # Function-next -4849 eb/jump loop/disp8 -4850 } -4851 # return null -4852 b8/copy-to-eax 0/imm32 -4853 $find-matching-function:end: -4854 # . restore registers -4855 59/pop-to-ecx -4856 # . epilogue -4857 89/<- %esp 5/r32/ebp -4858 5d/pop-to-ebp -4859 c3/return -4860 -4861 find-matching-primitive: # primitives : (handle primitive), stmt : (handle statement) -> result/eax : (handle primitive) -4862 # . prologue -4863 55/push-ebp -4864 89/<- %ebp 4/r32/esp -4865 # . save registers -4866 51/push-ecx -4867 # var curr/ecx : (handle primitive) = primitives -4868 8b/-> *(ebp+8) 1/r32/ecx -4869 { -4870 $find-matching-primitive:loop: -4871 # if (curr == null) break -4872 81 7/subop/compare %ecx 0/imm32 -4873 0f 84/jump-if-= break/disp32 -4874 #? (write-buffered Stderr "prim: ") -4875 #? (write-buffered Stderr *ecx) # Primitive-name -4876 #? (write-buffered Stderr " => ") -4877 #? (write-buffered Stderr *(ecx+0xc)) # Primitive-subx-name -4878 #? (write-buffered Stderr "\n") -4879 #? (flush Stderr) -4880 # if match(curr, stmt) return curr -4881 { -4882 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax -4883 3d/compare-eax-and 0/imm32 -4884 74/jump-if-= break/disp8 -4885 89/<- %eax 1/r32/ecx -4886 eb/jump $find-matching-primitive:end/disp8 -4887 } -4888 $find-matching-primitive:next-primitive: +4578 Lit-var: +4579 "literal"/imm32/name +4580 Type-literal/imm32 +4581 1/imm32/some-block-depth +4582 0/imm32/no-stack-offset +4583 0/imm32/no-register +4584 +4585 Type-int: +4586 1/imm32/left/int +4587 0/imm32/right/null +4588 +4589 Type-literal: +4590 0/imm32/left/literal +4591 0/imm32/right/null +4592 +4593 == code +4594 emit-subx-primitive: # out: (addr buffered-file), stmt: (handle statement), primitive: (handle function) +4595 # . prologue +4596 55/push-ebp +4597 89/<- %ebp 4/r32/esp +4598 # . save registers +4599 50/push-eax +4600 51/push-ecx +4601 # ecx = primitive +4602 8b/-> *(ebp+0x10) 1/r32/ecx +4603 # emit primitive name +4604 (write-buffered *(ebp+8) *(ecx+0xc)) # Primitive-subx-name +4605 # emit rm32 if necessary +4606 (emit-subx-rm32 *(ebp+8) *(ecx+0x10) *(ebp+0xc)) # out, Primitive-subx-rm32, stmt +4607 # emit r32 if necessary +4608 (emit-subx-r32 *(ebp+8) *(ecx+0x14) *(ebp+0xc)) # out, Primitive-subx-r32, stmt +4609 # emit imm32 if necessary +4610 (emit-subx-imm32 *(ebp+8) *(ecx+0x18) *(ebp+0xc)) # out, Primitive-subx-imm32, stmt +4611 $emit-subx-primitive:end: +4612 # . restore registers +4613 59/pop-to-ecx +4614 58/pop-to-eax +4615 # . epilogue +4616 89/<- %esp 5/r32/ebp +4617 5d/pop-to-ebp +4618 c3/return +4619 +4620 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) +4621 # . prologue +4622 55/push-ebp +4623 89/<- %ebp 4/r32/esp +4624 # . save registers +4625 50/push-eax +4626 # if (l == 0) return +4627 81 7/subop/compare *(ebp+0xc) 0/imm32 +4628 74/jump-if-= $emit-subx-rm32:end/disp8 +4629 # +4630 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax +4631 (emit-subx-var-as-rm32 *(ebp+8) %eax) # out, var +4632 $emit-subx-rm32:end: +4633 # . restore registers +4634 58/pop-to-eax +4635 # . epilogue +4636 89/<- %esp 5/r32/ebp +4637 5d/pop-to-ebp +4638 c3/return +4639 +4640 get-stmt-operand-from-arg-location: # stmt: (handle statement), l: arg-location -> var/eax: (handle variable) +4641 # . prologue +4642 55/push-ebp +4643 89/<- %ebp 4/r32/esp +4644 # . save registers +4645 51/push-ecx +4646 # eax = l +4647 8b/-> *(ebp+0xc) 0/r32/eax +4648 # ecx = stmt +4649 8b/-> *(ebp+8) 1/r32/ecx +4650 # if (l == 1) return stmt->inouts->var +4651 { +4652 3d/compare-eax-and 1/imm32 +4653 75/jump-if-!= break/disp8 +4654 $get-stmt-operand-from-arg-location:1: +4655 8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts +4656 8b/-> *eax 0/r32/eax # Operand-var +4657 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +4658 } +4659 # if (l == 2) return stmt->inouts->next->var +4660 { +4661 3d/compare-eax-and 2/imm32 +4662 75/jump-if-!= break/disp8 +4663 $get-stmt-operand-from-arg-location:2: +4664 8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts +4665 8b/-> *(eax+4) 0/r32/eax # Operand-next +4666 8b/-> *eax 0/r32/eax # Operand-var +4667 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +4668 } +4669 # if (l == 3) return stmt->outputs +4670 { +4671 3d/compare-eax-and 3/imm32 +4672 75/jump-if-!= break/disp8 +4673 $get-stmt-operand-from-arg-location:3: +4674 8b/-> *(ecx+0xc) 0/r32/eax # Stmt1-outputs +4675 8b/-> *eax 0/r32/eax # Operand-var +4676 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +4677 } +4678 # abort +4679 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 +4680 $get-stmt-operand-from-arg-location:end: +4681 # . restore registers +4682 59/pop-to-ecx +4683 # . epilogue +4684 89/<- %esp 5/r32/ebp +4685 5d/pop-to-ebp +4686 c3/return +4687 +4688 $get-stmt-operand-from-arg-location:abort: +4689 # error("invalid arg-location " eax) +4690 (write-buffered Stderr "invalid arg-location ") +4691 (print-int32-buffered Stderr %eax) +4692 (write-buffered Stderr "\n") +4693 (flush Stderr) +4694 # . syscall(exit, 1) +4695 bb/copy-to-ebx 1/imm32 +4696 b8/copy-to-eax 1/imm32/exit +4697 cd/syscall 0x80/imm8 +4698 # never gets here +4699 +4700 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) +4701 # . prologue +4702 55/push-ebp +4703 89/<- %ebp 4/r32/esp +4704 # . save registers +4705 50/push-eax +4706 51/push-ecx +4707 # if (location == 0) return +4708 81 7/subop/compare *(ebp+0xc) 0/imm32 +4709 0f 84/jump-if-= $emit-subx-r32:end/disp32 +4710 # +4711 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax +4712 (maybe-get Registers *(eax+0x10) 8) # Var-register => eax: (addr register-index) +4713 (write-buffered *(ebp+8) Space) +4714 (print-int32-buffered *(ebp+8) *eax) +4715 (write-buffered *(ebp+8) "/r32") +4716 $emit-subx-r32:end: +4717 # . restore registers +4718 59/pop-to-ecx +4719 58/pop-to-eax +4720 # . epilogue +4721 89/<- %esp 5/r32/ebp +4722 5d/pop-to-ebp +4723 c3/return +4724 +4725 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) +4726 # . prologue +4727 55/push-ebp +4728 89/<- %ebp 4/r32/esp +4729 # . save registers +4730 50/push-eax +4731 51/push-ecx +4732 # if (location == 0) return +4733 81 7/subop/compare *(ebp+0xc) 0/imm32 +4734 74/jump-if-= $emit-subx-imm32:end/disp8 +4735 # +4736 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax +4737 (write-buffered *(ebp+8) Space) +4738 (write-buffered *(ebp+8) *eax) # Var-name +4739 (write-buffered *(ebp+8) "/imm32") +4740 $emit-subx-imm32:end: +4741 # . restore registers +4742 59/pop-to-ecx +4743 58/pop-to-eax +4744 # . epilogue +4745 89/<- %esp 5/r32/ebp +4746 5d/pop-to-ebp +4747 c3/return +4748 +4749 emit-subx-call: # out: (addr buffered-file), stmt: (handle statement), callee: (handle function) +4750 # . prologue +4751 55/push-ebp +4752 89/<- %ebp 4/r32/esp +4753 # . save registers +4754 50/push-eax +4755 51/push-ecx +4756 # +4757 (write-buffered *(ebp+8) "(") +4758 # - emit function name +4759 8b/-> *(ebp+0x10) 1/r32/ecx +4760 (write-buffered *(ebp+8) *(ecx+4)) # Function-subx-name +4761 # - emit arguments +4762 # var curr/ecx: (handle list var) = stmt->inouts +4763 8b/-> *(ebp+0xc) 1/r32/ecx +4764 8b/-> *(ecx+8) 1/r32/ecx # Stmt1-inouts +4765 { +4766 # if (curr == null) break +4767 81 7/subop/compare %ecx 0/imm32 +4768 74/jump-if-= break/disp8 +4769 # +4770 (emit-subx-call-operand *(ebp+8) *ecx) +4771 # curr = curr->next +4772 8b/-> *(ecx+4) 1/r32/ecx +4773 eb/jump loop/disp8 +4774 } +4775 # +4776 (write-buffered *(ebp+8) ")") +4777 $emit-subx-call:end: +4778 # . restore registers +4779 59/pop-to-ecx +4780 58/pop-to-eax +4781 # . epilogue +4782 89/<- %esp 5/r32/ebp +4783 5d/pop-to-ebp +4784 c3/return +4785 +4786 emit-subx-call-operand: # out: (addr buffered-file), operand: (handle variable) +4787 # . prologue +4788 55/push-ebp +4789 89/<- %ebp 4/r32/esp +4790 # . save registers +4791 50/push-eax +4792 # eax = operand +4793 8b/-> *(ebp+0xc) 0/r32/eax +4794 # if (operand->register) emit "%__" +4795 { +4796 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register +4797 74/jump-if-= break/disp8 +4798 $emit-subx-call-operand:register: +4799 (write-buffered *(ebp+8) " %") +4800 (write-buffered *(ebp+8) *(eax+0x10)) # Var-register +4801 e9/jump $emit-subx-call-operand:end/disp32 +4802 } +4803 # else if (operand->stack-offset) emit "*(ebp+__)" +4804 { +4805 81 7/subop/compare *(eax+0xc) 0/imm32 # Var-stack-offset +4806 74/jump-if-= break/disp8 +4807 $emit-subx-call-operand:stack: +4808 (write-buffered *(ebp+8) Space) +4809 (write-buffered *(ebp+8) "*(ebp+") +4810 8b/-> *(ebp+0xc) 0/r32/eax +4811 (print-int32-buffered *(ebp+8) *(eax+0xc)) # Var-stack-offset +4812 (write-buffered *(ebp+8) ")") +4813 e9/jump $emit-subx-call-operand:end/disp32 +4814 } +4815 # else if (operand->type == literal) emit "__" +4816 { +4817 50/push-eax +4818 8b/-> *(eax+4) 0/r32/eax # Var-type +4819 81 7/subop/compare *eax 0/imm32 # Tree-left +4820 58/pop-to-eax +4821 75/jump-if-!= break/disp8 +4822 $emit-subx-call-operand:literal: +4823 (write-buffered *(ebp+8) Space) +4824 (write-buffered *(ebp+8) *eax) +4825 } +4826 $emit-subx-call-operand:end: +4827 # . restore registers +4828 58/pop-to-eax +4829 # . epilogue +4830 89/<- %esp 5/r32/ebp +4831 5d/pop-to-ebp +4832 c3/return +4833 +4834 emit-subx-var-as-rm32: # out: (addr buffered-file), operand: (handle variable) +4835 # . prologue +4836 55/push-ebp +4837 89/<- %ebp 4/r32/esp +4838 # . save registers +4839 50/push-eax +4840 # eax = operand +4841 8b/-> *(ebp+0xc) 0/r32/eax +4842 # if (operand->register) emit "%__" +4843 { +4844 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register +4845 74/jump-if-= break/disp8 +4846 $emit-subx-var-as-rm32:register: +4847 (write-buffered *(ebp+8) " %") +4848 (write-buffered *(ebp+8) *(eax+0x10)) # Var-register +4849 } +4850 # else if (operand->stack-offset) emit "*(ebp+__)" +4851 { +4852 81 7/subop/compare *(eax+0xc) 0/imm32 # Var-stack-offset +4853 74/jump-if-= break/disp8 +4854 $emit-subx-var-as-rm32:stack: +4855 (write-buffered *(ebp+8) Space) +4856 (write-buffered *(ebp+8) "*(ebp+") +4857 8b/-> *(ebp+0xc) 0/r32/eax +4858 (print-int32-buffered *(ebp+8) *(eax+0xc)) # Var-stack-offset +4859 (write-buffered *(ebp+8) ")") +4860 } +4861 $emit-subx-var-as-rm32:end: +4862 # . restore registers +4863 58/pop-to-eax +4864 # . epilogue +4865 89/<- %esp 5/r32/ebp +4866 5d/pop-to-ebp +4867 c3/return +4868 +4869 find-matching-function: # functions: (addr function), stmt: (handle statement) -> result/eax: (handle function) +4870 # . prologue +4871 55/push-ebp +4872 89/<- %ebp 4/r32/esp +4873 # . save registers +4874 51/push-ecx +4875 # var curr/ecx: (handle function) = functions +4876 8b/-> *(ebp+8) 1/r32/ecx +4877 { +4878 # if (curr == null) break +4879 81 7/subop/compare %ecx 0/imm32 +4880 74/jump-if-= break/disp8 +4881 # if match(stmt, curr) return curr +4882 { +4883 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax +4884 3d/compare-eax-and 0/imm32 +4885 74/jump-if-= break/disp8 +4886 89/<- %eax 1/r32/ecx +4887 eb/jump $find-matching-function:end/disp8 +4888 } 4889 # curr = curr->next -4890 8b/-> *(ecx+0x20) 1/r32/ecx # Primitive-next -4891 e9/jump loop/disp32 +4890 8b/-> *(ecx+0x14) 1/r32/ecx # Function-next +4891 eb/jump loop/disp8 4892 } 4893 # return null 4894 b8/copy-to-eax 0/imm32 -4895 $find-matching-primitive:end: +4895 $find-matching-function:end: 4896 # . restore registers 4897 59/pop-to-ecx 4898 # . epilogue @@ -4912,128 +4912,128 @@ if ('onhashchange' in window) { 4900 5d/pop-to-ebp 4901 c3/return 4902 -4903 mu-stmt-matches-function?: # stmt : (handle statement), function : (handle function) => result/eax : boolean +4903 find-matching-primitive: # primitives: (handle primitive), stmt: (handle statement) -> result/eax: (handle primitive) 4904 # . prologue 4905 55/push-ebp 4906 89/<- %ebp 4/r32/esp 4907 # . save registers 4908 51/push-ecx -4909 # return function->name == stmt->operation +4909 # var curr/ecx: (handle primitive) = primitives 4910 8b/-> *(ebp+8) 1/r32/ecx -4911 8b/-> *(ebp+0xc) 0/r32/eax -4912 (string-equal? *(ecx+4) *eax) # Stmt1-operation, Function-name => eax -4913 $mu-stmt-matches-function?:end: -4914 # . restore registers -4915 59/pop-to-ecx -4916 # . epilogue -4917 89/<- %esp 5/r32/ebp -4918 5d/pop-to-ebp -4919 c3/return -4920 -4921 mu-stmt-matches-primitive?: # stmt : (handle statement), primitive : (handle primitive) => result/eax : boolean -4922 # A mu stmt matches a primitive if the name matches, all the inout vars -4923 # match, and all the output vars match. -4924 # Vars match if types match and registers match. -4925 # In addition, a stmt output matches a primitive's output if types match -4926 # and the primitive has a wildcard register. -4927 # . prologue -4928 55/push-ebp -4929 89/<- %ebp 4/r32/esp -4930 # . save registers -4931 51/push-ecx -4932 52/push-edx -4933 53/push-ebx -4934 56/push-esi -4935 57/push-edi -4936 # ecx = stmt -4937 8b/-> *(ebp+8) 1/r32/ecx -4938 # edx = primitive -4939 8b/-> *(ebp+0xc) 2/r32/edx -4940 { -4941 $mu-stmt-matches-primitive?:check-name: -4942 # if (primitive->name != stmt->operation) return false -4943 (string-equal? *(ecx+4) *edx) # Stmt1-operation, Primitive-name => eax -4944 3d/compare-eax-and 0/imm32 -4945 75/jump-if-!= break/disp8 -4946 b8/copy-to-eax 0/imm32 -4947 e9/jump $mu-stmt-matches-primitive?:end/disp32 -4948 } -4949 $mu-stmt-matches-primitive?:check-inouts: -4950 # for (curr/esi in stmt->inouts, curr2/edi in primitive->inouts) -4951 8b/-> *(ecx+8) 6/r32/esi # Stmt1-inouts -4952 8b/-> *(edx+4) 7/r32/edi # Primitive-inouts -4953 { -4954 # if (curr == 0 && curr2 == 0) move on to check outputs -4955 { -4956 81 7/subop/compare %esi 0/imm32 -4957 75/jump-if-!= break/disp8 -4958 $mu-stmt-matches-primitive?:stmt-inout-is-null: -4959 { -4960 81 7/subop/compare %edi 0/imm32 -4961 75/jump-if-!= break/disp8 -4962 # -4963 e9/jump $mu-stmt-matches-primitive?:check-outputs/disp32 -4964 } -4965 # return false -4966 b8/copy-to-eax 0/imm32/false -4967 e9/jump $mu-stmt-matches-primitive?:end/disp32 -4968 } -4969 # if (curr2 == 0) return false -4970 { -4971 81 7/subop/compare %edi 0/imm32 -4972 75/jump-if-!= break/disp8 -4973 $mu-stmt-matches-primitive?:prim-inout-is-null: -4974 b8/copy-to-eax 0/imm32/false -4975 e9/jump $mu-stmt-matches-primitive?:end/disp32 -4976 } -4977 # if (curr != curr2) return false -4978 { -4979 (operand-matches-primitive? *esi *edi) # => eax -4980 3d/compare-eax-and 0/imm32 -4981 75/jump-if-!= break/disp8 -4982 b8/copy-to-eax 0/imm32/false -4983 e9/jump $mu-stmt-matches-primitive?:end/disp32 -4984 } -4985 # curr=curr->next -4986 8b/-> *(esi+4) 6/r32/esi # Operand-next -4987 # curr2=curr2->next -4988 8b/-> *(edi+4) 7/r32/edi # Operand-next -4989 eb/jump loop/disp8 +4911 { +4912 $find-matching-primitive:loop: +4913 # if (curr == null) break +4914 81 7/subop/compare %ecx 0/imm32 +4915 0f 84/jump-if-= break/disp32 +4916 #? (write-buffered Stderr "prim: ") +4917 #? (write-buffered Stderr *ecx) # Primitive-name +4918 #? (write-buffered Stderr " => ") +4919 #? (write-buffered Stderr *(ecx+0xc)) # Primitive-subx-name +4920 #? (write-buffered Stderr "\n") +4921 #? (flush Stderr) +4922 # if match(curr, stmt) return curr +4923 { +4924 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax +4925 3d/compare-eax-and 0/imm32 +4926 74/jump-if-= break/disp8 +4927 89/<- %eax 1/r32/ecx +4928 eb/jump $find-matching-primitive:end/disp8 +4929 } +4930 $find-matching-primitive:next-primitive: +4931 # curr = curr->next +4932 8b/-> *(ecx+0x20) 1/r32/ecx # Primitive-next +4933 e9/jump loop/disp32 +4934 } +4935 # return null +4936 b8/copy-to-eax 0/imm32 +4937 $find-matching-primitive:end: +4938 # . restore registers +4939 59/pop-to-ecx +4940 # . epilogue +4941 89/<- %esp 5/r32/ebp +4942 5d/pop-to-ebp +4943 c3/return +4944 +4945 mu-stmt-matches-function?: # stmt: (handle statement), function: (handle function) => result/eax: boolean +4946 # . prologue +4947 55/push-ebp +4948 89/<- %ebp 4/r32/esp +4949 # . save registers +4950 51/push-ecx +4951 # return function->name == stmt->operation +4952 8b/-> *(ebp+8) 1/r32/ecx +4953 8b/-> *(ebp+0xc) 0/r32/eax +4954 (string-equal? *(ecx+4) *eax) # Stmt1-operation, Function-name => eax +4955 $mu-stmt-matches-function?:end: +4956 # . restore registers +4957 59/pop-to-ecx +4958 # . epilogue +4959 89/<- %esp 5/r32/ebp +4960 5d/pop-to-ebp +4961 c3/return +4962 +4963 mu-stmt-matches-primitive?: # stmt: (handle statement), primitive: (handle primitive) => result/eax: boolean +4964 # A mu stmt matches a primitive if the name matches, all the inout vars +4965 # match, and all the output vars match. +4966 # Vars match if types match and registers match. +4967 # In addition, a stmt output matches a primitive's output if types match +4968 # and the primitive has a wildcard register. +4969 # . prologue +4970 55/push-ebp +4971 89/<- %ebp 4/r32/esp +4972 # . save registers +4973 51/push-ecx +4974 52/push-edx +4975 53/push-ebx +4976 56/push-esi +4977 57/push-edi +4978 # ecx = stmt +4979 8b/-> *(ebp+8) 1/r32/ecx +4980 # edx = primitive +4981 8b/-> *(ebp+0xc) 2/r32/edx +4982 { +4983 $mu-stmt-matches-primitive?:check-name: +4984 # if (primitive->name != stmt->operation) return false +4985 (string-equal? *(ecx+4) *edx) # Stmt1-operation, Primitive-name => eax +4986 3d/compare-eax-and 0/imm32 +4987 75/jump-if-!= break/disp8 +4988 b8/copy-to-eax 0/imm32 +4989 e9/jump $mu-stmt-matches-primitive?:end/disp32 4990 } -4991 $mu-stmt-matches-primitive?:check-outputs: -4992 # for (curr/esi in stmt->outputs, curr2/edi in primitive->outputs) -4993 8b/-> *(ecx+0xc) 6/r32/esi # Stmt1-outputs -4994 8b/-> *(edx+8) 7/r32/edi # Primitive-outputs +4991 $mu-stmt-matches-primitive?:check-inouts: +4992 # for (curr/esi in stmt->inouts, curr2/edi in primitive->inouts) +4993 8b/-> *(ecx+8) 6/r32/esi # Stmt1-inouts +4994 8b/-> *(edx+4) 7/r32/edi # Primitive-inouts 4995 { -4996 # if (curr == 0) return (curr2 == 0) +4996 # if (curr == 0 && curr2 == 0) move on to check outputs 4997 { -4998 $mu-stmt-matches-primitive?:check-output: -4999 81 7/subop/compare %esi 0/imm32 -5000 75/jump-if-!= break/disp8 +4998 81 7/subop/compare %esi 0/imm32 +4999 75/jump-if-!= break/disp8 +5000 $mu-stmt-matches-primitive?:stmt-inout-is-null: 5001 { 5002 81 7/subop/compare %edi 0/imm32 5003 75/jump-if-!= break/disp8 -5004 # return true -5005 b8/copy-to-eax 1/imm32 -5006 e9/jump $mu-stmt-matches-primitive?:end/disp32 -5007 } -5008 # return false -5009 b8/copy-to-eax 0/imm32 -5010 e9/jump $mu-stmt-matches-primitive?:end/disp32 -5011 } -5012 # if (curr2 == 0) return false -5013 { -5014 81 7/subop/compare %edi 0/imm32 -5015 75/jump-if-!= break/disp8 -5016 b8/copy-to-eax 0/imm32 +5004 # +5005 e9/jump $mu-stmt-matches-primitive?:check-outputs/disp32 +5006 } +5007 # return false +5008 b8/copy-to-eax 0/imm32/false +5009 e9/jump $mu-stmt-matches-primitive?:end/disp32 +5010 } +5011 # if (curr2 == 0) return false +5012 { +5013 81 7/subop/compare %edi 0/imm32 +5014 75/jump-if-!= break/disp8 +5015 $mu-stmt-matches-primitive?:prim-inout-is-null: +5016 b8/copy-to-eax 0/imm32/false 5017 e9/jump $mu-stmt-matches-primitive?:end/disp32 5018 } 5019 # if (curr != curr2) return false 5020 { -5021 (operand-matches-primitive? *esi *edi) # List-value List-value => eax +5021 (operand-matches-primitive? *esi *edi) # => eax 5022 3d/compare-eax-and 0/imm32 5023 75/jump-if-!= break/disp8 -5024 b8/copy-to-eax 0/imm32 +5024 b8/copy-to-eax 0/imm32/false 5025 e9/jump $mu-stmt-matches-primitive?:end/disp32 5026 } 5027 # curr=curr->next @@ -5042,1039 +5042,1081 @@ if ('onhashchange' in window) { 5030 8b/-> *(edi+4) 7/r32/edi # Operand-next 5031 eb/jump loop/disp8 5032 } -5033 $mu-stmt-matches-primitive?:return-true: -5034 b8/copy-to-eax 1/imm32 -5035 $mu-stmt-matches-primitive?:end: -5036 # . restore registers -5037 5f/pop-to-edi -5038 5e/pop-to-esi -5039 5b/pop-to-ebx -5040 5a/pop-to-edx -5041 59/pop-to-ecx -5042 # . epilogue -5043 89/<- %esp 5/r32/ebp -5044 5d/pop-to-ebp -5045 c3/return -5046 -5047 operand-matches-primitive?: # var : (handle var), prim-var : (handle var) => result/eax : boolean -5048 # . prologue -5049 55/push-ebp -5050 89/<- %ebp 4/r32/esp -5051 # . save registers -5052 56/push-esi -5053 57/push-edi -5054 # esi = var -5055 8b/-> *(ebp+8) 6/r32/esi -5056 # edi = prim-var -5057 8b/-> *(ebp+0xc) 7/r32/edi -5058 # if (var->type != prim-var->type) return false -5059 (type-equal? *(esi+4) *(edi+4)) # Var-type, Var-type => eax -5060 3d/compare-eax-and 0/imm32 -5061 b8/copy-to-eax 0/imm32/false -5062 74/jump-if-= $operand-matches-primitive?:end/disp8 -5063 # return false if var->register doesn't match prim-var->register -5064 { -5065 # if addresses are equal, don't return here -5066 8b/-> *(esi+0x10) 0/r32/eax -5067 39/compare *(edi+0x10) 0/r32/eax -5068 74/jump-if-= break/disp8 -5069 # if either address is 0, return false -5070 3d/compare-eax-and 0/imm32 -5071 74/jump-if-= $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result -5072 81 7/subop/compare *(edi+0x10) 0/imm32 -5073 74/jump-if-= $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result -5074 # if prim-var->register is "*", return true -5075 (string-equal? *(edi+0x10) "*") # Var-register -5076 3d/compare-eax-and 0/imm32 -5077 b8/copy-to-eax 1/imm32/true -5078 75/jump-if-!= $operand-matches-primitive?:end/disp8 -5079 # if string contents don't match, return false -5080 (string-equal? *(esi+0x10) *(edi+0x10)) # Var-register Var-register -5081 3d/compare-eax-and 0/imm32 -5082 b8/copy-to-eax 0/imm32/false -5083 74/jump-if-= $operand-matches-primitive?:end/disp8 -5084 } -5085 # return true -5086 b8/copy-to-eax 1/imm32/true -5087 $operand-matches-primitive?:end: -5088 # . restore registers -5089 5f/pop-to-edi -5090 5e/pop-to-esi -5091 # . epilogue -5092 89/<- %esp 5/r32/ebp -5093 5d/pop-to-ebp -5094 c3/return -5095 -5096 type-equal?: # a : (handle tree type-id), b : (handle tree type-id) => result/eax : boolean -5097 # . prologue -5098 55/push-ebp -5099 89/<- %ebp 4/r32/esp -5100 # . save registers -5101 51/push-ecx -5102 52/push-edx -5103 # ecx = a -5104 8b/-> *(ebp+8) 1/r32/ecx -5105 # edx = b -5106 8b/-> *(ebp+0xc) 2/r32/edx -5107 # if (a == b) return true -5108 8b/-> %ecx 0/r32/eax # Var-type -5109 39/compare %edx 0/r32/eax # Var-type -5110 b8/copy-to-eax 1/imm32/true -5111 74/jump-if-= $type-equal?:end/disp8 -5112 # if (a < MAX_TYPE_ID) return false -5113 81 7/subop/compare %ecx 0x10000/imm32 -5114 b8/copy-to-eax 0/imm32/false -5115 72/jump-if-addr< $type-equal?:end/disp8 -5116 # if (b < MAX_TYPE_ID) return false -5117 81 7/subop/compare %edx 0x10000/imm32 -5118 b8/copy-to-eax 0/imm32/false -5119 72/jump-if-addr< $type-equal?:end/disp8 -5120 # if (!type-equal?(a->left, b->left)) return false -5121 (type-equal? *ecx *edx) # Tree-left, Tree-left => eax -5122 3d/compare-eax-and 0/imm32 -5123 74/jump-if-= $type-equal?:end/disp8 -5124 # return type-equal?(a->right, b->right) -5125 (type-equal? *(ecx+4) *(edx+4)) # Tree-right, Tree-right => eax -5126 $type-equal?:end: -5127 # . restore registers -5128 5a/pop-to-edx -5129 59/pop-to-ecx -5130 # . epilogue -5131 89/<- %esp 5/r32/ebp -5132 5d/pop-to-ebp -5133 c3/return -5134 -5135 test-emit-subx-statement-primitive: -5136 # Primitive operation on a variable on the stack. -5137 # increment foo -5138 # => -5139 # ff 0/subop/increment *(ebp-8) -5140 # -5141 # There's a variable on the var stack as follows: -5142 # name: 'foo' -5143 # type: int -5144 # stack-offset: -8 -5145 # -5146 # There's a primitive with this info: -5147 # name: 'increment' -5148 # inouts: int/mem -5149 # value: 'ff 0/subop/increment' -5150 # -5151 # There's nothing in functions. -5152 # -5153 # . prologue -5154 55/push-ebp -5155 89/<- %ebp 4/r32/esp -5156 # setup -5157 (clear-stream _test-output-stream) -5158 (clear-stream $_test-output-buffered-file->buffer) -5159 # var type/ecx : (handle tree type-id) = int -5160 68/push 0/imm32/right/null -5161 68/push 1/imm32/left/int -5162 89/<- %ecx 4/r32/esp -5163 # var var-foo/ecx : var -5164 68/push 0/imm32/no-register -5165 68/push -8/imm32/stack-offset -5166 68/push 1/imm32/block-depth -5167 51/push-ecx -5168 68/push "foo"/imm32 -5169 89/<- %ecx 4/r32/esp -5170 # var operand/ebx : (list var) -5171 68/push 0/imm32/next -5172 51/push-ecx/var-foo -5173 89/<- %ebx 4/r32/esp -5174 # var stmt/esi : statement -5175 68/push 0/imm32/next -5176 68/push 0/imm32/outputs -5177 53/push-ebx/operands -5178 68/push "increment"/imm32/operation -5179 68/push 1/imm32 -5180 89/<- %esi 4/r32/esp -5181 # var primitives/ebx : primitive -5182 68/push 0/imm32/next -5183 68/push 0/imm32/output-is-write-only -5184 68/push 0/imm32/no-imm32 -5185 68/push 0/imm32/no-r32 -5186 68/push 1/imm32/rm32-is-first-inout -5187 68/push "ff 0/subop/increment"/imm32/subx-name -5188 68/push 0/imm32/outputs -5189 53/push-ebx/inouts # hack; in practice we won't have the same var in function definition and call -5190 68/push "increment"/imm32/name -5191 89/<- %ebx 4/r32/esp -5192 # convert -5193 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) -5194 (flush _test-output-buffered-file) -5195 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5201 # check output -5202 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive") -5203 # . epilogue -5204 89/<- %esp 5/r32/ebp -5205 5d/pop-to-ebp -5206 c3/return -5207 -5208 test-emit-subx-statement-primitive-register: -5209 # Primitive operation on a variable in a register. -5210 # foo <- increment -5211 # => -5212 # ff 0/subop/increment %eax # sub-optimal, but should suffice -5213 # -5214 # There's a variable on the var stack as follows: -5215 # name: 'foo' -5216 # type: int -5217 # register: 'eax' -5218 # -5219 # There's a primitive with this info: -5220 # name: 'increment' -5221 # out: int/reg -5222 # value: 'ff 0/subop/increment' -5223 # -5224 # There's nothing in functions. -5225 # -5226 # . prologue -5227 55/push-ebp -5228 89/<- %ebp 4/r32/esp -5229 # setup -5230 (clear-stream _test-output-stream) -5231 (clear-stream $_test-output-buffered-file->buffer) -5232 # var type/ecx : (handle tree type-id) = int -5233 68/push 0/imm32/right/null -5234 68/push 1/imm32/left/int -5235 89/<- %ecx 4/r32/esp -5236 # var var-foo/ecx : var in eax -5237 68/push "eax"/imm32/register -5238 68/push 0/imm32/no-stack-offset -5239 68/push 1/imm32/block-depth -5240 51/push-ecx -5241 68/push "foo"/imm32 -5242 89/<- %ecx 4/r32/esp -5243 # var operand/ebx : (list var) -5244 68/push 0/imm32/next -5245 51/push-ecx/var-foo -5246 89/<- %ebx 4/r32/esp -5247 # var stmt/esi : statement -5248 68/push 0/imm32/next -5249 53/push-ebx/outputs -5250 68/push 0/imm32/inouts -5251 68/push "increment"/imm32/operation -5252 68/push 1/imm32 -5253 89/<- %esi 4/r32/esp -5254 # var formal-var/ebx : var in any register -5255 68/push Any-register/imm32 -5256 68/push 0/imm32/no-stack-offset -5257 68/push 1/imm32/block-depth -5258 ff 6/subop/push *(ecx+4) # Var-type -5259 68/push "dummy"/imm32 -5260 89/<- %ebx 4/r32/esp -5261 # var operand/ebx : (list var) -5262 68/push 0/imm32/next -5263 53/push-ebx/formal-var -5264 89/<- %ebx 4/r32/esp -5265 # var primitives/ebx : primitive -5266 68/push 0/imm32/next -5267 68/push 0/imm32/output-is-write-only -5268 68/push 0/imm32/no-imm32 -5269 68/push 0/imm32/no-r32 -5270 68/push 3/imm32/rm32-in-first-output -5271 68/push "ff 0/subop/increment"/imm32/subx-name -5272 53/push-ebx/outputs -5273 68/push 0/imm32/inouts -5274 68/push "increment"/imm32/name -5275 89/<- %ebx 4/r32/esp -5276 # convert -5277 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) -5278 (flush _test-output-buffered-file) -5279 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5285 # check output -5286 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-primitive-register") -5287 # . epilogue -5288 89/<- %esp 5/r32/ebp -5289 5d/pop-to-ebp -5290 c3/return -5291 -5292 test-emit-subx-statement-select-primitive: -5293 # Select the right primitive between overloads. -5294 # foo <- increment -5295 # => -5296 # ff 0/subop/increment %eax # sub-optimal, but should suffice -5297 # -5298 # There's a variable on the var stack as follows: -5299 # name: 'foo' -5300 # type: int -5301 # register: 'eax' -5302 # -5303 # There's two primitives, as follows: -5304 # - name: 'increment' -5305 # out: int/reg -5306 # value: 'ff 0/subop/increment' -5307 # - name: 'increment' -5308 # inout: int/mem -5309 # value: 'ff 0/subop/increment' -5310 # -5311 # There's nothing in functions. -5312 # -5313 # . prologue -5314 55/push-ebp -5315 89/<- %ebp 4/r32/esp -5316 # setup -5317 (clear-stream _test-output-stream) -5318 (clear-stream $_test-output-buffered-file->buffer) -5319 # var type/ecx : (handle tree type-id) = int -5320 68/push 0/imm32/right/null -5321 68/push 1/imm32/left/int -5322 89/<- %ecx 4/r32/esp -5323 # var var-foo/ecx : var in eax -5324 68/push "eax"/imm32/register -5325 68/push 0/imm32/no-stack-offset -5326 68/push 1/imm32/block-depth -5327 51/push-ecx -5328 68/push "foo"/imm32 -5329 89/<- %ecx 4/r32/esp -5330 # var real-outputs/edi : (list var) -5331 68/push 0/imm32/next -5332 51/push-ecx/var-foo -5333 89/<- %edi 4/r32/esp -5334 # var stmt/esi : statement -5335 68/push 0/imm32/next -5336 57/push-edi/outputs -5337 68/push 0/imm32/inouts -5338 68/push "increment"/imm32/operation -5339 68/push 1/imm32 -5340 89/<- %esi 4/r32/esp -5341 # var formal-var/ebx : var in any register -5342 68/push Any-register/imm32 -5343 68/push 0/imm32/no-stack-offset -5344 68/push 1/imm32/block-depth -5345 ff 6/subop/push *(ecx+4) # Var-type -5346 68/push "dummy"/imm32 -5347 89/<- %ebx 4/r32/esp -5348 # var formal-outputs/ebx : (list var) = {formal-var, 0} -5349 68/push 0/imm32/next -5350 53/push-ebx/formal-var -5351 89/<- %ebx 4/r32/esp -5352 # var primitive1/ebx : primitive -5353 68/push 0/imm32/next -5354 68/push 0/imm32/output-is-write-only -5355 68/push 0/imm32/no-imm32 -5356 68/push 0/imm32/no-r32 -5357 68/push 3/imm32/rm32-in-first-output -5358 68/push "ff 0/subop/increment"/imm32/subx-name -5359 53/push-ebx/outputs/formal-outputs -5360 68/push 0/imm32/inouts -5361 68/push "increment"/imm32/name -5362 89/<- %ebx 4/r32/esp -5363 # var primitives/ebx : primitive -5364 53/push-ebx/next -5365 68/push 0/imm32/output-is-write-only -5366 68/push 0/imm32/no-imm32 -5367 68/push 0/imm32/no-r32 -5368 68/push 1/imm32/rm32-is-first-inout -5369 68/push "ff 0/subop/increment"/imm32/subx-name -5370 68/push 0/imm32/outputs -5371 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call -5372 68/push "increment"/imm32/name -5373 89/<- %ebx 4/r32/esp -5374 # convert -5375 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) -5376 (flush _test-output-buffered-file) -5377 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5383 # check output -5384 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive") -5385 # . epilogue -5386 89/<- %esp 5/r32/ebp -5387 5d/pop-to-ebp -5388 c3/return -5389 -5390 test-emit-subx-statement-select-primitive-2: -5391 # Select the right primitive between overloads. -5392 # foo <- increment -5393 # => -5394 # ff 0/subop/increment %eax # sub-optimal, but should suffice -5395 # -5396 # There's a variable on the var stack as follows: -5397 # name: 'foo' -5398 # type: int -5399 # register: 'eax' -5400 # -5401 # There's two primitives, as follows: -5402 # - name: 'increment' -5403 # out: int/reg -5404 # value: 'ff 0/subop/increment' -5405 # - name: 'increment' -5406 # inout: int/mem -5407 # value: 'ff 0/subop/increment' -5408 # -5409 # There's nothing in functions. -5410 # -5411 # . prologue -5412 55/push-ebp -5413 89/<- %ebp 4/r32/esp -5414 # setup -5415 (clear-stream _test-output-stream) -5416 (clear-stream $_test-output-buffered-file->buffer) -5417 # var type/ecx : (handle tree type-id) = int -5418 68/push 0/imm32/right/null -5419 68/push 1/imm32/left/int -5420 89/<- %ecx 4/r32/esp -5421 # var var-foo/ecx : var in eax -5422 68/push "eax"/imm32/register -5423 68/push 0/imm32/no-stack-offset -5424 68/push 1/imm32/block-depth -5425 51/push-ecx -5426 68/push "foo"/imm32 -5427 89/<- %ecx 4/r32/esp -5428 # var inouts/edi : (list var) -5429 68/push 0/imm32/next -5430 51/push-ecx/var-foo -5431 89/<- %edi 4/r32/esp -5432 # var stmt/esi : statement -5433 68/push 0/imm32/next -5434 68/push 0/imm32/outputs -5435 57/push-edi/inouts -5436 68/push "increment"/imm32/operation -5437 68/push 1/imm32 -5438 89/<- %esi 4/r32/esp -5439 # var formal-var/ebx : var in any register -5440 68/push Any-register/imm32 -5441 68/push 0/imm32/no-stack-offset -5442 68/push 1/imm32/block-depth -5443 ff 6/subop/push *(ecx+4) # Var-type -5444 68/push "dummy"/imm32 -5445 89/<- %ebx 4/r32/esp -5446 # var operand/ebx : (list var) -5447 68/push 0/imm32/next -5448 53/push-ebx/formal-var -5449 89/<- %ebx 4/r32/esp -5450 # var primitive1/ebx : primitive -5451 68/push 0/imm32/next -5452 68/push 0/imm32/output-is-write-only -5453 68/push 0/imm32/no-imm32 -5454 68/push 0/imm32/no-r32 -5455 68/push 3/imm32/rm32-in-first-output -5456 68/push "ff 0/subop/increment"/imm32/subx-name -5457 53/push-ebx/outputs/formal-outputs -5458 68/push 0/imm32/inouts -5459 68/push "increment"/imm32/name -5460 89/<- %ebx 4/r32/esp -5461 # var primitives/ebx : primitive -5462 53/push-ebx/next -5463 68/push 0/imm32/output-is-write-only -5464 68/push 0/imm32/no-imm32 -5465 68/push 0/imm32/no-r32 -5466 68/push 1/imm32/rm32-is-first-inout -5467 68/push "ff 0/subop/increment"/imm32/subx-name -5468 68/push 0/imm32/outputs -5469 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call -5470 68/push "increment"/imm32/name -5471 89/<- %ebx 4/r32/esp -5472 # convert -5473 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) -5474 (flush _test-output-buffered-file) -5475 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5481 # check output -5482 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2") -5483 # . epilogue -5484 89/<- %esp 5/r32/ebp -5485 5d/pop-to-ebp -5486 c3/return -5487 -5488 test-increment-register: -5489 # Select the right primitive between overloads. -5490 # foo <- increment -5491 # => -5492 # 50/increment-eax -5493 # -5494 # There's a variable on the var stack as follows: -5495 # name: 'foo' -5496 # type: int -5497 # register: 'eax' -5498 # -5499 # Primitives are the global definitions. -5500 # -5501 # There are no functions defined. -5502 # -5503 # . prologue -5504 55/push-ebp -5505 89/<- %ebp 4/r32/esp -5506 # setup -5507 (clear-stream _test-output-stream) -5508 (clear-stream $_test-output-buffered-file->buffer) -5509 # var type/ecx : (handle tree type-id) = int -5510 68/push 0/imm32/right/null -5511 68/push 1/imm32/left/int -5512 89/<- %ecx 4/r32/esp -5513 # var var-foo/ecx : var in eax -5514 68/push "eax"/imm32/register -5515 68/push 0/imm32/no-stack-offset -5516 68/push 1/imm32/block-depth -5517 51/push-ecx -5518 68/push "foo"/imm32 -5519 89/<- %ecx 4/r32/esp -5520 # var real-outputs/edi : (list var) -5521 68/push 0/imm32/next -5522 51/push-ecx/var-foo -5523 89/<- %edi 4/r32/esp -5524 # var stmt/esi : statement -5525 68/push 0/imm32/next -5526 57/push-edi/outputs -5527 68/push 0/imm32/inouts -5528 68/push "increment"/imm32/operation -5529 68/push 1/imm32/regular-statement -5530 89/<- %esi 4/r32/esp -5531 # convert -5532 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -5533 (flush _test-output-buffered-file) -5534 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5540 # check output -5541 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") -5542 # . epilogue -5543 89/<- %esp 5/r32/ebp -5544 5d/pop-to-ebp -5545 c3/return -5546 -5547 test-increment-var: -5548 # Select the right primitive between overloads. -5549 # foo <- increment -5550 # => -5551 # ff 0/subop/increment %eax # sub-optimal, but should suffice -5552 # -5553 # There's a variable on the var stack as follows: -5554 # name: 'foo' -5555 # type: int -5556 # register: 'eax' -5557 # -5558 # Primitives are the global definitions. -5559 # -5560 # There are no functions defined. -5561 # -5562 # . prologue -5563 55/push-ebp -5564 89/<- %ebp 4/r32/esp -5565 # setup -5566 (clear-stream _test-output-stream) -5567 (clear-stream $_test-output-buffered-file->buffer) -5568 # var type/ecx : (handle tree type-id) = int -5569 68/push 0/imm32/right/null -5570 68/push 1/imm32/left/int -5571 89/<- %ecx 4/r32/esp -5572 # var var-foo/ecx : var in eax -5573 68/push "eax"/imm32/register -5574 68/push 0/imm32/no-stack-offset -5575 68/push 1/imm32/block-depth -5576 51/push-ecx -5577 68/push "foo"/imm32 -5578 89/<- %ecx 4/r32/esp -5579 # var inouts/edi : (list var) -5580 68/push 0/imm32/next -5581 51/push-ecx/var-foo -5582 89/<- %edi 4/r32/esp -5583 # var stmt/esi : statement -5584 68/push 0/imm32/next -5585 68/push 0/imm32/outputs -5586 57/push-edi/inouts -5587 68/push "increment"/imm32/operation -5588 68/push 1/imm32 -5589 89/<- %esi 4/r32/esp -5590 # convert -5591 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -5592 (flush _test-output-buffered-file) -5593 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5599 # check output -5600 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-increment-var") -5601 # . epilogue -5602 89/<- %esp 5/r32/ebp -5603 5d/pop-to-ebp -5604 c3/return -5605 -5606 test-add-reg-to-reg: -5607 # var1/reg <- add var2/reg -5608 # => -5609 # 01/add %var1 var2 -5610 # -5611 # . prologue -5612 55/push-ebp -5613 89/<- %ebp 4/r32/esp -5614 # setup -5615 (clear-stream _test-output-stream) -5616 (clear-stream $_test-output-buffered-file->buffer) -5617 # var type/ecx : (handle tree type-id) = int -5618 68/push 0/imm32/right/null -5619 68/push 1/imm32/left/int +5033 $mu-stmt-matches-primitive?:check-outputs: +5034 # for (curr/esi in stmt->outputs, curr2/edi in primitive->outputs) +5035 8b/-> *(ecx+0xc) 6/r32/esi # Stmt1-outputs +5036 8b/-> *(edx+8) 7/r32/edi # Primitive-outputs +5037 { +5038 # if (curr == 0) return (curr2 == 0) +5039 { +5040 $mu-stmt-matches-primitive?:check-output: +5041 81 7/subop/compare %esi 0/imm32 +5042 75/jump-if-!= break/disp8 +5043 { +5044 81 7/subop/compare %edi 0/imm32 +5045 75/jump-if-!= break/disp8 +5046 # return true +5047 b8/copy-to-eax 1/imm32 +5048 e9/jump $mu-stmt-matches-primitive?:end/disp32 +5049 } +5050 # return false +5051 b8/copy-to-eax 0/imm32 +5052 e9/jump $mu-stmt-matches-primitive?:end/disp32 +5053 } +5054 # if (curr2 == 0) return false +5055 { +5056 81 7/subop/compare %edi 0/imm32 +5057 75/jump-if-!= break/disp8 +5058 b8/copy-to-eax 0/imm32 +5059 e9/jump $mu-stmt-matches-primitive?:end/disp32 +5060 } +5061 # if (curr != curr2) return false +5062 { +5063 (operand-matches-primitive? *esi *edi) # List-value List-value => eax +5064 3d/compare-eax-and 0/imm32 +5065 75/jump-if-!= break/disp8 +5066 b8/copy-to-eax 0/imm32 +5067 e9/jump $mu-stmt-matches-primitive?:end/disp32 +5068 } +5069 # curr=curr->next +5070 8b/-> *(esi+4) 6/r32/esi # Operand-next +5071 # curr2=curr2->next +5072 8b/-> *(edi+4) 7/r32/edi # Operand-next +5073 eb/jump loop/disp8 +5074 } +5075 $mu-stmt-matches-primitive?:return-true: +5076 b8/copy-to-eax 1/imm32 +5077 $mu-stmt-matches-primitive?:end: +5078 # . restore registers +5079 5f/pop-to-edi +5080 5e/pop-to-esi +5081 5b/pop-to-ebx +5082 5a/pop-to-edx +5083 59/pop-to-ecx +5084 # . epilogue +5085 89/<- %esp 5/r32/ebp +5086 5d/pop-to-ebp +5087 c3/return +5088 +5089 operand-matches-primitive?: # var: (handle var), prim-var: (handle var) => result/eax: boolean +5090 # . prologue +5091 55/push-ebp +5092 89/<- %ebp 4/r32/esp +5093 # . save registers +5094 56/push-esi +5095 57/push-edi +5096 # esi = var +5097 8b/-> *(ebp+8) 6/r32/esi +5098 # edi = prim-var +5099 8b/-> *(ebp+0xc) 7/r32/edi +5100 # if (var->type != prim-var->type) return false +5101 (type-equal? *(esi+4) *(edi+4)) # Var-type, Var-type => eax +5102 3d/compare-eax-and 0/imm32 +5103 b8/copy-to-eax 0/imm32/false +5104 74/jump-if-= $operand-matches-primitive?:end/disp8 +5105 # return false if var->register doesn't match prim-var->register +5106 { +5107 # if addresses are equal, don't return here +5108 8b/-> *(esi+0x10) 0/r32/eax +5109 39/compare *(edi+0x10) 0/r32/eax +5110 74/jump-if-= break/disp8 +5111 # if either address is 0, return false +5112 3d/compare-eax-and 0/imm32 +5113 74/jump-if-= $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result +5114 81 7/subop/compare *(edi+0x10) 0/imm32 +5115 74/jump-if-= $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result +5116 # if prim-var->register is "*", return true +5117 (string-equal? *(edi+0x10) "*") # Var-register +5118 3d/compare-eax-and 0/imm32 +5119 b8/copy-to-eax 1/imm32/true +5120 75/jump-if-!= $operand-matches-primitive?:end/disp8 +5121 # if string contents don't match, return false +5122 (string-equal? *(esi+0x10) *(edi+0x10)) # Var-register Var-register +5123 3d/compare-eax-and 0/imm32 +5124 b8/copy-to-eax 0/imm32/false +5125 74/jump-if-= $operand-matches-primitive?:end/disp8 +5126 } +5127 # return true +5128 b8/copy-to-eax 1/imm32/true +5129 $operand-matches-primitive?:end: +5130 # . restore registers +5131 5f/pop-to-edi +5132 5e/pop-to-esi +5133 # . epilogue +5134 89/<- %esp 5/r32/ebp +5135 5d/pop-to-ebp +5136 c3/return +5137 +5138 type-equal?: # a: (handle tree type-id), b: (handle tree type-id) => result/eax: boolean +5139 # . prologue +5140 55/push-ebp +5141 89/<- %ebp 4/r32/esp +5142 # . save registers +5143 51/push-ecx +5144 52/push-edx +5145 # ecx = a +5146 8b/-> *(ebp+8) 1/r32/ecx +5147 # edx = b +5148 8b/-> *(ebp+0xc) 2/r32/edx +5149 # if (a == b) return true +5150 8b/-> %ecx 0/r32/eax # Var-type +5151 39/compare %edx 0/r32/eax # Var-type +5152 b8/copy-to-eax 1/imm32/true +5153 74/jump-if-= $type-equal?:end/disp8 +5154 # if (a < MAX_TYPE_ID) return false +5155 81 7/subop/compare %ecx 0x10000/imm32 +5156 b8/copy-to-eax 0/imm32/false +5157 72/jump-if-addr< $type-equal?:end/disp8 +5158 # if (b < MAX_TYPE_ID) return false +5159 81 7/subop/compare %edx 0x10000/imm32 +5160 b8/copy-to-eax 0/imm32/false +5161 72/jump-if-addr< $type-equal?:end/disp8 +5162 # if (!type-equal?(a->left, b->left)) return false +5163 (type-equal? *ecx *edx) # Tree-left, Tree-left => eax +5164 3d/compare-eax-and 0/imm32 +5165 74/jump-if-= $type-equal?:end/disp8 +5166 # return type-equal?(a->right, b->right) +5167 (type-equal? *(ecx+4) *(edx+4)) # Tree-right, Tree-right => eax +5168 $type-equal?:end: +5169 # . restore registers +5170 5a/pop-to-edx +5171 59/pop-to-ecx +5172 # . epilogue +5173 89/<- %esp 5/r32/ebp +5174 5d/pop-to-ebp +5175 c3/return +5176 +5177 test-emit-subx-statement-primitive: +5178 # Primitive operation on a variable on the stack. +5179 # increment foo +5180 # => +5181 # ff 0/subop/increment *(ebp-8) +5182 # +5183 # There's a variable on the var stack as follows: +5184 # name: 'foo' +5185 # type: int +5186 # stack-offset: -8 +5187 # +5188 # There's a primitive with this info: +5189 # name: 'increment' +5190 # inouts: int/mem +5191 # value: 'ff 0/subop/increment' +5192 # +5193 # There's nothing in functions. +5194 # +5195 # . prologue +5196 55/push-ebp +5197 89/<- %ebp 4/r32/esp +5198 # setup +5199 (clear-stream _test-output-stream) +5200 (clear-stream $_test-output-buffered-file->buffer) +5201 # var type/ecx: (handle tree type-id) = int +5202 68/push 0/imm32/right/null +5203 68/push 1/imm32/left/int +5204 89/<- %ecx 4/r32/esp +5205 # var var-foo/ecx: var +5206 68/push 0/imm32/no-register +5207 68/push -8/imm32/stack-offset +5208 68/push 1/imm32/block-depth +5209 51/push-ecx +5210 68/push "foo"/imm32 +5211 89/<- %ecx 4/r32/esp +5212 # var operand/ebx: (list var) +5213 68/push 0/imm32/next +5214 51/push-ecx/var-foo +5215 89/<- %ebx 4/r32/esp +5216 # var stmt/esi: statement +5217 68/push 0/imm32/next +5218 68/push 0/imm32/outputs +5219 53/push-ebx/operands +5220 68/push "increment"/imm32/operation +5221 68/push 1/imm32 +5222 89/<- %esi 4/r32/esp +5223 # var primitives/ebx: primitive +5224 68/push 0/imm32/next +5225 68/push 0/imm32/output-is-write-only +5226 68/push 0/imm32/no-imm32 +5227 68/push 0/imm32/no-r32 +5228 68/push 1/imm32/rm32-is-first-inout +5229 68/push "ff 0/subop/increment"/imm32/subx-name +5230 68/push 0/imm32/outputs +5231 53/push-ebx/inouts # hack; in practice we won't have the same var in function definition and call +5232 68/push "increment"/imm32/name +5233 89/<- %ebx 4/r32/esp +5234 # convert +5235 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) +5236 (flush _test-output-buffered-file) +5237 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5243 # check output +5244 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive") +5245 # . epilogue +5246 89/<- %esp 5/r32/ebp +5247 5d/pop-to-ebp +5248 c3/return +5249 +5250 test-emit-subx-statement-primitive-register: +5251 # Primitive operation on a variable in a register. +5252 # foo <- increment +5253 # => +5254 # ff 0/subop/increment %eax # sub-optimal, but should suffice +5255 # +5256 # There's a variable on the var stack as follows: +5257 # name: 'foo' +5258 # type: int +5259 # register: 'eax' +5260 # +5261 # There's a primitive with this info: +5262 # name: 'increment' +5263 # out: int/reg +5264 # value: 'ff 0/subop/increment' +5265 # +5266 # There's nothing in functions. +5267 # +5268 # . prologue +5269 55/push-ebp +5270 89/<- %ebp 4/r32/esp +5271 # setup +5272 (clear-stream _test-output-stream) +5273 (clear-stream $_test-output-buffered-file->buffer) +5274 # var type/ecx: (handle tree type-id) = int +5275 68/push 0/imm32/right/null +5276 68/push 1/imm32/left/int +5277 89/<- %ecx 4/r32/esp +5278 # var var-foo/ecx: var in eax +5279 68/push "eax"/imm32/register +5280 68/push 0/imm32/no-stack-offset +5281 68/push 1/imm32/block-depth +5282 51/push-ecx +5283 68/push "foo"/imm32 +5284 89/<- %ecx 4/r32/esp +5285 # var operand/ebx: (list var) +5286 68/push 0/imm32/next +5287 51/push-ecx/var-foo +5288 89/<- %ebx 4/r32/esp +5289 # var stmt/esi: statement +5290 68/push 0/imm32/next +5291 53/push-ebx/outputs +5292 68/push 0/imm32/inouts +5293 68/push "increment"/imm32/operation +5294 68/push 1/imm32 +5295 89/<- %esi 4/r32/esp +5296 # var formal-var/ebx: var in any register +5297 68/push Any-register/imm32 +5298 68/push 0/imm32/no-stack-offset +5299 68/push 1/imm32/block-depth +5300 ff 6/subop/push *(ecx+4) # Var-type +5301 68/push "dummy"/imm32 +5302 89/<- %ebx 4/r32/esp +5303 # var operand/ebx: (list var) +5304 68/push 0/imm32/next +5305 53/push-ebx/formal-var +5306 89/<- %ebx 4/r32/esp +5307 # var primitives/ebx: primitive +5308 68/push 0/imm32/next +5309 68/push 0/imm32/output-is-write-only +5310 68/push 0/imm32/no-imm32 +5311 68/push 0/imm32/no-r32 +5312 68/push 3/imm32/rm32-in-first-output +5313 68/push "ff 0/subop/increment"/imm32/subx-name +5314 53/push-ebx/outputs +5315 68/push 0/imm32/inouts +5316 68/push "increment"/imm32/name +5317 89/<- %ebx 4/r32/esp +5318 # convert +5319 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) +5320 (flush _test-output-buffered-file) +5321 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5327 # check output +5328 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-primitive-register") +5329 # . epilogue +5330 89/<- %esp 5/r32/ebp +5331 5d/pop-to-ebp +5332 c3/return +5333 +5334 test-emit-subx-statement-select-primitive: +5335 # Select the right primitive between overloads. +5336 # foo <- increment +5337 # => +5338 # ff 0/subop/increment %eax # sub-optimal, but should suffice +5339 # +5340 # There's a variable on the var stack as follows: +5341 # name: 'foo' +5342 # type: int +5343 # register: 'eax' +5344 # +5345 # There's two primitives, as follows: +5346 # - name: 'increment' +5347 # out: int/reg +5348 # value: 'ff 0/subop/increment' +5349 # - name: 'increment' +5350 # inout: int/mem +5351 # value: 'ff 0/subop/increment' +5352 # +5353 # There's nothing in functions. +5354 # +5355 # . prologue +5356 55/push-ebp +5357 89/<- %ebp 4/r32/esp +5358 # setup +5359 (clear-stream _test-output-stream) +5360 (clear-stream $_test-output-buffered-file->buffer) +5361 # var type/ecx: (handle tree type-id) = int +5362 68/push 0/imm32/right/null +5363 68/push 1/imm32/left/int +5364 89/<- %ecx 4/r32/esp +5365 # var var-foo/ecx: var in eax +5366 68/push "eax"/imm32/register +5367 68/push 0/imm32/no-stack-offset +5368 68/push 1/imm32/block-depth +5369 51/push-ecx +5370 68/push "foo"/imm32 +5371 89/<- %ecx 4/r32/esp +5372 # var real-outputs/edi: (list var) +5373 68/push 0/imm32/next +5374 51/push-ecx/var-foo +5375 89/<- %edi 4/r32/esp +5376 # var stmt/esi: statement +5377 68/push 0/imm32/next +5378 57/push-edi/outputs +5379 68/push 0/imm32/inouts +5380 68/push "increment"/imm32/operation +5381 68/push 1/imm32 +5382 89/<- %esi 4/r32/esp +5383 # var formal-var/ebx: var in any register +5384 68/push Any-register/imm32 +5385 68/push 0/imm32/no-stack-offset +5386 68/push 1/imm32/block-depth +5387 ff 6/subop/push *(ecx+4) # Var-type +5388 68/push "dummy"/imm32 +5389 89/<- %ebx 4/r32/esp +5390 # var formal-outputs/ebx: (list var) = {formal-var, 0} +5391 68/push 0/imm32/next +5392 53/push-ebx/formal-var +5393 89/<- %ebx 4/r32/esp +5394 # var primitive1/ebx: primitive +5395 68/push 0/imm32/next +5396 68/push 0/imm32/output-is-write-only +5397 68/push 0/imm32/no-imm32 +5398 68/push 0/imm32/no-r32 +5399 68/push 3/imm32/rm32-in-first-output +5400 68/push "ff 0/subop/increment"/imm32/subx-name +5401 53/push-ebx/outputs/formal-outputs +5402 68/push 0/imm32/inouts +5403 68/push "increment"/imm32/name +5404 89/<- %ebx 4/r32/esp +5405 # var primitives/ebx: primitive +5406 53/push-ebx/next +5407 68/push 0/imm32/output-is-write-only +5408 68/push 0/imm32/no-imm32 +5409 68/push 0/imm32/no-r32 +5410 68/push 1/imm32/rm32-is-first-inout +5411 68/push "ff 0/subop/increment"/imm32/subx-name +5412 68/push 0/imm32/outputs +5413 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call +5414 68/push "increment"/imm32/name +5415 89/<- %ebx 4/r32/esp +5416 # convert +5417 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) +5418 (flush _test-output-buffered-file) +5419 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5425 # check output +5426 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive") +5427 # . epilogue +5428 89/<- %esp 5/r32/ebp +5429 5d/pop-to-ebp +5430 c3/return +5431 +5432 test-emit-subx-statement-select-primitive-2: +5433 # Select the right primitive between overloads. +5434 # foo <- increment +5435 # => +5436 # ff 0/subop/increment %eax # sub-optimal, but should suffice +5437 # +5438 # There's a variable on the var stack as follows: +5439 # name: 'foo' +5440 # type: int +5441 # register: 'eax' +5442 # +5443 # There's two primitives, as follows: +5444 # - name: 'increment' +5445 # out: int/reg +5446 # value: 'ff 0/subop/increment' +5447 # - name: 'increment' +5448 # inout: int/mem +5449 # value: 'ff 0/subop/increment' +5450 # +5451 # There's nothing in functions. +5452 # +5453 # . prologue +5454 55/push-ebp +5455 89/<- %ebp 4/r32/esp +5456 # setup +5457 (clear-stream _test-output-stream) +5458 (clear-stream $_test-output-buffered-file->buffer) +5459 # var type/ecx: (handle tree type-id) = int +5460 68/push 0/imm32/right/null +5461 68/push 1/imm32/left/int +5462 89/<- %ecx 4/r32/esp +5463 # var var-foo/ecx: var in eax +5464 68/push "eax"/imm32/register +5465 68/push 0/imm32/no-stack-offset +5466 68/push 1/imm32/block-depth +5467 51/push-ecx +5468 68/push "foo"/imm32 +5469 89/<- %ecx 4/r32/esp +5470 # var inouts/edi: (list var) +5471 68/push 0/imm32/next +5472 51/push-ecx/var-foo +5473 89/<- %edi 4/r32/esp +5474 # var stmt/esi: statement +5475 68/push 0/imm32/next +5476 68/push 0/imm32/outputs +5477 57/push-edi/inouts +5478 68/push "increment"/imm32/operation +5479 68/push 1/imm32 +5480 89/<- %esi 4/r32/esp +5481 # var formal-var/ebx: var in any register +5482 68/push Any-register/imm32 +5483 68/push 0/imm32/no-stack-offset +5484 68/push 1/imm32/block-depth +5485 ff 6/subop/push *(ecx+4) # Var-type +5486 68/push "dummy"/imm32 +5487 89/<- %ebx 4/r32/esp +5488 # var operand/ebx: (list var) +5489 68/push 0/imm32/next +5490 53/push-ebx/formal-var +5491 89/<- %ebx 4/r32/esp +5492 # var primitive1/ebx: primitive +5493 68/push 0/imm32/next +5494 68/push 0/imm32/output-is-write-only +5495 68/push 0/imm32/no-imm32 +5496 68/push 0/imm32/no-r32 +5497 68/push 3/imm32/rm32-in-first-output +5498 68/push "ff 0/subop/increment"/imm32/subx-name +5499 53/push-ebx/outputs/formal-outputs +5500 68/push 0/imm32/inouts +5501 68/push "increment"/imm32/name +5502 89/<- %ebx 4/r32/esp +5503 # var primitives/ebx: primitive +5504 53/push-ebx/next +5505 68/push 0/imm32/output-is-write-only +5506 68/push 0/imm32/no-imm32 +5507 68/push 0/imm32/no-r32 +5508 68/push 1/imm32/rm32-is-first-inout +5509 68/push "ff 0/subop/increment"/imm32/subx-name +5510 68/push 0/imm32/outputs +5511 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call +5512 68/push "increment"/imm32/name +5513 89/<- %ebx 4/r32/esp +5514 # convert +5515 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) +5516 (flush _test-output-buffered-file) +5517 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5523 # check output +5524 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2") +5525 # . epilogue +5526 89/<- %esp 5/r32/ebp +5527 5d/pop-to-ebp +5528 c3/return +5529 +5530 test-increment-register: +5531 # Select the right primitive between overloads. +5532 # foo <- increment +5533 # => +5534 # 50/increment-eax +5535 # +5536 # There's a variable on the var stack as follows: +5537 # name: 'foo' +5538 # type: int +5539 # register: 'eax' +5540 # +5541 # Primitives are the global definitions. +5542 # +5543 # There are no functions defined. +5544 # +5545 # . prologue +5546 55/push-ebp +5547 89/<- %ebp 4/r32/esp +5548 # setup +5549 (clear-stream _test-output-stream) +5550 (clear-stream $_test-output-buffered-file->buffer) +5551 # var type/ecx: (handle tree type-id) = int +5552 68/push 0/imm32/right/null +5553 68/push 1/imm32/left/int +5554 89/<- %ecx 4/r32/esp +5555 # var var-foo/ecx: var in eax +5556 68/push "eax"/imm32/register +5557 68/push 0/imm32/no-stack-offset +5558 68/push 1/imm32/block-depth +5559 51/push-ecx +5560 68/push "foo"/imm32 +5561 89/<- %ecx 4/r32/esp +5562 # var real-outputs/edi: (list var) +5563 68/push 0/imm32/next +5564 51/push-ecx/var-foo +5565 89/<- %edi 4/r32/esp +5566 # var stmt/esi: statement +5567 68/push 0/imm32/next +5568 57/push-edi/outputs +5569 68/push 0/imm32/inouts +5570 68/push "increment"/imm32/operation +5571 68/push 1/imm32/regular-statement +5572 89/<- %esi 4/r32/esp +5573 # convert +5574 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +5575 (flush _test-output-buffered-file) +5576 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5582 # check output +5583 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") +5584 # . epilogue +5585 89/<- %esp 5/r32/ebp +5586 5d/pop-to-ebp +5587 c3/return +5588 +5589 test-increment-var: +5590 # Select the right primitive between overloads. +5591 # foo <- increment +5592 # => +5593 # ff 0/subop/increment %eax # sub-optimal, but should suffice +5594 # +5595 # There's a variable on the var stack as follows: +5596 # name: 'foo' +5597 # type: int +5598 # register: 'eax' +5599 # +5600 # Primitives are the global definitions. +5601 # +5602 # There are no functions defined. +5603 # +5604 # . prologue +5605 55/push-ebp +5606 89/<- %ebp 4/r32/esp +5607 # setup +5608 (clear-stream _test-output-stream) +5609 (clear-stream $_test-output-buffered-file->buffer) +5610 # var type/ecx: (handle tree type-id) = int +5611 68/push 0/imm32/right/null +5612 68/push 1/imm32/left/int +5613 89/<- %ecx 4/r32/esp +5614 # var var-foo/ecx: var in eax +5615 68/push "eax"/imm32/register +5616 68/push 0/imm32/no-stack-offset +5617 68/push 1/imm32/block-depth +5618 51/push-ecx +5619 68/push "foo"/imm32 5620 89/<- %ecx 4/r32/esp -5621 # var var-var1/ecx : var in eax -5622 68/push "eax"/imm32/register -5623 68/push 0/imm32/no-stack-offset -5624 68/push 1/imm32/block-depth -5625 51/push-ecx -5626 68/push "var1"/imm32 -5627 89/<- %ecx 4/r32/esp -5628 # var var-var2/edx : var in ecx -5629 68/push "ecx"/imm32/register -5630 68/push 0/imm32/no-stack-offset -5631 68/push 1/imm32/block-depth -5632 ff 6/subop/push *(ecx+4) # Var-type -5633 68/push "var2"/imm32 -5634 89/<- %edx 4/r32/esp -5635 # var inouts/esi : (list var2) -5636 68/push 0/imm32/next -5637 52/push-edx/var-var2 -5638 89/<- %esi 4/r32/esp -5639 # var outputs/edi : (list var1) -5640 68/push 0/imm32/next -5641 51/push-ecx/var-var1 -5642 89/<- %edi 4/r32/esp -5643 # var stmt/esi : statement -5644 68/push 0/imm32/next -5645 57/push-edi/outputs -5646 56/push-esi/inouts -5647 68/push "add"/imm32/operation -5648 68/push 1/imm32 -5649 89/<- %esi 4/r32/esp -5650 # convert -5651 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -5652 (flush _test-output-buffered-file) -5653 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5659 # check output -5660 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") -5661 # . epilogue -5662 89/<- %esp 5/r32/ebp -5663 5d/pop-to-ebp -5664 c3/return -5665 -5666 test-add-reg-to-mem: -5667 # add-to var1 var2/reg -5668 # => -5669 # 01/add *(ebp+__) var2 -5670 # -5671 # . prologue -5672 55/push-ebp -5673 89/<- %ebp 4/r32/esp -5674 # setup -5675 (clear-stream _test-output-stream) -5676 (clear-stream $_test-output-buffered-file->buffer) -5677 # var type/ecx : (handle tree type-id) = int -5678 68/push 0/imm32/right/null -5679 68/push 1/imm32/left/int -5680 89/<- %ecx 4/r32/esp -5681 # var var-var1/ecx : var -5682 68/push 0/imm32/no-register -5683 68/push 8/imm32/stack-offset -5684 68/push 1/imm32/block-depth -5685 51/push-ecx -5686 68/push "var1"/imm32 -5687 89/<- %ecx 4/r32/esp -5688 # var var-var2/edx : var in ecx -5689 68/push "ecx"/imm32/register -5690 68/push 0/imm32/no-stack-offset -5691 68/push 1/imm32/block-depth -5692 ff 6/subop/push *(ecx+4) # Var-type -5693 68/push "var2"/imm32 -5694 89/<- %edx 4/r32/esp -5695 # var inouts/esi : (list var2) -5696 68/push 0/imm32/next -5697 52/push-edx/var-var2 -5698 89/<- %esi 4/r32/esp -5699 # var inouts = (list var1 var2) -5700 56/push-esi/next -5701 51/push-ecx/var-var1 -5702 89/<- %esi 4/r32/esp -5703 # var stmt/esi : statement -5704 68/push 0/imm32/next -5705 68/push 0/imm32/outputs -5706 56/push-esi/inouts -5707 68/push "add-to"/imm32/operation -5708 68/push 1/imm32 -5709 89/<- %esi 4/r32/esp -5710 # convert -5711 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -5712 (flush _test-output-buffered-file) -5713 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5719 # check output -5720 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") -5721 # . epilogue -5722 89/<- %esp 5/r32/ebp -5723 5d/pop-to-ebp -5724 c3/return -5725 -5726 test-add-mem-to-reg: -5727 # var1/reg <- add var2 -5728 # => -5729 # 03/add *(ebp+__) var1 -5730 # -5731 # . prologue -5732 55/push-ebp -5733 89/<- %ebp 4/r32/esp -5734 # setup -5735 (clear-stream _test-output-stream) -5736 (clear-stream $_test-output-buffered-file->buffer) -5737 # var type/ecx : (handle tree type-id) = int -5738 68/push 0/imm32/right/null -5739 68/push 1/imm32/left/int -5740 89/<- %ecx 4/r32/esp -5741 # var var-var1/ecx : var in eax -5742 68/push "eax"/imm32/register -5743 68/push 0/imm32/no-stack-offset -5744 68/push 1/imm32/block-depth -5745 51/push-ecx -5746 68/push "var1"/imm32 -5747 89/<- %ecx 4/r32/esp -5748 # var var-var2/edx : var -5749 68/push 0/imm32/no-register -5750 68/push 8/imm32/stack-offset -5751 68/push 1/imm32/block-depth -5752 ff 6/subop/push *(ecx+4) # Var-type -5753 68/push "var2"/imm32 -5754 89/<- %edx 4/r32/esp -5755 # var inouts/esi : (list var2) -5756 68/push 0/imm32/next -5757 52/push-edx/var-var2 -5758 89/<- %esi 4/r32/esp -5759 # var outputs/edi : (list var1) -5760 68/push 0/imm32/next -5761 51/push-ecx/var-var1 -5762 89/<- %edi 4/r32/esp -5763 # var stmt/esi : statement -5764 68/push 0/imm32/next -5765 57/push-edi/outputs -5766 56/push-esi/inouts -5767 68/push "add"/imm32/operation -5768 68/push 1/imm32 -5769 89/<- %esi 4/r32/esp -5770 # convert -5771 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -5772 (flush _test-output-buffered-file) -5773 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5779 # check output -5780 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") -5781 # . epilogue -5782 89/<- %esp 5/r32/ebp -5783 5d/pop-to-ebp -5784 c3/return -5785 -5786 test-add-literal-to-eax: -5787 # var1/eax <- add 0x34 -5788 # => -5789 # 05/add-to-eax 0x34/imm32 -5790 # -5791 # . prologue -5792 55/push-ebp -5793 89/<- %ebp 4/r32/esp -5794 # setup -5795 (clear-stream _test-output-stream) -5796 (clear-stream $_test-output-buffered-file->buffer) -5797 # var type/ecx : (handle tree type-id) = int -5798 68/push 0/imm32/right/null -5799 68/push 1/imm32/left/int -5800 89/<- %ecx 4/r32/esp -5801 # var var-var1/ecx : var in eax -5802 68/push "eax"/imm32/register -5803 68/push 0/imm32/no-stack-offset -5804 68/push 1/imm32/block-depth -5805 51/push-ecx -5806 68/push "var1"/imm32 -5807 89/<- %ecx 4/r32/esp -5808 # var type/edx : (handle tree type-id) = literal -5809 68/push 0/imm32/right/null -5810 68/push 0/imm32/left/literal -5811 89/<- %edx 4/r32/esp -5812 # var var-var2/edx : var literal -5813 68/push 0/imm32/no-register -5814 68/push 0/imm32/no-stack-offset -5815 68/push 1/imm32/block-depth -5816 52/push-edx -5817 68/push "0x34"/imm32 -5818 89/<- %edx 4/r32/esp -5819 # var inouts/esi : (list var2) -5820 68/push 0/imm32/next -5821 52/push-edx/var-var2 -5822 89/<- %esi 4/r32/esp -5823 # var outputs/edi : (list var1) -5824 68/push 0/imm32/next -5825 51/push-ecx/var-var1 -5826 89/<- %edi 4/r32/esp -5827 # var stmt/esi : statement -5828 68/push 0/imm32/next -5829 57/push-edi/outputs -5830 56/push-esi/inouts -5831 68/push "add"/imm32/operation -5832 68/push 1/imm32 -5833 89/<- %esi 4/r32/esp -5834 # convert -5835 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -5836 (flush _test-output-buffered-file) -5837 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5843 # check output -5844 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") -5845 # . epilogue -5846 89/<- %esp 5/r32/ebp -5847 5d/pop-to-ebp -5848 c3/return -5849 -5850 test-add-literal-to-reg: -5851 # var1/ecx <- add 0x34 -5852 # => -5853 # 81 0/subop/add %ecx 0x34/imm32 -5854 # -5855 # . prologue -5856 55/push-ebp -5857 89/<- %ebp 4/r32/esp -5858 # setup -5859 (clear-stream _test-output-stream) -5860 (clear-stream $_test-output-buffered-file->buffer) -5861 # var type/ecx : (handle tree type-id) = int -5862 68/push 0/imm32/right/null -5863 68/push 1/imm32/left/int -5864 89/<- %ecx 4/r32/esp -5865 # var var-var1/ecx : var in ecx -5866 68/push "ecx"/imm32/register -5867 68/push 0/imm32/no-stack-offset -5868 68/push 1/imm32/block-depth -5869 51/push-ecx -5870 68/push "var1"/imm32 -5871 89/<- %ecx 4/r32/esp -5872 # var type/edx : (handle tree type-id) = literal -5873 68/push 0/imm32/right/null -5874 68/push 0/imm32/left/literal -5875 89/<- %edx 4/r32/esp -5876 # var var-var2/edx : var literal -5877 68/push 0/imm32/no-register -5878 68/push 0/imm32/no-stack-offset -5879 68/push 1/imm32/block-depth -5880 52/push-edx -5881 68/push "0x34"/imm32 -5882 89/<- %edx 4/r32/esp -5883 # var inouts/esi : (list var2) -5884 68/push 0/imm32/next -5885 52/push-edx/var-var2 -5886 89/<- %esi 4/r32/esp -5887 # var outputs/edi : (list var1) -5888 68/push 0/imm32/next -5889 51/push-ecx/var-var1 -5890 89/<- %edi 4/r32/esp -5891 # var stmt/esi : statement -5892 68/push 0/imm32/next -5893 57/push-edi/outputs -5894 56/push-esi/inouts -5895 68/push "add"/imm32/operation -5896 68/push 1/imm32 -5897 89/<- %esi 4/r32/esp -5898 # convert -5899 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -5900 (flush _test-output-buffered-file) -5901 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5907 # check output -5908 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") -5909 # . epilogue -5910 89/<- %esp 5/r32/ebp -5911 5d/pop-to-ebp -5912 c3/return -5913 -5914 test-add-literal-to-mem: -5915 # add-to var1, 0x34 -5916 # => -5917 # 81 0/subop/add %eax 0x34/imm32 -5918 # -5919 # . prologue -5920 55/push-ebp -5921 89/<- %ebp 4/r32/esp -5922 # setup -5923 (clear-stream _test-output-stream) -5924 (clear-stream $_test-output-buffered-file->buffer) -5925 # var type/ecx : (handle tree type-id) = int -5926 68/push 0/imm32/right/null -5927 68/push 1/imm32/left/int -5928 89/<- %ecx 4/r32/esp -5929 # var var-var1/ecx : var -5930 68/push 0/imm32/no-register -5931 68/push 8/imm32/stack-offset -5932 68/push 1/imm32/block-depth -5933 51/push-ecx -5934 68/push "var1"/imm32 -5935 89/<- %ecx 4/r32/esp -5936 # var type/edx : (handle tree type-id) = literal -5937 68/push 0/imm32/right/null -5938 68/push 0/imm32/left/literal -5939 89/<- %edx 4/r32/esp -5940 # var var-var2/edx : var literal -5941 68/push 0/imm32/no-register -5942 68/push 0/imm32/no-stack-offset -5943 68/push 1/imm32/block-depth -5944 52/push-edx -5945 68/push "0x34"/imm32 -5946 89/<- %edx 4/r32/esp -5947 # var inouts/esi : (list var2) -5948 68/push 0/imm32/next -5949 52/push-edx/var-var2 -5950 89/<- %esi 4/r32/esp -5951 # var inouts = (list var1 inouts) -5952 56/push-esi/next -5953 51/push-ecx/var-var1 -5954 89/<- %esi 4/r32/esp -5955 # var stmt/esi : statement -5956 68/push 0/imm32/next -5957 68/push 0/imm32/outputs -5958 56/push-esi/inouts -5959 68/push "add-to"/imm32/operation -5960 68/push 1/imm32 -5961 89/<- %esi 4/r32/esp -5962 # convert -5963 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -5964 (flush _test-output-buffered-file) -5965 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -5971 # check output -5972 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") -5973 # . epilogue -5974 89/<- %esp 5/r32/ebp -5975 5d/pop-to-ebp -5976 c3/return -5977 -5978 test-emit-subx-statement-function-call: -5979 # Call a function on a variable on the stack. -5980 # f foo -5981 # => -5982 # (f2 *(ebp-8)) -5983 # (Changing the function name supports overloading in general, but here it -5984 # just serves to help disambiguate things.) -5985 # -5986 # There's a variable on the var stack as follows: -5987 # name: 'foo' -5988 # type: int -5989 # stack-offset: -8 -5990 # -5991 # There's nothing in primitives. -5992 # -5993 # There's a function with this info: -5994 # name: 'f' -5995 # inout: int/mem -5996 # value: 'f2' -5997 # -5998 # . prologue -5999 55/push-ebp -6000 89/<- %ebp 4/r32/esp -6001 # setup -6002 (clear-stream _test-output-stream) -6003 (clear-stream $_test-output-buffered-file->buffer) -6004 # var type/ecx : (handle tree type-id) = int -6005 68/push 0/imm32/right/null -6006 68/push 1/imm32/left/int -6007 89/<- %ecx 4/r32/esp -6008 # var var-foo/ecx : var -6009 68/push 0/imm32/no-register -6010 68/push -8/imm32/stack-offset -6011 68/push 0/imm32/block-depth -6012 51/push-ecx -6013 68/push "foo"/imm32 -6014 89/<- %ecx 4/r32/esp -6015 # var operands/esi : (list var) -6016 68/push 0/imm32/next -6017 51/push-ecx/var-foo -6018 89/<- %esi 4/r32/esp -6019 # var stmt/esi : statement -6020 68/push 0/imm32/next -6021 68/push 0/imm32/outputs -6022 56/push-esi/inouts -6023 68/push "f"/imm32/operation -6024 68/push 1/imm32 -6025 89/<- %esi 4/r32/esp -6026 # var functions/ebx : function -6027 68/push 0/imm32/next -6028 68/push 0/imm32/body -6029 68/push 0/imm32/outputs -6030 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call -6031 68/push "f2"/imm32/subx-name -6032 68/push "f"/imm32/name -6033 89/<- %ebx 4/r32/esp -6034 # convert -6035 (emit-subx-statement _test-output-buffered-file %esi 0 %ebx) -6036 (flush _test-output-buffered-file) -6037 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -6043 # check output -6044 (check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call") -6045 # . epilogue -6046 89/<- %esp 5/r32/ebp -6047 5d/pop-to-ebp -6048 c3/return -6049 -6050 test-emit-subx-statement-function-call-with-literal-arg: -6051 # Call a function on a literal. -6052 # f 34 -6053 # => -6054 # (f2 34) -6055 # -6056 # . prologue -6057 55/push-ebp -6058 89/<- %ebp 4/r32/esp -6059 # setup -6060 (clear-stream _test-output-stream) -6061 (clear-stream $_test-output-buffered-file->buffer) -6062 # var type/ecx : (handle tree type-id) = literal -6063 68/push 0/imm32/right/null -6064 68/push 0/imm32/left/literal -6065 89/<- %ecx 4/r32/esp -6066 # var var-foo/ecx : var literal -6067 68/push 0/imm32/no-register -6068 68/push 0/imm32/no-stack-offset -6069 68/push 0/imm32/block-depth -6070 51/push-ecx -6071 68/push "34"/imm32 -6072 89/<- %ecx 4/r32/esp -6073 # var operands/esi : (list var) -6074 68/push 0/imm32/next -6075 51/push-ecx/var-foo -6076 89/<- %esi 4/r32/esp -6077 # var stmt/esi : statement -6078 68/push 0/imm32/next -6079 68/push 0/imm32/outputs -6080 56/push-esi/inouts -6081 68/push "f"/imm32/operation -6082 68/push 1/imm32 -6083 89/<- %esi 4/r32/esp -6084 # var functions/ebx : function -6085 68/push 0/imm32/next -6086 68/push 0/imm32/body -6087 68/push 0/imm32/outputs -6088 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call -6089 68/push "f2"/imm32/subx-name -6090 68/push "f"/imm32/name -6091 89/<- %ebx 4/r32/esp -6092 # convert -6093 (emit-subx-statement _test-output-buffered-file %esi 0 %ebx) -6094 (flush _test-output-buffered-file) -6095 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -6101 # check output -6102 (check-next-stream-line-equal _test-output-stream "(f2 34)" "F - test-emit-subx-statement-function-call-with-literal-arg") -6103 # . epilogue -6104 89/<- %esp 5/r32/ebp -6105 5d/pop-to-ebp -6106 c3/return -6107 -6108 emit-subx-prologue: # out : (addr buffered-file) -6109 # . prologue -6110 55/push-ebp -6111 89/<- %ebp 4/r32/esp -6112 # -6113 (write-buffered *(ebp+8) "# . prologue\n") -6114 (write-buffered *(ebp+8) "55/push-ebp\n") -6115 (write-buffered *(ebp+8) "89/<- %ebp 4/r32/esp\n") -6116 $emit-subx-prologue:end: -6117 # . epilogue -6118 89/<- %esp 5/r32/ebp -6119 5d/pop-to-ebp -6120 c3/return -6121 -6122 emit-subx-epilogue: # out : (addr buffered-file) -6123 # . prologue -6124 55/push-ebp -6125 89/<- %ebp 4/r32/esp -6126 # -6127 (write-buffered *(ebp+8) "# . epilogue\n") -6128 (write-buffered *(ebp+8) "89/<- %esp 5/r32/ebp\n") -6129 (write-buffered *(ebp+8) "5d/pop-to-ebp\n") -6130 (write-buffered *(ebp+8) "c3/return\n") -6131 $emit-subx-epilogue:end: -6132 # . epilogue -6133 89/<- %esp 5/r32/ebp -6134 5d/pop-to-ebp -6135 c3/return +5621 # var inouts/edi: (list var) +5622 68/push 0/imm32/next +5623 51/push-ecx/var-foo +5624 89/<- %edi 4/r32/esp +5625 # var stmt/esi: statement +5626 68/push 0/imm32/next +5627 68/push 0/imm32/outputs +5628 57/push-edi/inouts +5629 68/push "increment"/imm32/operation +5630 68/push 1/imm32 +5631 89/<- %esi 4/r32/esp +5632 # convert +5633 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +5634 (flush _test-output-buffered-file) +5635 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5641 # check output +5642 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-increment-var") +5643 # . epilogue +5644 89/<- %esp 5/r32/ebp +5645 5d/pop-to-ebp +5646 c3/return +5647 +5648 test-add-reg-to-reg: +5649 # var1/reg <- add var2/reg +5650 # => +5651 # 01/add %var1 var2 +5652 # +5653 # . prologue +5654 55/push-ebp +5655 89/<- %ebp 4/r32/esp +5656 # setup +5657 (clear-stream _test-output-stream) +5658 (clear-stream $_test-output-buffered-file->buffer) +5659 # var type/ecx: (handle tree type-id) = int +5660 68/push 0/imm32/right/null +5661 68/push 1/imm32/left/int +5662 89/<- %ecx 4/r32/esp +5663 # var var-var1/ecx: var in eax +5664 68/push "eax"/imm32/register +5665 68/push 0/imm32/no-stack-offset +5666 68/push 1/imm32/block-depth +5667 51/push-ecx +5668 68/push "var1"/imm32 +5669 89/<- %ecx 4/r32/esp +5670 # var var-var2/edx: var in ecx +5671 68/push "ecx"/imm32/register +5672 68/push 0/imm32/no-stack-offset +5673 68/push 1/imm32/block-depth +5674 ff 6/subop/push *(ecx+4) # Var-type +5675 68/push "var2"/imm32 +5676 89/<- %edx 4/r32/esp +5677 # var inouts/esi: (list var2) +5678 68/push 0/imm32/next +5679 52/push-edx/var-var2 +5680 89/<- %esi 4/r32/esp +5681 # var outputs/edi: (list var1) +5682 68/push 0/imm32/next +5683 51/push-ecx/var-var1 +5684 89/<- %edi 4/r32/esp +5685 # var stmt/esi: statement +5686 68/push 0/imm32/next +5687 57/push-edi/outputs +5688 56/push-esi/inouts +5689 68/push "add"/imm32/operation +5690 68/push 1/imm32 +5691 89/<- %esi 4/r32/esp +5692 # convert +5693 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +5694 (flush _test-output-buffered-file) +5695 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5701 # check output +5702 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") +5703 # . epilogue +5704 89/<- %esp 5/r32/ebp +5705 5d/pop-to-ebp +5706 c3/return +5707 +5708 test-add-reg-to-mem: +5709 # add-to var1 var2/reg +5710 # => +5711 # 01/add *(ebp+__) var2 +5712 # +5713 # . prologue +5714 55/push-ebp +5715 89/<- %ebp 4/r32/esp +5716 # setup +5717 (clear-stream _test-output-stream) +5718 (clear-stream $_test-output-buffered-file->buffer) +5719 # var type/ecx: (handle tree type-id) = int +5720 68/push 0/imm32/right/null +5721 68/push 1/imm32/left/int +5722 89/<- %ecx 4/r32/esp +5723 # var var-var1/ecx: var +5724 68/push 0/imm32/no-register +5725 68/push 8/imm32/stack-offset +5726 68/push 1/imm32/block-depth +5727 51/push-ecx +5728 68/push "var1"/imm32 +5729 89/<- %ecx 4/r32/esp +5730 # var var-var2/edx: var in ecx +5731 68/push "ecx"/imm32/register +5732 68/push 0/imm32/no-stack-offset +5733 68/push 1/imm32/block-depth +5734 ff 6/subop/push *(ecx+4) # Var-type +5735 68/push "var2"/imm32 +5736 89/<- %edx 4/r32/esp +5737 # var inouts/esi: (list var2) +5738 68/push 0/imm32/next +5739 52/push-edx/var-var2 +5740 89/<- %esi 4/r32/esp +5741 # var inouts = (list var1 var2) +5742 56/push-esi/next +5743 51/push-ecx/var-var1 +5744 89/<- %esi 4/r32/esp +5745 # var stmt/esi: statement +5746 68/push 0/imm32/next +5747 68/push 0/imm32/outputs +5748 56/push-esi/inouts +5749 68/push "add-to"/imm32/operation +5750 68/push 1/imm32 +5751 89/<- %esi 4/r32/esp +5752 # convert +5753 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +5754 (flush _test-output-buffered-file) +5755 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5761 # check output +5762 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") +5763 # . epilogue +5764 89/<- %esp 5/r32/ebp +5765 5d/pop-to-ebp +5766 c3/return +5767 +5768 test-add-mem-to-reg: +5769 # var1/reg <- add var2 +5770 # => +5771 # 03/add *(ebp+__) var1 +5772 # +5773 # . prologue +5774 55/push-ebp +5775 89/<- %ebp 4/r32/esp +5776 # setup +5777 (clear-stream _test-output-stream) +5778 (clear-stream $_test-output-buffered-file->buffer) +5779 # var type/ecx: (handle tree type-id) = int +5780 68/push 0/imm32/right/null +5781 68/push 1/imm32/left/int +5782 89/<- %ecx 4/r32/esp +5783 # var var-var1/ecx: var in eax +5784 68/push "eax"/imm32/register +5785 68/push 0/imm32/no-stack-offset +5786 68/push 1/imm32/block-depth +5787 51/push-ecx +5788 68/push "var1"/imm32 +5789 89/<- %ecx 4/r32/esp +5790 # var var-var2/edx: var +5791 68/push 0/imm32/no-register +5792 68/push 8/imm32/stack-offset +5793 68/push 1/imm32/block-depth +5794 ff 6/subop/push *(ecx+4) # Var-type +5795 68/push "var2"/imm32 +5796 89/<- %edx 4/r32/esp +5797 # var inouts/esi: (list var2) +5798 68/push 0/imm32/next +5799 52/push-edx/var-var2 +5800 89/<- %esi 4/r32/esp +5801 # var outputs/edi: (list var1) +5802 68/push 0/imm32/next +5803 51/push-ecx/var-var1 +5804 89/<- %edi 4/r32/esp +5805 # var stmt/esi: statement +5806 68/push 0/imm32/next +5807 57/push-edi/outputs +5808 56/push-esi/inouts +5809 68/push "add"/imm32/operation +5810 68/push 1/imm32 +5811 89/<- %esi 4/r32/esp +5812 # convert +5813 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +5814 (flush _test-output-buffered-file) +5815 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5821 # check output +5822 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") +5823 # . epilogue +5824 89/<- %esp 5/r32/ebp +5825 5d/pop-to-ebp +5826 c3/return +5827 +5828 test-add-literal-to-eax: +5829 # var1/eax <- add 0x34 +5830 # => +5831 # 05/add-to-eax 0x34/imm32 +5832 # +5833 # . prologue +5834 55/push-ebp +5835 89/<- %ebp 4/r32/esp +5836 # setup +5837 (clear-stream _test-output-stream) +5838 (clear-stream $_test-output-buffered-file->buffer) +5839 # var type/ecx: (handle tree type-id) = int +5840 68/push 0/imm32/right/null +5841 68/push 1/imm32/left/int +5842 89/<- %ecx 4/r32/esp +5843 # var var-var1/ecx: var in eax +5844 68/push "eax"/imm32/register +5845 68/push 0/imm32/no-stack-offset +5846 68/push 1/imm32/block-depth +5847 51/push-ecx +5848 68/push "var1"/imm32 +5849 89/<- %ecx 4/r32/esp +5850 # var type/edx: (handle tree type-id) = literal +5851 68/push 0/imm32/right/null +5852 68/push 0/imm32/left/literal +5853 89/<- %edx 4/r32/esp +5854 # var var-var2/edx: var literal +5855 68/push 0/imm32/no-register +5856 68/push 0/imm32/no-stack-offset +5857 68/push 1/imm32/block-depth +5858 52/push-edx +5859 68/push "0x34"/imm32 +5860 89/<- %edx 4/r32/esp +5861 # var inouts/esi: (list var2) +5862 68/push 0/imm32/next +5863 52/push-edx/var-var2 +5864 89/<- %esi 4/r32/esp +5865 # var outputs/edi: (list var1) +5866 68/push 0/imm32/next +5867 51/push-ecx/var-var1 +5868 89/<- %edi 4/r32/esp +5869 # var stmt/esi: statement +5870 68/push 0/imm32/next +5871 57/push-edi/outputs +5872 56/push-esi/inouts +5873 68/push "add"/imm32/operation +5874 68/push 1/imm32 +5875 89/<- %esi 4/r32/esp +5876 # convert +5877 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +5878 (flush _test-output-buffered-file) +5879 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5885 # check output +5886 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") +5887 # . epilogue +5888 89/<- %esp 5/r32/ebp +5889 5d/pop-to-ebp +5890 c3/return +5891 +5892 test-add-literal-to-reg: +5893 # var1/ecx <- add 0x34 +5894 # => +5895 # 81 0/subop/add %ecx 0x34/imm32 +5896 # +5897 # . prologue +5898 55/push-ebp +5899 89/<- %ebp 4/r32/esp +5900 # setup +5901 (clear-stream _test-output-stream) +5902 (clear-stream $_test-output-buffered-file->buffer) +5903 # var type/ecx: (handle tree type-id) = int +5904 68/push 0/imm32/right/null +5905 68/push 1/imm32/left/int +5906 89/<- %ecx 4/r32/esp +5907 # var var-var1/ecx: var in ecx +5908 68/push "ecx"/imm32/register +5909 68/push 0/imm32/no-stack-offset +5910 68/push 1/imm32/block-depth +5911 51/push-ecx +5912 68/push "var1"/imm32 +5913 89/<- %ecx 4/r32/esp +5914 # var type/edx: (handle tree type-id) = literal +5915 68/push 0/imm32/right/null +5916 68/push 0/imm32/left/literal +5917 89/<- %edx 4/r32/esp +5918 # var var-var2/edx: var literal +5919 68/push 0/imm32/no-register +5920 68/push 0/imm32/no-stack-offset +5921 68/push 1/imm32/block-depth +5922 52/push-edx +5923 68/push "0x34"/imm32 +5924 89/<- %edx 4/r32/esp +5925 # var inouts/esi: (list var2) +5926 68/push 0/imm32/next +5927 52/push-edx/var-var2 +5928 89/<- %esi 4/r32/esp +5929 # var outputs/edi: (list var1) +5930 68/push 0/imm32/next +5931 51/push-ecx/var-var1 +5932 89/<- %edi 4/r32/esp +5933 # var stmt/esi: statement +5934 68/push 0/imm32/next +5935 57/push-edi/outputs +5936 56/push-esi/inouts +5937 68/push "add"/imm32/operation +5938 68/push 1/imm32 +5939 89/<- %esi 4/r32/esp +5940 # convert +5941 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +5942 (flush _test-output-buffered-file) +5943 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +5949 # check output +5950 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") +5951 # . epilogue +5952 89/<- %esp 5/r32/ebp +5953 5d/pop-to-ebp +5954 c3/return +5955 +5956 test-add-literal-to-mem: +5957 # add-to var1, 0x34 +5958 # => +5959 # 81 0/subop/add %eax 0x34/imm32 +5960 # +5961 # . prologue +5962 55/push-ebp +5963 89/<- %ebp 4/r32/esp +5964 # setup +5965 (clear-stream _test-output-stream) +5966 (clear-stream $_test-output-buffered-file->buffer) +5967 # var type/ecx: (handle tree type-id) = int +5968 68/push 0/imm32/right/null +5969 68/push 1/imm32/left/int +5970 89/<- %ecx 4/r32/esp +5971 # var var-var1/ecx: var +5972 68/push 0/imm32/no-register +5973 68/push 8/imm32/stack-offset +5974 68/push 1/imm32/block-depth +5975 51/push-ecx +5976 68/push "var1"/imm32 +5977 89/<- %ecx 4/r32/esp +5978 # var type/edx: (handle tree type-id) = literal +5979 68/push 0/imm32/right/null +5980 68/push 0/imm32/left/literal +5981 89/<- %edx 4/r32/esp +5982 # var var-var2/edx: var literal +5983 68/push 0/imm32/no-register +5984 68/push 0/imm32/no-stack-offset +5985 68/push 1/imm32/block-depth +5986 52/push-edx +5987 68/push "0x34"/imm32 +5988 89/<- %edx 4/r32/esp +5989 # var inouts/esi: (list var2) +5990 68/push 0/imm32/next +5991 52/push-edx/var-var2 +5992 89/<- %esi 4/r32/esp +5993 # var inouts = (list var1 inouts) +5994 56/push-esi/next +5995 51/push-ecx/var-var1 +5996 89/<- %esi 4/r32/esp +5997 # var stmt/esi: statement +5998 68/push 0/imm32/next +5999 68/push 0/imm32/outputs +6000 56/push-esi/inouts +6001 68/push "add-to"/imm32/operation +6002 68/push 1/imm32 +6003 89/<- %esi 4/r32/esp +6004 # convert +6005 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +6006 (flush _test-output-buffered-file) +6007 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +6013 # check output +6014 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") +6015 # . epilogue +6016 89/<- %esp 5/r32/ebp +6017 5d/pop-to-ebp +6018 c3/return +6019 +6020 test-emit-subx-statement-function-call: +6021 # Call a function on a variable on the stack. +6022 # f foo +6023 # => +6024 # (f2 *(ebp-8)) +6025 # (Changing the function name supports overloading in general, but here it +6026 # just serves to help disambiguate things.) +6027 # +6028 # There's a variable on the var stack as follows: +6029 # name: 'foo' +6030 # type: int +6031 # stack-offset: -8 +6032 # +6033 # There's nothing in primitives. +6034 # +6035 # There's a function with this info: +6036 # name: 'f' +6037 # inout: int/mem +6038 # value: 'f2' +6039 # +6040 # . prologue +6041 55/push-ebp +6042 89/<- %ebp 4/r32/esp +6043 # setup +6044 (clear-stream _test-output-stream) +6045 (clear-stream $_test-output-buffered-file->buffer) +6046 # var type/ecx: (handle tree type-id) = int +6047 68/push 0/imm32/right/null +6048 68/push 1/imm32/left/int +6049 89/<- %ecx 4/r32/esp +6050 # var var-foo/ecx: var +6051 68/push 0/imm32/no-register +6052 68/push -8/imm32/stack-offset +6053 68/push 0/imm32/block-depth +6054 51/push-ecx +6055 68/push "foo"/imm32 +6056 89/<- %ecx 4/r32/esp +6057 # var operands/esi: (list var) +6058 68/push 0/imm32/next +6059 51/push-ecx/var-foo +6060 89/<- %esi 4/r32/esp +6061 # var stmt/esi: statement +6062 68/push 0/imm32/next +6063 68/push 0/imm32/outputs +6064 56/push-esi/inouts +6065 68/push "f"/imm32/operation +6066 68/push 1/imm32 +6067 89/<- %esi 4/r32/esp +6068 # var functions/ebx: function +6069 68/push 0/imm32/next +6070 68/push 0/imm32/body +6071 68/push 0/imm32/outputs +6072 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call +6073 68/push "f2"/imm32/subx-name +6074 68/push "f"/imm32/name +6075 89/<- %ebx 4/r32/esp +6076 # convert +6077 (emit-subx-statement _test-output-buffered-file %esi 0 %ebx) +6078 (flush _test-output-buffered-file) +6079 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +6085 # check output +6086 (check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call") +6087 # . epilogue +6088 89/<- %esp 5/r32/ebp +6089 5d/pop-to-ebp +6090 c3/return +6091 +6092 test-emit-subx-statement-function-call-with-literal-arg: +6093 # Call a function on a literal. +6094 # f 34 +6095 # => +6096 # (f2 34) +6097 # +6098 # . prologue +6099 55/push-ebp +6100 89/<- %ebp 4/r32/esp +6101 # setup +6102 (clear-stream _test-output-stream) +6103 (clear-stream $_test-output-buffered-file->buffer) +6104 # var type/ecx: (handle tree type-id) = literal +6105 68/push 0/imm32/right/null +6106 68/push 0/imm32/left/literal +6107 89/<- %ecx 4/r32/esp +6108 # var var-foo/ecx: var literal +6109 68/push 0/imm32/no-register +6110 68/push 0/imm32/no-stack-offset +6111 68/push 0/imm32/block-depth +6112 51/push-ecx +6113 68/push "34"/imm32 +6114 89/<- %ecx 4/r32/esp +6115 # var operands/esi: (list var) +6116 68/push 0/imm32/next +6117 51/push-ecx/var-foo +6118 89/<- %esi 4/r32/esp +6119 # var stmt/esi: statement +6120 68/push 0/imm32/next +6121 68/push 0/imm32/outputs +6122 56/push-esi/inouts +6123 68/push "f"/imm32/operation +6124 68/push 1/imm32 +6125 89/<- %esi 4/r32/esp +6126 # var functions/ebx: function +6127 68/push 0/imm32/next +6128 68/push 0/imm32/body +6129 68/push 0/imm32/outputs +6130 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call +6131 68/push "f2"/imm32/subx-name +6132 68/push "f"/imm32/name +6133 89/<- %ebx 4/r32/esp +6134 # convert +6135 (emit-subx-statement _test-output-buffered-file %esi 0 %ebx) +6136 (flush _test-output-buffered-file) +6137 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +6143 # check output +6144 (check-next-stream-line-equal _test-output-stream "(f2 34)" "F - test-emit-subx-statement-function-call-with-literal-arg") +6145 # . epilogue +6146 89/<- %esp 5/r32/ebp +6147 5d/pop-to-ebp +6148 c3/return +6149 +6150 emit-subx-prologue: # out: (addr buffered-file) +6151 # . prologue +6152 55/push-ebp +6153 89/<- %ebp 4/r32/esp +6154 # +6155 (write-buffered *(ebp+8) "# . prologue\n") +6156 (write-buffered *(ebp+8) "55/push-ebp\n") +6157 (write-buffered *(ebp+8) "89/<- %ebp 4/r32/esp\n") +6158 $emit-subx-prologue:end: +6159 # . epilogue +6160 89/<- %esp 5/r32/ebp +6161 5d/pop-to-ebp +6162 c3/return +6163 +6164 emit-subx-epilogue: # out: (addr buffered-file) +6165 # . prologue +6166 55/push-ebp +6167 89/<- %ebp 4/r32/esp +6168 # +6169 (write-buffered *(ebp+8) "# . epilogue\n") +6170 (write-buffered *(ebp+8) "89/<- %esp 5/r32/ebp\n") +6171 (write-buffered *(ebp+8) "5d/pop-to-ebp\n") +6172 (write-buffered *(ebp+8) "c3/return\n") +6173 $emit-subx-epilogue:end: +6174 # . epilogue +6175 89/<- %esp 5/r32/ebp +6176 5d/pop-to-ebp +6177 c3/return -- cgit 1.4.1-2-gfad0